home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: SysTools / SysTools.zip / pmcron03.zip / cron_pm.c < prev    next >
C/C++ Source or Header  |  1996-05-09  |  140KB  |  2,760 lines

  1. /* Copyright (c) 1995 Florian Große-Coosmann, RCS section at the eof         */
  2. /* This is the PM frontend. This frontend should be preferred.               */
  3. /* Look to the function ClientWndProc at the very bottom of the module.      */
  4. /* It is the standard user interface.                                        */
  5. /* Many interesting functions belonging to this frontend are placed in the   */
  6. /* module cronmain.c, since they are shared with the cron_det.c module.      */
  7. /*                                                                           */
  8. /* FIXME: We are using Presentation Parameters (PresParam) to change and set */
  9. /*        the current font. This isn't the right way I think. In the function*/
  10. /*        CheckMetric the metric claims about a system proportional (e.g.)   */
  11. /*        but GpiQueryLogicalFont persists in a courier font. That's wrong.  */
  12. /*        Therefore, there must be an error in the GPI or the functions      */
  13. /*        uses different sources of their output (I think they do so).       */
  14. /*        Thus, we can't use logical fonts to do the three things together:  */
  15. /*        1) Figuring out the current font                                   */
  16. /*        2) Setting the new font                                            */
  17. /*        3) Allow of a font setting by an external font manager (must work) */
  18. /*        Are there any gurus which can resolve the problems? Ideas may help,*/
  19. /*        too.  Florian                                                      */
  20. #define INCL_NOCOMMON
  21. #define INCL_DOSFILEMGR
  22. #define INCL_DOSRESOURCES
  23. #define INCL_DOSMEMMGR
  24. #define INCL_DOSDEVICES
  25. #define INCL_DOSDEVIOCTL
  26. #define INCL_WINDIALOGS
  27. #define INCL_WINMESSAGEMGR
  28. #define INCL_WINWINDOWMGR
  29. #define INCL_WINERRORS
  30. #define INCL_WINSYS
  31. #define INCL_WINLISTBOXES
  32. #define INCL_WINENTRYFIELDS
  33. #define INCL_WINBUTTONS
  34. #define INCL_WINSTDFILE
  35. #define INCL_WINSTDBOOK
  36. #define INCL_WINFRAMEMGR
  37. #define INCL_WINMENUS
  38. #define INCL_WININPUT
  39. #define INCL_WINHELP
  40. #define INCL_WINCLIPBOARD
  41. #define INCL_GPILOGCOLORTABLE
  42.  
  43. #define INCL_DOSSEMAPHORES
  44.  
  45. #include <os2.h>
  46.  
  47. #include <sys/types.h>
  48. #include <sys/timeb.h>
  49. #include <dirent.h>
  50. #include <ctype.h>
  51. #include <fnmatch.h>
  52. #include <io.h>
  53. #include <string.h>
  54. #include <signal.h>
  55. #include "server.h"
  56.  
  57. static LONG  LineStart;                 /* font depenging values, see        */
  58. static LONG  FontHeight,FontBase;       /* CheckMetric()                     */
  59. static ULONG CurrentState = IDS_StatusAtStartup;   /* buffered states of     */
  60. static time_t NextStartTime = (time_t) -1;   /* the program                  */
  61. static HWND  CrontabsWindow = (HWND) 0; /* identifies the crontabs entries   */
  62.                                         /* window                            */
  63. static HWND hwndHelpInstance = (HWND) 0;  /* identifies the help window      */
  64. static COLOR Foreground = CLR_NEUTRAL,Background = CLR_BACKGROUND;
  65.                                         /* Colors                            */
  66.  
  67. /*****************************************************************************/
  68. /*  function name : PMError                                                  */
  69. /*                                                                           */
  70. /*  arguments     : string describing an error, owner of the error window    */
  71. /*                                                                           */
  72. /*  description   : prints the error string to the desktop. If the owner     */
  73. /*                  is not set (owner == (HWND) 0) either the hwndFrame or   */
  74. /*                  the HWND_DESKTOP is used (depends on the existence if    */
  75. /*                  hwndFrame)                                               */
  76. /*****************************************************************************/
  77. void PMError(const char *s,HWND owner)
  78. {
  79.    if (owner == (HWND) 0)
  80.       owner = (hwndFrame != (HWND) 0) ? hwndFrame : HWND_DESKTOP;
  81.  
  82.    WinMessageBox(HWND_DESKTOP,
  83.                  owner,
  84.                  s,
  85.                  Get(IDS_Title),
  86.                  0,
  87.                  MB_OK | MB_ICONHAND | MB_APPLMODAL);
  88. }
  89.  
  90. /*****************************************************************************/
  91. /*  function name : PMFatalError                                             */
  92. /*                                                                           */
  93. /*  arguments     : see Error.                                               */
  94. /*                                                                           */
  95. /*  description   : see Error but terminates the program.                    */
  96. /*****************************************************************************/
  97. void PMFatalError(const char *s,HWND owner)
  98. {
  99.    Error(s,owner);
  100.    WinDestroyMsgQueue(hmq);             /* clean up used resources           */
  101.    WinTerminate(hab);
  102.    exit(3);
  103. }
  104.  
  105. /*****************************************************************************/
  106. /*  function name : WinError                                                 */
  107. /*                                                                           */
  108. /*  arguments     : owner of the error window                                */
  109. /*                                                                           */
  110. /*  description   : figures out the description of the latest error that     */
  111. /*                  relates to the GPI and prints it to the desktop.         */
  112. /*                  If the owner is not set (owner == (HWND) 0) either       */
  113. /*                  the hwndFrame or the HWND_DESKTOP is used (depends       */
  114. /*                  on the existence if hwndFrame)                           */
  115. /*****************************************************************************/
  116. void WinError(HWND owner)
  117. {
  118.    PERRINFO perr;
  119.    static PCSZ pcsz = "unknown error";
  120.    PULONG pul;
  121.  
  122.    if (owner == (HWND) 0)
  123.       owner = (hwndFrame != (HWND) 0) ? hwndFrame : HWND_DESKTOP;
  124.    if ((perr = WinGetErrorInfo(hab)) != NULL) {
  125.       pul = (PULONG) ((PSZ) perr + perr->offaoffszMsg);  /* only get the 1st */
  126.       pcsz = (PCSZ) perr + *pul;        /* description, I've never seen more */
  127.    }
  128.  
  129.    WinMessageBox(HWND_DESKTOP,
  130.                  owner,
  131.                  pcsz,
  132.                  Get(IDS_Title),
  133.                  0,
  134.                  MB_OK | MB_ICONHAND | MB_APPLMODAL);
  135.    if (perr != NULL)
  136.       WinFreeErrorInfo(perr);
  137. }
  138.  
  139. /*****************************************************************************/
  140. /*  function name : FatalWinError                                            */
  141. /*                                                                           */
  142. /*  arguments     : see WinError.                                            */
  143. /*                                                                           */
  144. /*  description   : see WinError but terminates the program.                 */
  145. /*****************************************************************************/
  146. void FatalWinError(HWND owner)
  147. {
  148.    WinError(owner);
  149.    WinDestroyMsgQueue (hmq);
  150.    WinTerminate (hab);
  151.    exit(3);
  152. }
  153.  
  154. #ifdef DEBUG
  155. void DumpMessage(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
  156. {
  157.    static struct { USHORT number; char *name; } msgs[] = {
  158.       {0x0000, "WM_NULL"                      },
  159.       {0x0001, "WM_CREATE"                    },
  160.       {0x0002, "WM_DESTROY"                   },
  161.       {0x0004, "WM_ENABLE"                    },
  162.       {0x0005, "WM_SHOW"                      },
  163.       {0x0006, "WM_MOVE"                      },
  164.       {0x0007, "WM_SIZE"                      },
  165.       {0x0008, "WM_ADJUSTWINDOWPOS"           },
  166.       {0x0009, "WM_CALCVALIDRECTS"            },
  167.       {0x000a, "WM_SETWINDOWPARAMS"           },
  168.       {0x000b, "WM_QUERYWINDOWPARAMS"         },
  169.       {0x000c, "WM_HITTEST"                   },
  170.       {0x000d, "WM_ACTIVATE"                  },
  171.       {0x000f, "WM_SETFOCUS"                  },
  172.       {0x0010, "WM_SETSELECTION"              },
  173.       {0x0011, "WM_PPAINT"                    },
  174.       {0x0012, "WM_PSETFOCUS"                 },
  175.       {0x0013, "WM_PSYSCOLORCHANGE"           },
  176.       {0x0014, "WM_PSIZE"                     },
  177.       {0x0015, "WM_PACTIVATE"                 },
  178.       {0x0016, "WM_PCONTROL"                  },
  179.       {0x0020, "WM_COMMAND"                   },
  180.       {0x0021, "WM_SYSCOMMAND"                },
  181.       {0x0022, "WM_HELP"                      },
  182.       {0x0023, "WM_PAINT"                     },
  183.       {0x0024, "WM_TIMER"                     },
  184.       {0x0025, "WM_SEM1"                      },
  185.       {0x0026, "WM_SEM2"                      },
  186.       {0x0027, "WM_SEM3"                      },
  187.       {0x0028, "WM_SEM4"                      },
  188.       {0x0029, "WM_CLOSE"                     },
  189.       {0x002a, "WM_QUIT"                      },
  190.       {0x002b, "WM_SYSCOLORCHANGE"            },
  191.       {0x002d, "WM_SYSVALUECHANGED"           },
  192.       {0x002e, "WM_APPTERMINATENOTIFY"        },
  193.       {0x002f, "WM_PRESPARAMCHANGED"          },
  194.       {0x0030, "WM_CONTROL"                   },
  195.       {0x0031, "WM_VSCROLL"                   },
  196.       {0x0032, "WM_HSCROLL"                   },
  197.       {0x0033, "WM_INITMENU"                  },
  198.       {0x0034, "WM_MENUSELECT"                },
  199.       {0x0035, "WM_MENUEND"                   },
  200.       {0x0036, "WM_DRAWITEM"                  },
  201.       {0x0037, "WM_MEASUREITEM"               },
  202.       {0x0038, "WM_CONTROLPOINTER"            },
  203.       {0x003a, "WM_QUERYDLGCODE"              },
  204.       {0x003b, "WM_INITDLG"                   },
  205.       {0x003c, "WM_SUBSTITUTESTRING"          },
  206.       {0x003d, "WM_MATCHMNEMONIC"             },
  207.       {0x003e, "WM_SAVEAPPLICATION"           },
  208.       {0x0040, "WM_FLASHWINDOW"               },
  209.       {0x0041, "WM_FORMATFRAME"               },
  210.       {0x0042, "WM_UPDATEFRAME"               },
  211.       {0x0043, "WM_FOCUSCHANGE"               },
  212.       {0x0044, "WM_SETBORDERSIZE"             },
  213.       {0x0045, "WM_TRACKFRAME"                },
  214.       {0x0046, "WM_MINMAXFRAME"               },
  215.       {0x0047, "WM_SETICON"                   },
  216.       {0x0048, "WM_QUERYICON"                 },
  217.       {0x0049, "WM_SETACCELTABLE"             },
  218.       {0x004a, "WM_QUERYACCELTABLE"           },
  219.       {0x004b, "WM_TRANSLATEACCEL"            },
  220.       {0x004c, "WM_QUERYTRACKINFO"            },
  221.       {0x004d, "WM_QUERYBORDERSIZE"           },
  222.       {0x004e, "WM_NEXTMENU"                  },
  223.       {0x004f, "WM_ERASEBACKGROUND"           },
  224.       {0x0050, "WM_QUERYFRAMEINFO"            },
  225.       {0x0051, "WM_QUERYFOCUSCHAIN"           },
  226.       {0x0052, "WM_OWNERPOSCHANGE"            },
  227.       {0x0053, "WM_CALCFRAMERECT"             },
  228.       {0x0055, "WM_WINDOWPOSCHANGED"          },
  229.       {0x0056, "WM_ADJUSTFRAMEPOS"            },
  230.       {0x0059, "WM_QUERYFRAMECTLCOUNT"        },
  231.       {0x005B, "WM_QUERYHELPINFO"             },
  232.       {0x005C, "WM_SETHELPINFO"               },
  233.       {0x005D, "WM_ERROR"                     },
  234.       {0x005E, "WM_REALIZEPALETTE"            },
  235.       {0x0060, "WM_RENDERFMT"                 },
  236.       {0x0061, "WM_RENDERALLFMTS"             },
  237.       {0x0062, "WM_DESTROYCLIPBOARD"          },
  238.       {0x0063, "WM_PAINTCLIPBOARD"            },
  239.       {0x0064, "WM_SIZECLIPBOARD"             },
  240.       {0x0065, "WM_HSCROLLCLIPBOARD"          },
  241.       {0x0066, "WM_VSCROLLCLIPBOARD"          },
  242.       {0x0067, "WM_DRAWCLIPBOARD"             },
  243.       {0x0070, "WM_MOUSEMOVE"                 },
  244.       {0x0071, "WM_BUTTON1DOWN"               },
  245.       {0x0072, "WM_BUTTON1UP"                 },
  246.       {0x0073, "WM_BUTTON1DBLCLK"             },
  247.       {0x0074, "WM_BUTTON2DOWN"               },
  248.       {0x0075, "WM_BUTTON2UP"                 },
  249.       {0x0076, "WM_BUTTON2DBLCLK"             },
  250.       {0x0077, "WM_BUTTON3DOWN"               },
  251.       {0x0078, "WM_BUTTON3UP"                 },
  252.       {0x0079, "WM_BUTTON3DBLCLK"             },
  253.       {0x007a, "WM_CHAR"                      },
  254.       {0x007b, "WM_VIOCHAR"                   },
  255.       {0x007c, "WM_JOURNALNOTIFY"             },
  256.       {0x007D, "WM_MOUSEMAP"                  },
  257.       {0x00A0, "WM_DDE_INITIATE"              },
  258.       {0x00A1, "WM_DDE_REQUEST"               },
  259.       {0x00A2, "WM_DDE_ACK"                   },
  260.       {0x00A3, "WM_DDE_DATA"                  },
  261.       {0x00A4, "WM_DDE_ADVISE"                },
  262.       {0x00A5, "WM_DDE_UNADVISE"              },
  263.       {0x00A6, "WM_DDE_POKE"                  },
  264.       {0x00A7, "WM_DDE_EXECUTE"               },
  265.       {0x00A8, "WM_DDE_TERMINATE"             },
  266.       {0x00A9, "WM_DDE_INITIATEACK"           },
  267.       {0x00AF, "WM_DDE_LAST"                  },
  268.       {0x00b0, "WM_DBCSFIRST"                 },
  269.       {0x00cf, "WM_DBCSLAST"                  },
  270.       {0x0100, "SM_SETHANDLE"                 },
  271.       {0x0101, "SM_QUERYHANDLE"               },
  272.       {0x0120, "BM_CLICK"                     },
  273.       {0x0121, "BM_QUERYCHECKINDEX"           },
  274.       {0x0122, "BM_QUERYHILITE"               },
  275.       {0x0123, "BM_SETHILITE"                 },
  276.       {0x0124, "BM_QUERYCHECK"                },
  277.       {0x0125, "BM_SETCHECK"                  },
  278.       {0x0126, "BM_SETDEFAULT"                },
  279.       {0x0140, "EM_QUERYCHANGED"              },
  280.       {0x0141, "EM_QUERYSEL"                  },
  281.       {0x0142, "EM_SETSEL"                    },
  282.       {0x0143, "EM_SETTEXTLIMIT"              },
  283.       {0x0144, "EM_CUT"                       },
  284.       {0x0145, "EM_COPY"                      },
  285.       {0x0146, "EM_CLEAR"                     },
  286.       {0x0147, "EM_PASTE"                     },
  287.       {0x0148, "EM_QUERYFIRSTCHAR"            },
  288.       {0x0149, "EM_SETFIRSTCHAR"              },
  289.       {0x014a, "EM_QUERYREADONLY"             },
  290.       {0x014b, "EM_SETREADONLY"               },
  291.       {0x014c, "EM_SETINSERTMODE"             },
  292.       {0x0160, "LM_QUERYITEMCOUNT"            },
  293.       {0x0161, "LM_INSERTITEM"                },
  294.       {0x0162, "LM_SETTOPINDEX"               },
  295.       {0x0163, "LM_DELETEITEM"                },
  296.       {0x0164, "LM_SELECTITEM"                },
  297.       {0x0165, "LM_QUERYSELECTION"            },
  298.       {0x0166, "LM_SETITEMTEXT"               },
  299.       {0x0167, "LM_QUERYITEMTEXTLENGTH"       },
  300.       {0x0168, "LM_QUERYITEMTEXT"             },
  301.       {0x0169, "LM_SETITEMHANDLE"             },
  302.       {0x016a, "LM_QUERYITEMHANDLE"           },
  303.       {0x016b, "LM_SEARCHSTRING"              },
  304.       {0x016c, "LM_SETITEMHEIGHT"             },
  305.       {0x016d, "LM_QUERYTOPINDEX"             },
  306.       {0x016e, "LM_DELETEALL"                 },
  307.       {0x0170, "CBM_SHOWLIST"                 },
  308.       {0x0171, "CBM_HILITE"                   },
  309.       {0x0172, "CBM_ISLISTSHOWING"            },
  310.       {0x0180, "MM_INSERTITEM"                },
  311.       {0x0181, "MM_DELETEITEM"                },
  312.       {0x0182, "MM_QUERYITEM"                 },
  313.       {0x0183, "MM_SETITEM"                   },
  314.       {0x0184, "MM_QUERYITEMCOUNT"            },
  315.       {0x0185, "MM_STARTMENUMODE"             },
  316.       {0x0186, "MM_ENDMENUMODE"               },
  317.       {0x0188, "MM_REMOVEITEM"                },
  318.       {0x0189, "MM_SELECTITEM"                },
  319.       {0x018a, "MM_QUERYSELITEMID"            },
  320.       {0x018b, "MM_QUERYITEMTEXT"             },
  321.       {0x018c, "MM_QUERYITEMTEXTLENGTH"       },
  322.       {0x018d, "MM_SETITEMHANDLE"             },
  323.       {0x018e, "MM_SETITEMTEXT"               },
  324.       {0x018f, "MM_ITEMPOSITIONFROMID"        },
  325.       {0x0190, "MM_ITEMIDFROMPOSITION"        },
  326.       {0x0191, "MM_QUERYITEMATTR"             },
  327.       {0x0192, "MM_SETITEMATTR"               },
  328.       {0x0193, "MM_ISITEMVALID"               },
  329.       {0x0194, "MM_QUERYITEMRECT"             },
  330.       {0x01a0, "SBM_SETSCROLLBAR"             },
  331.       {0x01a1, "SBM_SETPOS"                   },
  332.       {0x01a2, "SBM_QUERYPOS"                 },
  333.       {0x01a3, "SBM_QUERYRANGE"               },
  334.       {0x01a6, "SBM_SETTHUMBSIZE"             },
  335.       {0x01b0, "MLM_SETTEXTLIMIT"             },
  336.       {0x01b1, "MLM_QUERYTEXTLIMIT"           },
  337.       {0x01b2, "MLM_SETFORMATRECT"            },
  338.       {0x01b3, "MLM_QUERYFORMATRECT"          },
  339.       {0x01b4, "MLM_SETWRAP"                  },
  340.       {0x01b5, "MLM_QUERYWRAP"                },
  341.       {0x01b6, "MLM_SETTABSTOP"               },
  342.       {0x01b7, "MLM_QUERYTABSTOP"             },
  343.       {0x01b8, "MLM_SETREADONLY"              },
  344.       {0x01b9, "MLM_QUERYREADONLY"            },
  345.       {0x01ba, "MLM_QUERYCHANGED"             },
  346.       {0x01bb, "MLM_SETCHANGED"               },
  347.       {0x01bc, "MLM_QUERYLINECOUNT"           },
  348.       {0x01bd, "MLM_CHARFROMLINE"             },
  349.       {0x01be, "MLM_LINEFROMCHAR"             },
  350.       {0x01bf, "MLM_QUERYLINELENGTH"          },
  351.       {0x01c0, "MLM_QUERYTEXTLENGTH"          },
  352.       {0x01c1, "MLM_FORMAT"                   },
  353.       {0x01c2, "MLM_SETIMPORTEXPORT"          },
  354.       {0x01c3, "MLM_IMPORT"                   },
  355.       {0x01c4, "MLM_EXPORT"                   },
  356.       {0x01c6, "MLM_DELETE"                   },
  357.       {0x01c7, "MLM_QUERYFORMATLINELENGTH"    },
  358.       {0x01c8, "MLM_QUERYFORMATTEXTLENGTH"    },
  359.       {0x01c9, "MLM_INSERT"                   },
  360.       {0x01ca, "MLM_SETSEL"                   },
  361.       {0x01cb, "MLM_QUERYSEL"                 },
  362.       {0x01cc, "MLM_QUERYSELTEXT"             },
  363.       {0x01cd, "MLM_QUERYUNDO"                },
  364.       {0x01ce, "MLM_UNDO"                     },
  365.       {0x01cf, "MLM_RESETUNDO"                },
  366.       {0x01d0, "MLM_QUERYFONT"                },
  367.       {0x01d1, "MLM_SETFONT"                  },
  368.       {0x01d2, "MLM_SETTEXTCOLOR"             },
  369.       {0x01d3, "MLM_QUERYTEXTCOLOR"           },
  370.       {0x01d4, "MLM_SETBACKCOLOR"             },
  371.       {0x01d5, "MLM_QUERYBACKCOLOR"           },
  372.       {0x01d6, "MLM_QUERYFIRSTCHAR"           },
  373.       {0x01d7, "MLM_SETFIRSTCHAR"             },
  374.       {0x01d8, "MLM_CUT"                      },
  375.       {0x01d9, "MLM_COPY"                     },
  376.       {0x01da, "MLM_PASTE"                    },
  377.       {0x01db, "MLM_CLEAR"                    },
  378.       {0x01dc, "MLM_ENABLEREFRESH"            },
  379.       {0x01dd, "MLM_DISABLEREFRESH"           },
  380.       {0x01de, "MLM_SEARCH"                   },
  381.       {0x01df, "MLM_QUERYIMPORTEXPORT"        },
  382.       {0x01e3, "TBM_SETHILITE"                },
  383.       {0x01e4, "TBM_QUERYHILITE"              },
  384.       {0x0200, "SPBM_OVERRIDESETLIMITS"       },
  385.       {0x0201, "SPBM_QUERYLIMITS"             },
  386.       {0x0202, "SPBM_SETTEXTLIMIT"            },
  387.       {0x0203, "SPBM_SPINUP"                  },
  388.       {0x0204, "SPBM_SPINDOWN"                },
  389.       {0x0205, "SPBM_QUERYVALUE"              },
  390.       {0x0206, "SPBM_SETARRAY"                },
  391.       {0x0207, "SPBM_SETLIMITS"               },
  392.       {0x0208, "SPBM_SETCURRENTVALUE"         },
  393.       {0x0209, "SPBM_SETMASTER"               },
  394.       {0x0220, "HM_MSG_BASE"                  },
  395.       {0x0221, "HM_DISMISS_WINDOW"            },
  396.       {0x0222, "HM_DISPLAY_HELP"              },
  397.       {0x0223, "HM_GENERAL_HELP(EXT_HELP)"    },
  398.       {0x0224, "HM_SET_ACTIVE_WINDOW"         },
  399.       {0x0225, "HM_LOAD_HELP_TABLE"           },
  400.       {0x0226, "HM_CREATE_HELP_TABLE"         },
  401.       {0x0227, "HM_SET_HELP_WINDOW_TITLE"     },
  402.       {0x0228, "HM_SET_SHOW_PANEL_ID"         },
  403.       {0x0229, "HM_REPLACE_USING_HELP"        },
  404.       {0x022a, "HM_HELP_INDEX"                },
  405.       {0x022b, "HM_HELP_CONTENTS"             },
  406.       {0x022c, "HM_KEYS_HELP"                 },
  407.       {0x022d, "HM_SET_HELP_LIBRARY_NAME"     },
  408.       {0x022e, "HM_ERROR"                     },
  409.       {0x022f, "HM_HELPSUBITEM_NOT_FOUND"     },
  410.       {0x0230, "HM_QUERY_KEYS_HELP"           },
  411.       {0x0231, "HM_TUTORIAL"                  },
  412.       {0x0232, "HM_EXT_HELP_UNDEFINED"        },
  413.       {0x0233, "HM_ACTIONBAR_COMMAND"         },
  414.       {0x0234, "HM_INFORM"                    },
  415.       {0x0238, "HM_SET_OBJCOM_WINDOW"         },
  416.       {0x0239, "HM_UPDATE_OBJCOM_WINDOW_CHAIN"},
  417.       {0x023a, "HM_QUERY_DDF_DATA"            },
  418.       {0x023b, "HM_INVALIDATE_DDF_DATA"       },
  419.       {0x023c, "HM_QUERY"                     },
  420.       {0x023d, "HM_SET_COVERPAGE_SIZE"        },
  421.       {0x0242, "HM_NOTIFY"                    },
  422.       {0x0243, "HM_SET_USERDATA"              },
  423.       {0x0244, "HM_CONTROL"                   },
  424.       {0x0310, "WM_DRAGFIRST"                 },
  425.       {0x031f, "DM_DISCARDOBJECT"             },
  426.       {0x0320, "DM_PRINTOBJECT"               },
  427.       {0x0321, "DM_DRAGOVERNOTIFY"            },
  428.       {0x0322, "DM_RENDERFILE"                },
  429.       {0x0323, "DM_FILERENDERED"              },
  430.       {0x0324, "DM_DRAGERROR"                 },
  431.       {0x0325, "DM_EMPHASIZETARGET"           },
  432.       {0x0326, "DM_DRAGFILECOMPLETE"          },
  433.       {0x0327, "DM_RENDERPREPARE"             },
  434.       {0x0328, "DM_RENDERCOMPLETE"            },
  435.       {0x0329, "DM_RENDER"                    },
  436.       {0x032a, "DM_PRINT"                     },
  437.       {0x032b, "DM_ENDCONVERSATION"           },
  438.       {0x032c, "DM_DROPHELP"                  },
  439.       {0x032d, "DM_DRAGLEAVE"                 },
  440.       {0x032e, "DM_DRAGOVER"                  },
  441.       {0x032f, "DM_DROP"                      },
  442.       {0x0330, "CM_ALLOCDETAILFIELDINFO"      },
  443.       {0x0331, "CM_ALLOCRECORD"               },
  444.       {0x0332, "CM_ARRANGE"                   },
  445.       {0x0333, "CM_ERASERECORD"               },
  446.       {0x0334, "CM_FILTER"                    },
  447.       {0x0335, "CM_FREEDETAILFIELDINFO"       },
  448.       {0x0336, "CM_FREERECORD"                },
  449.       {0x0337, "CM_HORZSCROLLSPLITWINDOW"     },
  450.       {0x0338, "CM_INSERTDETAILFIELDINFO"     },
  451.       {0x0339, "CM_INSERTRECORD"              },
  452.       {0x033a, "CM_INVALIDATEDETAILFIELDINFO" },
  453.       {0x033b, "CM_INVALIDATERECORD"          },
  454.       {0x033c, "CM_PAINTBACKGROUND"           },
  455.       {0x033d, "CM_QUERYCNRINFO"              },
  456.       {0x033e, "CM_QUERYDETAILFIELDINFO"      },
  457.       {0x033f, "CM_QUERYDRAGIMAGE"            },
  458.       {0x0340, "CM_QUERYRECORD"               },
  459.       {0x0341, "CM_QUERYRECORDEMPHASIS"       },
  460.       {0x0342, "CM_QUERYRECORDFROMRECT"       },
  461.       {0x0343, "CM_QUERYRECORDRECT"           },
  462.       {0x0344, "CM_QUERYVIEWPORTRECT"         },
  463.       {0x0345, "CM_REMOVEDETAILFIELDINFO"     },
  464.       {0x0346, "CM_REMOVERECORD"              },
  465.       {0x0347, "CM_SCROLLWINDOW"              },
  466.       {0x0348, "CM_SEARCHSTRING"              },
  467.       {0x0349, "CM_SETCNRINFO"                },
  468.       {0x034a, "CM_SETRECORDEMPHASIS"         },
  469.       {0x034b, "CM_SORTRECORD"                },
  470.       {0x034c, "CM_OPENEDIT"                  },
  471.       {0x034d, "CM_CLOSEEDIT"                 },
  472.       {0x034e, "CM_COLLAPSETREE"              },
  473.       {0x034f, "CM_EXPANDTREE"                },
  474.       {0x0350, "CM_QUERYRECORDINFO"           },
  475.       {0x0353, "BKM_CALCPAGERECT"             },
  476.       {0x0354, "BKM_DELETEPAGE"               },
  477.       {0x0355, "BKM_INSERTPAGE"               },
  478.       {0x0356, "BKM_INVALIDATETABS"           },
  479.       {0x0357, "BKM_TURNTOPAGE"               },
  480.       {0x0358, "BKM_QUERYPAGECOUNT"           },
  481.       {0x0359, "BKM_QUERYPAGEID"              },
  482.       {0x035a, "BKM_QUERYPAGEDATA"            },
  483.       {0x035b, "BKM_QUERYPAGEWINDOWHWND"      },
  484.       {0x035c, "BKM_QUERYTABBITMAP"           },
  485.       {0x035d, "BKM_QUERYTABTEXT"             },
  486.       {0x035e, "BKM_SETDIMENSIONS"            },
  487.       {0x035f, "BKM_SETPAGEDATA"              },
  488.       {0x0360, "BKM_SETPAGEWINDOWHWND"        },
  489.       {0x0361, "BKM_SETSTATUSLINETEXT"        },
  490.       {0x0362, "BKM_SETTABBITMAP"             },
  491.       {0x0363, "BKM_SETTABTEXT"               },
  492.       {0x0364, "BKM_SETNOTEBOOKCOLORS"        },
  493.       {0x0365, "BKM_QUERYPAGESTYLE"           },
  494.       {0x0366, "BKM_QUERYSTATUSLINETEXT"      },
  495.       {0x0369, "SLM_ADDDETENT"                },
  496.       {0x036a, "SLM_QUERYDETENTPOS"           },
  497.       {0x036b, "SLM_QUERYSCALETEXT"           },
  498.       {0x036c, "SLM_QUERYSLIDERINFO"          },
  499.       {0x036d, "SLM_QUERYTICKPOS"             },
  500.       {0x036e, "SLM_QUERYTICKSIZE"            },
  501.       {0x036f, "SLM_REMOVEDETENT"             },
  502.       {0x0370, "SLM_SETSCALETEXT"             },
  503.       {0x0371, "SLM_SETSLIDERINFO"            },
  504.       {0x0372, "SLM_SETTICKSIZE"              },
  505.       {0x0375, "VM_QUERYITEM"                 },
  506.       {0x0376, "VM_QUERYITEMATTR"             },
  507.       {0x0377, "VM_QUERYMETRICS"              },
  508.       {0x0378, "VM_QUERYSELECTEDITEM"         },
  509.       {0x0379, "VM_SELECTITEM"                },
  510.       {0x037a, "VM_SETITEM"                   },
  511.       {0x037b, "VM_SETITEMATTR"               },
  512.       {0x037c, "VM_SETMETRICS"                },
  513.       {0x0410, "WM_CHORD"                     },
  514.       {0x0411, "WM_BUTTON1MOTIONSTART"        },
  515.       {0x0412, "WM_BUTTON1MOTIONEND"          },
  516.       {0x0413, "WM_BUTTON1CLICK"              },
  517.       {0x0414, "WM_BUTTON2MOTIONSTART"        },
  518.       {0x0415, "WM_BUTTON2MOTIONEND"          },
  519.       {0x0416, "WM_BUTTON2CLICK"              },
  520.       {0x0417, "WM_BUTTON3MOTIONSTART"        },
  521.       {0x0418, "WM_BUTTON3MOTIONEND"          },
  522.       {0x0419, "WM_BUTTON3CLICK"              },
  523.       {0x0420, "WM_BEGINDRAG"                 },
  524.       {0x0421, "WM_ENDDRAG"                   },
  525.       {0x0422, "WM_SINGLESELECT"              },
  526.       {0x0423, "WM_OPEN"                      },
  527.       {0x0424, "WM_CONTEXTMENU"               },
  528.       {0x0425, "WM_CONTEXTHELP"               },
  529.       {0x0426, "WM_TEXTEDIT"                  },
  530.       {0x0427, "WM_BEGINSELECT"               },
  531.       {0x0428, "WM_ENDSELECT"                 },
  532.       {0x0431, "MM_QUERYDEFAULTITEMID"        },
  533.       {0x0432, "MM_SETDEFAULTITEMID"          },
  534.       {0x04C0, "WM_PENFIRST"                  },
  535.       {0x04FF, "WM_PENLAST"                   },
  536.       {0x0500, "WM_MMPMFIRST"                 },
  537.       {0x05FF, "WM_MMPMLAST"                  },
  538.       {0x0F00, "WM_HELPBASE"                  },
  539.       {0x0FFF, "WM_HELPTOP"                   },
  540.       {0x1000, "WM_USER"                      },
  541.       {0x1028, "FDM_FILTER"                   },
  542.       {0x1029, "FDM_VALIDATE"                 },
  543.       {0x102A, "FDM_ERROR"                    },
  544.       {0x1032, "FNTM_FACENAMECHANGED"         },
  545.       {0x1033, "FNTM_POINTSIZECHANGED"        },
  546.       {0x1034, "FNTM_STYLECHANGED"            },
  547.       {0x1035, "FNTM_COLORCHANGED"            },
  548.       {0x1036, "FNTM_UPDATEPREVIEW"           },
  549.       {0x1037, "FNTM_FILTERLIST"              },
  550.       {0xFFFF, "last possible message"        }
  551.    };
  552.    char *name,buf[10];
  553.    struct timeb t;
  554.    static int cnt = 0;
  555.    int first = 0,last = (sizeof(msgs) / sizeof(msgs[0])) - 1,mid;
  556.                                         /* we use int to detect underruns    */
  557.    while (last - first > 0) {
  558.       mid = first + (last - first) / 2;
  559.       if ((USHORT) msg == msgs[mid].number) {
  560.          last = first = mid;
  561.          break;
  562.       } else if ((USHORT) msg < msgs[mid].number)
  563.          last = mid - 1;
  564.       else
  565.          first = mid + 1;
  566.    }
  567.    if ((last != first) || ((USHORT) msg != msgs[first].number))
  568.       name = "unknown message";
  569.    else
  570.       name = msgs[first].name;
  571.    if (cnt == 0)
  572.       Dprintf("    Time    |  Window  | Msg  |  Param1  |  Param2  | Msg-Name\n");
  573.    ftime(&t);
  574.    strftime(buf,9,"%X",localtime(&t.time));
  575.    Dprintf("%s,%02d | %08lX | %04lX | %08lX | %08lX | %s\n",
  576.            buf,t.millitm / 10,
  577.            (ULONG) hwnd,msg,(ULONG) mp1,(ULONG) mp2,name);
  578.    if (cnt == 15)
  579.       cnt = 0;
  580.      else
  581.       cnt++;
  582. }
  583. #endif
  584.  
  585. /*****************************************************************************/
  586. /*  function name : SetPosOfWindow                                           */
  587. /*                                                                           */
  588. /*  arguments     : handle of the frame window                               */
  589. /*                                                                           */
  590. /*  description   : figures out the size and the position of the frame and   */
  591. /*                  writes the position to the getenv(USER_INI) file.        */
  592. /*****************************************************************************/
  593. void SetPosOfWindow(HWND framewin)
  594. {
  595.    SWP swp;
  596.    ULONG LocPrgFlags;
  597.    if (WinQueryWindowPos(framewin,&swp)) {
  598.       if ((swp.fl & (SWP_MINIMIZE | SWP_MAXIMIZE)) == 0) {
  599.          FrameRect.xLeft   = swp.x;
  600.          FrameRect.yBottom = swp.y;
  601.          FrameRect.xRight  = swp.cx;
  602.          FrameRect.yTop    = swp.cy;
  603.          LocPrgFlags = 0;
  604.       } else {                          /* if we are minimized or maximized  */
  605.                                         /* we can't use the swp. Instead, we */
  606.                                         /* ask the window for its restore    */
  607.                                         /* values.                           */
  608.          FrameRect.xLeft   = WinQueryWindowUShort(framewin,QWS_XRESTORE);
  609.          FrameRect.yBottom = WinQueryWindowUShort(framewin,QWS_YRESTORE);
  610.          FrameRect.xRight  = WinQueryWindowUShort(framewin,QWS_CXRESTORE);
  611.          FrameRect.yTop    = WinQueryWindowUShort(framewin,QWS_CYRESTORE);
  612.          if (swp.fl & SWP_MINIMIZE)
  613.             LocPrgFlags = PRG_START_MINIMIZED;
  614.          else
  615.             LocPrgFlags = PRG_START_MAXIMIZED;
  616.       }
  617.                                         /* We don't want unneeded writes,    */
  618.                                         /* thus we compare with the old pos. */
  619.       if (memcmp(&FrameRect,&SaveFrameRect,sizeof(FrameRect)) != 0)
  620.          ReWritePrfFlags |= REWRITE_SCREEN;
  621.       if ((ProgramFlags & (PRG_START_MINIMIZED | PRG_START_MAXIMIZED)) !=
  622.                                                                  LocPrgFlags) {
  623.          ProgramFlags &= (ULONG) ~(PRG_START_MINIMIZED | PRG_START_MAXIMIZED);
  624.          ProgramFlags |= LocPrgFlags;
  625.          ReWritePrfFlags |= REWRITE_FLAGS;
  626.       }
  627.    }
  628.    if (ReWritePrf())
  629.       SaveFrameRect = FrameRect;
  630. }
  631.  
  632. /*****************************************************************************/
  633. /*  function name : CheckMetric                                              */
  634. /*                                                                           */
  635. /*  arguments     : handle of a presentation space                           */
  636. /*                                                                           */
  637. /*  description   : set the global variables used to write strings to the    */
  638. /*                  client window. These vars depend on the used font.       */
  639. /*                                                                           */
  640. /*  note          : should be called very time the default font changes      */
  641. /*****************************************************************************/
  642. static void CheckMetric(HPS hps)
  643. {
  644.    FONTMETRICS metric;
  645.    ULONG Pointsize,proof;
  646.    static ULONG ScreenYResolution = 0;
  647.    char LocFontname[sizeof(Fontname)];
  648.  
  649.    if (!GpiQueryFontMetrics(hps,
  650.                             sizeof(metric),
  651.                             &metric))
  652.       FatalWinError((HWND) 0);
  653.  
  654.                                         /* first, compute the (new) font     */
  655.                                         /* description string. It may have   */
  656.                                         /* changed from outside.             */
  657.  
  658.    if (ScreenYResolution == 0) {        /* some outline fonts don't have the */
  659.       if (!DevQueryCaps(GpiQueryDevice(hps), /* point size directly coded in */
  660.                         CAPS_VERTICAL_FONT_RES, /* the sNominalPointsize.    */
  661.                         1,                   /* We need this to compute the  */
  662.                         &ScreenYResolution)) /* point size of the font.      */
  663.                                         /* We could use CAPS_GRAPHICS_CHAR_- */
  664.                                         /* HEIGHT, but that's not exact.     */
  665.          ScreenYResolution = 120;       /* this is the default in case of    */
  666.                                         /* 1024x768. The measurement is pels */
  667.                                         /* per inch.                         */
  668.  
  669.    }
  670.  
  671.    if (metric.fsDefn & FM_DEFN_OUTLINE) {
  672.                                         /*           EmHeight*PointsPerInch  */
  673.                                         /* Points =  ----------------------  */
  674.                                         /*                 PelsPerInch       */
  675.       Pointsize = metric.lEmHeight * 72;  /* (one point is 1/72 inch) Better */
  676.       Pointsize /= ScreenYResolution;   /* use two steps to avoid integer    */
  677.                                         /* division problems                 */
  678.       proof = Pointsize * ScreenYResolution;
  679.       proof /= 72;
  680.       if (proof != metric.lEmHeight)
  681.          Pointsize++;                   /* there was a rounding problem      */
  682.    } else                               /* with bitmap fonts the nominal     */
  683.       Pointsize = metric.sNominalPointSize / 10;   /* point size is correct. */
  684.  
  685.    sprintf(LocFontname,"%lu.%s",Pointsize,metric.szFacename);
  686.                                         /* we ignore Outline, Strikeout und  */
  687.                                         /* Underscore!                       */
  688.    if (strcmp(Fontname,LocFontname) != 0) {
  689.       strcpy(Fontname,LocFontname);
  690.       ReWritePrfFlags |= REWRITE_FONT;  /* ReWritePrf is done in RePaintAll  */
  691.       ReWritePrf();
  692.    }
  693.                                         /* compute the values we need to run */
  694.  
  695.    LineStart  = metric.lAveCharWidth;   /* left margin                       */
  696.                                         /* total height of on line           */
  697.    FontHeight = metric.lMaxBaselineExt + metric.lInternalLeading +
  698.                                                        metric.lExternalLeading;
  699.    FontBase   = metric.lMaxDescender;   /* where to position strings in one  */
  700.                                         /* line box                          */
  701. }
  702.  
  703. /*****************************************************************************/
  704. /*  function name : PaintLine                                                */
  705. /*                                                                           */
  706. /*  arguments     : line box to fill, handle of a presentation space,        */
  707. /*                  number of the line, flag: line needs an overwrite        */
  708. /*                                                                           */
  709. /*  return value  : 0 if nothing has been paint (line out of display),       */
  710. /*                  1 otherwise                                              */
  711. /*                                                                           */
  712. /*  description   : paints one of the (four?) lines of the client window.    */
  713. /*                  The first argument describes the size and the position   */
  714. /*                  of the line, the third the contents to use. If the       */
  715. /*                  fourth is set, the line is filled with the default       */
  716. /*                  background color before.                                 */
  717. /*                  Valid line numbers are:                                  */
  718. /*                                      (update this comment if changed!)    */
  719. /*                  0: current state of program, changed by the function     */
  720. /*                     NewProgramStatus                                      */
  721. /*                  1: next job start time, changed by the function          */
  722. /*                     NewStartTime                                          */
  723. /*                  2: current Crontabs filename                             */
  724. /*                  3: current output filename                               */
  725. /*                                                                           */
  726. /*  note          : clear is set if the calling function has already done    */
  727. /*                  the "ClearBackground".                                   */
  728. /*****************************************************************************/
  729. static int PaintLine(RECTL *line, HPS hps, int lineno, int clear)
  730. {
  731.    POINTL ptl;
  732.    PCSZ name,val;
  733.    char buf[40];
  734.  
  735.    ptl.x = LineStart;
  736.    ptl.y = line->yBottom + FontBase;
  737.                                         /* now, we have to display the line. */
  738.                                         /* Figure out the values:            */
  739.    switch (lineno) {
  740.       case 0:
  741.          name = Get(IDS_StatusLine);
  742.          val  = Get(CurrentState);
  743.          break;
  744.  
  745.       case 1:
  746.          name = Get(IDS_NextstartLine);
  747.          if (NextStartTime == (time_t) -1)
  748.             val = Get(IDS_NextstartUnknown);
  749.          else {
  750.             GetTime(buf,sizeof(buf),NextStartTime);
  751.             val = buf;
  752.          }
  753.          break;
  754.  
  755.       case 2:
  756.          name = Get(IDS_CurrCrontabsLine);
  757.          val  = Crontabs;
  758.          break;
  759.  
  760.       case 3:
  761.          name = Get(IDS_CurrOutputLine);
  762.          val  = CurrFilename;
  763.          break;
  764.  
  765.       default:
  766.          if (clear)
  767.             WinFillRect(hps,line,CLR_BACKGROUND);
  768.          return(0);
  769.    }
  770.                                         /* display the line                  */
  771.    if (clear)
  772.       WinFillRect(hps,line,CLR_BACKGROUND);
  773.    GpiCharStringAt(hps,&ptl,strlen(name),(PSZ) name);
  774.    GpiCharString(hps,strlen(val),(PSZ) val);
  775.    return(1);
  776. }
  777.  
  778. /*****************************************************************************/
  779. /*  function name : CheckColor                                               */
  780. /*                                                                           */
  781. /*  arguments     : handle of a presentation space, presentation parameter   */
  782. /*                  Id of color, system color Id of color, base number       */
  783. /*                  of color within Colors                                   */
  784. /*                                                                           */
  785. /*  return value  : color with to use for displaying text (foreground or     */
  786. /*                  background depending on parameters)                      */
  787. /*                                                                           */
  788. /*  description   : figures out which color to use. First, the system        */
  789. /*                  color is checked. If it has changed, it will become      */
  790. /*                  the new color and the corresponding presentation         */
  791. /*                  parameter is deleted. If the presentation parameter      */
  792. /*                  is set it will become the new color.                     */
  793. /*                  Otherwise the sstored color from Colors will be          */
  794. /*                  returned.                                                */
  795. /*                  The ReWritePrfFlags variable is set in case of           */
  796. /*                  changes.                                                 */
  797. /*****************************************************************************/
  798. static COLOR CheckColor(HPS hps,ULONG PresIndex,ULONG SysIndex,ULONG BaseIndex)
  799. {
  800.    COLOR clr;
  801.    COLOR sysclr;
  802.    ULONG dummy;
  803.    int save = 0;
  804.    clr =
  805.    sysclr = WinQuerySysColor(HWND_DESKTOP,SysIndex,0);
  806.    if (sysclr != Colors[BaseIndex]) {   /* The system color has changed!     */
  807.       WinRemovePresParam(hwndClient,PresIndex); /* This overwrites a presen- */
  808.       save = 1;                         /* tation parameter, delete it!      */
  809.       clr = Colors[BaseIndex] = Colors[BaseIndex + 1] = sysclr;
  810.    }
  811.    else if (WinQueryPresParam(hwndClient,
  812.                               PresIndex,
  813.                               0,
  814.                               &dummy,
  815.                               sizeof(COLOR),
  816.                               &clr,
  817.                               /* QPF_PURERGBCOLOR */ 0) != sizeof(COLOR))
  818.       clr = Colors[BaseIndex + 1];      /* use stored color                  */
  819.    if (clr != Colors[BaseIndex + 1]) {  /* User defined color has changed!   */
  820.       save = 1;
  821.       Colors[BaseIndex + 1] = clr;
  822.    }
  823.    if (save)
  824.       ReWritePrfFlags |= REWRITE_COLORS;
  825.    return(clr);
  826. }
  827.  
  828. /*****************************************************************************/
  829. /*  function name : SwitchColors                                             */
  830. /*                                                                           */
  831. /*  arguments     : handle of a presentation space                           */
  832. /*                                                                           */
  833. /*  description   : sets the foreground and the background color of the      */
  834. /*                  presentation space to Background and Foreground.         */
  835. /*****************************************************************************/
  836. static void SwitchColors(HPS hps)
  837. {
  838.    static LONG buf[4];
  839.    buf[0] = CLR_BACKGROUND;             /* remap the default background color*/
  840.    buf[1] = Background;                 /* to the right color                */
  841.    buf[2] = CLR_NEUTRAL;                /* we won't remap the default color. */
  842.    buf[3] = Foreground;                 /* Instead, we use the neutral color */
  843.                                         /* for normal printing, but we take  */
  844.                                         /* the default color as our default. */
  845.    GpiCreateLogColorTable(hps,0,LCOLF_INDRGB,0,4,buf);
  846.    GpiSetColor(hps,CLR_NEUTRAL);        /* switch to neutral as default color*/
  847. }
  848.  
  849. /*****************************************************************************/
  850. /*  function name : RePaintLine                                              */
  851. /*                                                                           */
  852. /*  arguments     : handle of the client window, number of the line to       */
  853. /*                  update                                                   */
  854. /*                                                                           */
  855. /*  return value  : 0 if nothing has been paint (window out of display),     */
  856. /*                  1 otherwise                                              */
  857. /*                                                                           */
  858. /*  description   : paints one of the lines of the client window. Prepares   */
  859. /*                  the paint and calls PaintLine. (look there for a         */
  860. /*                  description of any line).                                */
  861. /*                                                                           */
  862. /*  note          : never call on WM_PAINT, use RePaintAll instead! This     */
  863. /*                  function is called by an user defined change of the      */
  864. /*                  program status (WM_USER, see bottom)                     */
  865. /*****************************************************************************/
  866. static int RePaintLine(HWND hwnd,int lineno)
  867. {
  868.    HPS hps;
  869.    RECTL rcl,rclline;
  870.    int ret = 0;
  871.    if ((hps = WinGetPS(hwnd)) == (HPS) 0)
  872.       return(0);
  873.    SwitchColors(hps);
  874.    if (WinQueryWindowRect (hwnd, &rcl)) { /* compute the line                */
  875.       rclline = rcl;
  876.       rclline.yTop -= lineno * FontHeight;
  877.       rclline.yBottom = rclline.yTop - FontHeight;
  878.       rclline.yTop--;
  879.       if (rclline.yTop >= rcl.yBottom)  /* displayable?                      */
  880.          ret = PaintLine(&rclline, hps, lineno, 1);
  881.    }
  882.    WinReleasePS (hps);
  883.    return(ret);
  884. }
  885.  
  886. /*****************************************************************************/
  887. /*  function name : RePaintAll                                               */
  888. /*                                                                           */
  889. /*  arguments     : handle of the client window, message number causing      */
  890. /*                  the update                                               */
  891. /*                                                                           */
  892. /*  description   : paints all lines of the visible part of the client       */
  893. /*                  window. Prepares the paint and calls PaintLine.          */
  894. /*                  (look there for a description of any line).              */
  895. /*                  The message number is checked to determine wether        */
  896. /*                  called by a WM_PAINT. In this case we use other          */
  897. /*                  techniques to get an PS.                                 */
  898. /*****************************************************************************/
  899. static void RePaintAll(HWND hwnd,ULONG msg)
  900. {
  901.    HPS hps;
  902.    RECTL rcl,rclline;
  903.    int i;
  904.    static int first = 1;
  905.    if (first) {
  906.       first = 0;                        /* This MUST be placed first, be make*/
  907.       if (Fontname[0] != '\0')          /* a recursive call!!!               */
  908.          WinSetPresParam(hwnd,
  909.                          PP_FONTNAMESIZE,
  910.                          strlen(Fontname) + 1,
  911.                          Fontname);
  912.    }
  913.    if (msg == WM_PAINT)                 /* don't use GetPS: endless recursion*/
  914.       hps = WinBeginPaint(hwnd,NULLHANDLE,NULL);
  915.    else
  916.       hps = WinGetPS(hwnd);
  917.    if (hps == (HPS) 0)                  /* can't get a PS?                   */
  918.      return;
  919.  
  920.    Background = CheckColor(hps,         /* get default background color      */
  921.                            PP_BACKGROUNDCOLOR,
  922.                            SYSCLR_WINDOW,
  923.                            MYCLR_SYSBACKGROUND);
  924.    Foreground = CheckColor(hps,         /* get default foreground color      */
  925.                            PP_FOREGROUNDCOLOR,
  926.                            SYSCLR_WINDOWTEXT,
  927.                            MYCLR_SYSFOREGROUND);
  928.    SwitchColors(hps);
  929.  
  930.    CheckMetric(hps);                    /* figure out current font, may have */
  931.                                         /* changed                           */
  932.    ReWritePrf();
  933.    if (!WinQueryWindowRect(hwnd,&rcl)) {  /* window invisible (minimized)?   */
  934.       WinEndPaint(hps);
  935.       return;
  936.    }
  937.    WinFillRect(hps,&rcl,CLR_BACKGROUND);  /* clear background                */
  938.    rclline = rcl;
  939.    rclline.yBottom = rclline.yTop - FontHeight; /* 0. line                   */
  940.    rclline.yTop--;
  941.    for (i = 0;rclline.yTop >= rcl.yBottom;i++) {
  942.       if (!PaintLine(&rclline, hps, i, 0))   /* only some line my be dis-    */
  943.          break;                         /* played ignore invisible lines     */
  944.       rclline.yTop -= FontHeight;
  945.       rclline.yBottom -= FontHeight;
  946.    }
  947.  
  948.    if (msg == WM_PAINT)
  949.       WinEndPaint(hps);                 /* counterpart of BeginPaint         */
  950.    else
  951.       WinReleasePS(hps);                /* counterpart of GetPS              */
  952. }
  953.  
  954. /*****************************************************************************/
  955. /*  function name : SetCheckBox                                              */
  956. /*                                                                           */
  957. /*  arguments     : handle of the dialog, mask (PRG_???-flag), id of the     */
  958. /*                  dialog entry of the flag in the dialog                   */
  959. /*                                                                           */
  960. /*  description   : sets the dialog entry to checked/not checked depending   */
  961. /*                  on the (ProgramFlags & mask) state.                      */
  962. /*                                                                           */
  963. /*  note          : if called directly, don't forget to write to the         */
  964. /*                  INI-file if needed.                                      */
  965. /*****************************************************************************/
  966. static void SetCheckBox(HWND dlg,ULONG mask,USHORT id)
  967. {
  968.    USHORT flag = 0;                     /* 0 == button unchecked             */
  969.    if (ProgramFlags & mask)
  970.       flag = 1;                         /* 1 == button checked               */
  971.    WinSendDlgItemMsg(dlg,
  972.                      id,
  973.                      BM_SETCHECK,
  974.                      MPFROMSHORT(flag),
  975.                      MPVOID);
  976. }
  977.  
  978. /*****************************************************************************/
  979. /*  function name : DestroyHelpInstance                                      */
  980. /*                                                                           */
  981. /*  description   : destroys the help window if it has been opened           */
  982. /*****************************************************************************/
  983. void DestroyHelpInstance(void)
  984. {
  985.    if (hwndHelpInstance != (HWND) 0)
  986.       WinDestroyHelpInstance(hwndHelpInstance);
  987.    hwndHelpInstance = (HWND) 0;
  988. }
  989.  
  990. /*****************************************************************************/
  991. /*  function name : InitHelp                                                 */
  992. /*                                                                           */
  993. /*  return value  : 1 on success, 0 in case of an error                      */
  994. /*                                                                           */
  995. /*  description   : initializes the help: the help file is opened and        */
  996. /*                  associated to the main window. An error message is       */
  997. /*                  displayed in case of an error.                           */
  998. /*****************************************************************************/
  999. int InitHelp(void)
  1000. {
  1001.    HELPINIT hini;
  1002.    char fn[CCHMAXPATH + 2];
  1003.    char basename[8+1+3+1];
  1004.    USHORT i;
  1005.  
  1006.    memset(&hini,0,sizeof(hini));
  1007.    hini.cb = sizeof(HELPINIT);
  1008.    hini.phtHelpTable = (PHELPTABLE) MAKELONG(NLS(ID_CRON),0xFFFF);
  1009.    hini.pszHelpWindowTitle = (char *) Get(IDS_Title);
  1010.  
  1011. #ifdef DEBUG
  1012.    hini.fShowPanelId = CMIC_SHOW_PANEL_ID;
  1013. #else
  1014.    hini.fShowPanelId = CMIC_HIDE_PANEL_ID;
  1015. #endif
  1016.    strcpy(fn,"\"");                     /* The filename of the help file must*/
  1017.    strcat(fn,DefIOPath);                /* be quoted if it includes blanks   */
  1018.    for (i = 0;i < LanguagesCount;i++)
  1019.       if (Languages[i].code == Language)
  1020.          break;
  1021.    if (i >= (int) LanguagesCount)       /* Unknown value                     */
  1022.       i = 0;
  1023.    sprintf(basename,"crond%.3s.hlp",Languages[i].description);
  1024.    AppendPathComponent(fn,basename);
  1025.    strcat(fn,"\"");
  1026.    hini.pszHelpLibraryName = fn;
  1027.  
  1028.                                         /* create the instance               */
  1029.    hwndHelpInstance = WinCreateHelpInstance(hab,&hini);
  1030.    if ((hwndHelpInstance == (HWND) 0) || (hini.ulReturnCode != 0)) {
  1031.       DestroyHelpInstance();            /* window may exist!                 */
  1032.       PMError(Get(IDS_HelpCantLoad),(HWND) 0);
  1033.       return(0);
  1034.    }
  1035.                                         /* associate to our master frame     */
  1036.    if (!WinAssociateHelpInstance(hwndHelpInstance,hwndFrame)) {
  1037.       WinError((HWND) 0);
  1038.       DestroyHelpInstance();
  1039.       PMError(Get(IDS_HelpCantLoad),(HWND) 0);
  1040.       return(0);
  1041.    }
  1042.    return(1);
  1043. }
  1044.  
  1045. /*****************************************************************************/
  1046. /*  function name : DefaultHelp                                              */
  1047. /*                                                                           */
  1048. /*  arguments     : message id of the help instance (HM_...)                 */
  1049. /*                                                                           */
  1050. /*  description   : this function displays standard help topics (help for    */
  1051. /*                  keys, etc.)                                              */
  1052. /*                  An error message is displayed in case of an error.       */
  1053. /*****************************************************************************/
  1054. void DefaultHelp(ULONG msg)
  1055. {
  1056.    if (hwndHelpInstance != (HWND) 0)
  1057.       if (WinSendMsg(hwndHelpInstance,msg,MPVOID,MPVOID) != (MRESULT) FALSE)
  1058.          PMError(Get(IDS_HelpCantLoad),(HWND) 0);
  1059. }
  1060.  
  1061. /*****************************************************************************/
  1062. /*  function name : DisplayHelpPanel                                         */
  1063. /*                                                                           */
  1064. /*  arguments     : id of the panel to display                               */
  1065. /*                                                                           */
  1066. /*  description   : this function displays a specific help panel. This is    */
  1067. /*                  a helper function for system dialogs which will send     */
  1068. /*                  a WM_HELP. This message won't be correctly resolved      */
  1069. /*                  by the standard help mechanism.                          */
  1070. /*                  An error message is displayed in case of an error.       */
  1071. /*****************************************************************************/
  1072. void DisplayHelpPanel(ULONG idPanel)
  1073. {
  1074.    if (hwndHelpInstance != (HWND) 0)
  1075.       if (WinSendMsg(hwndHelpInstance,
  1076.                      HM_DISPLAY_HELP,
  1077.                      MPFROMLONG(idPanel),
  1078.                      MPFROMSHORT(HM_RESOURCEID)) != (MRESULT) FALSE)
  1079.          PMError(Get(IDS_HelpCantLoad),(HWND) 0);
  1080. }
  1081.  
  1082. /*****************************************************************************/
  1083. /*  function name : DriveIsLocalAndNotRemovable                              */
  1084. /*                                                                           */
  1085. /*  arguments     : drive number (0 = A:)                                    */
  1086. /*                                                                           */
  1087. /*  return value  : 1 if drive is local and not removable, 0 otherwise       */
  1088. /*                                                                           */
  1089. /*  description   : see return value                                         */
  1090. /*****************************************************************************/
  1091. static int DriveIsLocalAndNotRemovable(ULONG DriveNo)
  1092. {
  1093.    BYTE cmd[2];
  1094.    ULONG plen,dlen;
  1095.    BIOSPARAMETERBLOCK bpb;
  1096.                                         /* There is no need to check it the  */
  1097.                                         /* drive is a local drive. We use    */
  1098.                                         /* DevIOCtl. This function returns   */
  1099.                                         /* an error in case of a remote file */
  1100.                                         /* system.                           */
  1101.    cmd[0] = BUILD_BPB_FROM_MEDIUM;      /* Return default BPB                */
  1102.    cmd[1] = (BYTE) DriveNo;             /* Drivenumber (0 = A:)              */
  1103.    plen = sizeof(cmd);
  1104.    dlen = sizeof(bpb);
  1105.    if (DosDevIOCtl((HFILE) -1,
  1106.                    IOCTL_DISK,
  1107.                    DSK_GETDEVICEPARAMS,
  1108.                    cmd,
  1109.                    plen,
  1110.                    &plen,
  1111.                    &bpb,
  1112.                    dlen,
  1113.                    &dlen) != 0)
  1114.       return(0);
  1115.    if ((bpb.fsDeviceAttr & 1) &&        /* removable?                        */
  1116.        (bpb.bDeviceType == DEVTYPE_FIXED))   /* and fixed disk?              */
  1117.       return(1);
  1118.    return(0);
  1119. }
  1120.  
  1121. /*****************************************************************************/
  1122. /*  function name : PathChangeDlgProc                                        */
  1123. /*                                                                           */
  1124. /*  arguments     : see WinDefDlgProc                                        */
  1125. /*                                                                           */
  1126. /*  return value  : see WinDefDlgProc                                        */
  1127. /*                                                                           */
  1128. /*  description   : see WinDefDlgProc, we process some special events        */
  1129. /*                  here. The associated dialog is IDD_OUTPUT_PATH.          */
  1130. /*                  This function changes the output path.                   */
  1131. /*                                                                           */
  1132. /*  note          : don't call directly. This function is called by PM.      */
  1133. /*****************************************************************************/
  1134. static MRESULT EXPENTRY PathChangeDlgProc(HWND hwnd,ULONG msg,MPARAM mp1,
  1135.                                                                     MPARAM mp2)
  1136. {
  1137.    char *buf,component[CCHMAXPATH];
  1138.    HWND list;
  1139.    DIR *dir;
  1140.    struct dirent *ent;
  1141.    static char Drive[sizeof("[-?-] ") + sizeof(VOLUMELABEL)];
  1142.    FSINFO info;
  1143.    ULONG i,Disks;
  1144.    SHORT sel;
  1145.    MRESULT retval;
  1146.  
  1147.    switch (msg) {
  1148.       case WM_INITDLG:
  1149.          WinSendDlgItemMsg(hwnd,        /* set the maximum output path we    */
  1150.                            NLS(IDDE_OUTPUT_PATH_ENTRY),  /* can process      */
  1151.                            EM_SETTEXTLIMIT,
  1152.                            MPFROMLONG(CCHMAXPATH),
  1153.                            MPVOID);
  1154.          WinSetWindowULong(hwnd,QWL_USER,(ULONG) mp2);
  1155.          WinPostMsg(hwnd,WM_USER,MPVOID,MPVOID);   /* send a refresh to      */
  1156.          break;                         /* ourself                           */
  1157.  
  1158.       case WM_USER:
  1159.          buf = (char *) WinQueryWindowULong(hwnd,QWL_USER);
  1160.          FullName(buf);                 /* make a fully qualified pathname   */
  1161.          WinSetDlgItemText(hwnd,        /* copy the current output path to   */
  1162.                            NLS(IDDE_OUTPUT_PATH_ENTRY),  /* the dialog       */
  1163.                            (PSZ) buf);
  1164.  
  1165.          list = WinWindowFromID(hwnd,NLS(IDDE_OUTPUT_PATH_LIST));
  1166.          WinSendMsg(list,LM_DELETEALL,MPVOID,MPVOID); /* delete all entries  */
  1167.          if ((dir = opendir(buf)) != NULL) { /* fill up with the current     */
  1168.                                         /* possible subdirectories           */
  1169.             while ((ent = readdir(dir)) != NULL) {
  1170.                                         /* We allow plain subdirs and the    */
  1171.                                         /* parent only                       */
  1172.                if ((ent->d_attr | A_ARCHIVE) != (A_DIR | A_ARCHIVE))
  1173.                   continue;
  1174.                if (strcmp(ent->d_name,".") == 0)
  1175.                   continue;
  1176.                WinSendMsg(list,
  1177.                           LM_INSERTITEM,
  1178.                           MPFROMLONG(LIT_SORTASCENDING),
  1179.                           MPFROMP(ent->d_name));
  1180.             }
  1181.             closedir(dir);
  1182.          }
  1183.                                         /* now, insert possible drives. We   */
  1184.                                         /* don't allow readonly or removable */
  1185.                                         /* drives, but we can't determine    */
  1186.                                         /* them. Instead we exclude the      */
  1187.                                         /* diskette drives only.             */
  1188.          DosQueryCurrentDisk(&i,&Disks);  /* i is a dummy                    */
  1189.          for (i = 0;i < 26;i++)
  1190.             if (Disks & (1ul << i)) {
  1191.                if (!DriveIsLocalAndNotRemovable(i))
  1192.                   continue;
  1193.                if (DosQueryFSInfo(i + 1,FSIL_VOLSER,&info,sizeof(info)) != 0)
  1194.                   info.vol.szVolLabel[0] = '\0';
  1195.                sprintf(Drive,"[-%c-] %s",(char) ('A' + i),info.vol.szVolLabel);
  1196.                WinSendMsg(list,
  1197.                           LM_INSERTITEM,
  1198.                           MPFROMLONG(LIT_END),
  1199.                           MPFROMP(Drive));
  1200.             }
  1201.  
  1202.          return(MPFROMSHORT(TRUE));     /* we've processed the message       */
  1203.  
  1204.       case WM_CONTROL:
  1205.          if (mp1 == MPFROM2SHORT(NLS(IDDE_OUTPUT_PATH_LIST),LN_ENTER)) {
  1206.             retval = WinDefDlgProc(hwnd,msg,mp1,mp2);
  1207.             sel = (SHORT) (LONG) WinSendDlgItemMsg(hwnd,
  1208.                                                    NLS(IDDE_OUTPUT_PATH_LIST),
  1209.                                                    LM_QUERYSELECTION,
  1210.                                                    MPFROMSHORT(LIT_FIRST),
  1211.                                                    MPVOID);
  1212.             if (sel == LIT_NONE)
  1213.                return(retval);
  1214.             buf = (char *) WinQueryWindowULong(hwnd,QWL_USER);
  1215.             WinSendDlgItemMsg(hwnd,
  1216.                               NLS(IDDE_OUTPUT_PATH_LIST),
  1217.                               LM_QUERYITEMTEXT,
  1218.                               MPFROM2SHORT(sel,CCHMAXPATH),
  1219.                               MPFROMP(component));
  1220.             if ((component[0] == '[') && (component[1] == '-') &&
  1221.                 (component[3] == '-') && (component[4] == ']') &&
  1222.                 (component[5] == ' ')) {
  1223.                buf[0] = component[2];
  1224.                strcpy(buf + 1,":\\");
  1225.             } else
  1226.                AppendPathComponent(buf,component);
  1227.             WinPostMsg(hwnd,WM_USER,MPVOID,MPVOID);   /* send a refresh to   */
  1228.                                         /* ourself                           */
  1229.             return(retval);             /* message processed                 */
  1230.          }
  1231.          break;
  1232.  
  1233.       case WM_COMMAND:
  1234.          switch(LOUSHORT(mp1)) {
  1235.             case DID_OK:
  1236.                buf = (char *) WinQueryWindowULong(hwnd,QWL_USER);
  1237.                WinQueryDlgItemText(hwnd,
  1238.                                    NLS(IDDE_OUTPUT_PATH_ENTRY),
  1239.                                    CCHMAXPATH,
  1240.                                    component);
  1241.                FullName(component);
  1242.                if (_fncmp(component,OutputPath) == 0) /* path not changed?   */
  1243.                                         /* process if has been cancelled     */
  1244.                   WinDismissDlg(hwnd,DID_CANCEL);  /* kill the dialog        */
  1245.                else if (!CheckOutputPath(component))
  1246.                   PMError(Get(IDS_EnterValidOutput),hwnd);
  1247.                else {
  1248.                   strcpy(buf,component);
  1249.                   WinDismissDlg(hwnd,DID_OK);   /* kill the dialog           */
  1250.                }
  1251.                return(MPFROMSHORT(TRUE));  /* we've processed the message    */
  1252.  
  1253.             case DID_CANCEL:
  1254.                WinDismissDlg(hwnd,DID_CANCEL);  /* kill the dialog           */
  1255.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  1256.          }
  1257.          break;
  1258.  
  1259.    }
  1260.    return(WinDefDlgProc(hwnd,msg,mp1,mp2));
  1261.  
  1262. }
  1263.  
  1264. /*****************************************************************************/
  1265. /*  function name : OutputDlgProc                                            */
  1266. /*                                                                           */
  1267. /*  arguments     : see WinDefDlgProc                                        */
  1268. /*                                                                           */
  1269. /*  return value  : see WinDefDlgProc                                        */
  1270. /*                                                                           */
  1271. /*  description   : see WinDefDlgProc, we process some special events        */
  1272. /*                  here. The associated dialog is IDD_OUTPUT.               */
  1273. /*                  This function changes all output file related and user   */
  1274. /*                  changable values.                                        */
  1275. /*                                                                           */
  1276. /*  note          : don't call directly. This function is called by PM.      */
  1277. /*****************************************************************************/
  1278. static MRESULT EXPENTRY OutputDlgProc(HWND hwnd,ULONG msg,MPARAM mp1,
  1279.                                                                     MPARAM mp2)
  1280. {
  1281.    char buf[CCHMAXPATH];
  1282.    unsigned i;
  1283.    PCSZ errortext;
  1284.    ULONG NewThres,NewMax,NewNul;
  1285.    USHORT result;
  1286.    MPARAM mresult;
  1287.    HWND focus;
  1288.    USHORT id;
  1289.    static int AllowChanges = 1;
  1290.  
  1291.    switch (msg) {
  1292.       case WM_HELP:                     /* there are problems displaying the */
  1293.                                         /* correct help panel from the combo */
  1294.                                         /* boxes, since the boxes seen are   */
  1295.                                         /* childs of the original dlgitem.   */
  1296.                                         /* Thus, we look for owner (or       */
  1297.                                         /* parent) of the current focus      */
  1298.                                         /* window and display the associated */
  1299.                                         /* help panel if the focus window    */
  1300.                                         /* is a combo box window.            */
  1301.          focus = WinQueryFocus(HWND_DESKTOP);
  1302.          id = WinQueryWindowUShort(focus,QWS_ID);
  1303.          if ((id != CBID_LIST) && (id != CBID_EDIT))  /* focus not on a combo*/
  1304.             break;                      /* box? proceed with the default...  */
  1305.          DisplayHelpPanel(WinQueryWindowUShort(WinQueryWindow(focus,QW_OWNER),
  1306.                                                                       QWS_ID));
  1307.          return(MPFROMLONG(0));         /* we've processed the message       */
  1308.  
  1309.       case WM_INITDLG:
  1310.          AllowChanges = 0;              /* Don't allow automatically         */
  1311.                                         /* generated WM_USERs to ourself     */
  1312.          for (i = 2;i <= 10;i++) {      /* 2 - 10 different output files are */
  1313.             sprintf(buf,"%u",i);        /* acceptable, put the numbers in a  */
  1314.             WinSendDlgItemMsg(hwnd,     /* list box of a combo box           */
  1315.                               NLS(IDDE_OUTPUT_COUNT),
  1316.                               LM_INSERTITEM,
  1317.                               MPFROMSHORT(LIT_END),
  1318.                               buf);
  1319.          }
  1320.          sprintf(buf,"%u",MaxOutputs);  /* select current value as default   */
  1321.          WinSetDlgItemText(hwnd,
  1322.                            NLS(IDDE_OUTPUT_COUNT),
  1323.                            buf);
  1324.  
  1325.          for (i = 12;i <= 31;i++) {     /* put some good selections of a     */
  1326.             sprintf(buf,"%lu",1ul << i);  /* threshold in the related list   */
  1327.             WinSendDlgItemMsg(hwnd,     /* box of the combo box              */
  1328.                               NLS(IDDE_OUTPUT_THRES),
  1329.                               LM_INSERTITEM,
  1330.                               MPFROMSHORT(LIT_END),
  1331.                               buf);
  1332.          }
  1333.          sprintf(buf,"%lu",Threshold);  /* put the current value as default  */
  1334.          WinSetDlgItemText(hwnd,        /* into the box                      */
  1335.                            NLS(IDDE_OUTPUT_THRES),
  1336.                            buf);
  1337.  
  1338.          WinSendDlgItemMsg(hwnd,        /* set the maximum output path we    */
  1339.                            NLS(IDDE_OUTPUT_PATH),  /* can process            */
  1340.                            EM_SETTEXTLIMIT,
  1341.                            MPFROMLONG(CCHMAXPATH),
  1342.                            MPVOID);
  1343.          WinSetDlgItemText(hwnd,        /* copy the current output path to   */
  1344.                            NLS(IDDE_OUTPUT_PATH),  /* the dialog             */
  1345.                            OutputPath);
  1346.                                         /* set the button "ignore output" to */
  1347.                                         /* the current value                 */
  1348.          SetCheckBox(hwnd,PRG_OUTPUT_IS_NUL,NLS(IDDE_OUTPUT_IGNORE_OUTPUT));
  1349.          AllowChanges = 1;
  1350.          break;
  1351.  
  1352.       case WM_USER:                     /* send from ourself to set all      */
  1353.                                         /* changes                           */
  1354.          errortext = NULL;              /* no error is the default           */
  1355.          NewThres = Threshold;          /* in case of an unknown mistake     */
  1356.          if (WinQueryDlgItemText(hwnd,
  1357.                                  NLS(IDDE_OUTPUT_THRES),
  1358.                                  sizeof(buf),
  1359.                                  buf))
  1360.             ScanNumber(buf,&NewThres);  /* should success always since user  */
  1361.                                         /* can't change the possible values  */
  1362.  
  1363.          NewMax = MaxOutputs;           /* in case of an unknown mistake     */
  1364.          if (WinQueryDlgItemText(hwnd,
  1365.                                  NLS(IDDE_OUTPUT_COUNT),
  1366.                                  sizeof(buf),
  1367.                                  buf))
  1368.             ScanNumber(buf,&NewMax);    /* should success always since user  */
  1369.                                         /* can't change the possible values  */
  1370.  
  1371.          if (!WinQueryDlgItemText(hwnd, /* read and check output path        */
  1372.                                   NLS(IDDE_OUTPUT_PATH),
  1373.                                   sizeof(buf),
  1374.                                   buf))
  1375.             errortext = Get(IDS_EnterValidOutput);
  1376.          else if (!CheckOutputPath(buf))
  1377.             errortext = Get(IDS_EnterValidOutput);
  1378.  
  1379.          if (errortext == NULL) {       /* 'til now no errors ? accept the   */
  1380.                                         /* user selection set values         */
  1381.             i = 0;                      /* flag: no new output file          */
  1382.             if (_fncmp(buf,OutputPath) != 0) {
  1383.                strcpy(OutputPath,buf);  /* output path different?            */
  1384.                ReWritePrfFlags |= REWRITE_OUTPUTPATH;
  1385.                i = 1;
  1386.             }
  1387.             if (NewThres != Threshold) {  /* next Message call will change   */
  1388.                Threshold = NewThres;    /* the output file itself            */
  1389.                ReWritePrfFlags |= REWRITE_THRESHOLD;
  1390.             }
  1391.             if (NewMax != MaxOutputs) {
  1392.                MaxOutputs = (UCHAR) NewMax;
  1393.                ReWritePrfFlags |= REWRITE_MAXIMUM;
  1394.                if ((CurrOutput >= MaxOutputs) &&
  1395.                    ((ProgramFlags & PRG_OUTPUT_IS_NUL) == 0))
  1396.                   i = 1;                /* no longer in a valid interval     */
  1397.             }
  1398.             NewNul = (ULONG) WinQueryButtonCheckstate(hwnd,
  1399.                                                NLS(IDDE_OUTPUT_IGNORE_OUTPUT));
  1400.             if ((NewNul && ((ProgramFlags & PRG_OUTPUT_IS_NUL) == 0))||
  1401.                 (!NewNul && ((ProgramFlags & PRG_OUTPUT_IS_NUL) != 0))) {
  1402.                                         /* the state has changed             */
  1403.                if (NewNul)
  1404.                   ProgramFlags |= PRG_OUTPUT_IS_NUL;
  1405.                else
  1406.                   ProgramFlags &= ~((ULONG) PRG_OUTPUT_IS_NUL);
  1407.                ReWritePrfFlags |= REWRITE_FLAGS;
  1408.                i = 1;
  1409.             }
  1410.             if (i == 1) {               /* select another output file?       */
  1411.                BlockOutput();
  1412.                NextOutputFile(0);       /* select a new one (no append)      */
  1413.                UnBlockOutput();
  1414.             }
  1415.             ReWritePrf();
  1416.             return(MPFROMLONG(0));      /* we have processed the message     */
  1417.          }
  1418.                                         /* else: errortext != NULL           */
  1419.          Error(errortext,hwnd);
  1420.          return(MPFROMLONG(0));         /* we have processed the message     */
  1421.  
  1422.       case WM_CONTROL:
  1423.          mresult = WinDefDlgProc(hwnd,msg,mp1,mp2);
  1424.          if (((SHORT2FROMMP(mp1) == CBN_EFCHANGE) &&
  1425.               ((SHORT1FROMMP(mp1) == NLS(IDDE_OUTPUT_THRES)) ||
  1426.                (SHORT1FROMMP(mp1) == NLS(IDDE_OUTPUT_COUNT)))) ||
  1427.              (SHORT1FROMMP(mp1) == NLS(IDDE_OUTPUT_IGNORE_OUTPUT)))
  1428.             WinPostMsg(hwnd,WM_USER,MPVOID,MPVOID);   /* update values       */
  1429.          return(mresult);
  1430.  
  1431.       case WM_COMMAND:
  1432.          switch(NONLS(LOUSHORT(mp1))) {
  1433.             case IDDE_OUTPUT_PATHCHANGE:
  1434.                strcpy(buf,OutputPath);
  1435.                result = WinDlgBox(HWND_DESKTOP,
  1436.                                   hwnd,
  1437.                                   PathChangeDlgProc,
  1438.                                   0,
  1439.                                   NLS(IDD_OUTPUT_PATH),
  1440.                                   buf);
  1441.                if (result == DID_ERROR)
  1442.                   WinError((HWND) 0);
  1443.                else if (result == DID_OK) {
  1444.                   WinSetDlgItemText(hwnd, /* save the new path               */
  1445.                                     NLS(IDDE_OUTPUT_PATH),
  1446.                                     buf);
  1447.                   WinPostMsg(hwnd,WM_USER,MPVOID,MPVOID);   /* update values */
  1448.                }
  1449.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  1450.  
  1451.             case IDDE_OUTPUT_HELP:
  1452.                DisplayHelpPanel(NLS(IDD_OUTPUT));
  1453.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  1454.  
  1455.             default:                    /* don't expect any other commands!  */
  1456.                                         /* It may be the result of an ESC    */
  1457.                                         /* or other unsupported keys.        */
  1458.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  1459.          }
  1460.          break;
  1461.  
  1462.    }
  1463.    return(WinDefDlgProc(hwnd,msg,mp1,mp2));
  1464. }
  1465.  
  1466. /*****************************************************************************/
  1467. /*  function name : GeneralDlgProc                                           */
  1468. /*                                                                           */
  1469. /*  arguments     : see WinDefDlgProc                                        */
  1470. /*                                                                           */
  1471. /*  return value  : see WinDefDlgProc                                        */
  1472. /*                                                                           */
  1473. /*  description   : see WinDefDlgProc, we process some special events        */
  1474. /*                  here. The associated dialog is IDD_GENERAL.              */
  1475. /*                  This function changes all general and unspecific user    */
  1476. /*                  changable values.                                        */
  1477. /*                                                                           */
  1478. /*  note          : don't call directly. This function is called by PM.      */
  1479. /*****************************************************************************/
  1480. static MRESULT EXPENTRY GeneralDlgProc(HWND hwnd,ULONG msg,MPARAM mp1,
  1481.                                                                     MPARAM mp2)
  1482. {
  1483.    char buf[64];                        /* Hope, this is enough to hold the  */
  1484.                                         /* Language specifier                */
  1485.    USHORT i,j,NewLanguage;
  1486.    char *current;
  1487.    MPARAM mresult;
  1488.    HWND focus;
  1489.    USHORT id;
  1490.    SHORT len;
  1491.    static CHAR *Warning = NULL;
  1492.    static int AllowChanges = 1,new;
  1493.  
  1494.  
  1495.    switch (msg) {
  1496.       case WM_HELP:                     /* there are problems displaying the */
  1497.                                         /* correct help panel from the combo */
  1498.                                         /* boxes, since the boxes seen are   */
  1499.                                         /* childs of the original dlgitem.   */
  1500.                                         /* Thus, we look for owner (or       */
  1501.                                         /* parent) of the current focus      */
  1502.                                         /* window and display the associated */
  1503.                                         /* help panel if the focus window    */
  1504.                                         /* is a combo box window.            */
  1505.          focus = WinQueryFocus(HWND_DESKTOP);
  1506.          id = WinQueryWindowUShort(focus,QWS_ID);
  1507.          if ((id != CBID_LIST) && (id != CBID_EDIT))  /* focus not on a combo*/
  1508.             break;                      /* box? proceed with the default...  */
  1509.          DisplayHelpPanel(WinQueryWindowUShort(WinQueryWindow(focus,QW_OWNER),
  1510.                                                                       QWS_ID));
  1511.          return(MPFROMLONG(0));         /* we've processed the message       */
  1512.  
  1513.       case WM_INITDLG:
  1514.          AllowChanges = 0;              /* Don't allow automatically         */
  1515.                                         /* generated WM_USERs to ourself     */
  1516.          for (i = 0;i < LanguagesCount;i++) {   /* Insert all different      */
  1517.             new = 1;                    /* language specifiers               */
  1518.             for (j = 0;j < i;j++)
  1519.                if (Languages[j].code == Languages[i].code)
  1520.                   new = 0;
  1521.             if (new)
  1522.                WinSendDlgItemMsg(hwnd,  /* list box of a combo box           */
  1523.                                  NLS(IDDE_GENERAL_LANGUAGE),
  1524.                                  LM_INSERTITEM,
  1525.                                  MPFROMSHORT(LIT_SORTASCENDING),
  1526.                                  Languages[i].description);
  1527.          }
  1528.          for (current = "???",i = 0;i < LanguagesCount;i++)
  1529.             if (Languages[i].code == Language)
  1530.                current = Languages[i].description;
  1531.                                         /* select current value as default   */
  1532.          WinSetDlgItemText(hwnd,
  1533.                            NLS(IDDE_GENERAL_LANGUAGE),
  1534.                            current);
  1535.          if (Warning == NULL) {         /* First time?                       */
  1536.             len = WinQueryDlgItemTextLength(hwnd,
  1537.                                             NLS(IDDE_GENERAL_LANGUAGE_WARNING));
  1538.             if ((Warning = malloc(len + 1)) == NULL)
  1539.                PMFatalError(Get(IDS_NotEnoughMemory),hwnd);
  1540.             else
  1541.                WinQueryDlgItemText(hwnd,
  1542.                                    NLS(IDDE_GENERAL_LANGUAGE_WARNING),
  1543.                                    len + 1,
  1544.                                    Warning);
  1545.          }
  1546.          WinSetDlgItemText(hwnd,
  1547.                            NLS(IDDE_GENERAL_LANGUAGE_WARNING),
  1548.                            (CurrentLanguage == Language) ? "" : Warning);
  1549.          AllowChanges = 1;
  1550.          break;
  1551.  
  1552.       case WM_USER:                     /* send from ourself to set all      */
  1553.                                         /* changes                           */
  1554.          if (WinQueryDlgItemText(hwnd,
  1555.                                  NLS(IDDE_GENERAL_LANGUAGE),
  1556.                                  sizeof(buf),
  1557.                                  buf)) {
  1558.                                         /* should success always since user  */
  1559.                                         /* can't change the possible values  */
  1560.             NewLanguage = Language;
  1561.             for (i = 0;i < LanguagesCount;i++)
  1562.                if (strcmp(Languages[i].description,buf) == 0)
  1563.                   NewLanguage = Languages[i].code;
  1564.             if (NewLanguage != Language) {
  1565.                Language = NewLanguage;
  1566.                ReWritePrfFlags |= REWRITE_LANGUAGE;
  1567.                ReWritePrf();
  1568.             }
  1569.             WinSetDlgItemText(hwnd,
  1570.                               NLS(IDDE_GENERAL_LANGUAGE_WARNING),
  1571.                               (CurrentLanguage == Language) ? "" : Warning);
  1572.          }
  1573.          return(MPFROMLONG(0));         /* we have processed the message     */
  1574.  
  1575.       case WM_CONTROL:
  1576.          mresult = WinDefDlgProc(hwnd,msg,mp1,mp2);
  1577.          if ((SHORT2FROMMP(mp1) == CBN_EFCHANGE) &&
  1578.              (SHORT1FROMMP(mp1) == NLS(IDDE_GENERAL_LANGUAGE)))
  1579.             WinPostMsg(hwnd,WM_USER,MPVOID,MPVOID);   /* update values       */
  1580.          return(mresult);
  1581.  
  1582.       case WM_COMMAND:
  1583.          switch(NONLS(LOUSHORT(mp1))) {
  1584.             case IDDE_GENERAL_HELP:
  1585.                DisplayHelpPanel(NLS(IDD_GENERAL));
  1586.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  1587.  
  1588.             default:                    /* don't expect any other commands!  */
  1589.                                         /* It may be the result of an ESC    */
  1590.                                         /* or other unsupported keys.        */
  1591.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  1592.          }
  1593.          break;
  1594.  
  1595.    }
  1596.    return(WinDefDlgProc(hwnd,msg,mp1,mp2));
  1597. }
  1598.  
  1599. /*****************************************************************************/
  1600. /*  function name : TCPFileDlgProc                                           */
  1601. /*                                                                           */
  1602. /*  arguments     : see WinDefFileDlgProc                                    */
  1603. /*                                                                           */
  1604. /*  return value  : see WinDefFileDlgProc                                    */
  1605. /*                                                                           */
  1606. /*  description   : see WinDefFileDlgProc, we process some special events    */
  1607. /*                  here. The associated dialog is called by WinFileDlg.     */
  1608. /*                  This function changes the TCP/IP allow file name.        */
  1609. /*                                                                           */
  1610. /*  note          : don't call directly. This function is called by PM.      */
  1611. /*****************************************************************************/
  1612. static MRESULT EXPENTRY TCPFileDlgProc(HWND hwnd,ULONG msg,MPARAM mp1,
  1613.                                                                     MPARAM mp2)
  1614. {
  1615.  
  1616.    switch (msg) {
  1617.       case WM_HELP:
  1618.          DisplayHelpPanel(NLS(IDDE_TCP_FILENAMECHANGE));
  1619.          return(MPFROMLONG(0));         /* we've processed the message       */
  1620.  
  1621.       case FDM_VALIDATE:
  1622.          FullName((PSZ) mp1);           /* make a fully qualified filename   */
  1623.          if (_fncmp(TCPIP_Allow,(PSZ) mp1) == 0)   /* filename identical?    */
  1624.                return(MPFROMSHORT(TRUE)); /* we've processed the message, we */
  1625.                                         /* don't change anything             */
  1626.          if (!ReadAllow((PSZ) mp1)) {   /* can't read the file?              */
  1627.             Error(Get(IDS_InvalidFormat),hwnd);
  1628.             return(MPFROMSHORT(FALSE)); /* we've processed the message, the  */
  1629.                                         /* user must select another file     */
  1630.          }
  1631.          /* else */                     /* file has been read successfully   */
  1632.          ReWritePrfFlags |= REWRITE_TCPIP_ALLOW;
  1633.          strcpy(TCPIP_Allow,(PSZ) mp1);
  1634.          ReWritePrf();
  1635.          return(MPFROMSHORT(TRUE));     /* we've processed the message       */
  1636.                                         /* the system will close the dialog  */
  1637.    }
  1638.    return(WinDefFileDlgProc(hwnd,msg,mp1,mp2));
  1639. }
  1640.  
  1641. /*****************************************************************************/
  1642. /*  function name : TCPIPDlgProc                                             */
  1643. /*                                                                           */
  1644. /*  arguments     : see WinDefDlgProc                                        */
  1645. /*                                                                           */
  1646. /*  return value  : see WinDefDlgProc                                        */
  1647. /*                                                                           */
  1648. /*  description   : see WinDefDlgProc, we process some special events        */
  1649. /*                  here. The associated dialog is IDD_TCPIP.                */
  1650. /*                  This function changes all TCP/IP related and user        */
  1651. /*                  changable values.                                        */
  1652. /*                                                                           */
  1653. /*  note          : don't call directly. This function is called by PM.      */
  1654. /*****************************************************************************/
  1655. static MRESULT EXPENTRY TCPIPDlgProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
  1656. {
  1657.    FILEDLG fild;
  1658.    USHORT id;
  1659.    ULONG ButtonState;
  1660.    MRESULT mresult;
  1661.  
  1662.    switch (msg) {
  1663.       case WM_INITDLG:
  1664.          if (!TCPIPAvail) {
  1665.             if (ProgramFlags & PRG_ALLOW_TCPIP) {
  1666.                ProgramFlags &= ~PRG_ALLOW_TCPIP;
  1667.                ReWritePrf();
  1668.                Error(Get(IDS_NoTCPIPFound),hwnd);
  1669.             }
  1670.             SetCheckBox(hwnd,PRG_ALLOW_TCPIP,NLS(IDDE_TCP_ALLOWACCESS));
  1671.             WinEnableControl(hwnd,NLS(IDDE_TCP_ALLOWACCESS),FALSE);
  1672.          } else
  1673.             SetCheckBox(hwnd,PRG_ALLOW_TCPIP,NLS(IDDE_TCP_ALLOWACCESS));
  1674.          WinSetDlgItemText(hwnd,        /* copy the current output path to   */
  1675.                            NLS(IDDE_TCP_FILENAME), /* the dialog             */
  1676.                            TCPIP_Allow);
  1677.          break;
  1678.  
  1679.       case WM_CONTROL:
  1680.          mresult = WinDefDlgProc(hwnd,msg,mp1,mp2);
  1681.          id = SHORT1FROMMP(mp1);
  1682.          if (id == NLS(IDDE_TCP_ALLOWACCESS)) {
  1683.             ButtonState = (ULONG) WinQueryButtonCheckstate(hwnd,id);
  1684.             if ((ButtonState && ((ProgramFlags & PRG_ALLOW_TCPIP) == 0)) ||
  1685.                 (!ButtonState && ((ProgramFlags & PRG_ALLOW_TCPIP) != 0))) {
  1686.                                         /* the state has changed             */
  1687.                if (ButtonState)
  1688.                   ProgramFlags |= PRG_ALLOW_TCPIP;
  1689.                else
  1690.                   ProgramFlags &= ~((ULONG) PRG_ALLOW_TCPIP);
  1691.                ReWritePrfFlags |= REWRITE_FLAGS;
  1692.                ReWritePrf();
  1693.             }
  1694.          }
  1695.          return(mresult);
  1696.  
  1697.       case WM_COMMAND:
  1698.          switch(NONLS(LOUSHORT(mp1))) {
  1699.             case IDDE_TCP_FILENAMECHANGE:
  1700.                memset(&fild,0,sizeof(fild));
  1701.                fild.cbSize            = sizeof(fild);
  1702.                fild.fl                = FDS_CENTER |
  1703.                                         FDS_OPEN_DIALOG |
  1704.                                         FDS_HELPBUTTON |
  1705.                                         0;
  1706.                fild.pszTitle          = (PSZ) Get(IDS_TitleNewTCPIP);
  1707.                fild.pfnDlgProc        = TCPFileDlgProc;
  1708.                strcpy(fild.szFullFile,  TCPIP_Allow);
  1709.                if (!WinFileDlg(HWND_DESKTOP,hwnd,&fild))
  1710.                   WinError((HWND) 0);
  1711.                WinSetDlgItemText(hwnd,  /* copy the current output path to   */
  1712.                                  NLS(IDDE_TCP_FILENAME), /* the dialog       */
  1713.                                  TCPIP_Allow);
  1714.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  1715.  
  1716.             case IDDE_TCP_HELP:
  1717.                DisplayHelpPanel(NLS(IDD_TCP));
  1718.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  1719.  
  1720.             default:                    /* don't expect any other commands!  */
  1721.                                         /* It may be the result of an ESC    */
  1722.                                         /* or other unsupported keys.        */
  1723.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  1724.  
  1725.          }
  1726.          break;
  1727.  
  1728.    }
  1729.    return(WinDefDlgProc(hwnd,msg,mp1,mp2));
  1730. }
  1731.  
  1732. /*****************************************************************************/
  1733. /*  function name : CronFileDlgProc                                          */
  1734. /*                                                                           */
  1735. /*  arguments     : see WinDefFileDlgProc                                    */
  1736. /*                                                                           */
  1737. /*  return value  : see WinDefFileDlgProc                                    */
  1738. /*                                                                           */
  1739. /*  description   : see WinDefFileDlgProc, we process some special events    */
  1740. /*                  here. The associated dialog is called by WinFileDlg.     */
  1741. /*                  This function changes the Crontabs file name.            */
  1742. /*                                                                           */
  1743. /*  note          : don't call directly. This function is called by PM.      */
  1744. /*****************************************************************************/
  1745. static MRESULT EXPENTRY CronFileDlgProc(HWND hwnd,ULONG msg,MPARAM mp1,
  1746.                                                                     MPARAM mp2)
  1747. {
  1748.    switch (msg) {
  1749.       case WM_HELP:
  1750.          DisplayHelpPanel(NLS(IDDE_CRON_FILENAMECHANGE));
  1751.          return(MPFROMLONG(0));         /* we've processed the message       */
  1752.  
  1753.       case FDM_VALIDATE:
  1754.          FullName((PSZ) mp1);           /* make a fully qualified filename   */
  1755.          if (_fncmp(Crontabs,(PSZ) mp1) == 0)   /* filename identical?       */
  1756.                return(MPFROMSHORT(TRUE)); /* we've processed the message, we */
  1757.                                         /* don't change anything             */
  1758.          if (!ReReadCrontabs((PSZ) mp1)) {   /* can't read the file?         */
  1759.             Error(Get(IDS_InvalidFormat),hwnd);
  1760.             return(MPFROMSHORT(FALSE)); /* we've processed the message, the  */
  1761.                                         /* user must select another file     */
  1762.          }
  1763.          /* else */                     /* file has been read successfully   */
  1764.          ReWritePrfFlags |= REWRITE_CRONFILENAME;
  1765.          strcpy(Crontabs,(PSZ) mp1);
  1766.          ReWritePrf();
  1767.          return(MPFROMSHORT(TRUE));     /* we've processed the message       */
  1768.                                         /* the system will close the dialog  */
  1769.    }
  1770.    return(WinDefFileDlgProc(hwnd,msg,mp1,mp2));
  1771. }
  1772.  
  1773. /*****************************************************************************/
  1774. /*  function name : CronDlgProc                                              */
  1775. /*                                                                           */
  1776. /*  arguments     : see WinDefDlgProc                                        */
  1777. /*                                                                           */
  1778. /*  return value  : see WinDefDlgProc                                        */
  1779. /*                                                                           */
  1780. /*  description   : see WinDefDlgProc, we process some special events        */
  1781. /*                  here. The associated dialog is IDD_CRON_FILE             */
  1782. /*                  This function changes all Crontabs related and user      */
  1783. /*                  changable values.                                        */
  1784. /*                                                                           */
  1785. /*  note          : don't call directly. This function is called by PM.      */
  1786. /*****************************************************************************/
  1787. static MRESULT EXPENTRY CronDlgProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
  1788. {
  1789.    FILEDLG fild;
  1790.    USHORT id;
  1791.    ULONG prgflag,ButtonState;
  1792.    MRESULT mresult;
  1793.  
  1794.    switch (msg) {
  1795.       case WM_INITDLG:
  1796.          SetCheckBox(hwnd,PRG_RUNATSTARTUP,NLS(IDDE_CRON_ATSTARTUP));
  1797.          SetCheckBox(hwnd,PRG_RUNATEXIT,   NLS(IDDE_CRON_ATEXIT));
  1798.          WinSetDlgItemText(hwnd,        /* copy the current output path to   */
  1799.                            NLS(IDDE_CRON_FILENAME),   /* the dialog          */
  1800.                            Crontabs);
  1801.          break;
  1802.  
  1803.       case WM_CONTROL:
  1804.          mresult = WinDefDlgProc(hwnd,msg,mp1,mp2);
  1805.          id = SHORT1FROMMP(mp1);
  1806.          if ((id == NLS(IDDE_CRON_ATSTARTUP)) ||
  1807.              (id == NLS(IDDE_CRON_ATEXIT))) {
  1808.             if (id == NLS(IDDE_CRON_ATSTARTUP))
  1809.                prgflag = PRG_RUNATSTARTUP;
  1810.             else
  1811.                prgflag = PRG_RUNATEXIT;
  1812.             ButtonState = (ULONG) WinQueryButtonCheckstate(hwnd,id);
  1813.             if ((ButtonState && ((ProgramFlags & prgflag) == 0)) ||
  1814.                 (!ButtonState && ((ProgramFlags & prgflag) != 0))) {
  1815.                                         /* the state has changed             */
  1816.                if (ButtonState)
  1817.                   ProgramFlags |= prgflag;
  1818.                else
  1819.                   ProgramFlags &= ~prgflag;
  1820.                ReWritePrfFlags |= REWRITE_FLAGS;
  1821.                ReWritePrf();
  1822.             }
  1823.          }
  1824.          return(mresult);
  1825.  
  1826.       case WM_COMMAND:
  1827.          switch(NONLS(LOUSHORT(mp1))) {
  1828.             case IDDE_CRON_FILENAMECHANGE:
  1829.                memset(&fild,0,sizeof(fild));
  1830.                fild.cbSize            = sizeof(fild);
  1831.                fild.fl                = FDS_CENTER |
  1832.                                         FDS_OPEN_DIALOG |
  1833.                                         FDS_HELPBUTTON |
  1834.                                         0;
  1835.                fild.pszTitle          = (PSZ) Get(IDS_TitleNewCron);
  1836.                fild.pfnDlgProc        = CronFileDlgProc;
  1837.                strcpy(fild.szFullFile,  Crontabs);
  1838.                if (!WinFileDlg(HWND_DESKTOP,hwnd,&fild))
  1839.                   WinError((HWND) 0);
  1840.                WinSetDlgItemText(hwnd,  /* copy the current output path to   */
  1841.                                  NLS(IDDE_CRON_FILENAME),   /* the dialog    */
  1842.                                  Crontabs);
  1843.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  1844.  
  1845.             case IDDE_CRON_HELP:
  1846.                DisplayHelpPanel(NLS(IDD_CRON_FILE));
  1847.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  1848.  
  1849.             default:                    /* don't expect any other commands!  */
  1850.                                         /* It may be the result of an ESC    */
  1851.                                         /* or other unsupported keys.        */
  1852.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  1853.  
  1854.          }
  1855.          break;
  1856.  
  1857.    }
  1858.    return(WinDefDlgProc(hwnd,msg,mp1,mp2));
  1859. }
  1860.  
  1861. /*****************************************************************************/
  1862. /*  function name : CrontabsDlgProc                                          */
  1863. /*                                                                           */
  1864. /*  arguments     : see WinDefDlgProc                                        */
  1865. /*                                                                           */
  1866. /*  return value  : see WinDefDlgProc                                        */
  1867. /*                                                                           */
  1868. /*  description   : see WinDefDlgProc, we process some special events        */
  1869. /*                  here. The associated dialog is IDD_CRONTABS              */
  1870. /*                  This function allows the user to change Crontabs         */
  1871. /*                  elements online.                                         */
  1872. /*                                                                           */
  1873. /*  note          : don't call directly. This function is called by PM.      */
  1874. /*****************************************************************************/
  1875. static MRESULT EXPENTRY CrontabsDlgProc(HWND hwnd,ULONG msg,MPARAM mp1,
  1876.                                                                     MPARAM mp2)
  1877. {
  1878.    ULONG len,err,err2;
  1879.    HWND list;
  1880.    SHORT sel,deleted;
  1881.    char *buf,*ptr,*line;
  1882.    char tmpbuf[1024];
  1883.    static ULONG CurrentlyEditedNumber = (ULONG) -1;
  1884.    LIST_ENTRY *aktentry;
  1885.    BOOL ok;
  1886.    PVOID ClipData;
  1887.    MRESULT mresult;
  1888.  
  1889.    switch (msg) {
  1890.       case WM_INITDLG:
  1891.          CrontabsWindow = hwnd;
  1892.          WinPostMsg(hwnd,WM_USER,MPVOID,MPVOID);
  1893.          WinSendDlgItemMsg(hwnd,        /* set the maximum command line we   */
  1894.                            NLS(IDDE_CRONTABS_ENTRY),  /* allow               */
  1895.                            EM_SETTEXTLIMIT,
  1896.                            MPFROMLONG(4095),
  1897.                            MPVOID);
  1898.          break;
  1899.  
  1900.       case WM_DESTROY:
  1901.          CrontabsWindow = (HWND) 0;
  1902.          EditEntryNumber = CurrentlyEditedNumber = (ULONG) -1;
  1903.          break;
  1904.  
  1905.       case WM_USER:
  1906.                                         /* don't allow user to use the edit  */
  1907.                                         /* button                            */
  1908.          WinEnableControl(hwnd,NLS(IDDE_CRONTABS_EDIT),FALSE);
  1909.          if (CurrentlyEditedNumber != (ULONG) -1)  /* We must aware of a     */
  1910.             if (EditEntryNumber == (ULONG) -1) {   /* currently edited job   */
  1911.                WinEnableControl(hwnd,NLS(IDDE_CRONTABS_CHANGE),FALSE);
  1912.                WinEnableControl(hwnd,NLS(IDDE_CRONTABS_ABORT),FALSE);
  1913.                PMError(Get(IDS_JobJustDeleted),hwnd);
  1914.                CurrentlyEditedNumber = (ULONG) -1;
  1915.             }
  1916.          WinEnableControl(hwnd,NLS(IDDE_CRONTABS_DELETE),FALSE);
  1917.          list = WinWindowFromID(hwnd,NLS(IDDE_CRONTABS_LIST));
  1918.          WinSendMsg(list,LM_DELETEALL,MPVOID,MPVOID); /* delete all entries  */
  1919.          BlockProcess();
  1920.          buf = ptr = CreateList(CL_PM);
  1921.          UnBlockProcess();
  1922.          while (ptr != NULL) {
  1923.             line = ptr;
  1924.             while (isspace(*line))
  1925.                line++;
  1926.             if ((ptr = strpbrk(line,"\r\n")) != NULL)
  1927.                *ptr++ = '\0';
  1928.             if (*line != '\0')          /* Don't display empty lines         */
  1929.                WinSendMsg(list,
  1930.                           LM_INSERTITEM,
  1931.                           MPFROMLONG(LIT_END),
  1932.                           MPFROMP(line));
  1933.          }
  1934.          if (buf != NULL)
  1935.             free(buf);
  1936.          break;
  1937.  
  1938.       case WM_CONTROL:
  1939.                                         /* figure out the selection status   */
  1940.                                         /* of the list if modified           */
  1941.          if (mp1 == MPFROM2SHORT(NLS(IDDE_CRONTABS_LIST),LN_SELECT)) {
  1942.             list = WinWindowFromID(hwnd,NLS(IDDE_CRONTABS_LIST));
  1943.             mresult = WinDefDlgProc(hwnd,msg,mp1,mp2);
  1944.                                         /* the selection is modified. If only*/
  1945.                                         /* one item is selected, we'll allow */
  1946.                                         /* to edit the entry.                */
  1947.             ok = FALSE;
  1948.             sel = (SHORT) (LONG) WinSendMsg(list,
  1949.                                             LM_QUERYSELECTION,
  1950.                                             MPFROMSHORT(LIT_FIRST),
  1951.                                             MPVOID);
  1952.             if (sel != LIT_NONE) {
  1953.                WinEnableControl(hwnd,NLS(IDDE_CRONTABS_DELETE),TRUE);
  1954.                if (LIT_NONE == (SHORT) (LONG) WinSendMsg(list,
  1955.                                                          LM_QUERYSELECTION,
  1956.                                                          MPFROMSHORT(sel),
  1957.                                                          MPVOID))
  1958.                   ok = TRUE;
  1959.             } else
  1960.                WinEnableControl(hwnd,NLS(IDDE_CRONTABS_DELETE),FALSE);
  1961.             WinEnableControl(hwnd,NLS(IDDE_CRONTABS_EDIT),ok);
  1962.             return(mresult);
  1963.          } else if (mp1 == MPFROM2SHORT(NLS(IDDE_CRONTABS_ENTRY),EN_CHANGE)) {
  1964.             if (WinQueryDlgItemTextLength(hwnd,NLS(IDDE_CRONTABS_ENTRY)) == 0)
  1965.                WinEnableControl(hwnd,NLS(IDDE_CRONTABS_ADD),FALSE);
  1966.             else
  1967.                WinEnableControl(hwnd,NLS(IDDE_CRONTABS_ADD),TRUE);
  1968.          }
  1969.          break;
  1970.  
  1971.       case WM_COMMAND:
  1972.          switch(NONLS(LOUSHORT(mp1))) {
  1973.             case IDDE_CRONTABS_ADD:
  1974.                len = (ULONG) WinQueryDlgItemTextLength(hwnd,
  1975.                                                      NLS(IDDE_CRONTABS_ENTRY));
  1976.                if ((buf = malloc(len + 1)) == NULL) {
  1977.                   PMError(Get(IDS_NotEnoughMemory),hwnd);
  1978.                   return(MPFROMSHORT(TRUE)); /* we've processed the message  */
  1979.                }
  1980.                WinQueryDlgItemText(hwnd,
  1981.                                    NLS(IDDE_CRONTABS_ENTRY),
  1982.                                    len + 1,
  1983.                                    buf);
  1984.                BlockProcess();
  1985.                err = NewEntry(buf,len,tmpbuf);
  1986.                UnBlockProcess();
  1987.                if (err == 0) {
  1988.                   WinPostMsg(hwnd,WM_USER,MPVOID,MPVOID);
  1989.                   DosPostEventSem(CronSem);  /* compute next starting time   */
  1990.                   WinSetDlgItemText(hwnd,NLS(IDDE_CRONTABS_ENTRY),"");
  1991.                   EditEntryNumber = CurrentlyEditedNumber = (ULONG) -1;
  1992.                   WinEnableControl(hwnd,NLS(IDDE_CRONTABS_CHANGE),FALSE);
  1993.                   WinEnableControl(hwnd,NLS(IDDE_CRONTABS_ABORT),FALSE);
  1994.                } else
  1995.                   PMError(GetError(err),hwnd);
  1996.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  1997.  
  1998.             case IDDE_CRONTABS_CHANGE:
  1999.                len = (ULONG) WinQueryDlgItemTextLength(hwnd,
  2000.                                                      NLS(IDDE_CRONTABS_ENTRY));
  2001.                if ((buf = malloc(len + 1)) == NULL) {
  2002.                   PMError(Get(IDS_NotEnoughMemory),hwnd);
  2003.                   return(MPFROMSHORT(TRUE)); /* we've processed the message  */
  2004.                }
  2005.                WinQueryDlgItemText(hwnd,
  2006.                                    NLS(IDDE_CRONTABS_ENTRY),
  2007.                                    len + 1,
  2008.                                    buf);
  2009.                BlockProcess();
  2010.                if ((err = NewEntry(buf,len,tmpbuf)) == 0)
  2011.                   err2 = DeleteEntryNum(EditEntryNumber + 1,tmpbuf);
  2012.                else
  2013.                   err2 = 0;             /* make compiler happy               */
  2014.                UnBlockProcess();
  2015.                if (err == 0) {
  2016.                   WinPostMsg(hwnd,WM_USER,MPVOID,MPVOID);
  2017.                   DosPostEventSem(CronSem);  /* compute next starting time   */
  2018.                   WinSetDlgItemText(hwnd,NLS(IDDE_CRONTABS_ENTRY),"");
  2019.                   EditEntryNumber = CurrentlyEditedNumber = (ULONG) -1;
  2020.                   WinEnableControl(hwnd,NLS(IDDE_CRONTABS_CHANGE),FALSE);
  2021.                   WinEnableControl(hwnd,NLS(IDDE_CRONTABS_ABORT),FALSE);
  2022.                   if (err2 != 0)
  2023.                      PMError(GetError(err),hwnd);
  2024.                } else
  2025.                   PMError(GetError(err),hwnd);
  2026.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  2027.  
  2028.             case IDDE_CRONTABS_ABORT:
  2029.                WinSetDlgItemText(hwnd,NLS(IDDE_CRONTABS_ENTRY),"");
  2030.                EditEntryNumber = CurrentlyEditedNumber = (ULONG) -1;
  2031.                WinEnableControl(hwnd,NLS(IDDE_CRONTABS_CHANGE),FALSE);
  2032.                WinEnableControl(hwnd,NLS(IDDE_CRONTABS_ABORT),FALSE);
  2033.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  2034.  
  2035.             case IDDE_CRONTABS_DELETE:
  2036.                list = WinWindowFromID(hwnd,NLS(IDDE_CRONTABS_LIST));
  2037.                BlockProcess();
  2038.                for (sel = LIT_FIRST,deleted = 0;;) {
  2039.                   sel = (SHORT) (LONG) WinSendMsg(list,
  2040.                                                   LM_QUERYSELECTION,
  2041.                                                   MPFROMSHORT(sel),
  2042.                                                   MPVOID);
  2043.                   if (sel != LIT_NONE) {
  2044.                      if ((err = DeleteEntryNum(sel + 1 - deleted,tmpbuf)) != 0)
  2045.                         break;
  2046.                      deleted++;
  2047.                   } else
  2048.                      break;
  2049.                }
  2050.                UnBlockProcess();
  2051.                if (deleted) {
  2052.                   WinPostMsg(hwnd,WM_USER,MPVOID,MPVOID);
  2053.                   DosPostEventSem(CronSem);  /* compute next starting time   */
  2054.                }
  2055.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  2056.  
  2057.             case IDDE_CRONTABS_EDIT:
  2058.                list = WinWindowFromID(hwnd,NLS(IDDE_CRONTABS_LIST));
  2059.                BlockProcess();
  2060.                sel = (SHORT) (LONG) WinSendMsg(list,
  2061.                                                LM_QUERYSELECTION,
  2062.                                                MPFROMSHORT(LIT_FIRST),
  2063.                                                MPVOID);
  2064.                if (sel == LIT_NONE) {   /* oops, this should never happen    */
  2065.                   UnBlockProcess();     /* since the push-button should      */
  2066.                   return(MPFROMSHORT(TRUE)); /* be disabled in this case!    */
  2067.                }
  2068.                if ((aktentry = LookupEntryNum((ULONG) (LONG) sel + 1,0)) ==
  2069.                                                                         NULL) {
  2070.                   UnBlockProcess();     /* this will be a true error, it may */
  2071.                   return(MPFROMSHORT(TRUE)); /* be generated due race        */
  2072.                }                             /* conditions                   */
  2073.  
  2074.                EditEntryNumber = CurrentlyEditedNumber = (ULONG) (LONG) sel;
  2075.                WinSetDlgItemText(hwnd,
  2076.                                  NLS(IDDE_CRONTABS_ENTRY),
  2077.                                  aktentry->s);
  2078.                                         /* allow user to use the Change butt.*/
  2079.                WinEnableControl(hwnd,NLS(IDDE_CRONTABS_CHANGE),TRUE);
  2080.                WinEnableControl(hwnd,NLS(IDDE_CRONTABS_ABORT),TRUE);
  2081.                                         /* put data into clipboard           */
  2082.                if (WinOpenClipbrd(hab)) {
  2083.                   ok = FALSE;
  2084.                   if (DosAllocSharedMem(&ClipData,
  2085.                                         NULL,
  2086.                                         strlen(aktentry->s) + 1,
  2087.                                         PAG_READ | PAG_WRITE | PAG_COMMIT |
  2088.                                                  OBJ_TILE | OBJ_GIVEABLE) == 0)
  2089.                      ok = TRUE;
  2090.                   if (ok) {
  2091.                      strcpy(ClipData,aktentry->s);
  2092.                      ok = WinSetClipbrdData(hab,
  2093.                                             (ULONG) ClipData,
  2094.                                             CF_TEXT,
  2095.                                             CFI_POINTER);
  2096.                      if (!ok)
  2097.                         DosFreeMem(ClipData);
  2098.                   }
  2099.                   WinCloseClipbrd(hab);
  2100.                   if (ok)
  2101.                      WinMessageBox(HWND_DESKTOP,
  2102.                                    hwnd,
  2103.                                    Get(IDS_EntryInClipboard),
  2104.                                    Get(IDS_Title),
  2105.                                    0,
  2106.                                    MB_OK | MB_ICONASTERISK | MB_MOVEABLE);
  2107.                }
  2108.                UnBlockProcess();
  2109.                WinSetFocus(HWND_DESKTOP,
  2110.                            WinWindowFromID(hwnd,NLS(IDDE_CRONTABS_ENTRY)));
  2111.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  2112.  
  2113.             case IDDE_CRONTABS_HELP:
  2114.                DisplayHelpPanel(NLS(IDD_CRONTABS));
  2115.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  2116.  
  2117.             default:                    /* don't expect any other commands!  */
  2118.                                         /* It may be the result of an ESC    */
  2119.                                         /* or other unsupported keys.        */
  2120.                return(MPFROMSHORT(TRUE)); /* we've processed the message     */
  2121.          }
  2122.          break;
  2123.  
  2124.    }
  2125.    return(WinDefDlgProc(hwnd,msg,mp1,mp2));
  2126. }
  2127.  
  2128. /*****************************************************************************/
  2129. /*  function name : InsertDlgIntoNoteBook                                    */
  2130. /*                                                                           */
  2131. /*  arguments     : Handle of the notebook, Id of the dialog, dialog         */
  2132. /*                  procedure, statusline, major tab text, buffer to         */
  2133. /*                  update the maximum major tab text size, BKA_MAJOR,       */
  2134. /*                  BKA_MINOR or 0 reflecting the page style,                */
  2135. /*                  buffer to hold the pagebutton size.                      */
  2136. /*                                                                           */
  2137. /*  return value  : window handle of the newly created notebook page or      */
  2138. /*                  NULLHANDLE in case of an error.                          */
  2139. /*                                                                           */
  2140. /*  description   : inserts the page into the notebook with the given        */
  2141. /*                  handle. The statusline text and the tab text is used     */
  2142. /*                  in case of an error, only. On default, the strings       */
  2143. /*                  are taken from the resource of the current module. We    */
  2144. /*                  figure out the title of the dialog. The first part of    */
  2145. /*                  it defines the tab text, the second one the status       */
  2146. /*                  line text. The separator is a '|'.                       */
  2147. /*                  In case of a major tab this function determines the      */
  2148. /*                  size needed to display the tab text. If it needs more    */
  2149. /*                  space than the current value these values are updated.   */
  2150. /*****************************************************************************/
  2151. static HWND InsertDlgIntoNoteBook(HWND pages,USHORT DlgId,PFNWP DlgProc,
  2152.                                   PSZ Statusline,PSZ Tabtext,PPOINTL maxtext,
  2153.                                   USHORT majorminor,PSHORT pgbutton)
  2154. {
  2155.    HWND hwndPage;
  2156.    ULONG PageId;
  2157.    HPS hps;
  2158.    POINTL box[TXTBOX_TOPRIGHT + 1];
  2159.    MPARAM mp2;
  2160.    FONTMETRICS metric;
  2161.    char buf[256];
  2162.    ULONG size;
  2163.    DLGTEMPLATE *pdlg;
  2164.    DLGTITEM *pitem;
  2165.  
  2166.    mp2 = MPFROM2SHORT((BKA_STATUSTEXTON | BKA_AUTOPAGESIZE | majorminor),
  2167.                                                                      BKA_LAST);
  2168.    PageId = (ULONG) WinSendMsg(pages,
  2169.                                BKM_INSERTPAGE,
  2170.                                MPVOID,  /* not used, we call with BKA_LAST   */
  2171.                                mp2);
  2172.    if (PageId == 0)
  2173.       return(NULLHANDLE);
  2174.  
  2175.    hwndPage = WinLoadDlg(pages,         /* parent                            */
  2176.                          NULLHANDLE,    /* owner                             */
  2177.                          DlgProc,
  2178.                          0,             /* module                            */
  2179.                          DlgId,
  2180.                          NULL);         /* creation params                   */
  2181.    if (hwndPage == (HWND) 0) {
  2182.       WinSendMsg(pages,                 /* in case of an error we delete     */
  2183.                  BKM_DELETEPAGE,        /* the newly created page            */
  2184.                  MPFROMLONG(PageId),
  2185.                  MPFROMSHORT(BKA_SINGLE));
  2186.       return(NULLHANDLE);
  2187.    }
  2188.  
  2189.    if (!WinSendMsg(pages,               /* can't assign the dialog to the    */
  2190.                    BKM_SETPAGEWINDOWHWND, /* page?                           */
  2191.                    MPFROMLONG(PageId),
  2192.                    MPFROMHWND(hwndPage))) {
  2193.       WinSendMsg(pages,
  2194.                  BKM_DELETEPAGE,
  2195.                  MPFROMLONG(PageId),
  2196.                  MPFROMSHORT(BKA_SINGLE));
  2197.       return(NULLHANDLE);
  2198.    }
  2199.  
  2200.                                         /* We wanna set the TabText of the   */
  2201.                                         /* notebook to the dialog title      */
  2202.                                         /* because of NLS. We get this       */
  2203.                                         /* information from the system, thus,*/
  2204.                                         /* we get the resource from the      */
  2205.                                         /* program module and look for the   */
  2206.                                         /* title value.                      */
  2207.    DosQueryResourceSize(0,
  2208.                         RT_DIALOG,
  2209.                         DlgId,
  2210.                         &size);
  2211.    if (size >= sizeof(DLGTEMPLATE)) {   /* values acceptable?                */
  2212.       DosGetResource(0,                 /* load dialog                       */
  2213.                      RT_DIALOG,
  2214.                      DlgId,
  2215.                      (PPVOID)(&pdlg));
  2216.       if (pdlg->offadlgti + sizeof(DLGTITEM) <= size) {  /* first item       */
  2217.                                         /* within valid memory?              */
  2218.          pitem = (PDLGTITEM) ((char *) pdlg + pdlg->offadlgti);
  2219.                                         /* pitem should be the title element */
  2220.          if (pitem->offText + pitem->cchText <= size) {  /* title accessable?*/
  2221.             strncpy(buf,(char *) pdlg + pitem->offText,255);
  2222.             buf[255] = 0;
  2223.             Tabtext = buf;
  2224.             if ((Statusline = strchr(buf,'|')) != NULL)
  2225.                *Statusline++ = 0;
  2226.          }
  2227.       }
  2228.       DosFreeResource(pdlg);
  2229.    }
  2230.  
  2231.    if (Statusline != NULL)              /* Statusline defined?               */
  2232.       WinSendMsg(pages,
  2233.                  BKM_SETSTATUSLINETEXT,
  2234.                  MPFROMLONG(PageId),
  2235.                  MPFROMP(Statusline));
  2236.  
  2237.    if (majorminor == 0)                 /* don't process any tab related     */
  2238.       return(hwndPage);                 /* statements und return gracefully  */
  2239.  
  2240.    WinSendMsg(pages,                    /* set the new tabtext               */
  2241.               BKM_SETTABTEXT,
  2242.               MPFROMLONG(PageId),
  2243.               MPFROMP(Tabtext));
  2244.                                         /* calculate the length and height   */
  2245.    hps = WinGetPS(pages);
  2246.    if (!GpiQueryFontMetrics(hps,
  2247.                             sizeof(metric),
  2248.                             &metric))
  2249.       FatalWinError((HWND) 0);
  2250.    GpiQueryTextBox(hps,strlen(Tabtext),Tabtext,TXTBOX_TOPRIGHT + 1,box);
  2251.    box[TXTBOX_TOPRIGHT].x += 2 * metric.lAveCharWidth;   /* some space around*/
  2252.    if (maxtext->x < box[TXTBOX_TOPRIGHT].x)
  2253.       maxtext->x = box[TXTBOX_TOPRIGHT].x;
  2254.    maxtext->y = metric.lMaxBaselineExt + 2 * (metric.lInternalLeading +
  2255.                                                       metric.lExternalLeading);
  2256.    *pgbutton = (SHORT) metric.lMaxBaselineExt;
  2257.    WinReleasePS(hps);
  2258.    return(hwndPage);
  2259. }
  2260.  
  2261. /*****************************************************************************/
  2262. /*  function name : StartNoteBook                                            */
  2263. /*                                                                           */
  2264. /*  arguments     : handle of the notebook dialog window                     */
  2265. /*                                                                           */
  2266. /*  return value  : window handle of the first notebook page or NULLHANDLE   */
  2267. /*                  in case of an error.                                     */
  2268. /*                                                                           */
  2269. /*  description   : prepares the notebook. All sub-dialogs will be           */
  2270. /*                  included and the colors will be set to default dialog    */
  2271. /*                  colors.                                                  */
  2272. /*****************************************************************************/
  2273. static ULONG StartNoteBook(HWND hwnd)
  2274. {
  2275.    HWND hwndPages;
  2276.    POINTL maxmajor,maxminor;
  2277.    SHORT pgbutton;
  2278.    HWND FirstPage;
  2279.  
  2280.    hwndPages = WinWindowFromID(hwnd,NLS(IDDE_NOTEBOOK_PAGES));
  2281.    WinSendMsg(hwndPages,
  2282.               BKM_SETNOTEBOOKCOLORS,
  2283.               MPFROMLONG(SYSCLR_DIALOGBACKGROUND),
  2284.               MPFROMSHORT(BKA_BACKGROUNDPAGECOLORINDEX));
  2285.    WinSendMsg(hwndPages,
  2286.               BKM_SETNOTEBOOKCOLORS,
  2287.               MPFROMLONG(SYSCLR_DIALOGBACKGROUND),
  2288.               MPFROMSHORT(BKA_BACKGROUNDMAJORCOLORINDEX));
  2289.    WinSendMsg(hwndPages,
  2290.               BKM_SETNOTEBOOKCOLORS,
  2291.               MPFROMLONG(SYSCLR_DIALOGBACKGROUND),
  2292.               MPFROMSHORT(BKA_BACKGROUNDMINORCOLORINDEX));
  2293.    maxmajor.x = maxmajor.y = 0;
  2294.    maxminor.x = maxminor.y = 0;
  2295.                                         /* now, insert the pages             */
  2296.    if ((FirstPage = InsertDlgIntoNoteBook(hwndPages,
  2297.                                           NLS(IDD_CRON_FILE),
  2298.                                           CronDlgProc,
  2299.                                           "1 (2)", /* not used               */
  2300.                                           "1",  /* not used                  */
  2301.                                           &maxmajor,
  2302.                                           BKA_MAJOR,
  2303.                                           &pgbutton)) != NULLHANDLE)
  2304.       InsertDlgIntoNoteBook(hwndPages,  /* insert the sub-page on success    */
  2305.                             NLS(IDD_CRONTABS),  /* only                      */
  2306.                             CrontabsDlgProc,
  2307.                             "2 (2)",    /* not used                          */
  2308.                             "",         /* not used                          */
  2309.                             &maxminor,
  2310.                             BKA_MINOR,
  2311.                             &pgbutton);
  2312.  
  2313.    InsertDlgIntoNoteBook(hwndPages,
  2314.                          NLS(IDD_OUTPUT),
  2315.                          OutputDlgProc,
  2316.                          NULL,
  2317.                          "2",           /* not used                          */
  2318.                          &maxmajor,
  2319.                          BKA_MAJOR,
  2320.                          &pgbutton);
  2321.    InsertDlgIntoNoteBook(hwndPages,
  2322.                          NLS(IDD_TCP),
  2323.                          TCPIPDlgProc,
  2324.                          NULL,
  2325.                          "3",           /* not used                          */
  2326.                          &maxmajor,
  2327.                          BKA_MAJOR,
  2328.                          &pgbutton);
  2329.    InsertDlgIntoNoteBook(hwndPages,
  2330.                          NLS(IDD_GENERAL),
  2331.                          GeneralDlgProc,
  2332.                          NULL,
  2333.                          "4",           /* not used                          */
  2334.                          &maxmajor,
  2335.                          BKA_MAJOR,
  2336.                          &pgbutton);
  2337.  
  2338.    WinSendMsg(hwndPages,                /* set the tab size                  */
  2339.               BKM_SETDIMENSIONS,
  2340.               MPFROM2SHORT((SHORT) maxmajor.x,(SHORT) maxmajor.y),
  2341.               MPFROMSHORT(BKA_MAJORTAB));
  2342.    WinSendMsg(hwndPages,                /* set the minor tab size            */
  2343.               BKM_SETDIMENSIONS,
  2344.               MPFROM2SHORT((SHORT) maxminor.x,(SHORT) maxminor.y),
  2345.               MPFROMSHORT(BKA_MINORTAB));
  2346.    WinSendMsg(hwndPages,                /* set the button size               */
  2347.               BKM_SETDIMENSIONS,
  2348.               MPFROM2SHORT(pgbutton,pgbutton),
  2349.               MPFROMSHORT(BKA_PAGEBUTTON));
  2350.    return(FirstPage);
  2351. }
  2352.  
  2353. /*****************************************************************************/
  2354. /*  function name : ResizePages                                              */
  2355. /*                                                                           */
  2356. /*  arguments     : frame window handle of the notebook dialog               */
  2357. /*                                                                           */
  2358. /*  description   : the frame and its client must been formatted.            */
  2359. /*                  the function computes the size of the client window      */
  2360. /*                  and sets the notebook to the full size.                  */
  2361. /*****************************************************************************/
  2362. static void ResizePages(HWND hwnd)
  2363. {
  2364.    SWP swp;
  2365.    RECTL rcl;
  2366.                                         /* The frame and its client must been*/
  2367.                                         /* formatted. (hwnd is the frame)    */
  2368.                                         /* Compute the size of the client    */
  2369.                                         /* window                            */
  2370.    WinQueryWindowPos(hwnd,&swp);
  2371.    rcl.xLeft = rcl.xRight = swp.x;
  2372.    rcl.yBottom = rcl.yTop = swp.y;
  2373.    rcl.xRight += swp.cx;
  2374.    rcl.yTop += swp.cy;
  2375.                                         /* rcl contents the frame RECTL      */
  2376.    WinCalcFrameRect(hwnd,&rcl,TRUE);
  2377.                                         /* now it contents the client RECTL  */
  2378.  
  2379.                                         /* query the notebook SWP            */
  2380.    WinQueryWindowPos(WinWindowFromID(hwnd,NLS(IDDE_NOTEBOOK_PAGES)),&swp);
  2381.                                         /* and set it back with the newly    */
  2382.                                         /* calculated size                   */
  2383.    WinSetWindowPos(WinWindowFromID(hwnd,NLS(IDDE_NOTEBOOK_PAGES)),
  2384.                    swp.hwndInsertBehind,
  2385.                    swp.x,
  2386.                    swp.y,
  2387.                    rcl.xRight - rcl.xLeft,
  2388.                    rcl.yTop - rcl.yBottom,
  2389.                    swp.fl);
  2390. }
  2391.  
  2392. /*****************************************************************************/
  2393. /*  function name : NotebookDlgProc                                          */
  2394. /*                                                                           */
  2395. /*  arguments     : see WinDefDlgProc                                        */
  2396. /*                                                                           */
  2397. /*  return value  : see WinDefDlgProc                                        */
  2398. /*                                                                           */
  2399. /*  description   : see WinDefDlgProc, we process some special events        */
  2400. /*                  here. The associated dialog is IDD_NOTEBOOK.             */
  2401. /*                  This function services the notebook related windows.     */
  2402. /*                                                                           */
  2403. /*  note          : don't call directly. This function is called by PM.      */
  2404. /*****************************************************************************/
  2405. static MRESULT EXPENTRY NotebookDlgProc(HWND hwnd,ULONG msg,MPARAM mp1,
  2406.                                                                     MPARAM mp2)
  2407. {
  2408.    MRESULT result;
  2409.  
  2410.    switch (msg) {
  2411.       case WM_FORMATFRAME:              /* We want to adjust the client      */
  2412.                                         /* dialogs within the notebook to    */
  2413.                                         /* the full size.                    */
  2414.          result = WinDefDlgProc(hwnd,msg,mp1,mp2);
  2415.          ResizePages(hwnd);
  2416.          return(result);
  2417.  
  2418.       case WM_INITDLG:                  /* create the notebook and post its  */
  2419.          WinPostMsg(hwnd,               /* first window handle to ourself to */
  2420.                     WM_USER,            /* activate the window after all     */
  2421.                     MPFROMLONG(StartNoteBook(hwnd)),  /* initializations     */
  2422.                     MPVOID);
  2423.          ResizePages(hwnd);
  2424.          break;
  2425.  
  2426.       case WM_USER:
  2427.          WinSetActiveWindow(HWND_DESKTOP,(HWND) mp1);
  2428.          return(MPFROMSHORT(TRUE));     /* we've processed the message       */
  2429.  
  2430.    }
  2431.    return(WinDefDlgProc(hwnd,msg,mp1,mp2));
  2432. }
  2433.  
  2434. /*****************************************************************************/
  2435. /*  function name : DisableMenuEntry                                         */
  2436. /*                                                                           */
  2437. /*  arguments     : id of the item of the main menu                          */
  2438. /*                                                                           */
  2439. /*  description   : disables the access to the given menu entry.             */
  2440. /*****************************************************************************/
  2441. static void DisableMenuEntry(USHORT id)
  2442. {
  2443.    WinSendMsg(WinWindowFromID(hwndFrame,FID_MENU),
  2444.               MM_SETITEMATTR,
  2445.               MPFROM2SHORT(id,TRUE),
  2446.               MPFROM2SHORT(MIA_DISABLED,MIA_DISABLED));
  2447. }
  2448.  
  2449. /*****************************************************************************/
  2450. /*  function name : ClientWndProc                                            */
  2451. /*                                                                           */
  2452. /*  arguments     : see WinDefWindowProc                                     */
  2453. /*                                                                           */
  2454. /*  return value  : see WinDefWindowProc                                     */
  2455. /*                                                                           */
  2456. /*  description   : see WinDefFileDlgProc, we process some special events    */
  2457. /*                  here. The function is called by WinCreateStdWindow.      */
  2458. /*                  This is the user visible main process and interface.     */
  2459. /*                                                                           */
  2460. /*  note          : don't call directly. This function is called by PM.      */
  2461. /*****************************************************************************/
  2462. MRESULT EXPENTRY ClientWndProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
  2463. {
  2464.    HWND menu;
  2465. #if 0
  2466.                                         /* let's catch all messages and look */
  2467.                                         /* for an interesting and unprocessed*/
  2468.                                         /* message                           */
  2469.    DumpMessage(hwnd,msg,mp1,mp2);
  2470. #endif
  2471.    switch (msg) {
  2472.       case WM_CREATE:                   /* we want to initialize the help    */
  2473.                                         /* window. I think, it'll look nicer */
  2474.                                         /* to open the window before         */
  2475.                                         /* displaying any errors...          */
  2476.          WinPostMsg(hwnd,WM_USER + 1,MPVOID,MPVOID);
  2477.          break;
  2478.  
  2479.       case WM_DESTROY:
  2480.          DestroyHelpInstance();
  2481.          break;
  2482.  
  2483.       case WM_CLOSE:                    /* don't close on the first time!    */
  2484.          GlobalStop++;                  /* set the stop flag and inform the  */
  2485.          if (CronSem != (HEV) 0)        /* cron thread to terminate. On its  */
  2486.             DosPostEventSem(CronSem);   /* termination it will send us one   */
  2487.          if (pipehandle != -1)          /* more WM_CLOSE. This will be       */
  2488.             close(pipehandle);          /* passed und the window and the     */
  2489.          pipehandle = -1;               /* process dies. Nice: double close  */
  2490.          if (GlobalStop == 1)           /* by the user is processed and we   */
  2491.             return(MPFROMLONG(0));      /* die at once.                      */
  2492.          break;
  2493.  
  2494.       case WM_ERASEBACKGROUND:          /* don't erase! WM_PAINT is send in  */
  2495.          return(MPFROMSHORT(FALSE));    /* the following and will do all.    */
  2496.  
  2497.       case WM_PRESPARAMCHANGED:         /* one of the presentation parameters*/
  2498.                                         /* has changed. We must repaint (and */
  2499.                                         /* use the new values) in case of    */
  2500.                                         /* foreground and background colors  */
  2501.                                         /* and if the font changes. Note:    */
  2502.                                         /* SysValue changes causes a WM_PAINT*/
  2503.                                         /* Thus, there is no need to look for*/
  2504.                                         /* a WM_SYSVALUECHANGED or a         */
  2505.                                         /* WM_SYSCOLORCHANGE                 */
  2506.          if (((ULONG) mp1 == PP_FOREGROUNDCOLOR) ||
  2507.              ((ULONG) mp1 == PP_BACKGROUNDCOLOR) ||
  2508.              ((ULONG) mp1 == PP_FONTNAMESIZE))
  2509.             RePaintAll(hwnd,msg);
  2510.          break;
  2511.  
  2512.       case WM_PAINT:                    /* repaint the complete window       */
  2513.          RePaintAll(hwnd,msg);
  2514.          return(MPFROMLONG(0));
  2515.  
  2516.       case WM_USER:                     /* One state of the user visible     */
  2517.          if ((ULONG) mp1 != WINDOW_REFRESH)  /* states has changed. Show it. */
  2518.             break;
  2519.          RePaintLine(hwnd,(int) mp2);   /* mp2 is the number of the status   */
  2520.          return(MPFROMLONG(0));         /* line which contents has changed   */
  2521.  
  2522.       case WM_USER + 1:                 /* initialize the help window        */
  2523.          if (!InitHelp()) {
  2524.             DisableMenuEntry(NLS(IDME_HELPINDEX));
  2525.             DisableMenuEntry(NLS(IDME_HELPGENERAL));
  2526.             DisableMenuEntry(NLS(IDME_HELPUSINGHELP));
  2527.             DisableMenuEntry(NLS(IDME_HELPKEYS));
  2528.          }
  2529.          return(MPFROMLONG(0));
  2530.  
  2531.       case WM_INITMENU:
  2532.          if (ProgramFlags & PRG_OUTPUT_IS_NUL)
  2533.             DisableMenuEntry(NLS(IDME_NEXTFILE));
  2534.          else
  2535.             WinSendMsg((HWND) mp2,
  2536.                        MM_SETITEMATTR,
  2537.                        MPFROM2SHORT(NLS(IDME_NEXTFILE),TRUE),
  2538.                        MPFROM2SHORT(MIA_DISABLED,0));
  2539.          break;
  2540.  
  2541.       case WM_MOVE:                     /* save the new window position      */
  2542.          SetPosOfWindow(hwndFrame);
  2543.          break;
  2544.  
  2545.       case HM_QUERY_KEYS_HELP:
  2546.                                         /*return id of key help panel        */
  2547.           return((MRESULT) (unsigned) NLS(IDME_HELPKEYS));
  2548.           break;
  2549.  
  2550.       case WM_COMMAND:
  2551.          menu = WinWindowFromID(hwndFrame,FID_MENU);
  2552.          switch(NONLS(LOUSHORT(mp1))) {
  2553.             case IDME_NEXTFILE:         /* set next output file              */
  2554.                BlockOutput();
  2555.                if (NextOutputFile(0) == -1) {
  2556.                   UnBlockOutput();
  2557.                   Error(Get(IDS_NoOutputFile),(HWND) 0);
  2558.                } else
  2559.                   UnBlockOutput();
  2560.                break;
  2561.  
  2562.             case IDD_NOTEBOOK:          /* Start the Notebook                */
  2563.                if (WinDlgBox(HWND_DESKTOP,
  2564.                              hwndFrame,
  2565.                              NotebookDlgProc,
  2566.                              0,
  2567.                              NLS(IDD_NOTEBOOK),
  2568.                              (PSZ) NULL) == DID_ERROR)
  2569.                   WinError((HWND) 0);
  2570.                break;
  2571.  
  2572.             case IDME_HELPINDEX:
  2573.                DefaultHelp(HM_HELP_INDEX);
  2574.                break;
  2575.  
  2576.             case IDME_HELPGENERAL:
  2577.                DefaultHelp(HM_EXT_HELP);
  2578.                break;
  2579.  
  2580.             case IDME_HELPUSINGHELP:
  2581.                DefaultHelp(HM_DISPLAY_HELP);
  2582.                break;
  2583.  
  2584.             case IDME_HELPKEYS:
  2585.                DefaultHelp(HM_KEYS_HELP);
  2586.                break;
  2587.  
  2588.             case IDD_ABOUT:             /* show the about box                */
  2589.                if (WinDlgBox(HWND_DESKTOP,
  2590.                              hwndFrame,
  2591.                              WinDefDlgProc,
  2592.                              0,
  2593.                              NLS(IDD_ABOUT),
  2594.                              (PSZ) NULL) == DID_ERROR)
  2595.                   WinError((HWND) 0);
  2596.                break;
  2597.  
  2598.          }
  2599.          break;
  2600.    }
  2601.    return(WinDefWindowProc(hwnd,msg,mp1,mp2));
  2602. }
  2603.  
  2604. /*****************************************************************************/
  2605. /*  function name : PMNewProgramStatus                                       */
  2606. /*                                                                           */
  2607. /*  arguments     : ID of the resource string which should be display as     */
  2608. /*                  the new program status, use IDS_Status...-strings        */
  2609. /*                                                                           */
  2610. /*  description   : displays the new program status (normal, at startup,     */
  2611. /*                  etc.) on the program status line.                        */
  2612. /*****************************************************************************/
  2613. void PMNewProgramStatus(ULONG NewStatus)
  2614. {                                       /* string acceptable?                */
  2615.    if ((NewStatus >= IDS_StatusAtStartup) &&
  2616.                                       (NewStatus <= IDS_StatusCommunication)) {
  2617.       CurrentState = NewStatus;
  2618.       if (hwndClient != 0)              /* client is up? send the client:    */
  2619.                                         /* line 0 has changed                */
  2620.          WinPostMsg(hwndClient,WM_USER,(MPARAM) WINDOW_REFRESH,(MPARAM) 0);
  2621.    }
  2622. }
  2623.  
  2624. /*****************************************************************************/
  2625. /*  function name : PMNewStartTime                                           */
  2626. /*                                                                           */
  2627. /*  arguments     : time of the job that will be started next.               */
  2628. /*                                                                           */
  2629. /*  description   : displays the time of the next starting job on the        */
  2630. /*                  related display line. The time may be (time_t) -1. In    */
  2631. /*                  this case there are either no periodically running       */
  2632. /*                  jobs or no job time is in the computing distance (24-    */
  2633. /*                  48 hours)                                                */
  2634. /*****************************************************************************/
  2635. void PMNewStartTime(time_t time)
  2636. {
  2637.    NextStartTime = time;
  2638.    if (hwndClient != 0)                 /* client is up? send the client:    */
  2639.                                         /* line 1 has changed                */
  2640.       WinPostMsg(hwndClient,WM_USER,(MPARAM) WINDOW_REFRESH,(MPARAM) 1);
  2641. }
  2642.  
  2643. /*****************************************************************************/
  2644. /*  function name : PMNewOutputFile                                          */
  2645. /*                                                                           */
  2646. /*  description   : displays the current output file on the related          */
  2647. /*                  display line.                                            */
  2648. /*****************************************************************************/
  2649. void PMNewOutputFile(void)
  2650. {
  2651.    if (hwndClient != 0)                 /* client is up? send the client:    */
  2652.                                         /* line 1 has changed                */
  2653.       WinPostMsg(hwndClient,WM_USER,(MPARAM) WINDOW_REFRESH,(MPARAM) 3);
  2654. }
  2655.  
  2656. /*****************************************************************************/
  2657. /*  function name : PMStopPM                                                 */
  2658. /*                                                                           */
  2659. /*  description   : Send the PM window a WM_CLOSE. The program should        */
  2660. /*                  terminate. The window has already received a WM_CLOSE    */
  2661. /*                  and will die now since StopPM is called from the         */
  2662. /*                  daemon thread.                                           */
  2663. /*                                                                           */
  2664. /*  note          : don't call if you don't know what you are doing!         */
  2665. /*****************************************************************************/
  2666. void PMStopPM(void)
  2667. {
  2668.    WinPostMsg(hwndClient,WM_CLOSE,MPVOID,MPVOID);
  2669. }
  2670.  
  2671. /*****************************************************************************/
  2672. /*  function name : PMJobsModified                                           */
  2673. /*                                                                           */
  2674. /*  description   : Send the notebook dialog "Crontabs" a WM_USER. This      */
  2675. /*                  will advise it to refresh since the list of jobs has     */
  2676. /*                  been changed.                                            */
  2677. /*****************************************************************************/
  2678. void PMJobsModified(void)
  2679. {
  2680.    if (CrontabsWindow != (HWND) 0)
  2681.       WinPostMsg(CrontabsWindow,WM_USER,MPVOID,MPVOID);
  2682. }
  2683.  
  2684. /*****************************************************************************/
  2685. /*  function name : PMStop                                                   */
  2686. /*                                                                           */
  2687. /*  arguments     : signal number generated by the runtime system            */
  2688. /*                                                                           */
  2689. /*  description   : This is a signal routine. This routine will shut down    */
  2690. /*                  the program gracefully if the user or the system sends   */
  2691. /*                  a signal (SIG_TERM, ^C or ^Break)                        */
  2692. /*                  On the first call the programm will be stoped normally   */
  2693. /*                  (with atexit execution in the cron thread). On the       */
  2694. /*                  second call the program dies with exit since we can      */
  2695. /*                  assume that the user has detected an error in the        */
  2696. /*                  atexit exeution and wants an emergency stop.             */
  2697. /*                  We must be very careful. If the signal is SIG_TERM       */
  2698. /*                  the runtime system will stop the program on              */
  2699. /*                  return. This isn't acceptable. Therefore we need the     */
  2700. /*                  use of longjmp.                                          */
  2701. /*                                                                           */
  2702. /*  note          : don't call directly                                      */
  2703. /*****************************************************************************/
  2704. void PMStop(int code)
  2705. {
  2706.    static int first = 1;
  2707.    if (first) {                         /* first call?                       */
  2708.       first = 0;
  2709.       GlobalStop++;                     /* show other threads this circum-   */
  2710.                                         /* stance                            */
  2711.       if (CronSem != (HEV) 0)           /* cron thread alive? awake it!      */
  2712.          DosPostEventSem(CronSem);      /* let atexit execution run          */
  2713.       if (pipehandle != -1)             /* Pipe open? close it, maybe it has */
  2714.          close(pipehandle);             /* blocked the joblist               */
  2715.       pipehandle = -1;
  2716.       signal(code,SIG_ACK);
  2717.       if (SetJumpEnabled)               /* can we use longjmp?               */
  2718.          longjmp(PrgEnd,1);
  2719.       else
  2720.          exit(0);
  2721.    }
  2722.                                         /* else called twice                 */
  2723.    signal(code,SIG_IGN);
  2724.    FatalError(Get(IDS_DieOnSigSig),(HWND) 0);
  2725. }
  2726.  
  2727. /* RCS depending informations
  2728.  *
  2729.  * $Name: Version121 $
  2730.  *
  2731.  * $Log: cron_pm.c $
  2732.  * Revision 1.6  1996/05/09 09:59:33  Florian
  2733.  * Problems with blanks in the help filename fixed.
  2734.  *
  2735.  * Revision 1.5  1995/10/18 09:46:08  Florian
  2736.  * Some cosmetic changes, of course.
  2737.  * Used font, colors and window state will be reused on restart.
  2738.  * Determination and displaying of possible output drives rewritten.
  2739.  * Crontabs window enhanced, user may change entries and may use the
  2740.  * clipboard, pushbutton selection changed to possible values.
  2741.  *
  2742.  * Revision 1.4  1995/08/03 07:43:46  Florian
  2743.  * NLS supported (English and German)
  2744.  *
  2745.  * Revision 1.3  1995/03/06 11:52:11  Florian
  2746.  * Many bugs fixed.
  2747.  * Fully supported online help.
  2748.  * Notebook layout revised.
  2749.  *
  2750.  * Revision 1.2  1995/02/20 12:53:23  Florian
  2751.  * All dialogs are placed into a notebook.
  2752.  * Some bugs fixed.
  2753.  *
  2754.  * Revision 1.1  1995/02/03 10:42:25  Florian
  2755.  * Initial revision
  2756.  *
  2757.  *
  2758.  */
  2759. static char rcsid[] = "@(#)$Id: cron_pm.c 1.6 1996/05/09 09:59:33 Florian Exp $";
  2760.