home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / wps / tools / filebar / source / filebar.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-18  |  229.9 KB  |  4,880 lines

  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. //                                FileBar
  4. //
  5. //         OS/2 Application Launch Facility and WPS Shell Replacement
  6. //
  7. //                         Written By Eric A. Wolf
  8. //                 Copyright (C) 1994 - All Rights Reserved
  9. //
  10. // This source code may be used for reference ONLY!  It is provided AS-IS and no
  11. // guarantees are made as to its utility, functionality or correctness.  It is
  12. // provided solely as a guide to aid aspiring OS/2 2.x Presentation Manager
  13. // programmers in developing their own PM applications.  No modifications are
  14. // to be made to this code for re-release as a same or different product.  This
  15. // code must be distributed (in its original entirety) with the executable
  16. // portion of this product.
  17. //
  18. //          -- Please register this shareware product for $10 today --
  19. //                          See documentation for details
  20. //
  21. // Project Start Date:      December 26, 1993
  22. // Project Completion Date: January   3, 1994
  23. //
  24. // Written using Borland C++ for OS/2, version 1.0, Borland Resource Workshop,
  25. //               and the IBM OS/2 2.1 bitmap/icon editor
  26. //
  27. // File Last Modified:      March 8, 1994
  28. //
  29. ////////////////////////////////////////////////////////////////////////////////
  30.  
  31.  
  32. ////////////////////////////////////////////////////////////////////////////////
  33. // set compile-time flags for what os/2 header information should be included
  34. ////////////////////////////////////////////////////////////////////////////////
  35. #define INCL_PM
  36. #define INCL_DOSSESMGR
  37. #define INCL_DOSERRORS
  38. #define INCL_DOSMISC
  39. #define INCL_WINPOINTERS
  40. #define INCL_WINPROGRAMLIST
  41. #define INCL_WINSTDFILE
  42. #define INCL_WINWORKPLACE
  43. #define INCL_DOSPROCESS
  44.  
  45. ////////////////////////////////////////////////////////////////////////////////
  46. // include C, C++, OS/2, application and resource header files
  47. ////////////////////////////////////////////////////////////////////////////////
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50. #include <ctype.h>
  51. #include <string.h>
  52. #include <time.h>
  53. #include "filebar.h"
  54. #include "dll/filebar.h"                      // include DLL function prototypes
  55.  
  56. ////////////////////////////////////////////////////////////////////////////////
  57. // MakeHourglassPointer - macro to make the mouse pointer the hourglass
  58. ////////////////////////////////////////////////////////////////////////////////
  59. #define MakeHourglassPointer() {                                                               \
  60.                                  HPOINTER pointer;                                             \
  61.                                  pointer = WinQuerySysPointer( HWND_DESKTOP, SPTR_WAIT, FALSE);\
  62.                                  WinSetPointer( HWND_DESKTOP, pointer );                       \
  63.                                }
  64.  
  65.  
  66. ////////////////////////////////////////////////////////////////////////////////
  67. // MakeArrowPointer - macro to make the mouse pointer the arrow
  68. ////////////////////////////////////////////////////////////////////////////////
  69. #define MakeArrowPointer() {                                                                \
  70.                              HPOINTER pointer;                                              \
  71.                              pointer = WinQuerySysPointer( HWND_DESKTOP, SPTR_ARROW, FALSE);\
  72.                              WinSetPointer( HWND_DESKTOP, pointer );                        \
  73.                            }
  74.  
  75.  
  76. ////////////////////////////////////////////////////////////////////////////////
  77. // writeString - writes a string out with quotes on either side
  78. ////////////////////////////////////////////////////////////////////////////////
  79. #define writeString(stream, string) fprintf(stream, "\"%s\"\n", string)
  80.  
  81.  
  82. ////////////////////////////////////////////////////////////////////////////////
  83. // define application constants
  84. ////////////////////////////////////////////////////////////////////////////////
  85. #define EXTERN
  86. #define TEMPSTRING            64
  87. #define AT_TOP                TRUE
  88. #define AT_BOTTOM             FALSE
  89. #define TIMERID               1
  90. #define MAXTASKS              30
  91. #define MAXMENUS              7
  92. #define MAXITEMS              24
  93. #define MAXPATH               CCHMAXPATH+1
  94. #define MAXACTIONSTRINGLENGTH MAXPATH
  95. #define MAXITEMNAMELENGTH     24
  96. #define MAXMENUNAMELENGTH     20
  97. #define MAXARGSTRINGLENGTH    32
  98. #define MAXDIRSTRINGLENGTH    MAXPATH
  99. #define WINDOWED              1
  100. #define FULLSCREEN            2
  101. #define PM                    4
  102. #define DOS                   8
  103. #define OS2                   16
  104. #define WINOS2                32
  105. #define STARTMIN              64
  106. #define STARTMAX              128
  107. #define WPSFOLDER             256
  108. #define STARTASWPS            512
  109. #define SCALED                128
  110. #define TILED                 64
  111. #define OS2SHELL              "CMD.EXE"
  112. #define OPTIONFILE            "FILEBAR.INI"
  113. #define LAUNCHFILE            "STARTPRG.CMD"
  114. #define LAUNCHINPUTS          "/C STARTPRG.CMD"
  115. #define SEPARATOR             "────────────────────────"
  116. #define WPSDESKTOPNAME        "Desktop"
  117. #define FILEBARMENUON         "~FileBar"
  118. #define FILEBARMENUOFF        "\x04"
  119. #define TASKMENUON            "~Task List"
  120. #define TASKMENUOFF           "~Tasks"
  121. #define STARTINPUT            '['
  122. #define ENDINPUT              ']'
  123. #define BITMAPNAME            "\\FILEBAR.BMP\0"
  124. #define CHIMESOUNDFILE        "\\CHIME.WAV\0"
  125. #define NOCOLOR               1
  126. #define MAXSTARTITEMS         10
  127. #define WPSBUFFER             4096
  128. #define MAXALARMS             32
  129. #define SCHEDULE_EVERYHOUR    1
  130. #define SCHEDULE_EVERYDAY     2
  131. #define SCHEDULE_EVERYWEEK    4
  132. #define SCHEDULE_EVERYMONTH   8
  133. #define SCHEDULE_EVERYYEAR    16
  134. #define SCHEDULE_USEWAVFILE   32
  135. #define SCHEDULE_SOUNDONLY    64
  136. #define SCHEDULE_LAUNCHAPP    128
  137. #define BOOLEAN               INT
  138. #define LAUNCHED              0
  139.  
  140. ////////////////////////////////////////////////////////////////////////////////
  141. // define function prototypes
  142. ////////////////////////////////////////////////////////////////////////////////
  143. VOID validateTimeEntry( VOID );
  144. VOID sortTimeEntries( INT );
  145. VOID displayBackground( VOID );
  146. VOID resizeMenu( VOID );
  147. VOID readOptionFile( VOID );
  148. VOID writeOptionFile( VOID );
  149. VOID readString( FILE*, CHAR* );
  150. VOID restartTimer( VOID );
  151. VOID displayTimeDate( VOID );
  152. VOID SwapTwoMenus( SHORT, SHORT );
  153. VOID SwapTwoItems( SHORT, SHORT, SHORT );
  154. VOID updateItemList( HWND );
  155. VOID updateEditItemData( HWND hWnd );
  156. VOID updateEditItemData( HWND hWnd );
  157. VOID ExecuteStartUpList( VOID );
  158. VOID updateCalendar( HWND );
  159. VOID ringChime( CHAR* );
  160. VOID checkAlarms( SHORT, SHORT, SHORT, SHORT, SHORT );
  161. VOID updateTimeDisplay( VOID );
  162. VOID reviseScheduledItem( INT );
  163. BYTE numberOfDaysInMonth( INT, INT );
  164. SHORT startApplication( SHORT, SHORT );
  165. MRESULT EXPENTRY ClientWndProc( HWND, ULONG, MPARAM, MPARAM );
  166. MRESULT EXPENTRY GenericProc( HWND, ULONG, MPARAM, MPARAM );
  167. MRESULT EXPENTRY TimeDateProc( HWND, ULONG, MPARAM, MPARAM );
  168. MRESULT EXPENTRY EditMenuProc( HWND, ULONG, MPARAM, MPARAM );
  169. MRESULT EXPENTRY AddAMenuProc( HWND, ULONG, MPARAM, MPARAM );
  170. MRESULT EXPENTRY EditItemProc( HWND, ULONG, MPARAM, MPARAM );
  171. MRESULT EXPENTRY EditItemDataProc( HWND, ULONG, MPARAM, MPARAM );
  172. MRESULT EXPENTRY AddAnItemProc( HWND, ULONG, MPARAM, MPARAM );
  173. MRESULT EXPENTRY menuHandler( HWND, ULONG, MPARAM, MPARAM );
  174. MRESULT EXPENTRY EnterParamProc( HWND, ULONG, MPARAM, MPARAM );
  175. MRESULT EXPENTRY backgroundProc( HWND, ULONG, MPARAM, MPARAM );
  176. MRESULT EXPENTRY startupProc( HWND, ULONG, MPARAM, MPARAM );
  177. MRESULT EXPENTRY schedulerProc( HWND, ULONG, MPARAM, MPARAM );
  178. MRESULT EXPENTRY scheduleProc( HWND, ULONG, MPARAM, MPARAM );
  179. MRESULT EXPENTRY reminderNoteProc( HWND, ULONG, MPARAM, MPARAM );
  180. MRESULT EXPENTRY itemProc( HWND, ULONG, MPARAM, MPARAM );
  181. MRESULT EXPENTRY showAllItemsProc( HWND, ULONG, MPARAM, MPARAM );
  182. MRESULT EXPENTRY LaunchItemProc( HWND, ULONG, MPARAM, MPARAM );
  183.  
  184. extern "C" {
  185.     #define INCL_REXXSAA
  186.     #include "rexxsaa.h"
  187.     RexxStart rexxStart;
  188.     }
  189.  
  190.  
  191. ////////////////////////////////////////////////////////////////////////////////
  192. // define alarm/task scheduler item structure
  193. ////////////////////////////////////////////////////////////////////////////////
  194. struct ALARMS {
  195.     BYTE  AlarmYear;
  196.     BYTE  AlarmMonth;
  197.     BYTE  AlarmDay;
  198.     BYTE  AlarmHour;
  199.     BYTE  AlarmMinute;
  200.     BYTE  options;
  201.     CHAR  ReminderWAV[MAXACTIONSTRINGLENGTH];
  202.     CHAR  ActionToDo[MAXACTIONSTRINGLENGTH];
  203. };
  204.  
  205.  
  206. ////////////////////////////////////////////////////////////////////////////////
  207. // define global variables
  208. ////////////////////////////////////////////////////////////////////////////////
  209. const    BYTE daysInMonth[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
  210. struct   ALARMS alarm[MAXALARMS];
  211. HAB      hab;
  212. HMQ      hmq;
  213. PID      TaskId[MAXTASKS];
  214. PFNWP    menuMessageHandler;
  215. FILEDLG  fileDlgInfo;
  216. MENUITEM menuData[MAXMENUS];
  217. LONG     ScreenSizeX   = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN) + 2;
  218. LONG     ScreenSizeY   = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  219. LONG     MenuHeight    = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU) + 2;
  220. LONG     sysMenuHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU) + 2;
  221. ULONG    noteTimerNumber;
  222. ULONG    timerNumber;
  223. ULONG    timeOption = TIMEANDDATE;
  224. USHORT   year;
  225. SHORT    day;
  226. SHORT    month;
  227. SHORT    startDay;
  228. SHORT    ItemSelection;
  229. SHORT    MenuSelection;
  230. SHORT    ProgType[MAXMENUS][MAXITEMS];
  231. SHORT    oldProgType;
  232. HWND     hwndClient;
  233. HWND     hwndFrame;
  234. HWND     hwndMenu;
  235. HWND     TaskHandle[MAXTASKS];
  236. BYTE     NumItems[MAXMENUS];
  237. CHAR     MenuName[MAXMENUS][MAXMENUNAMELENGTH];
  238. CHAR     ItemName[MAXMENUS][MAXITEMS][MAXITEMNAMELENGTH];
  239. CHAR     ActionToDo[MAXMENUS][MAXITEMS][MAXACTIONSTRINGLENGTH];
  240. CHAR     CmdLnArgs[MAXMENUS][MAXITEMS][MAXARGSTRINGLENGTH];
  241. CHAR     Directory[MAXMENUS][MAXITEMS][MAXACTIONSTRINGLENGTH];
  242. CHAR     backgroundBitmap[MAXACTIONSTRINGLENGTH];
  243. CHAR     hourlyChimeWavFile[MAXACTIONSTRINGLENGTH];
  244. CHAR     variableText[MAXARGSTRINGLENGTH-2];
  245. CHAR     oldItemName[MAXITEMNAMELENGTH];
  246. CHAR     oldDirectory[MAXACTIONSTRINGLENGTH];
  247. CHAR     oldAction[MAXACTIONSTRINGLENGTH];
  248. CHAR     oldCmdLn[MAXARGSTRINGLENGTH];
  249. CHAR     parameterTitle[MAXITEMNAMELENGTH];
  250. CHAR     tmpBuffer[MAXPATH];
  251. INT      backgroundAttr = 3 + TILED;
  252. INT      numAlarms = 0;
  253. INT      numberOfAlarms;
  254. INT      repeatTime = 60;
  255. INT      EditItem;
  256. INT      NumMenus;
  257. INT      taskItemSelected;
  258. INT      numStartItems = 0;
  259. INT      StartUpMenu[MAXSTARTITEMS];
  260. INT      StartUpItem[MAXSTARTITEMS];
  261. PCHAR    ParameterTextPtr;
  262. PCHAR    currentReminderWavFile;
  263. BOOLEAN  alreadyChimed = FALSE;
  264. BOOLEAN  BarPosition = AT_TOP;
  265. BOOLEAN  HourlyChime = TRUE;
  266. BOOLEAN  FileBarMenuOn = TRUE;
  267. BOOLEAN  timeSync;
  268. BOOLEAN  checkBeforeDelete = TRUE;
  269. BOOLEAN  showBackground = FALSE;
  270. BOOLEAN  isBackgroundDisplayed = FALSE;
  271. BOOLEAN  startUp = TRUE;
  272. BOOLEAN  DoStartUpList = FALSE;
  273. BOOLEAN  UpdateMenu[MAXMENUS];
  274. BOOLEAN  maximizeDesktop = FALSE;
  275. BOOLEAN  interceptMsg = TRUE;
  276.  
  277. ////////////////////////////////////////////////////////////////////////////////
  278. // main function - application entry point
  279. ////////////////////////////////////////////////////////////////////////////////
  280. main( int argc, char* argv[] )
  281. {
  282.     hab = WinInitialize(0);                   // handle: anchor block
  283.     hmq = WinCreateMsgQueue(hab, 0);          // handle: message queue
  284.     CHAR ClassName[] = "FileBar";             // store a name for our class
  285.     MENUITEM menuItem;                        // used to modify menu data
  286.  
  287.     //--------------------------------------------------------------------------
  288.     // register the window class
  289.     //--------------------------------------------------------------------------
  290.     WinRegisterClass(hab,
  291.                      ClassName,      // name of class being registered
  292.                      ClientWndProc,  // window procedure for class
  293.                      0,              // class style
  294.                      0);             // extra memory to reserve
  295.  
  296.     //--------------------------------------------------------------------------
  297.     // create a window with a menu bar added on.  Note that the menu bar could
  298.     // be defined in the WinCreateStdWindow call (set the resource id equal= to
  299.     // MENUBAR) but is not since I need a handle to the menu (so I can later
  300.     // modify the menu).  Thus, WinLoadMenu is used following WinCreateStdWindow
  301.     //--------------------------------------------------------------------------
  302.     ULONG FrameFlags = FCF_AUTOICON|FCF_TASKLIST|FCF_BORDER|FCF_MENU;
  303.     hwndFrame = WinCreateStdWindow(HWND_DESKTOP,       // parent
  304.                                         WS_VISIBLE,    // style
  305.                                         &FrameFlags,   // control data
  306.                                         ClassName,     // client name
  307.                                         "FileBar",     // title bar text
  308.                                         0,             // client style
  309.                                         NULLHANDLE,    // resource handle
  310.                                         MENUBAR,       // resource id
  311.                                         &hwndClient);  // client pointer
  312.  
  313.     //--------------------------------------------------------------------------
  314.     // move and size application to span entire top of desktop
  315.     //--------------------------------------------------------------------------
  316.     WinSetWindowPos( hwndFrame, (HWND)0, 0, (ScreenSizeY-MenuHeight),
  317.                      ScreenSizeX, MenuHeight, SWP_MOVE|SWP_SIZE|SWP_MINIMIZE);
  318.     hwndMenu = WinWindowFromID( hwndFrame, FID_MENU );
  319.  
  320.     MakeHourglassPointer ();                  // switch to hourglass cursor
  321.                                               // during initialization
  322.  
  323.     //--------------------------------------------------------------------------
  324.     // perform basic initialization
  325.     //--------------------------------------------------------------------------
  326.     NumMenus = 0;
  327.     MenuSelection = 100;
  328.  
  329.     // initialize all actions to do nothing
  330.     for ( short i = 0; i < MAXMENUS; i++ )
  331.         for (short j = 0; j < MAXITEMS; j++)
  332.             ActionToDo[i][j][0] = '\0';
  333.  
  334.     for ( short k = 0; k < MAXMENUS; k++ ) {
  335.         WinSendMsg( hwndMenu, MM_QUERYITEM, MPFROM2SHORT(100*(k+1),TRUE),MPFROMP(&menuData[k]));
  336.         menuItem = menuData[k];
  337.         menuItem.afStyle = MIS_STATIC;
  338.         menuItem.afAttribute = MIA_DISABLED;
  339.         menuItem.hwndSubMenu = (HWND)0;
  340.         WinSendMsg( hwndMenu, MM_SETITEM, MPFROM2SHORT(100*(k+1),TRUE),MPFROMP(&menuItem));
  341.         WinSetMenuItemText( hwndMenu, 100*(k+1), "");
  342.         UpdateMenu[ k ] = FALSE;
  343.         NumItems[ k ] = 0;
  344.         }
  345.  
  346.     memset( &fileDlgInfo, 0, sizeof(FILEDLG));
  347.     fileDlgInfo.cbSize = sizeof(fileDlgInfo);
  348.  
  349.     menuMessageHandler = WinSubclassWindow( hwndMenu, menuHandler );
  350.  
  351.     //--------------------------------------------------------------------------
  352.     // change to directory that application executable is started from
  353.     //--------------------------------------------------------------------------
  354.     //DosQueryCurrentDisk( &OS2BootDrive, (ULONG*)&tmpBuffer );
  355.     if (argc > 0) {
  356.         strncpy( tmpBuffer, argv[0], sizeof(tmpBuffer) );
  357.         if (tmpBuffer[1]==':')
  358.             DosSetDefaultDisk( (ULONG)(toupper(tmpBuffer[0])-'A' + 1) );
  359.  
  360.         i = strlen(tmpBuffer);
  361.         while ((tmpBuffer[i]!='\\') && (i>0))
  362.            i--;
  363.  
  364.         if (i) {
  365.             tmpBuffer[i]='\0';
  366.             if (DosSetCurrentDir( tmpBuffer )!=0) {
  367.                 char mesg[]="Could not switch to the directory holding the application";
  368.                 WinMessageBox( HWND_DESKTOP, hwndFrame, mesg, tmpBuffer, 0,
  369.                                MB_MOVEABLE|MB_ERROR|MB_OK);
  370.                 }
  371.             }
  372.         strcpy( backgroundBitmap, tmpBuffer );
  373.         strcat( backgroundBitmap, BITMAPNAME );
  374.         strcpy( hourlyChimeWavFile, tmpBuffer );
  375.         strcat( hourlyChimeWavFile, CHIMESOUNDFILE );
  376.         }
  377.  
  378.     //--------------------------------------------------------------------------
  379.     // record time and date for scheduler program
  380.     //--------------------------------------------------------------------------
  381.     {
  382.         struct tm *time_now;
  383.         time_t currentTime;
  384.  
  385.         tzset();
  386.         time(¤tTime);
  387.         time_now = localtime( ¤tTime );
  388.         month = time_now->tm_mon;
  389.         year = time_now->tm_year;
  390.     }
  391.  
  392.     //--------------------------------------------------------------------------
  393.     // read in the user option file and set up the menu bar appropriately
  394.     // check the user time/date option and put it on the menu bar
  395.     // reset our timer in case they want the current time displayed
  396.     //--------------------------------------------------------------------------
  397.     readOptionFile();                         // read in option file
  398.     sortTimeEntries( numAlarms );             // sort the alarm entries
  399.     restartTimer();                           // resync our clock
  400.     updateTimeDisplay();                      // display current date/time
  401.  
  402.     // make FileBar visible
  403.     WinSetWindowPos( hwndFrame, (HWND)0, 0, 0, 0, 0, SWP_RESTORE);
  404.  
  405.  
  406.     if ((maximizeDesktop) && (BarPosition==AT_TOP)) {
  407.         ULONG numItems;
  408.         ULONG Buffer;
  409.         PSWBLOCK SwitchBlockPtr;
  410.  
  411.         // get the # of items and the switch list from the system
  412.         numItems = WinQuerySwitchList( hab, NULL, 0 );
  413.         Buffer = (numItems * sizeof(SWENTRY)) + sizeof(HSWITCH);
  414.         PVOID my = new BYTE[Buffer];
  415.         WinQuerySwitchList( hab, (SWBLOCK*)my, Buffer );
  416.         SwitchBlockPtr = (PSWBLOCK)(my);
  417.  
  418.         for (short j = 0; j < numItems; j++ )
  419.             if (strcmp(SwitchBlockPtr->aswentry[j].swctl.szSwtitle, WPSDESKTOPNAME) == 0) {
  420.                 WinSetWindowPos( SwitchBlockPtr->aswentry[j].swctl.hwnd,
  421.                                  (HWND)0, 0, 0, 0, 0, SWP_MAXIMIZE);
  422.                 WinSetWindowPos( SwitchBlockPtr->aswentry[j].swctl.hwnd,
  423.                                  (HWND)0, 0, 0, ScreenSizeX,
  424.                                  ScreenSizeY-MenuHeight+sysMenuHeight+1, SWP_MOVE|SWP_SIZE);
  425.                 }
  426.  
  427.         }
  428.  
  429.     displayBackground();                      // restore user background bitmap
  430.     ExecuteStartUpList();                     // start execution list
  431.     MakeArrowPointer ();                      // switch back to arrow pointer,
  432.  
  433.     WinSetParent( hwndFrame, HWND_DESKTOP, FALSE );
  434.     WinSetFocus( HWND_DESKTOP, hwndFrame );
  435.  
  436.     //--------------------------------------------------------------------------
  437.     // initialize our DLL so that we intercept window sizing messages
  438.     //--------------------------------------------------------------------------
  439.     FileBarInit( hwndFrame );
  440.     setFileBarScreen( (BOOL)(BarPosition==AT_TOP), MenuHeight, (interceptMsg==TRUE) );
  441.  
  442.     //--------------------------------------------------------------------------
  443.     // create a message queue and then as long as there are messages to get,
  444.     // get them and dispatch them to our message handlers
  445.     //--------------------------------------------------------------------------
  446.     {
  447.         QMSG qmsg;                                     // create a message queue
  448.  
  449.         while( WinGetMsg( hab, &qmsg, (HWND)0, 0, 0 ) !=FALSE )
  450.             WinDispatchMsg( hab, &qmsg );
  451.     }
  452.  
  453.     //--------------------------------------------------------------------------
  454.     // our application is done.  Destroy timer, window, the message queue and
  455.     // release the DLL.  Call the system to destroy anchor block and do the
  456.     // final clean up work
  457.     //--------------------------------------------------------------------------
  458.     if (timerNumber != 0)
  459.         WinStopTimer( hab, hwndClient, timerNumber );
  460.     FileBarQuit();                                // release the DLL from memory
  461.     WinDestroyWindow(hwndFrame);
  462.     WinDestroyMsgQueue(hmq);
  463.     WinTerminate(hab);
  464.     return 0;
  465. }
  466.  
  467.  
  468. ////////////////////////////////////////////////////////////////////////////////
  469. // a new font has been selected for our menu, resize and redraw the menubar
  470. ////////////////////////////////////////////////////////////////////////////////
  471. VOID resizeMenu()
  472. {
  473.     HPS hps;
  474.     FONTMETRICS fm;
  475.  
  476.     hps = WinGetPS( hwndMenu );
  477.     GpiQueryFontMetrics(hps, sizeof(FONTMETRICS), &fm);
  478.     MenuHeight = fm.lLowerCaseDescent + fm.lMaxAscender + 4;
  479.     if (MenuHeight < (fm.lLowerCaseDescent + fm.lLowerCaseAscent + 2))
  480.         MenuHeight = fm.lLowerCaseDescent + fm.lLowerCaseAscent + 2;
  481.     if (MenuHeight < (WinQuerySysValue(HWND_DESKTOP, SV_CYMENU) + 2))
  482.         MenuHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU) + 2;
  483.     WinReleasePS( hps );
  484.  
  485.     if (BarPosition==AT_BOTTOM)
  486.         WinSetWindowPos( hwndFrame, (HWND)0, 0, -1,
  487.                          ScreenSizeX, MenuHeight, SWP_MOVE|SWP_SIZE);
  488.     else
  489.         WinSetWindowPos( hwndFrame, (HWND)0, 0, (ScreenSizeY-MenuHeight)+1,
  490.                          ScreenSizeX, MenuHeight, SWP_MOVE|SWP_SIZE);
  491.     setFileBarScreen( (BOOL)(BarPosition==AT_TOP), MenuHeight, (interceptMsg==TRUE) );
  492. }
  493.  
  494.  
  495. ////////////////////////////////////////////////////////////////////////////////
  496. // subclassed menu handler for main application window
  497. ////////////////////////////////////////////////////////////////////////////////
  498. MRESULT EXPENTRY menuHandler(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  499. {
  500.     switch (msg) {
  501.         //----------------------------------------------------------------------
  502.         // if a menu has been highlighted, save which one it is so that we know
  503.         // which task to affect if something is chosen off cascading menu
  504.         //----------------------------------------------------------------------
  505.         case WM_MENUSELECT:
  506.         {
  507.             if ((SHORT1FROMMP(mp1)>TASKLIST_MENU) && (SHORT1FROMMP(mp1)<99))
  508.                 taskItemSelected = SHORT1FROMMP(mp1);
  509.         }
  510.         //----------------------------------------------------------------------
  511.         // resize menubar if a font was just dropped on us
  512.         //----------------------------------------------------------------------
  513.         case WM_PRESPARAMCHANGED:
  514.         {
  515.             if ( (ULONG)mp1 == PP_FONTNAMESIZE)
  516.                 resizeMenu();
  517.         }
  518.         //----------------------------------------------------------------------
  519.         // nothing of interest, pass it onto the system for default processing
  520.         //----------------------------------------------------------------------
  521.         default:
  522.             break;
  523.         }
  524.     return menuMessageHandler(hwnd, msg, mp1, mp2);
  525. }
  526.  
  527.  
  528. //////////////////////////////////////////////////////////////////////////////
  529. // This is the message processing facility for the main application thread
  530. ////////////////////////////////////////////////////////////////////////////////
  531. MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  532. {
  533.     switch (msg) {
  534.         //----------------------------------------------------------------------
  535.         // if the application is terminating, write user settings to a file
  536.         //----------------------------------------------------------------------
  537.         case WM_CLOSE:
  538.         case WM_SAVEAPPLICATION:
  539.         case WM_QUIT: {
  540.             writeOptionFile();
  541.             return WinDefWindowProc(hwnd, msg, mp1, mp2);  // default processing
  542.             }
  543.         //----------------------------------------------------------------------
  544.         // the application has been designed such that a WM_TIMER is sent by the
  545.         // system every minute (so that we can update our time on the menubar
  546.         // if necessary)
  547.         //----------------------------------------------------------------------
  548.         case WM_TIMER: {
  549.             if (!timeSync) {
  550.                 WinStopTimer( hab, hwndClient, timerNumber );
  551.                 timerNumber = WinStartTimer( hab, hwndClient, TIMERID, 60000);
  552.                 timeSync = TRUE;
  553.                 }
  554.             displayTimeDate();
  555.             return WinDefWindowProc(hwnd, msg, mp1, mp2);  // default processing
  556.             }
  557.         //----------------------------------------------------------------------
  558.         // a WM_INITMENU message is sent just prior to any pulldown menu being
  559.         // displayed.  This gives us a chance to change its contents before it
  560.         // is displayed.  If necessary, we update menu contents for user menus
  561.         //----------------------------------------------------------------------
  562.         case WM_INITMENU: {
  563.             SHORT menuId = SHORT1FROMMP(mp1);
  564.             //------------------------------------------------------------------
  565.             // if the FileBar menu is being readied for display, make sure the
  566.             // move-bar top/bottom item and check items read appropriately!
  567.             //------------------------------------------------------------------
  568.             if (menuId == FILEBAR_MENU) {
  569.                 if (BarPosition == AT_TOP )
  570.                     WinSetMenuItemText( HWNDFROMMP( mp2 ), FILEBAR_MOVEBAR,
  571.                                         "~Move to Bottom");
  572.                 else
  573.                     WinSetMenuItemText( HWNDFROMMP( mp2 ), FILEBAR_MOVEBAR,
  574.                                         "~Move to Top");
  575.                 WinCheckMenuItem( hwndMenu, FILEBAR_STARTUP, DoStartUpList);
  576.                 WinCheckMenuItem( hwndMenu, FILEBAR_DISPLAYBACKGROUND, showBackground);
  577.                 WinCheckMenuItem( hwndMenu, FILEBAR_FILEBARMENU, (TRUE - FileBarMenuOn));
  578.                 WinCheckMenuItem( hwndMenu, FILEBAR_CONFIRMCLOSE, checkBeforeDelete);
  579.                 WinCheckMenuItem( hwndMenu, FILEBAR_RESIZEWPS, maximizeDesktop);
  580.                 WinCheckMenuItem( hwndMenu, FILEBAR_INTERCEPTMSG, interceptMsg );
  581.                 WinEnableMenuItem( hwndMenu, FILEBAR_RESIZEWPS, (BarPosition==AT_TOP));
  582.                 return WinDefWindowProc(hwnd, msg, mp1, mp2);  // default processing
  583.                 }
  584.             //------------------------------------------------------------------
  585.             // if the user is pulling down the task list, put a current copy of
  586.             // the task list in the menu and store copies of all the tasks id
  587.             // numbers and handles just in case they want to jump to one of them
  588.             //------------------------------------------------------------------
  589.             if (menuId == TASKLIST_MENU) {
  590.                 PCHAR text;
  591.                 MENUITEM menuItem;
  592.                 USHORT index;
  593.                 ULONG numItems;
  594.                 ULONG Buffer;
  595.                 PSWBLOCK SwitchBlockPtr;
  596.  
  597.                 // clear out the menu, get it ready for new task entries
  598.                 for (short i = menuId+1; i <= menuId+MAXITEMS; i++ )
  599.                     WinSendMsg( HWNDFROMMP( mp2 ), MM_DELETEITEM,
  600.                                 MPFROM2SHORT( i, TRUE ), 0 );
  601.  
  602.                 // get the # of items and the switch list from the system
  603.                 numItems = WinQuerySwitchList( hab, NULL, 0 );
  604.                 Buffer = (numItems * sizeof(SWENTRY)) + sizeof(HSWITCH);
  605.                 PVOID my = new BYTE[Buffer];
  606.                 WinQuerySwitchList( hab, (SWBLOCK*)my, Buffer );
  607.  
  608.                 // insert each task as an entry under the task list menu
  609.                 SwitchBlockPtr = (PSWBLOCK)(my);
  610.                 menuItem.iPosition = 0;
  611.                 menuItem.afStyle = MIS_MULTMENU|MIS_SINGLE;
  612.                 menuItem.afAttribute = 0;
  613.                 menuItem.id = TASKLIST_MENU;
  614.  
  615.                 for (short j = 0; j < numItems; j++ ) {
  616.                     menuItem.id++;
  617.                     if ((SwitchBlockPtr->aswentry[j].swctl.uchVisibility != SWL_GRAYED) &&
  618.                         (SwitchBlockPtr->aswentry[j].swctl.uchVisibility != SWL_INVISIBLE) &&
  619.                         (SwitchBlockPtr->aswentry[j].swctl.hwnd != hwndFrame)) {
  620.  
  621.                         // load in the cascading menu for this task entry
  622.                         menuItem.hwndSubMenu = WinLoadMenu(hwndMenu, 0, TASKMENUCLOSE);
  623.  
  624.                         // remove ctrl characters from task list
  625.                         index = 0;
  626.                         text = SwitchBlockPtr->aswentry[j].swctl.szSwtitle;
  627.                         while (text[++index]!='\0')
  628.                             if (text[index]<' ')
  629.                                 text[index]=' ';
  630.  
  631.                         // enter task into the menu structure
  632.                         WinSendMsg( HWNDFROMMP(mp2), MM_INSERTITEM,
  633.                                    (MENUITEM*)&menuItem,
  634.                                   &(SwitchBlockPtr->aswentry[j].swctl.szSwtitle) );
  635.  
  636.                         TaskId[j] = SwitchBlockPtr->aswentry[j].swctl.idProcess;
  637.                         TaskHandle[j] = SwitchBlockPtr->aswentry[j].swctl.hwnd;
  638.                         WinSetWindowBits(menuItem.hwndSubMenu, QWL_STYLE, MS_CONDITIONALCASCADE, MS_CONDITIONALCASCADE);
  639.                         WinSendMsg(menuItem.hwndSubMenu, MM_SETDEFAULTITEMID, MPFROMSHORT(TASK_SWITCHTO), NULL);
  640.                         }
  641.                     }
  642.                 delete( my );
  643.                 return WinDefWindowProc(hwnd, msg, mp1, mp2);  // default processing
  644.                 }
  645.             //------------------------------------------------------------------
  646.             // one of the user menus is being initialized; if it has been marked
  647.             // as needing to be updated, fill the menu with the current items
  648.             // the user has set up
  649.             //------------------------------------------------------------------
  650.             if (menuId >= 100) {
  651.                 int MenuToUpdate = menuId / 100 - 1;
  652.  
  653.                 if ( UpdateMenu[ MenuToUpdate ] ) {
  654.                     UpdateMenu[ MenuToUpdate ] = FALSE;
  655.                         {
  656.                         MENUITEM menuItem;
  657.  
  658.                         for (short i = menuId+1; i < menuId+MAXITEMS+1; i++ )
  659.                             WinSendMsg( HWNDFROMMP( mp2 ), MM_DELETEITEM,
  660.                                         MPFROM2SHORT( i, TRUE ), 0 );
  661.                         menuItem.iPosition = MIT_END;
  662.                         menuItem.afStyle = MIS_TEXT;
  663.                         menuItem.afAttribute = 0;
  664.                         menuItem.hItem = 0;
  665.                         menuItem.hwndSubMenu = (HWND)0;
  666.                         menuItem.id = menuId;
  667.                         for (short j = 0; j < NumItems[ MenuToUpdate ]; j++ ) {
  668.                             menuItem.id++;
  669.                             if (ItemName[MenuToUpdate][j][0] != '\0')
  670.                                 WinSendMsg( HWNDFROMMP(mp2), MM_INSERTITEM,
  671.                                             (MENUITEM*)&menuItem,
  672.                                             ItemName[MenuToUpdate][j] );
  673.                             else {
  674.                                 menuItem.afStyle = MIS_SEPARATOR;
  675.                                 WinSendMsg( HWNDFROMMP(mp2), MM_INSERTITEM,
  676.                                             (MENUITEM*)&menuItem,
  677.                                             ItemName[MenuToUpdate][j] );
  678.                                 menuItem.afStyle = MIS_TEXT;
  679.                                 }
  680.                             }
  681.                         }
  682.                     }
  683.                 }
  684.             }
  685.  
  686.  
  687.         //----------------------------------------------------------------------
  688.         //----------------------------------------------------------------------
  689.         case WM_COMMAND: {
  690.             USHORT command = SHORT1FROMMP(mp1);
  691.  
  692.             //------------------------------------------------------------------
  693.             // uer has altered check state of "resize desktop on boot" item
  694.             //------------------------------------------------------------------
  695.             if ( command == FILEBAR_RESIZEWPS) {
  696.                 maximizeDesktop = TRUE - maximizeDesktop;
  697.                 return 0;
  698.                 }
  699.             //------------------------------------------------------------------
  700.             // user has altered check state of "always on top" item
  701.             //------------------------------------------------------------------
  702.             if ( command == FILEBAR_INTERCEPTMSG) {
  703.                 interceptMsg = TRUE - interceptMsg;
  704.                 setFileBarScreen( (BOOL)(BarPosition==AT_TOP), MenuHeight, (interceptMsg==TRUE) );
  705.                 return 0;
  706.                 }
  707.             //------------------------------------------------------------------
  708.             // show the display background dialog box
  709.             //------------------------------------------------------------------
  710.             if ( command == FILEBAR_STARTUP) {
  711.                 WinDlgBox(HWND_DESKTOP,
  712.                           hwnd,
  713.                           (PFNWP)startupProc,
  714.                           0,
  715.                           STARTUP_DIALOG,
  716.                           (PVOID)NULL);
  717.                 return 0;
  718.                 }
  719.             //------------------------------------------------------------------
  720.             // user has invoked the scheduler
  721.             //------------------------------------------------------------------
  722.             if ( command == TIMEDATE) {
  723.                 WinDlgBox(HWND_DESKTOP,
  724.                           hwnd,
  725.                           (PFNWP)schedulerProc,
  726.                           0,
  727.                           SCHEDULER,
  728.                           (PVOID)NULL);
  729.                 return 0;
  730.                 }
  731.             //------------------------------------------------------------------
  732.             // expand or shrink FileBar system menus
  733.             //------------------------------------------------------------------
  734.             if ( command == FILEBAR_FILEBARMENU) {
  735.                 CHAR menuOn[] = FILEBARMENUON;
  736.                 CHAR menuOff[] = FILEBARMENUOFF;
  737.                 CHAR taskOn[] = TASKMENUON;
  738.                 CHAR taskOff[] = TASKMENUOFF;
  739.  
  740.                 FileBarMenuOn = TRUE - FileBarMenuOn;
  741.                 if (FileBarMenuOn) {
  742.                     WinSetMenuItemText( hwndMenu, FILEBAR_MENU, menuOn);
  743.                     WinSetMenuItemText( hwndMenu, TASKLIST_MENU, taskOn);
  744.                     }
  745.                 else {
  746.                     WinSetMenuItemText( hwndMenu, FILEBAR_MENU, menuOff);
  747.                     WinSetMenuItemText( hwndMenu, TASKLIST_MENU, taskOff);
  748.                     }
  749.                 return 0;
  750.                 }
  751.             //------------------------------------------------------------------
  752.             // show the display background dialog box
  753.             //------------------------------------------------------------------
  754.             if ( command == FILEBAR_DISPLAYBACKGROUND) {
  755.                 WinDlgBox(HWND_DESKTOP,
  756.                           hwnd,
  757.                           (PFNWP)backgroundProc,
  758.                           0,
  759.                           BACKGROUNDWIN,
  760.                           (PVOID)NULL);
  761.                 displayBackground();
  762.                 return 0;
  763.                 }
  764.             //------------------------------------------------------------------
  765.             // user has altered "confirm on task close" check state
  766.             //------------------------------------------------------------------
  767.             if ( command == FILEBAR_CONFIRMCLOSE) {
  768.                 checkBeforeDelete = TRUE - checkBeforeDelete;
  769.                 return 0;
  770.                 }
  771.             //------------------------------------------------------------------
  772.             // close the chosen task
  773.             //------------------------------------------------------------------
  774.             if ( command == TASK_CLOSE) {
  775.                 ULONG numItems;
  776.                 ULONG Buffer;
  777.                 PSWBLOCK SwitchBlockPtr;
  778.                 PID killedTaskId;
  779.                 HWND killedTaskHandle;
  780.  
  781.                 if (checkBeforeDelete) {
  782.                     if (WinMessageBox( HWND_DESKTOP, hwnd,
  783.                                        "Closing may result in the destruction of unsaved data.  Are you sure you want to close this task?",
  784.                                        "FileBar - Close Task", 0,
  785.                                        MB_MOVEABLE|MB_ICONQUESTION|MB_YESNO) == MBID_NO)
  786.                         return 0;
  787.                     }
  788.  
  789.                 killedTaskId = TaskId[taskItemSelected - TASKLIST_MENU - 1];
  790.                 killedTaskHandle = TaskHandle[taskItemSelected - TASKLIST_MENU - 1];
  791.                 WinSendMsg( killedTaskHandle, WM_CLOSE, 0, 0 );
  792.  
  793.                 // get the # of items and the switch list from the system
  794.                 numItems = WinQuerySwitchList( hab, NULL, 0 );
  795.                 Buffer = (numItems * sizeof(SWENTRY)) + sizeof(HSWITCH);
  796.                 PVOID my = new BYTE[Buffer];
  797.                 WinQuerySwitchList( hab, (SWBLOCK*)my, Buffer );
  798.                 SwitchBlockPtr = (PSWBLOCK)(my);
  799.  
  800.                 // if task did not close willingly, kill its process!
  801.                 for (short j = 0; j < numItems; j++ )
  802.                     if (SwitchBlockPtr->aswentry[j].swctl.hwnd == killedTaskHandle)
  803.                         DosKillProcess( DKP_PROCESS, killedTaskId );
  804.                 delete( my );
  805.  
  806.                 return 0;
  807.                 }
  808.             //------------------------------------------------------------------
  809.             // show the chosen task
  810.             //------------------------------------------------------------------
  811.             if ( command == TASK_SHOW) {
  812.                 WinSetWindowPos( TaskHandle[taskItemSelected - TASKLIST_MENU- 1],
  813.                                  (HWND)0, 0, 0, 0, 0, SWP_SHOW);
  814.                 return 0;
  815.                 }
  816.             //------------------------------------------------------------------
  817.             // hide the chosen task
  818.             //------------------------------------------------------------------
  819.             if ( command == TASK_HIDE) {
  820.                 WinSetWindowPos( TaskHandle[taskItemSelected - TASKLIST_MENU- 1],
  821.                                  (HWND)0, 0, 0, 0, 0, SWP_HIDE);
  822.                 return 0;
  823.                 }
  824.             //------------------------------------------------------------------
  825.             // maximize the chosen task
  826.             //------------------------------------------------------------------
  827.             if ( command == TASK_MAX) {
  828.                 HSWITCH switchHandle = WinQuerySwitchHandle( TaskHandle[taskItemSelected - TASKLIST_MENU- 1],
  829.                                                              TaskId[taskItemSelected - TASKLIST_MENU- 1]);
  830.  
  831.                 WinShowWindow( TaskHandle[taskItemSelected - TASKLIST_MENU- 1], TRUE );
  832.                 WinSetWindowPos( TaskHandle[taskItemSelected - TASKLIST_MENU- 1],
  833.                                  (HWND)0, 0, 0, 0, 0, SWP_MAXIMIZE);
  834.                 WinSwitchToProgram( switchHandle );
  835.                 return 0;
  836.                 }
  837.             //------------------------------------------------------------------
  838.             // minimize the chosen task
  839.             //------------------------------------------------------------------
  840.             if ( command == TASK_MIN) {
  841.                 WinShowWindow( TaskHandle[taskItemSelected - TASKLIST_MENU- 1], TRUE );
  842.                 WinSetWindowPos( TaskHandle[taskItemSelected - TASKLIST_MENU- 1],
  843.                                  (HWND)0, 0, 0, 0, 0, SWP_MINIMIZE);
  844.                 return 0;
  845.                 }
  846.             //------------------------------------------------------------------
  847.             // the user has selected something from the tasklist menu, switch
  848.             // control to that task, if possible
  849.             //------------------------------------------------------------------
  850.             if ( command == TASK_SWITCHTO) {
  851.                 CHAR title[] = "FileBar Task Switch Error";
  852.                 HSWITCH switchHandle;
  853.                 switchHandle = WinQuerySwitchHandle( TaskHandle[taskItemSelected - TASKLIST_MENU-1],
  854.                                                      TaskId[taskItemSelected - TASKLIST_MENU-1]);
  855.  
  856.                 if (switchHandle == 0) {
  857.                     CHAR text[] = "ERROR!  Could not locate task!  The task may have already terminated.";
  858.                     WinMessageBox( HWND_DESKTOP, hwnd, text, title, 0,
  859.                                    MB_MOVEABLE|MB_ERROR|MB_OK);
  860.                     return 0;
  861.                     }
  862.                 if (WinSwitchToProgram( switchHandle ) != 0) {
  863.                     CHAR text[] = "ERROR!  Could not switch to task!";
  864.                     WinMessageBox( HWND_DESKTOP, hwnd, text, title, 0,
  865.                                    MB_MOVEABLE|MB_ERROR|MB_OK);
  866.                     }
  867.                 WinShowWindow( TaskHandle[taskItemSelected - TASKLIST_MENU - 1], TRUE );
  868.                 return 0;
  869.                 }
  870.             //------------------------------------------------------------------
  871.             //  user wants to shutdown system
  872.             //------------------------------------------------------------------
  873.             if ( command == 99 ) {
  874.                 char text[] = "Are you sure that you want to close all windows and active programs and shutdown your system?  Select OK to continue shutdown.  Select Cancel to end this task.";
  875.                 if (WinMessageBox( HWND_DESKTOP, hwndFrame, text,
  876.                                    "FileBar - Shutdown System", 0,
  877.                                    MB_DEFBUTTON2|MB_MOVEABLE|MB_ICONEXCLAMATION|MB_OKCANCEL) == MBID_CANCEL)
  878.                     return 0;
  879.  
  880.                 writeOptionFile();
  881.                 WinSetWindowPos( hwndFrame, (HWND)0, 0, 0, 0, 0, SWP_HIDE);
  882.                 WinPostMsg( hwndClient, WM_QUIT, 0, 0 );
  883.                 WinShutdownSystem( WinQueryAnchorBlock( HWND_DESKTOP ), hmq );
  884.                 }
  885.             //------------------------------------------------------------------
  886.             // the user has selected an item off the user menus.  Activate the
  887.             // item they have selected
  888.             //------------------------------------------------------------------
  889.             if (( command > 99 ) && (command % 100)) {
  890.                 INT MenuToUpdate = command / 100 - 1;
  891.                 INT ItemToUpdate = command % 100 - 1;
  892.  
  893.                 if ((ItemToUpdate>=MAXITEMS) || (MenuToUpdate>=MAXMENUS))
  894.                     return 0;
  895.  
  896.                 if ((MenuToUpdate >= 0) && (MenuToUpdate<MAXMENUS))
  897.                     startApplication( MenuToUpdate, ItemToUpdate );
  898.  
  899.                 return 0;
  900.                 }
  901.             //------------------------------------------------------------------
  902.             // it was not a tasklist or user item, process now as usual
  903.             //------------------------------------------------------------------
  904.             switch( command ) {
  905.                 //--------------------------------------------------------------
  906.                 // the user wants to save current options
  907.                 //--------------------------------------------------------------
  908.                 case FILEBAR_SAVEOPTIONS: {
  909.                     char title[] = "FileBar - Save Menu Configuration";
  910.                     char message[] = "The current user menu configuration has been successfully saved!";
  911.  
  912.                     writeOptionFile();
  913.                     WinMessageBox( HWND_DESKTOP, hwnd, message, title, 0,
  914.                                    MB_MOVEABLE|MB_INFORMATION|MB_OK);
  915.                     return 0;
  916.                 }
  917.                 //--------------------------------------------------------------
  918.                 // the user wants to edit the menu structure
  919.                 //--------------------------------------------------------------
  920.                 case FILEBAR_EDITMENU: {
  921.                     return (VOID*)WinDlgBox(HWND_DESKTOP,
  922.                                             hwnd,
  923.                                             (PFNWP)EditMenuProc,
  924.                                             0,
  925.                                             EDITMENU,
  926.                                             (PVOID)NULL);
  927.                     }
  928.                 //--------------------------------------------------------------
  929.                 // the user wants to select their time/date display options
  930.                 //--------------------------------------------------------------
  931.                 case FILEBAR_TIMEOPTION: {
  932.                     return (VOID*)WinDlgBox(HWND_DESKTOP,
  933.                                             hwnd,
  934.                                             (PFNWP)TimeDateProc,
  935.                                             0,
  936.                                             TIMEOPTIONS,
  937.                                             (PVOID)NULL);
  938.                     }
  939.                 //--------------------------------------------------------------
  940.                 // the user wants to get general help on filebar
  941.                 //--------------------------------------------------------------
  942.                 case FILEBAR_GENHELP: {
  943.                     return (VOID*)WinDlgBox(HWND_DESKTOP,
  944.                                             hwnd,
  945.                                             (PFNWP)GenericProc,
  946.                                             0,
  947.                                             GENERAL_HELP,
  948.                                             (PVOID)NULL);
  949.                     }
  950.                 //--------------------------------------------------------------
  951.                 // the user wants to see product information for filebar
  952.                 //--------------------------------------------------------------
  953.                 case FILEBAR_PRODINFO: {
  954.                     return (VOID*)WinDlgBox(HWND_DESKTOP,
  955.                                             hwnd,
  956.                                             (PFNWP)GenericProc,
  957.                                             0,
  958.                                             PRODUCT_INFO,
  959.                                             (PVOID)NULL);
  960.                     }
  961.                 //--------------------------------------------------------------
  962.                 // the user wishes to move the filebar from its current position
  963.                 // to either to the top or bottom of the desktop
  964.                 //--------------------------------------------------------------
  965.                 case FILEBAR_MOVEBAR: {
  966.                     if (BarPosition==AT_TOP) {
  967.                         BarPosition = AT_BOTTOM;
  968.                         WinSetWindowPos( hwndFrame, (HWND)0, 0, -1,
  969.                                          ScreenSizeX, MenuHeight, SWP_MOVE);
  970.                         }
  971.                     else {
  972.                         BarPosition = AT_TOP;
  973.                         WinSetWindowPos( hwndFrame, (HWND)0, 0, (ScreenSizeY-MenuHeight)+1,
  974.                                          ScreenSizeX, MenuHeight, SWP_MOVE);
  975.                         }
  976.                     setFileBarScreen( (BOOL)(BarPosition==AT_TOP), MenuHeight, (interceptMsg==TRUE) );
  977.                     return 0;
  978.                     }
  979.                 //--------------------------------------------------------------
  980.                 // the user wishes to exit the filebar application
  981.                 //--------------------------------------------------------------
  982.                 case FILEBAR_EXIT: {
  983.                     return (VOID*)WinPostMsg( hwnd, WM_QUIT, 0, 0);
  984.                     }
  985.                 //--------------------------------------------------------------
  986.                 // something besides our menus sent a message, pass the message
  987.                 // to the system for default processing
  988.                 //--------------------------------------------------------------
  989.                 default:
  990.                     break;
  991.                 }
  992.             }
  993.         //----------------------------------------------------------------------
  994.         // we were sent a message that we don't care about, pass it onto system
  995.         // for default processing
  996.         //----------------------------------------------------------------------
  997.         default:
  998.             break;
  999.         };
  1000.     return WinDefWindowProc(hwnd, msg, mp1, mp2);  // default processing
  1001. }
  1002.  
  1003.  
  1004. ////////////////////////////////////////////////////////////////////////////////
  1005. // readOptionFile - will read the option file (generated by the app) from disk,
  1006. // if it exists and will restore the application to the state in which it was
  1007. // last left
  1008. ////////////////////////////////////////////////////////////////////////////////
  1009. void readOptionFile( void )
  1010. {
  1011.     int currentMenu = 100;
  1012.     FILE *optionFile;
  1013.  
  1014.     //--------------------------------------------------------------------------
  1015.     // if the option file exists on disk, read it in and restore old menu,
  1016.     // otherwise we will return and rely on default values
  1017.     //--------------------------------------------------------------------------
  1018.     if ((optionFile = fopen(OPTIONFILE,"rt")) != NULL) {
  1019.         RGB2 rgb = {0,0,0,0};
  1020.         ULONG color;
  1021.         INT a,b,c,d,e,f;
  1022.  
  1023.         MenuHeight  = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU) + 2;
  1024.  
  1025.         fscanf(optionFile, "%d %d", &timeOption, &BarPosition);
  1026.         // restore user's desired bar position
  1027.         if (BarPosition==AT_BOTTOM) {
  1028.             WinSetWindowPos( hwndFrame, (HWND)0, 0, 0, 0, 0 , SWP_MOVE|SWP_RESTORE);
  1029.             WinSetWindowPos( hwndFrame, (HWND)0, 0, -1,
  1030.                              ScreenSizeX, MenuHeight, SWP_MOVE|SWP_SIZE);
  1031.             WinSetWindowPos( hwndFrame, (HWND)0, 0, 0, 0, 0 , SWP_MOVE|SWP_MINIMIZE);
  1032.             }
  1033.         else {
  1034.             WinSetWindowPos( hwndFrame, (HWND)0, 0, (ScreenSizeY-MenuHeight)+1,
  1035.                              ScreenSizeX, MenuHeight, SWP_MOVE|SWP_SIZE);
  1036.             }
  1037.         setFileBarScreen( (BOOL)(BarPosition==AT_TOP), MenuHeight, (interceptMsg==TRUE) );
  1038.  
  1039.         // restore user's menus and menu choices
  1040.         fscanf(optionFile, "%d", &NumMenus);
  1041.         for (short i = 0; i < NumMenus; i++ ) {
  1042.             UpdateMenu[i] = TRUE;
  1043.             readString( optionFile, (CHAR*)&MenuName[i] );
  1044.  
  1045.             WinSendMsg( hwndMenu, MM_SETITEM, MPFROM2SHORT(100*i+100,TRUE),MPFROMP(&menuData[i]));
  1046.             WinSetMenuItemText( hwndMenu, 100*i+100, &MenuName[i]);
  1047.  
  1048.             fscanf(optionFile, "%d", &a);
  1049.             NumItems[i] = (BYTE)(a % 256);
  1050.             for (short j = 0; j < NumItems[i]; j++) {
  1051.                 readString( optionFile, (CHAR*)&ItemName[i][j] );
  1052.                 readString( optionFile, (CHAR*)&ActionToDo[i][j] );
  1053.                 readString( optionFile, (CHAR*)&CmdLnArgs[i][j] );
  1054.                 readString( optionFile, (CHAR*)&Directory[i][j] );
  1055.                 fscanf( optionFile, "%d", &a );
  1056.                 ProgType[i][j] = a % 1024;
  1057.                 }
  1058.             currentMenu = currentMenu + 100;
  1059.             }
  1060.  
  1061.         readString( optionFile, (CHAR*)&tmpBuffer );
  1062.         if (tmpBuffer[0]!='\0') {
  1063.             WinSetPresParam( hwndMenu, PP_FONTNAMESIZE, sizeof(tmpBuffer), &tmpBuffer );
  1064.             WinSetWindowPos( hwndFrame, (HWND)0, 0, 0, 0, 0, SWP_RESTORE);
  1065.             resizeMenu();
  1066.             WinSetWindowPos( hwndFrame, (HWND)0, 0, 0, 0, 0, SWP_MINIMIZE);
  1067.             }
  1068.  
  1069.         fscanf( optionFile, "%d", &checkBeforeDelete );
  1070.         if (fscanf( optionFile, "%d", &FileBarMenuOn )!=EOF) {
  1071.             CHAR menuOn[] = FILEBARMENUON;
  1072.             CHAR menuOff[] = FILEBARMENUOFF;
  1073.             CHAR taskOn[] = TASKMENUON;
  1074.             CHAR taskOff[] = TASKMENUOFF;
  1075.  
  1076.             if (FileBarMenuOn) {
  1077.                 WinSetMenuItemText( hwndMenu, FILEBAR_MENU, menuOn);
  1078.                 WinSetMenuItemText( hwndMenu, TASKLIST_MENU, taskOn);
  1079.                 }
  1080.             else {
  1081.                 WinSetMenuItemText( hwndMenu, FILEBAR_MENU, menuOff);
  1082.                 WinSetMenuItemText( hwndMenu, TASKLIST_MENU, taskOff);
  1083.                 }
  1084.             }
  1085.  
  1086.         if (fscanf( optionFile, "%d", &showBackground )!=EOF) {
  1087.             fscanf( optionFile, "%d", &backgroundAttr );
  1088.             readString( optionFile, (CHAR*)&backgroundBitmap );
  1089.             }
  1090.  
  1091.         for (i=PP_FOREGROUNDCOLOR; i<=PP_BORDERCOLOR; i=i+2)
  1092.             if (fscanf(optionFile, "%ld", &color )!=EOF)
  1093.                 if ( color != NOCOLOR) {
  1094.                     rgb.bRed = (BYTE)(color/65536);
  1095.                     color = color%65536;
  1096.                     rgb.bGreen = (BYTE)(color/256);
  1097.                     color = color%256;
  1098.                     rgb.bBlue = (BYTE)(color);
  1099.                     WinSetPresParam( hwndMenu, i, sizeof(rgb), &rgb);
  1100.                     }
  1101.  
  1102.         for (i=PP_ACTIVECOLOR; i<=PP_INACTIVETEXTBGNDCOLOR; i=i+2)
  1103.             if (fscanf(optionFile, "%ld", &color )!=EOF)
  1104.                 if ( color != NOCOLOR) {
  1105.                     rgb.bRed = (BYTE)(color/65536);
  1106.                     color = color%65536;
  1107.                     rgb.bGreen = (BYTE)(color/256);
  1108.                     color = color%256;
  1109.                     rgb.bBlue = (BYTE)(color);
  1110.                     WinSetPresParam( hwndMenu, i, sizeof(rgb), &rgb);
  1111.                     }
  1112.  
  1113.         if (fscanf(optionFile, "%ld", &color )!=EOF)
  1114.             if ( color != NOCOLOR) {
  1115.                 rgb.bRed = (BYTE)(color/65536);
  1116.                 color = color%65536;
  1117.                 rgb.bGreen = (BYTE)(color/256);
  1118.                 color = color%256;
  1119.                 rgb.bBlue = (BYTE)(color);
  1120.                 WinSetPresParam( hwndMenu, PP_SHADOW, sizeof(rgb), &rgb);
  1121.                 }
  1122.  
  1123.         for (i=PP_MENUFOREGROUNDCOLOR; i<=PP_MENUDISABLEDBGNDCOLOR; i=i+2)
  1124.             if (fscanf(optionFile, "%ld", &color )!=EOF)
  1125.                 if ( color != NOCOLOR) {
  1126.                     rgb.bRed = (BYTE)(color/65536);
  1127.                     color = color%65536;
  1128.                     rgb.bGreen = (BYTE)(color/256);
  1129.                     color = color%256;
  1130.                     rgb.bBlue = (BYTE)(color);
  1131.                     WinSetPresParam( hwndMenu, i, sizeof(rgb), &rgb);
  1132.                     }
  1133.  
  1134.         if (fscanf(optionFile, "%d %d", &DoStartUpList, &numStartItems ) != EOF) {
  1135.             for (i=0; i<numStartItems; i++)
  1136.                 fscanf(optionFile, "%d %d", &StartUpMenu[i], &StartUpItem[i] );
  1137.  
  1138.             }
  1139.  
  1140.         if (fscanf(optionFile, "%d", &HourlyChime ) != EOF)
  1141.             readString( optionFile, (CHAR*)&hourlyChimeWavFile );
  1142.  
  1143.         // read in current task scheduler tasks
  1144.         if (fscanf(optionFile, "%d %d %d %d", &maximizeDesktop, &repeatTime, &interceptMsg, &numAlarms ) != EOF)
  1145.             setFileBarScreen( (BOOL)(BarPosition==AT_TOP), MenuHeight, (interceptMsg==TRUE) );
  1146.             for (i=0; i<numAlarms; i++) {
  1147.                 fscanf(optionFile, "%d %d %d %d %d %d", &a,&b,&c,&d,&e,&f);
  1148.                 alarm[i].AlarmHour   = a % 256;
  1149.                 alarm[i].AlarmMinute = b % 256;
  1150.                 alarm[i].AlarmMonth  = c % 256;
  1151.                 alarm[i].AlarmDay    = d % 256;
  1152.                 alarm[i].AlarmYear   = e % 256;
  1153.                 alarm[i].options     = f % 256;
  1154.                 readString( optionFile, (CHAR*)&alarm[i].ActionToDo );
  1155.                 readString( optionFile, (CHAR*)&alarm[i].ReminderWAV );
  1156.                 }
  1157.  
  1158.         fclose( optionFile );
  1159.         }
  1160. }
  1161.  
  1162.  
  1163. ////////////////////////////////////////////////////////////////////////////////
  1164. // writeOptionFile - will write the application state to the option file
  1165. ////////////////////////////////////////////////////////////////////////////////
  1166. void writeOptionFile( void )
  1167. {
  1168.     SHORT currentMenu = 100;
  1169.     FILE *optionFile;
  1170.  
  1171.     //--------------------------------------------------------------------------
  1172.     // if the option file exists on disk, read it in and restore old menu,
  1173.     // otherwise we will return and rely on default values
  1174.     //--------------------------------------------------------------------------
  1175.     if ((optionFile = fopen(OPTIONFILE, "wt")) == NULL)
  1176.         // if not able to save, alert the user
  1177.         WinMessageBox( HWND_DESKTOP, hwndClient, "Error writing FileBar configuration file!  Application data was NOT saved!",
  1178.                        0, 0, MB_MOVEABLE|MB_ERROR|MB_OK);
  1179.     else {
  1180.         ULONG length;
  1181.         RGB2 rgb;
  1182.  
  1183.         // save user's desired bar position
  1184.         fprintf(optionFile, "%d %d\n", timeOption, BarPosition);
  1185.         // save user's menus and menu choices
  1186.         fprintf(optionFile, "%d\n", NumMenus);
  1187.         for (short i = 0; i < NumMenus; i++ ) {
  1188.             writeString( optionFile, (CHAR*)&MenuName[i] );
  1189.             fprintf(optionFile, "%d\n", NumItems[i]);
  1190.             for (short j = 0; j < NumItems[i]; j++) {
  1191.                 writeString( optionFile, (CHAR*)&ItemName[i][j] );
  1192.                 writeString( optionFile, (CHAR*)&ActionToDo[i][j] );
  1193.                 writeString( optionFile, (CHAR*)&CmdLnArgs[i][j] );
  1194.                 writeString( optionFile, (CHAR*)&Directory[i][j] );
  1195.                 fprintf( optionFile, "%d\n", ProgType[i][j] );
  1196.                 }
  1197.             currentMenu = currentMenu + 100;
  1198.             }
  1199.  
  1200.         if (WinQueryPresParam( hwndMenu, PP_FONTNAMESIZE, 0, &length, sizeof(tmpBuffer), &tmpBuffer, 0)!=FALSE)
  1201.             writeString( optionFile, (CHAR*)&tmpBuffer );
  1202.         else
  1203.             fprintf( optionFile, "\"\"\n" );
  1204.         fprintf( optionFile, "%d\n%d\n%d\n%d\n", checkBeforeDelete, FileBarMenuOn, showBackground, backgroundAttr );
  1205.         writeString( optionFile, (CHAR*)&backgroundBitmap );
  1206.  
  1207.         // save menu scheme of colors
  1208.         for (i=PP_FOREGROUNDCOLOR; i<=PP_BORDERCOLOR; i=i+2) {
  1209.             if (WinQueryPresParam( hwndMenu, i, 0, 0, sizeof(rgb), &rgb, 0) != 0)
  1210.                 fprintf(optionFile, "%ld\n", (ULONG)(rgb.bRed*65536+rgb.bGreen*256+rgb.bBlue) );
  1211.             else fprintf(optionFile, "%ld\n", NOCOLOR );
  1212.             }
  1213.  
  1214.         for (i=PP_ACTIVECOLOR; i<=PP_INACTIVETEXTBGNDCOLOR; i=i+2) {
  1215.             if (WinQueryPresParam( hwndMenu, i, 0, 0, sizeof(rgb), &rgb, 0) != 0)
  1216.                 fprintf(optionFile, "%ld\n", (ULONG)(rgb.bRed*65536+rgb.bGreen*256+rgb.bBlue) );
  1217.             else fprintf(optionFile, "%ld\n", NOCOLOR );
  1218.             }
  1219.  
  1220.         if (WinQueryPresParam( hwndMenu, PP_SHADOW, 0, 0, sizeof(rgb), &rgb, 0) != 0)
  1221.             fprintf(optionFile, "%ld\n", (ULONG)(rgb.bRed*65536+rgb.bGreen*256+rgb.bBlue) );
  1222.         else fprintf(optionFile, "%ld\n", NOCOLOR );
  1223.  
  1224.         for (i=PP_MENUFOREGROUNDCOLOR; i<=PP_MENUDISABLEDBGNDCOLOR; i=i+2) {
  1225.             if (WinQueryPresParam( hwndMenu, i, 0, 0, sizeof(rgb), &rgb, 0) != 0)
  1226.                 fprintf(optionFile, "%ld\n", (ULONG)(rgb.bRed*65536+rgb.bGreen*256+rgb.bBlue) );
  1227.             else fprintf(optionFile, "%ld\n", NOCOLOR );
  1228.             }
  1229.  
  1230.         fprintf(optionFile, "%d\n%d\n", DoStartUpList, numStartItems );
  1231.         for (i=0; i<numStartItems; i++)
  1232.             fprintf(optionFile, "%d\n%d\n", StartUpMenu[i], StartUpItem[i] );
  1233.  
  1234.         fprintf(optionFile, "%d\n", HourlyChime );
  1235.         writeString( optionFile, (CHAR*)&hourlyChimeWavFile );
  1236.  
  1237.         // save current task scheduler items
  1238.         fprintf(optionFile, "%d %d %d %d\n", maximizeDesktop, repeatTime, interceptMsg, numAlarms );
  1239.         for (i=0; i<numAlarms; i++) {
  1240.             fprintf(optionFile, "%d %d %d %d %d %d\n", alarm[i].AlarmHour,
  1241.                                                        alarm[i].AlarmMinute,
  1242.                                                        alarm[i].AlarmMonth,
  1243.                                                        alarm[i].AlarmDay,
  1244.                                                        alarm[i].AlarmYear,
  1245.                                                        alarm[i].options );
  1246.             writeString( optionFile, (CHAR*)&alarm[i].ActionToDo );
  1247.             writeString( optionFile, (CHAR*)&alarm[i].ReminderWAV );
  1248.             }
  1249.         fclose( optionFile );
  1250.         }
  1251. }
  1252.  
  1253.  
  1254. ////////////////////////////////////////////////////////////////////////////////
  1255. // readString will read a sequence of characters that is bounded on both sides
  1256. // by quote (") characters (We can't use fscanf because it won't read spaces)
  1257. ////////////////////////////////////////////////////////////////////////////////
  1258. VOID readString( FILE* stream, CHAR* buffer )
  1259. {
  1260.     do {                               // search for first " character
  1261.         if (fscanf( stream, "%c", buffer)==EOF) break;
  1262.     } while ( (*buffer) !='"');
  1263.     buffer--;
  1264.     do {                               // keep putting characters into the buffer
  1265.         buffer++;                      // " character
  1266.         if (fscanf( stream, "%c", buffer)==EOF) break;
  1267.     } while ( (*buffer) !='"');
  1268.     *buffer = '\0';                    // store a NULL to terminate the string
  1269. }
  1270.  
  1271.  
  1272. ////////////////////////////////////////////////////////////////////////////////
  1273. // Message handler for a generic information-only dialog box (help & prod info)
  1274. ////////////////////////////////////////////////////////////////////////////////
  1275. MRESULT EXPENTRY GenericProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1276. {
  1277.    switch( msg )
  1278.     {
  1279.         //----------------------------------------------------------------------
  1280.         // when the dialog is being initialized, center it on desktop
  1281.         //----------------------------------------------------------------------
  1282.         case WM_INITDLG: {
  1283.             SWP swp;
  1284.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  1285.             WinSetWindowPos( hWnd, (HWND)0,
  1286.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  1287.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  1288.                              0, 0, SWP_MOVE);
  1289.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1290.             }
  1291.         //----------------------------------------------------------------------
  1292.         // if we receive any system message, dismiss the dialog box
  1293.         //----------------------------------------------------------------------
  1294.         case WM_COMMAND:
  1295.         {
  1296.             WinDismissDlg( hWnd, TRUE );
  1297.             return 0;
  1298.         }
  1299.         //----------------------------------------------------------------------
  1300.         // if nothing further we want to intercept, pass message onto system
  1301.         //----------------------------------------------------------------------
  1302.         default:
  1303.             break;
  1304.     }
  1305.     return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1306. }
  1307.  
  1308.  
  1309. ////////////////////////////////////////////////////////////////////////////////
  1310. // starts or restarts a timer to signal our program when the next minute occurs
  1311. ////////////////////////////////////////////////////////////////////////////////
  1312. VOID restartTimer( VOID )
  1313. {
  1314.     struct tm *time_now;
  1315.     time_t currentTime;
  1316.  
  1317.     tzset();
  1318.     time(¤tTime);
  1319.     time_now = localtime( ¤tTime );
  1320.     timeSync = FALSE;
  1321.  
  1322.     timerNumber = WinStartTimer( hab, hwndClient, TIMERID, (60-(time_now->tm_sec))*1000);
  1323. }
  1324.  
  1325.  
  1326. ////////////////////////////////////////////////////////////////////////////////
  1327. // ringChime - play a .WAV file sent to us as the parameter.
  1328. ////////////////////////////////////////////////////////////////////////////////
  1329. VOID ringChime( CHAR* soundFile )
  1330. {
  1331.     APIRET rc;
  1332.     char mesg[MAXPATH+384];
  1333.     RXSTRING  INSTORE[2];
  1334.     RXSTRING  retstr;
  1335.     SHORT ReturnCode;
  1336.     LONG offset = 0;
  1337.  
  1338.     if (soundFile == 0)
  1339.         return;
  1340.     if (soundFile[0] == 0) {
  1341.         WinAlarm( HWND_DESKTOP, WA_NOTE );
  1342.         return;
  1343.         }
  1344.  
  1345.     MakeHourglassPointer ();                       // switch to hourglass cursor
  1346.     offset = offset + sprintf(mesg+offset, "/* */\r\n");
  1347.     offset = offset + sprintf(mesg+offset, "rc = call RxFuncAdd('mciRxInit','MCIAPI',,\r\n'mciRxInit')\r\n");
  1348.     offset = offset + sprintf(mesg+offset, "rc = call mciRxInit()\r\n");
  1349.     offset = offset + sprintf(mesg+offset, "rc = mciRxSendString('open waveaudio',\r\n'alias wave shareable wait',,\r\n'RetStr','0','0')\r\n");
  1350.     offset = offset + sprintf(mesg+offset, "rc = mciRxSendString('load wave %s wait',,\r\n'RetStr','0','0')\r\n", soundFile );
  1351.     offset = offset + sprintf(mesg+offset, "rc = mciRxSendString('play wave wait',,\r\n'RetStr','0','0')\r\n" );
  1352.     offset = offset + sprintf(mesg+offset, "rc = mciRxSendString('close wave wait',,\r\n'RetStr','0','0')\r\n" );
  1353.     offset = offset + sprintf(mesg+offset, "call mciRxExit\r\n" );
  1354.     sprintf(mesg+offset, "exit\r\n\x1A\0" );
  1355.  
  1356.     INSTORE[0].strptr=mesg;
  1357.     INSTORE[0].strlength=strlen(mesg);
  1358.     INSTORE[1].strptr=NULL;
  1359.     INSTORE[1].strlength=0;
  1360.  
  1361.     rc = rexxStart((LONG)0,
  1362.               (PRXSTRING)0,
  1363.               (PSZ)LAUNCHFILE,
  1364.               (PRXSTRING)INSTORE,
  1365.               (PSZ)"CMD",
  1366.               (LONG)RXCOMMAND,
  1367.               (PRXSYSEXIT)0,
  1368.               (SHORT*)&ReturnCode,
  1369.               (PRXSTRING)&retstr);
  1370.  
  1371.     // if there was an error (ie: no MMPM), make a system beep
  1372.     if (rc)
  1373.         WinAlarm( HWND_DESKTOP, WA_NOTE );
  1374.  
  1375.     MakeArrowPointer ();                      // switch back to arrow pointer,
  1376. }
  1377.  
  1378.  
  1379. ////////////////////////////////////////////////////////////////////////////////
  1380. // update the time displayed on the FileBar menubar
  1381. ////////////////////////////////////////////////////////////////////////////////
  1382. VOID updateTimeDisplay( VOID ) {
  1383.     char tmp1[24];
  1384.     char tmp2[24];
  1385.     CHAR buffer[64] = { '\0' };
  1386.     struct tm *time_now;
  1387.     time_t currentTime;
  1388.  
  1389.     tzset();
  1390.     time(¤tTime);
  1391.     time_now = localtime( ¤tTime );
  1392.  
  1393.     if ((timeOption == TIMEONLY) || (timeOption == TIMEANDDATE)) {
  1394.         strftime( tmp1, sizeof(tmp1), "%I", time_now);
  1395.         strftime( tmp2, sizeof(tmp2), ":%M %p  ", time_now);
  1396.         if (tmp1[0] == '0')
  1397.             tmp1[0]=' ';
  1398.         strcat( buffer, tmp1 );
  1399.         strcat( buffer, tmp2 );
  1400.         }
  1401.     if (timeOption == TIMEANDDATE)
  1402.         strcat( buffer, " " );
  1403.     if ((timeOption == DATEONLY) || (timeOption == TIMEANDDATE)) {
  1404.         strftime( tmp1, sizeof(tmp1), "%B", time_now);
  1405.         strftime( tmp2, sizeof(tmp2), "%d, %Y  ", time_now);
  1406.  
  1407.         if (tmp2[0] == '0') {
  1408.             tmp2[0] = ' ';
  1409.             strcat( buffer, tmp1 );
  1410.             strcat( buffer, tmp2 );
  1411.             }
  1412.         else {
  1413.             strcat( buffer, tmp1 );
  1414.             strcat( buffer, " \0" );
  1415.             strcat( buffer, tmp2 );
  1416.             }
  1417.         }
  1418.     else if (timeOption == OTHERTIMEONLY)
  1419.         strftime( buffer, sizeof(buffer), "%H:%M  ", time_now);
  1420.     else if (timeOption == OTHERDATEONLY)
  1421.         strftime( buffer, sizeof(buffer), "%d %B %Y  ", time_now);
  1422.     else if (timeOption == OTHERTIMEANDDATE) {
  1423.         strftime( tmp1, sizeof(tmp1), "%H:%M ", time_now );
  1424.         strftime( tmp2, sizeof(tmp2), "%d %B %Y  ", time_now );
  1425.         if (tmp1[0] == '0')
  1426.             tmp1[0] = ' ';
  1427.         if (tmp2[0] == '0')
  1428.             tmp2[0] = ' ';
  1429.         else
  1430.             strcat( tmp1, " " );
  1431.         strcat( buffer, tmp1 );
  1432.         strcat( buffer, tmp2 );
  1433.         }
  1434.     if (buffer[0]=='0')
  1435.         buffer[0]=' ';
  1436.  
  1437.     WinSetMenuItemText( hwndMenu, TIMEDATE, &buffer );
  1438. }
  1439.  
  1440.  
  1441. ////////////////////////////////////////////////////////////////////////////////
  1442. // displayTimeDate is used to check to see if time/date on the FileBar menu
  1443. // needs updateing and also to check to see if any alarms need to be serviced
  1444. ////////////////////////////////////////////////////////////////////////////////
  1445. VOID displayTimeDate( VOID )
  1446. {
  1447.     struct tm *time_now;
  1448.     time_t currentTime;
  1449.  
  1450.     tzset();
  1451.     time(¤tTime);
  1452.     time_now = localtime( ¤tTime );
  1453.  
  1454.  
  1455.     if (timeOption != NONE)
  1456.         if (((timeOption != DATEONLY) && (timeOption != OTHERDATEONLY)) ||
  1457.              (time_now->tm_min == 0) )
  1458.             updateTimeDisplay();
  1459.  
  1460.     if (time_now->tm_min == 30)
  1461.         alreadyChimed = FALSE;
  1462.  
  1463.     if ((!alreadyChimed) && (time_now->tm_min == 0) && (HourlyChime)) {
  1464.         alreadyChimed = TRUE;
  1465.         ringChime( hourlyChimeWavFile );
  1466.         }
  1467.  
  1468.     checkAlarms( time_now->tm_hour, time_now->tm_min, time_now->tm_mon,
  1469.                  time_now->tm_mday, time_now->tm_year );
  1470. }
  1471.  
  1472.  
  1473. ////////////////////////////////////////////////////////////////////////////////
  1474. // Message handler for time and date option setting dialog
  1475. ////////////////////////////////////////////////////////////////////////////////
  1476. MRESULT EXPENTRY TimeDateProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1477. {
  1478.    switch( msg )
  1479.     {
  1480.         //----------------------------------------------------------------------
  1481.         // when the dialog is being initialized, center it on desktop and check
  1482.         // the appropriate radio button for whatever setting they currently have
  1483.         //----------------------------------------------------------------------
  1484.         case WM_INITDLG: {
  1485.             SWP swp;
  1486.  
  1487.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  1488.             WinSetWindowPos( hWnd, (HWND)0,
  1489.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  1490.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  1491.                              0, 0, SWP_MOVE);
  1492.             WinSendDlgItemMsg( hWnd, timeOption, BM_SETCHECK,
  1493.                                MPFROM2SHORT( 1, 0 ), 0);
  1494.             WinCheckButton( hWnd, PLAYCHIME, HourlyChime );
  1495.  
  1496.             WinSendDlgItemMsg( hWnd, CHIMEWAVFILE, EM_SETTEXTLIMIT,
  1497.                                MPFROM2SHORT( MAXACTIONSTRINGLENGTH-1, 0 ), 0 );
  1498.             WinSetDlgItemText( hWnd, CHIMEWAVFILE, hourlyChimeWavFile);
  1499.  
  1500.             break;
  1501.             }
  1502.         //----------------------------------------------------------------------
  1503.         // we received a change in control, update menubar time
  1504.         //----------------------------------------------------------------------
  1505.         case WM_CONTROL:
  1506.         {
  1507.             timeOption = NONE;
  1508.             if (WinQueryButtonCheckstate( hWnd, TIMEONLY ))
  1509.                 timeOption = TIMEONLY;
  1510.             else if (WinQueryButtonCheckstate( hWnd, DATEONLY ))
  1511.                 timeOption = DATEONLY;
  1512.             else if (WinQueryButtonCheckstate( hWnd, TIMEANDDATE ))
  1513.                 timeOption = TIMEANDDATE;
  1514.             else if (WinQueryButtonCheckstate( hWnd, OTHERTIMEONLY ))
  1515.                 timeOption = OTHERTIMEONLY;
  1516.             else if (WinQueryButtonCheckstate( hWnd, OTHERDATEONLY ))
  1517.                 timeOption = OTHERDATEONLY;
  1518.             else if (WinQueryButtonCheckstate( hWnd, OTHERTIMEANDDATE ))
  1519.                 timeOption = OTHERTIMEANDDATE;
  1520.  
  1521.             WinStopTimer( hab, hwndClient, timerNumber );
  1522.             restartTimer();
  1523.             updateTimeDisplay();
  1524.             break;
  1525.         }
  1526.  
  1527.         //----------------------------------------------------------------------
  1528.         // if we receive any system message, dismiss dialog and store new option
  1529.         //----------------------------------------------------------------------
  1530.         case WM_COMMAND:
  1531.         {
  1532.             USHORT command = SHORT1FROMMP(mp1);
  1533.             switch( command ) {
  1534.             case TESTWAVEFILE: {
  1535.                 WinQueryDlgItemText( hWnd, CHIMEWAVFILE, sizeof(hourlyChimeWavFile), hourlyChimeWavFile);
  1536.                 ringChime( hourlyChimeWavFile );
  1537.                 return 0;
  1538.                 }
  1539.             case FINDWAVFILE: {
  1540.                 CHAR title[] = "FileBar - Find a Hourly Chime .WAV file";
  1541.                 ULONG s;
  1542.                 HWND hwndDialog;
  1543.  
  1544.                 fileDlgInfo.fl = FDS_OPEN_DIALOG|FDS_CENTER;
  1545.                 fileDlgInfo.pszTitle = title;
  1546.  
  1547.                 strcpy(oldDirectory, fileDlgInfo.szFullFile);
  1548.                 strcat(fileDlgInfo.szFullFile, "*.WAV\0");
  1549.  
  1550.                 hwndDialog = WinFileDlg( HWND_DESKTOP, hWnd, &fileDlgInfo );
  1551.                 if (hwndDialog && (fileDlgInfo.lReturn == DID_OK)) {
  1552.                     strcpy( hourlyChimeWavFile, fileDlgInfo.szFullFile );
  1553.  
  1554.                     s=0;
  1555.                     while(fileDlgInfo.szFullFile[s]!='\0')
  1556.                         s++;
  1557.                     while((fileDlgInfo.szFullFile[s]!='\\') && (s>=0))
  1558.                         s--;
  1559.  
  1560.                     if (fileDlgInfo.szFullFile[s]=='\\')
  1561.                         fileDlgInfo.szFullFile[s+1]='\0';
  1562.                     else
  1563.                         fileDlgInfo.szFullFile[0]='\0';
  1564.  
  1565.                     WinSetDlgItemText( hWnd, CHIMEWAVFILE, hourlyChimeWavFile );
  1566.                     }
  1567.                 else
  1568.                     strcpy(fileDlgInfo.szFullFile, oldDirectory);
  1569.                 return 0;
  1570.                 }
  1571.             }
  1572.  
  1573.             timeOption = NONE;
  1574.             if (WinQueryButtonCheckstate( hWnd, TIMEONLY ))
  1575.                 timeOption = TIMEONLY;
  1576.             else if (WinQueryButtonCheckstate( hWnd, DATEONLY ))
  1577.                 timeOption = DATEONLY;
  1578.             else if (WinQueryButtonCheckstate( hWnd, TIMEANDDATE ))
  1579.                 timeOption = TIMEANDDATE;
  1580.             else if (WinQueryButtonCheckstate( hWnd, OTHERTIMEONLY ))
  1581.                 timeOption = OTHERTIMEONLY;
  1582.             else if (WinQueryButtonCheckstate( hWnd, OTHERDATEONLY ))
  1583.                 timeOption = OTHERDATEONLY;
  1584.             else if (WinQueryButtonCheckstate( hWnd, OTHERTIMEANDDATE ))
  1585.                 timeOption = OTHERTIMEANDDATE;
  1586.  
  1587.             HourlyChime = WinQueryButtonCheckstate( hWnd, PLAYCHIME );
  1588.  
  1589.             // stop current timer (if one exists) and start a new one
  1590.             // display new time and date according to new option setting
  1591.             WinStopTimer( hab, hwndClient, timerNumber );
  1592.             restartTimer();
  1593.             WinQueryDlgItemText( hWnd, CHIMEWAVFILE, sizeof(hourlyChimeWavFile), hourlyChimeWavFile);
  1594.             WinDismissDlg( hWnd, TRUE );
  1595.             return 0;
  1596.         }
  1597.         //----------------------------------------------------------------------
  1598.         // if nothing further we want to intercept, pass message onto system
  1599.         //----------------------------------------------------------------------
  1600.         default:
  1601.             break;
  1602.     }
  1603.     return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1604. }
  1605.  
  1606.  
  1607. ////////////////////////////////////////////////////////////////////////////////
  1608. // EditMenuProc - the message handler for editing a menu dialog box
  1609. ////////////////////////////////////////////////////////////////////////////////
  1610. MRESULT EXPENTRY EditMenuProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1611. {
  1612.     switch( msg )
  1613.     {
  1614.         //----------------------------------------------------------------------
  1615.         // if double-clicked an entry, allow them to edit it
  1616.         //----------------------------------------------------------------------
  1617.         case WM_CONTROL:
  1618.         {
  1619.             if ((SHORT1FROMMP(mp1)==CURMENULIST) && (SHORT2FROMMP(mp1)==LN_ENTER))
  1620.                 return WinSendMsg( hWnd, WM_COMMAND, MPFROM2SHORT( EDITMENUBUTTON, 0 ), mp2 );
  1621.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1622.         }
  1623.         //----------------------------------------------------------------------
  1624.         // when the dialog is being initialized, center it on desktop and put
  1625.         // the current data into appropriate list boxes
  1626.         //----------------------------------------------------------------------
  1627.         case WM_INITDLG: {
  1628.             SWP swp;
  1629.  
  1630.             for (short i=0; i<NumMenus; i++)
  1631.                 WinSendDlgItemMsg( hWnd, CURMENULIST, LM_INSERTITEM,
  1632.                                    MPFROM2SHORT( LIT_END, 0 ),
  1633.                                    MenuName[i] );
  1634.             if (NumMenus > 0) {
  1635.                 WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM,
  1636.                                    MPFROM2SHORT( 0, 0 ),
  1637.                                    MPFROM2SHORT( TRUE, 0 ) );
  1638.                 }
  1639.             else {
  1640.                 WinEnableControl( hWnd, EDITMENUBUTTON, FALSE );
  1641.                 WinEnableControl( hWnd, REMOVEMENU, FALSE );
  1642.                 WinEnableControl( hWnd, MOVEMENULEFT, FALSE );
  1643.                 WinEnableControl( hWnd, MOVEMENURIGHT, FALSE );
  1644.                 }
  1645.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  1646.             WinSetWindowPos( hWnd, (HWND)0,
  1647.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  1648.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  1649.                              0, 0, SWP_MOVE);
  1650.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1651.             }
  1652.         //----------------------------------------------------------------------
  1653.         // process a command message received from the system
  1654.         //----------------------------------------------------------------------
  1655.         case WM_COMMAND: {
  1656.             USHORT command = SHORT1FROMMP(mp1);
  1657.             switch( command )
  1658.                 {
  1659.                 //--------------------------------------------------------------
  1660.                 // if they pressed OK button, dismiss dialog and return
  1661.                 //--------------------------------------------------------------
  1662.                 case DID_OK: {
  1663.                     WinDismissDlg( hWnd, TRUE );
  1664.                     return 0;
  1665.                     }
  1666.                 //--------------------------------------------------------------
  1667.                 // they want to edit a menu
  1668.                 //--------------------------------------------------------------
  1669.                 case EDITMENUBUTTON: {
  1670.                     if (NumMenus == 0) {
  1671.                         WinAlarm(HWND_DESKTOP, WA_ERROR);
  1672.                         return 0;
  1673.                         }
  1674.                     // find out what menu they've selected in list box
  1675.                     MenuSelection = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, CURMENULIST,
  1676.                                                                      LM_QUERYSELECTION,
  1677.                                                                      MPFROM2SHORT( LIT_FIRST, 0 ),
  1678.                                                                      0 ) );
  1679.                     // display edit menu dialog box
  1680.                     WinDlgBox(HWND_DESKTOP,
  1681.                               hWnd,
  1682.                               (PFNWP)EditItemProc,
  1683.                               0,
  1684.                               EDITITEM,
  1685.                               (PVOID)NULL);
  1686.                     // change the item in the list box and select it
  1687.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_DELETEALL, 0, 0 );
  1688.                     for (short i=0; i<NumMenus; i++)
  1689.                         WinSendDlgItemMsg( hWnd, CURMENULIST, LM_INSERTITEM,
  1690.                                            MPFROM2SHORT( LIT_END, 0 ),
  1691.                                            MenuName[i] );
  1692.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM,
  1693.                                        MPFROM2SHORT( MenuSelection, 0 ),
  1694.                                        MPFROM2SHORT( TRUE, 0 ) );
  1695.                     return 0;
  1696.                     }
  1697.                 //--------------------------------------------------------------
  1698.                 // the user wants to add another menu to the menubar
  1699.                 //--------------------------------------------------------------
  1700.                 case ADDMENU: {
  1701.                     MenuSelection = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, CURMENULIST,
  1702.                                                                      LM_QUERYSELECTION,
  1703.                                                                      MPFROM2SHORT( LIT_FIRST, 0 ),
  1704.                                                                      0 ) );
  1705.                     // error if no room for another menu
  1706.                     if (NumMenus >= MAXMENUS) {
  1707.                         WinMessageBox( HWND_DESKTOP, hWnd,
  1708.                                        "Error!  Maximum number of user-menus already defined!",
  1709.                                        "Add A Menu", 0,
  1710.                                        MB_MOVEABLE|MB_ERROR|MB_OK);
  1711.                         return 0;
  1712.                         }
  1713.                     WinDlgBox(HWND_DESKTOP,
  1714.                               hWnd,
  1715.                               (PFNWP)AddAMenuProc,
  1716.                               0,
  1717.                               ADDAMENU,
  1718.                               (PVOID)NULL);
  1719.                     // if first menu to be added, enable buttons
  1720.                     if (NumMenus > 0) {
  1721.                         WinEnableControl( hWnd, EDITMENUBUTTON, TRUE );
  1722.                         WinEnableControl( hWnd, REMOVEMENU, TRUE );
  1723.                         WinEnableControl( hWnd, MOVEMENULEFT, TRUE );
  1724.                         WinEnableControl( hWnd, MOVEMENURIGHT, TRUE );
  1725.                         }
  1726.  
  1727.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_DELETEALL, 0, 0 );
  1728.                     for (short i=0; i<NumMenus; i++)
  1729.                         WinSendDlgItemMsg( hWnd, CURMENULIST, LM_INSERTITEM,
  1730.                                            MPFROM2SHORT( LIT_END, 0 ),
  1731.                                            MenuName[i] );
  1732.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM,
  1733.                                        MPFROM2SHORT( MenuSelection, 0 ),
  1734.                                        MPFROM2SHORT( TRUE, 0 ) );
  1735.                     return 0;
  1736.                     }
  1737.                 //--------------------------------------------------------------
  1738.                 // the user wants to remove a menu from the menu list box
  1739.                 //--------------------------------------------------------------
  1740.                 case REMOVEMENU: {
  1741.                     if (NumMenus == 0) {
  1742.                         WinAlarm(HWND_DESKTOP, WA_WARNING);
  1743.                         return 0;
  1744.                         }
  1745.  
  1746.                     if (NumMenus > 0)
  1747.                         if (WinMessageBox( HWND_DESKTOP, hWnd,
  1748.                                            "If you remove this menu, there will be no way to recover it.  Are you sure you want to remove this menu?",
  1749.                                            "Remove Menu", 0,
  1750.                                            MB_MOVEABLE|MB_WARNING|MB_YESNO|MB_DEFBUTTON2) == MBID_YES ) {
  1751.                             short index = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, CURMENULIST,
  1752.                                                                            LM_QUERYSELECTION,
  1753.                                                                            MPFROM2SHORT( LIT_FIRST, 0 ),
  1754.                                                                            0 ) );
  1755.                             MENUITEM menuItem;
  1756.  
  1757.                             // delete it from the lisr box
  1758.                             WinSendDlgItemMsg( hWnd, CURMENULIST, LM_DELETEITEM,
  1759.                                                MPFROM2SHORT( index, 0 ), 0 );
  1760.  
  1761.                             // delete it from menu structure
  1762.                             MakeHourglassPointer ();
  1763.                             WinSetMenuItemText( hwndMenu, 100*index+100, "" );
  1764.                             for (short i=index+1; i<MAXMENUS; i++)
  1765.                                 SwapTwoMenus( i-1, i );
  1766.                             NumItems[MAXMENUS-1] = 0;
  1767.                             MenuName[MAXMENUS-1][0] = '\0';
  1768.                             if (NumMenus > 0) {
  1769.                                 int newIndex = index-1;
  1770.                                 if (0 > newIndex)
  1771.                                     newIndex = 0;
  1772.  
  1773.                                 if (index == NumMenus-1)
  1774.                                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM,
  1775.                                                        MPFROM2SHORT( newIndex, 0 ),
  1776.                                                        MPFROM2SHORT( TRUE, 0 ) );
  1777.                                 else
  1778.                                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM,
  1779.                                                        MPFROM2SHORT( index, 0 ),
  1780.                                                        MPFROM2SHORT( TRUE, 0 ) );
  1781.                                 }
  1782.                             //NumItems[NumMenus] = 0;
  1783.                             WinSendMsg( hwndMenu, MM_QUERYITEM, MPFROM2SHORT(NumMenus*100,TRUE),MPFROMP(&menuData[index]));
  1784.                             menuItem = menuData[index];
  1785.                             menuItem.afStyle = MIS_STATIC;
  1786.                             menuItem.afAttribute = MIA_DISABLED;
  1787.                             WinSendMsg( hwndMenu, MM_SETITEM, MPFROM2SHORT(NumMenus*100,TRUE),MPFROMP(&menuItem));
  1788.                             WinSetMenuItemText( hwndMenu, 100*MAXMENUS, "" );
  1789.                             NumItems[ NumMenus ] = 0;
  1790.                             UpdateMenu[ NumMenus ] = FALSE;
  1791.                             NumMenus--;
  1792.  
  1793.                             // if we deleted only menu, disable menu buttons
  1794.                             if (NumMenus == 0) {
  1795.                                 WinEnableControl( hWnd, EDITMENUBUTTON, FALSE );
  1796.                                 WinEnableControl( hWnd, REMOVEMENU, FALSE );
  1797.                                 WinEnableControl( hWnd, MOVEMENULEFT, FALSE );
  1798.                                 WinEnableControl( hWnd, MOVEMENURIGHT, FALSE );
  1799.                                 }
  1800.                             MakeArrowPointer ();
  1801.                             }
  1802.                     return 0;
  1803.                     }
  1804.                 //--------------------------------------------------------------
  1805.                 // move menu left in menu structure
  1806.                 //--------------------------------------------------------------
  1807.                 case MOVEMENULEFT: {
  1808.                     short index = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, CURMENULIST,
  1809.                                                              LM_QUERYSELECTION,
  1810.                                                              MPFROM2SHORT( LIT_FIRST, 0 ),
  1811.                                                              0 ) );
  1812.                     if ((NumMenus == 0) || (index == 0)) {
  1813.                         WinAlarm(HWND_DESKTOP, WA_WARNING);
  1814.                         return 0;
  1815.                         }
  1816.                     MakeHourglassPointer ();
  1817.                     SwapTwoMenus( index-1, index );
  1818.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_DELETEITEM,
  1819.                                        MPFROM2SHORT( index, 0 ), 0 );
  1820.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_INSERTITEM,
  1821.                                        MPFROM2SHORT( index-1, 0 ), MenuName[index-1] );
  1822.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM,
  1823.                                        MPFROM2SHORT( index-1, 0 ),
  1824.                                        MPFROM2SHORT( TRUE, 0 ) );
  1825.                     MakeArrowPointer ();
  1826.                     return 0;
  1827.                     }
  1828.                 //--------------------------------------------------------------
  1829.                 // move menu right in menu structure
  1830.                 //--------------------------------------------------------------
  1831.                 case MOVEMENURIGHT: {
  1832.                     short index = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, CURMENULIST,
  1833.                                                              LM_QUERYSELECTION,
  1834.                                                              MPFROM2SHORT( LIT_FIRST, 0 ),
  1835.                                                              0 ) );
  1836.                     if ((NumMenus == 0) || (index == (NumMenus)-1)) {
  1837.                         WinAlarm(HWND_DESKTOP, WA_WARNING);
  1838.                         return 0;
  1839.                         }
  1840.                     MakeHourglassPointer ();
  1841.                     SwapTwoMenus( index, index+1 );
  1842.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_DELETEITEM,
  1843.                                        MPFROM2SHORT( index, 0 ), 0 );
  1844.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_INSERTITEM,
  1845.                                        MPFROM2SHORT( index+1, 0 ), MenuName[index+1] );
  1846.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM,
  1847.                                        MPFROM2SHORT( index+1, 0 ),
  1848.                                        MPFROM2SHORT( TRUE, 0 ) );
  1849.                     MakeArrowPointer ();
  1850.                     return 0;
  1851.                     }
  1852.                 //--------------------------------------------------------------
  1853.                 // nothing we care about, pass it onto the system default proc
  1854.                 //--------------------------------------------------------------
  1855.                 default:
  1856.                     return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1857.                 }
  1858.             }
  1859.         //----------------------------------------------------------------------
  1860.         // if nothing further we want to intercept, pass message onto system
  1861.         //----------------------------------------------------------------------
  1862.         default:
  1863.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1864.     }
  1865. }
  1866.  
  1867.  
  1868. ////////////////////////////////////////////////////////////////////////////////
  1869. // SwapTwoMenus will swap the FileBar stored information entries for two menus
  1870. // indicated by menu1 and menu2.  The text on the displayed menubar will also
  1871. // be changed to indicate the swap.
  1872. ////////////////////////////////////////////////////////////////////////////////
  1873. void SwapTwoMenus( short menu1, short menu2 )
  1874. {
  1875.     SHORT t1;
  1876.     BYTE t2;
  1877.  
  1878.     for (short i=0; i<MAXITEMS; i++) {
  1879.         strcpy( tmpBuffer, ItemName[menu1][i] );
  1880.         strcpy( ItemName[menu1][i], ItemName[menu2][i] );
  1881.         strcpy( ItemName[menu2][i], tmpBuffer );
  1882.         strcpy( tmpBuffer, ActionToDo[menu1][i] );
  1883.         strcpy( ActionToDo[menu1][i], ActionToDo[menu2][i] );
  1884.         strcpy( ActionToDo[menu2][i], tmpBuffer );
  1885.         strcpy( tmpBuffer, CmdLnArgs[menu1][i] );
  1886.         strcpy( CmdLnArgs[menu1][i], CmdLnArgs[menu2][i] );
  1887.         strcpy( CmdLnArgs[menu2][i], tmpBuffer );
  1888.         strcpy( tmpBuffer, Directory[menu1][i] );
  1889.         strcpy( Directory[menu1][i], Directory[menu2][i] );
  1890.         strcpy( Directory[menu2][i], tmpBuffer );
  1891.         t1 = ProgType[menu2][i];
  1892.         ProgType[menu2][i] = ProgType[menu1][i];
  1893.         ProgType[menu1][i] = t1;
  1894.         }
  1895.     t2 = NumItems[menu2];
  1896.     NumItems[menu2] = NumItems[menu1];
  1897.     NumItems[menu1] = t2;
  1898.     strcpy( tmpBuffer, MenuName[menu1] );
  1899.     strcpy( MenuName[menu1], MenuName[menu2] );
  1900.     strcpy( MenuName[menu2], tmpBuffer );
  1901.     UpdateMenu[menu1] = TRUE;
  1902.     UpdateMenu[menu2] = TRUE;
  1903.     WinSetMenuItemText( hwndMenu, 100+menu1*100, MenuName[menu1] );
  1904.     WinSetMenuItemText( hwndMenu, 100+menu2*100, MenuName[menu2] );
  1905. }
  1906.  
  1907.  
  1908. ////////////////////////////////////////////////////////////////////////////////
  1909. // AddAMenuProc - message handler for the dialog box that allows the user to
  1910. // add a menu to the menubar
  1911. ////////////////////////////////////////////////////////////////////////////////
  1912. MRESULT EXPENTRY AddAMenuProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1913. {
  1914.    switch( msg )
  1915.     {
  1916.         //----------------------------------------------------------------------
  1917.         // when the dialog is being initialized, center it on desktop and put
  1918.         // the current data into controls
  1919.         //----------------------------------------------------------------------
  1920.         case WM_INITDLG: {
  1921.             SWP swp;
  1922.             WinSendDlgItemMsg( hWnd, MENUNAME, EM_SETTEXTLIMIT,
  1923.                                MPFROM2SHORT( MAXMENUNAMELENGTH-1, 0 ), 0 );
  1924.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  1925.             WinSetWindowPos( hWnd, (HWND)0,
  1926.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  1927.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  1928.                              0, 0, SWP_MOVE);
  1929.             break;
  1930. //            return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1931.             }
  1932.         //----------------------------------------------------------------------
  1933.         // process a command message received from the system
  1934.         //----------------------------------------------------------------------
  1935.         case WM_COMMAND:
  1936.         {
  1937.             USHORT command = SHORT1FROMMP(mp1);
  1938.             switch( command )
  1939.                 {
  1940.                 //--------------------------------------------------------------
  1941.                 // user press OK button.  Add the menu name they entered into
  1942.                 // the menu structure and return
  1943.                 //--------------------------------------------------------------
  1944.                 case DID_OK: {
  1945.                     WinQueryDlgItemText( hWnd, MENUNAME, MAXMENUNAMELENGTH, MenuName[NumMenus]);
  1946.                     UpdateMenu[NumMenus] = TRUE;
  1947.                     NumItems[NumMenus] = 0;
  1948.                     menuData[NumMenus].afStyle = 0;
  1949.                     menuData[NumMenus].afAttribute = 0;
  1950.                     WinSendMsg( hwndMenu, MM_SETITEM, MPFROM2SHORT(100*NumMenus+100,TRUE),MPFROMP(&menuData[NumMenus]));
  1951.                     WinSetMenuItemText( hwndMenu, 100*NumMenus+100, &MenuName[NumMenus]);
  1952.                     MenuSelection = NumMenus;
  1953.                     NumMenus++;
  1954.                     WinDismissDlg( hWnd, TRUE );
  1955.                     return 0;
  1956.                     }
  1957.                 //--------------------------------------------------------------
  1958.                 // they decided not to add a menu, dismiss dialog and return
  1959.                 //--------------------------------------------------------------
  1960.                 case DID_CANCEL: {
  1961.                     WinDismissDlg( hWnd, TRUE );
  1962.                     return 0;
  1963.                     }
  1964.                 //--------------------------------------------------------------
  1965.                 // nothing we care about, pass on for default processing
  1966.                 //--------------------------------------------------------------
  1967.                 default:
  1968.                     break;
  1969. //                    return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1970.                 }
  1971.         }
  1972.         // ---------------------------------------------------------------------
  1973.         // if nothing further we want to intercept, pass message onto system
  1974.         // ---------------------------------------------------------------------
  1975.         default:
  1976.             break;
  1977. //            return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1978.     }
  1979.     return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1980. }
  1981.  
  1982.  
  1983. ////////////////////////////////////////////////////////////////////////////////
  1984. // Swap menu items item1 and item2 on menu Menu in the menu information arrays
  1985. ////////////////////////////////////////////////////////////////////////////////
  1986. VOID SwapTwoItems(SHORT Menu, SHORT item1, SHORT item2)
  1987. {
  1988.     SHORT t1;
  1989.     strcpy( tmpBuffer, ItemName[Menu][item2] );
  1990.     strcpy( ItemName[Menu][item2], ItemName[Menu][item1] );
  1991.     strcpy( ItemName[Menu][item1], tmpBuffer );
  1992.     strcpy( tmpBuffer, ActionToDo[Menu][item2] );
  1993.     strcpy( ActionToDo[Menu][item2], ActionToDo[Menu][item1] );
  1994.     strcpy( ActionToDo[Menu][item1], tmpBuffer );
  1995.     strcpy( tmpBuffer, CmdLnArgs[Menu][item2] );
  1996.     strcpy( CmdLnArgs[Menu][item2], CmdLnArgs[Menu][item1] );
  1997.     strcpy( CmdLnArgs[Menu][item1], tmpBuffer );
  1998.     strcpy( tmpBuffer, Directory[Menu][item2] );
  1999.     strcpy( Directory[Menu][item2], Directory[Menu][item1] );
  2000.     strcpy( Directory[Menu][item1], tmpBuffer );
  2001.     t1 = ProgType[Menu][item2];
  2002.     ProgType[Menu][item2] = ProgType[Menu][item1];
  2003.     ProgType[Menu][item1] = t1;
  2004. }
  2005.  
  2006.  
  2007. ////////////////////////////////////////////////////////////////////////////////
  2008. // updateItemList - refreshes the contents of the item list list-box in a dialog
  2009. ////////////////////////////////////////////////////////////////////////////////
  2010. VOID updateItemList( HWND hWnd )
  2011. {
  2012.     CHAR Separator[] = SEPARATOR;
  2013.     WinSendDlgItemMsg( hWnd, ITEMMENU, LM_DELETEALL, 0, 0 );
  2014.     for (short i=0; i<NumItems[MenuSelection]; i++)
  2015.         if (ItemName[MenuSelection][i][0] != '\0')
  2016.             WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM,
  2017.                                MPFROM2SHORT( LIT_END, 0 ),
  2018.                                ItemName[MenuSelection][i] );
  2019.         else
  2020.             WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM,
  2021.                                MPFROM2SHORT( LIT_END, 0 ),
  2022.                                Separator );
  2023.     if (NumItems[MenuSelection] > 0)
  2024.         WinSendDlgItemMsg( hWnd, ITEMMENU, LM_SELECTITEM,
  2025.                            MPFROM2SHORT( ItemSelection, 0 ),
  2026.                            MPFROM2SHORT( TRUE, 0 ) );
  2027. }
  2028.  
  2029.  
  2030. ////////////////////////////////////////////////////////////////////////////////
  2031. // EditItemProc - the message handler for the edit menu item dialog box
  2032. ////////////////////////////////////////////////////////////////////////////////
  2033. MRESULT EXPENTRY EditItemProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  2034. {
  2035.     switch( msg )
  2036.     {
  2037.         //----------------------------------------------------------------------
  2038.         // when the dialog is being initialized, center it on desktop and put
  2039.         // the current data into control fields
  2040.         //----------------------------------------------------------------------
  2041.         case WM_INITDLG: {
  2042.             SWP swp;
  2043.             WinSendDlgItemMsg( hWnd, MENUNAME, EM_SETTEXTLIMIT,
  2044.                                MPFROM2SHORT( MAXMENUNAMELENGTH-1, 0 ), 0 );
  2045.             WinSetDlgItemText( hWnd, MENUNAME, MenuName[MenuSelection]);
  2046.             ItemSelection = 0;
  2047.             updateItemList( hWnd );
  2048.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  2049.             WinSetWindowPos( hWnd, (HWND)0,
  2050.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  2051.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  2052.                              0, 0, SWP_MOVE);
  2053.             break;
  2054. //            return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2055.             }
  2056.         //----------------------------------------------------------------------
  2057.         // if there is a control message, update enabled status of buttons
  2058.         //----------------------------------------------------------------------
  2059.         case WM_CONTROL:
  2060.         {
  2061.             if ((SHORT1FROMMP(mp1)==ITEMMENU) && (SHORT2FROMMP(mp1)==LN_ENTER))
  2062.                 return WinSendMsg( hWnd, WM_COMMAND, MPFROM2SHORT( CHANGEITEM, 0 ), mp2 );
  2063.             break;
  2064. //            return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2065.         }
  2066.         //----------------------------------------------------------------------
  2067.         // process a command message received from the system
  2068.         //----------------------------------------------------------------------
  2069.         case WM_COMMAND:
  2070.         {
  2071.             USHORT command = SHORT1FROMMP(mp1);
  2072.             switch( command )
  2073.                 {
  2074.                 //--------------------------------------------------------------
  2075.                 // insert a separator into item list, if there is room
  2076.                 //--------------------------------------------------------------
  2077.                 case INSERTSEPARATOR: {
  2078.                     ItemSelection = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU,
  2079.                                                                      LM_QUERYSELECTION,
  2080.                                                                      MPFROM2SHORT( LIT_FIRST, 0 ),
  2081.                                                                      0 ) );
  2082.                     if (NumItems[MenuSelection] >= MAXITEMS-1) {
  2083.                         // error and return if no room
  2084.                         WinMessageBox( HWND_DESKTOP, hWnd,
  2085.                                        "Error!  Maximum number of items for this menu already defined!",
  2086.                                        "Add A Separator", 0,
  2087.                                        MB_MOVEABLE|MB_ERROR|MB_OK);
  2088.                         return 0;
  2089.                         }
  2090.  
  2091.                     // since this is a separator, blank out launch information
  2092.                     ItemSelection = 0;
  2093.                     if (NumItems[MenuSelection] > 0)
  2094.                         for (short i=NumItems[MenuSelection]-1; i>=0; i--)
  2095.                             SwapTwoItems( MenuSelection, i, i+1 );
  2096.  
  2097.                     ItemName[MenuSelection][ItemSelection][0]='\0';
  2098.                     NumItems[MenuSelection]++;
  2099.                     UpdateMenu[MenuSelection] = TRUE;
  2100.                     updateItemList( hWnd );
  2101.                     return 0;
  2102.                     }
  2103.                 //--------------------------------------------------------------
  2104.                 // user wants to add an item to the current menu
  2105.                 //--------------------------------------------------------------
  2106.                 case ADDITEM: {
  2107.                     ItemSelection = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU,
  2108.                                                                      LM_QUERYSELECTION,
  2109.                                                                      MPFROM2SHORT( LIT_FIRST, 0 ),
  2110.                                                                      0 ) );
  2111.                     // error and return if no room for another item
  2112.                     if (NumItems[MenuSelection] >= MAXITEMS) {
  2113.                         WinMessageBox( HWND_DESKTOP, hWnd,
  2114.                                        "Error!  Maximum number of items for this menu already defined!",
  2115.                                        "Add Item", 0,
  2116.                                        MB_MOVEABLE|MB_ERROR|MB_OK);
  2117.                         return 0;
  2118.                         }
  2119.                     // get new item via add item dialog box
  2120.                     WinDlgBox(HWND_DESKTOP,
  2121.                               hWnd,
  2122.                               (PFNWP)AddAnItemProc,
  2123.                               0,
  2124.                               ADDANITEM,
  2125.                               (PVOID)NULL);
  2126.                     // update item list with possible new item
  2127.                     updateItemList( hWnd );
  2128.                     return 0;
  2129.                     }
  2130.                 //--------------------------------------------------------------
  2131.                 // user wants to change a menu item
  2132.                 //--------------------------------------------------------------
  2133.                 case CHANGEITEM: {
  2134.                     ItemSelection = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU,
  2135.                                                                      LM_QUERYSELECTION,
  2136.                                                                      MPFROM2SHORT( LIT_FIRST, 0 ),
  2137.                                                                      0 ) );
  2138.                     if ((NumItems[MenuSelection] == 0) || (ItemName[MenuSelection][ItemSelection][0] == '\0')) {
  2139.                         WinAlarm(HWND_DESKTOP, WA_WARNING);
  2140.                         return 0;
  2141.                         }
  2142.                     WinDlgBox(HWND_DESKTOP,
  2143.                               hWnd,
  2144.                               (PFNWP)EditItemDataProc,
  2145.                               0,
  2146.                               EDITITEMDATA,
  2147.                               (PVOID)NULL);
  2148.                     updateItemList( hWnd );
  2149.                     return 0;
  2150.                     }
  2151.                 //--------------------------------------------------------------
  2152.                 // move item down in menu order
  2153.                 //--------------------------------------------------------------
  2154.                 case MOVEITEMDOWN: {
  2155.                     CHAR Separator[] = SEPARATOR;
  2156.                     short i = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU,
  2157.                                                                LM_QUERYSELECTION,
  2158.                                                                MPFROM2SHORT( LIT_FIRST, 0 ),
  2159.                                                                0 ) );
  2160.                     if ((i == NumItems[MenuSelection]-1) || (NumItems[MenuSelection] == 0)) {
  2161.                         WinAlarm(HWND_DESKTOP, WA_WARNING);
  2162.                         return 0;
  2163.                         }
  2164.                     SwapTwoItems( MenuSelection, i, i+1 );
  2165.                     WinSendDlgItemMsg( hWnd, ITEMMENU, LM_DELETEITEM,
  2166.                                        MPFROM2SHORT( i, 0 ),
  2167.                                        MPFROM2SHORT( TRUE, 0 ) );
  2168.                     if (ItemName[MenuSelection][i+1][0] == '\0')
  2169.                         WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM,
  2170.                                            MPFROM2SHORT( i+1, 0 ),
  2171.                                            Separator );
  2172.                     else WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM,
  2173.                                             MPFROM2SHORT( i+1, 0 ),
  2174.                                             &ItemName[MenuSelection][i+1] );
  2175.                     WinSendDlgItemMsg( hWnd, ITEMMENU, LM_SELECTITEM,
  2176.                                        MPFROM2SHORT( i+1, 0 ),
  2177.                                        MPFROM2SHORT( TRUE, 0 ) );
  2178.                     return 0;
  2179.                     }
  2180.                 //--------------------------------------------------------------
  2181.                 // move item up in menu order
  2182.                 //--------------------------------------------------------------
  2183.                 case MOVEITEMUP: {
  2184.                     CHAR Separator[] = SEPARATOR;
  2185.                     short i = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU,
  2186.                                                                LM_QUERYSELECTION,
  2187.                                                                MPFROM2SHORT( LIT_FIRST, 0 ),
  2188.                                                                0 ) );
  2189.                     if ((i == 0) || (NumItems[MenuSelection] == 0)) {
  2190.                         WinAlarm(HWND_DESKTOP, WA_WARNING);
  2191.                         return 0;
  2192.                         }
  2193.                     SwapTwoItems( MenuSelection, i-1, i );
  2194.                     WinSendDlgItemMsg( hWnd, ITEMMENU, LM_DELETEITEM,
  2195.                                        MPFROM2SHORT( i, 0 ),
  2196.                                        MPFROM2SHORT( TRUE, 0 ) );
  2197.                     if (ItemName[MenuSelection][i-1][0] == '\0')
  2198.                         WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM,
  2199.                                            MPFROM2SHORT( i-1, 0 ),
  2200.                                            Separator );
  2201.                     else WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM,
  2202.                                             MPFROM2SHORT( i-1, 0 ),
  2203.                                             &ItemName[MenuSelection][i-1] );
  2204.                     WinSendDlgItemMsg( hWnd, ITEMMENU, LM_SELECTITEM,
  2205.                                        MPFROM2SHORT( i-1, 0 ),
  2206.                                        MPFROM2SHORT( TRUE, 0 ) );
  2207.                     return 0;
  2208.                     }
  2209.                 //--------------------------------------------------------------
  2210.                 // remove a menu item
  2211.                 //--------------------------------------------------------------
  2212.                 case REMOVEITEM: {
  2213.                     if (NumItems[MenuSelection] == 0) {
  2214.                         WinAlarm(HWND_DESKTOP, WA_WARNING);
  2215.                         return 0;
  2216.                         }
  2217.  
  2218.                     if (NumItems[MenuSelection] > 0)
  2219.                         if (WinMessageBox( HWND_DESKTOP, hWnd,
  2220.                                            "If you remove this item, there will be no way to recover it.  Are you sure you want to remove this item?",
  2221.                                            "Remove Item", 0,
  2222.                                            MB_MOVEABLE|MB_WARNING|MB_YESNO|MB_DEFBUTTON2) == MBID_YES ) {
  2223.                             short index = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU,
  2224.                                                                            LM_QUERYSELECTION,
  2225.                                                                            MPFROM2SHORT( LIT_FIRST, 0 ),
  2226.                                                                            0 ) );
  2227.                             WinSendDlgItemMsg( hWnd, ITEMMENU, LM_DELETEITEM,
  2228.                                                MPFROM2SHORT( index, 0 ), 0 );
  2229.  
  2230.                             for (short i=index; i<MAXITEMS-1; i++) {
  2231.                                 strcpy( ItemName[MenuSelection][i], ItemName[MenuSelection][i+1]);
  2232.                                 strcpy( ActionToDo[MenuSelection][i], ActionToDo[MenuSelection][i+1]);
  2233.                                 strcpy( CmdLnArgs[MenuSelection][i], CmdLnArgs[MenuSelection][i+1]);
  2234.                                 strcpy( Directory[MenuSelection][i], Directory[MenuSelection][i+1]);
  2235.                                 ProgType[MenuSelection][i] = ProgType[MenuSelection][i+1];
  2236.                                 }
  2237.  
  2238.                             if (NumItems[MenuSelection] > 0) {
  2239.                                 int newIndex = index-1;
  2240.                                 if (0 > newIndex)
  2241.                                     newIndex = 0;
  2242.  
  2243.                                 if (index == NumItems[MenuSelection]-1)
  2244.                                     WinSendDlgItemMsg( hWnd, ITEMMENU, LM_SELECTITEM,
  2245.                                                        MPFROM2SHORT( newIndex, 0 ),
  2246.                                                        MPFROM2SHORT( TRUE, 0 ) );
  2247.                                 else
  2248.                                     WinSendDlgItemMsg( hWnd, ITEMMENU, LM_SELECTITEM,
  2249.                                                        MPFROM2SHORT( index, 0 ),
  2250.                                                        MPFROM2SHORT( TRUE, 0 ) );
  2251.                                 }
  2252.  
  2253.                             NumItems[MenuSelection]--;
  2254.                             }
  2255.                     return 0;
  2256.                     }
  2257.                 //--------------------------------------------------------------
  2258.                 // user is done editing a menu, save menu name and return
  2259.                 //--------------------------------------------------------------
  2260.                 case DID_OK: {
  2261.                     WinQueryDlgItemText( hWnd, MENUNAME, MAXMENUNAMELENGTH, MenuName[MenuSelection]);
  2262.                     WinSetMenuItemText( hwndMenu, 100*MenuSelection+100, &MenuName[MenuSelection]);
  2263.                     UpdateMenu[MenuSelection] = TRUE;
  2264.                     WinDismissDlg( hWnd, TRUE );
  2265.                     return 0;
  2266.                     }
  2267.                 //--------------------------------------------------------------
  2268.                 // not a message we care about, pass it onto the system
  2269.                 //--------------------------------------------------------------
  2270.                 default:
  2271.                     break;
  2272. //                    return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2273.                 }
  2274.         }
  2275.         //----------------------------------------------------------------------
  2276.         // if nothing further we want to intercept, pass message onto system
  2277.         //----------------------------------------------------------------------
  2278.         default:
  2279.            break;
  2280. //           return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2281.         }
  2282.     return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2283. }
  2284.  
  2285.  
  2286. ////////////////////////////////////////////////////////////////////////////////
  2287. // update the enable/disabled state of the program type buttons
  2288. ////////////////////////////////////////////////////////////////////////////////
  2289. void updateEditItemWindow( HWND hWnd )
  2290. {
  2291.     SHORT value = TRUE;
  2292.  
  2293.     if (WinQueryButtonCheckstate( hWnd, STARTWPS ))
  2294.         value = FALSE;
  2295.  
  2296.     WinEnableControl( hWnd, MAXIMIZED, value );
  2297.     WinEnableControl( hWnd, MINIMIZED, value );
  2298.     WinEnableControl( hWnd, FOLDER, value );
  2299.     WinEnableControl( hWnd, DOSWIN, value );
  2300.     WinEnableControl( hWnd, DOSFS, value );
  2301.     WinEnableControl( hWnd, OS2WIN, value );
  2302.     WinEnableControl( hWnd, OS2FS, value );
  2303.     WinEnableControl( hWnd, WINOS2WIN, value );
  2304.     WinEnableControl( hWnd, WINOS2FS, value );
  2305.     WinEnableControl( hWnd, PMAPP, value );
  2306.     WinEnableControl( hWnd, SETTINGSBUTTON, TRUE-value );
  2307.  
  2308.     if (WinQueryButtonCheckstate( hWnd, FOLDER )) {
  2309.         WinEnableControl( hWnd, MAXIMIZED, FALSE );
  2310.         WinEnableControl( hWnd, MINIMIZED, FALSE );
  2311.         }
  2312.  
  2313.     if ((WinQueryButtonCheckstate( hWnd, FOLDER )) || (WinQueryButtonCheckstate( hWnd, PMAPP )))
  2314.         WinEnableControl( hWnd, STARTWPS, FALSE );
  2315.     else
  2316.         WinEnableControl( hWnd, STARTWPS, TRUE );
  2317.  
  2318.     if (ActionToDo[MenuSelection][ItemSelection][0]=='\0')
  2319.         WinEnableControl( hWnd, SETTINGSBUTTON, FALSE );
  2320. }
  2321.  
  2322.  
  2323. ////////////////////////////////////////////////////////////////////////////////
  2324. // updateEditItemData - update the check states of all the buttons for the
  2325. // program item we are currently editing
  2326. ////////////////////////////////////////////////////////////////////////////////
  2327. void updateEditItemData( HWND hWnd )
  2328. {
  2329.     // put item name and length of longest possible name in entry field
  2330.     WinSendDlgItemMsg( hWnd, ITEMNAME, EM_SETTEXTLIMIT,
  2331.                        MPFROM2SHORT( MAXITEMNAMELENGTH-1, 0 ), 0 );
  2332.     WinSetDlgItemText( hWnd, ITEMNAME, ItemName[MenuSelection][ItemSelection]);
  2333.     // put path name and length of longest possible name in entry field
  2334.     WinSendDlgItemMsg( hWnd, PATHNAME, EM_SETTEXTLIMIT,
  2335.                        MPFROM2SHORT( MAXACTIONSTRINGLENGTH-1, 0 ), 0 );
  2336.     WinSetDlgItemText( hWnd, PATHNAME, ActionToDo[MenuSelection][ItemSelection]);
  2337.     // put argument and length of longest possible in entry field
  2338.     WinSendDlgItemMsg( hWnd, ARGUMENTS, EM_SETTEXTLIMIT,
  2339.                        MPFROM2SHORT( MAXARGSTRINGLENGTH-1, 0 ), 0 );
  2340.     WinSetDlgItemText( hWnd, ARGUMENTS, CmdLnArgs[MenuSelection][ItemSelection]);
  2341.     // put directory and length of longest possible directory in entry field
  2342.     WinSendDlgItemMsg( hWnd, DIRECTORY, EM_SETTEXTLIMIT,
  2343.                        MPFROM2SHORT( MAXDIRSTRINGLENGTH-1, 0 ), 0 );
  2344.     WinSetDlgItemText( hWnd, DIRECTORY, Directory[MenuSelection][ItemSelection]);
  2345.     // set appropriate radio button for program startup option
  2346.     WinCheckButton( hWnd, MAXIMIZED, FALSE );
  2347.     WinCheckButton( hWnd, MINIMIZED, FALSE );
  2348.     if (ProgType[MenuSelection][ItemSelection] & STARTMAX)
  2349.         WinCheckButton( hWnd, MAXIMIZED, TRUE );
  2350.     else if (ProgType[MenuSelection][ItemSelection] & STARTMIN)
  2351.         WinCheckButton( hWnd, MINIMIZED, TRUE );
  2352.     // set appropriate radio button for program startup option
  2353.     if (ProgType[MenuSelection][ItemSelection] & PM)
  2354.         WinCheckButton( hWnd, PMAPP, TRUE );
  2355.     else if (ProgType[MenuSelection][ItemSelection] & WPSFOLDER)
  2356.         WinCheckButton( hWnd, FOLDER, TRUE );
  2357.     else if ( (ProgType[MenuSelection][ItemSelection] & DOS) &&
  2358.               (ProgType[MenuSelection][ItemSelection] & WINDOWED))
  2359.         WinCheckButton( hWnd, DOSWIN, TRUE );
  2360.     else if ( (ProgType[MenuSelection][ItemSelection] & DOS) &&
  2361.             (ProgType[MenuSelection][ItemSelection] & FULLSCREEN))
  2362.         WinCheckButton( hWnd, DOSFS, TRUE );
  2363.     else if ( (ProgType[MenuSelection][ItemSelection] & OS2) &&
  2364.             (ProgType[MenuSelection][ItemSelection] & WINDOWED))
  2365.         WinCheckButton( hWnd, OS2WIN, TRUE );
  2366.     else if ( (ProgType[MenuSelection][ItemSelection] & OS2) &&
  2367.             (ProgType[MenuSelection][ItemSelection] & FULLSCREEN))
  2368.         WinCheckButton( hWnd, OS2FS, TRUE );
  2369.     else if ( (ProgType[MenuSelection][ItemSelection] & WINOS2) &&
  2370.             (ProgType[MenuSelection][ItemSelection] & WINDOWED))
  2371.         WinCheckButton( hWnd, WINOS2WIN, TRUE );
  2372.     else if ( (ProgType[MenuSelection][ItemSelection] & WINOS2) &&
  2373.             (ProgType[MenuSelection][ItemSelection] & FULLSCREEN))
  2374.         WinCheckButton( hWnd, WINOS2FS, TRUE );
  2375.     if (ProgType[MenuSelection][ItemSelection] & STARTASWPS)
  2376.         WinCheckButton( hWnd, STARTWPS, TRUE );
  2377.     else
  2378.         WinCheckButton( hWnd, STARTWPS, FALSE );
  2379.     updateEditItemWindow( hWnd );
  2380. }
  2381.  
  2382.  
  2383. ////////////////////////////////////////////////////////////////////////////////
  2384. // message handler for the dialog "edit an item's values"
  2385. ////////////////////////////////////////////////////////////////////////////////
  2386. MRESULT EXPENTRY EditItemDataProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  2387. {
  2388.     switch( msg )
  2389.     {
  2390.         //----------------------------------------------------------------------
  2391.         // if the object being drug over us is a single object, allow drag
  2392.         //----------------------------------------------------------------------
  2393.         case DM_DRAGOVER: {
  2394.             ULONG cbBuffer;
  2395.             DRAGITEM dragItem;
  2396.             PDRAGINFO dragInfoPtr;
  2397.             INT numObjects;
  2398.  
  2399.             dragInfoPtr = (PDRAGINFO)mp1;
  2400.             DrgAccessDraginfo(dragInfoPtr);
  2401.             numObjects = dragInfoPtr->cditem;
  2402.             cbBuffer = sizeof(DRAGITEM);
  2403.             DrgQueryDragitem( dragInfoPtr, cbBuffer, &dragItem, 0 );
  2404.             DrgFreeDraginfo(dragInfoPtr);
  2405.  
  2406.             // allow anything, if sent by itself, to be dropped on us
  2407.             if (numObjects == 1)
  2408.                 return MPFROM2SHORT( DOR_DROP, DO_UNKNOWN );
  2409.             return MPFROM2SHORT( DOR_NEVERDROP, DO_UNKNOWN );
  2410.             }
  2411.         //----------------------------------------------------------------------
  2412.         // allow the dropping of a WPS object to our window.  Once dropped, get
  2413.         // necessary info and fill in dialog with the info we retrieve
  2414.         //----------------------------------------------------------------------
  2415.         case DM_DROP: {
  2416.             PDRAGINFO dragInfoPtr;
  2417.             ULONG cbBuffer;
  2418.             DRAGITEM dragItem;
  2419.  
  2420.             dragInfoPtr = (PDRAGINFO)mp1;
  2421.             DrgAccessDraginfo(dragInfoPtr);
  2422.  
  2423.             cbBuffer = sizeof(DRAGITEM);
  2424.             DrgQueryDragitem( dragInfoPtr, cbBuffer, &dragItem, 0 );
  2425.  
  2426.             // get menu item name
  2427.             DrgQueryStrName( dragItem.hstrTargetName, sizeof(ItemName[MenuSelection][ItemSelection]), ItemName[MenuSelection][ItemSelection]);
  2428.             // get default directory
  2429.             DrgQueryStrName( dragItem.hstrContainerName, sizeof(Directory[MenuSelection][ItemSelection]), Directory[MenuSelection][ItemSelection]);
  2430.             // get path name
  2431.             DrgQueryStrName( dragItem.hstrSourceName, sizeof(ActionToDo[MenuSelection][ItemSelection]), ActionToDo[MenuSelection][ItemSelection]);
  2432.  
  2433.             ProgType[MenuSelection][ItemSelection] = WPSFOLDER;
  2434.             WinCheckButton( hWnd, FOLDER, TRUE );
  2435.  
  2436.             DrgFreeDraginfo(dragInfoPtr);
  2437.             updateEditItemData( hWnd );
  2438.             WinSetFocus( HWND_DESKTOP, hWnd );
  2439.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2440.             }
  2441.         //----------------------------------------------------------------------
  2442.         // when the dialog is being initialized, center it on desktop and put
  2443.         // the current data into control fields
  2444.         //----------------------------------------------------------------------
  2445.         case WM_INITDLG: {
  2446.             SWP swp;
  2447.  
  2448.             // center dialog on screen
  2449.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  2450.             WinSetWindowPos( hWnd, (HWND)0,
  2451.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  2452.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  2453.                              0, 0, SWP_MOVE);
  2454.  
  2455.             // save data in case of cancel or restore
  2456.             oldProgType = ProgType[MenuSelection][ItemSelection];
  2457.             strcpy( oldItemName, ItemName[MenuSelection][ItemSelection] );
  2458.             strcpy( oldDirectory, Directory[MenuSelection][ItemSelection] );
  2459.             strcpy( oldAction, ActionToDo[MenuSelection][ItemSelection] );
  2460.             strcpy( oldCmdLn, CmdLnArgs[MenuSelection][ItemSelection] );
  2461.  
  2462.             updateEditItemData( hWnd );
  2463.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2464.             }
  2465.         //----------------------------------------------------------------------
  2466.         // we received a control message, update enabling of buttons
  2467.         //----------------------------------------------------------------------
  2468.         case WM_CONTROL:
  2469.         {
  2470.             // make sure either maximize -or- minimize is checked, never both
  2471.             if ((SHORT1FROMMP(mp1)==MAXIMIZED) && (SHORT2FROMMP(mp1)==BN_CLICKED))
  2472.                 WinCheckButton( hWnd, MINIMIZED, FALSE );
  2473.             if ((SHORT1FROMMP(mp1)==MINIMIZED) && (SHORT2FROMMP(mp1)==BN_CLICKED))
  2474.                 WinCheckButton( hWnd, MAXIMIZED, FALSE );
  2475.             updateEditItemWindow( hWnd );
  2476.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2477.         }
  2478.         //----------------------------------------------------------------------
  2479.         // process a command message received from the system
  2480.         //----------------------------------------------------------------------
  2481.         case WM_COMMAND:
  2482.         {
  2483.             USHORT command = SHORT1FROMMP(mp1);
  2484.             switch( command )
  2485.                 {
  2486.                 //--------------------------------------------------------------
  2487.                 // open the settings notebook and allow user modifications
  2488.                 //--------------------------------------------------------------
  2489.                 case SETTINGSBUTTON: {
  2490.                     HOBJECT object;
  2491.  
  2492.                     // open settings for current program in dialog controls
  2493.                     WinQueryDlgItemText( hWnd, ITEMNAME, MAXITEMNAMELENGTH,
  2494.                                          ItemName[MenuSelection][ItemSelection]);
  2495.                     WinQueryDlgItemText( hWnd, PATHNAME, MAXACTIONSTRINGLENGTH,
  2496.                                          ActionToDo[MenuSelection][ItemSelection]);
  2497.                     WinQueryDlgItemText( hWnd, ARGUMENTS, MAXARGSTRINGLENGTH,
  2498.                                          CmdLnArgs[MenuSelection][ItemSelection]);
  2499.                     WinQueryDlgItemText( hWnd, DIRECTORY, MAXDIRSTRINGLENGTH,
  2500.                                          Directory[MenuSelection][ItemSelection]);
  2501.  
  2502.                     if (ProgType[MenuSelection][ItemSelection] & WPSFOLDER)
  2503.                         sprintf(tmpBuffer, "%s%s\0", Directory[MenuSelection][ItemSelection],ActionToDo[MenuSelection][ItemSelection]);
  2504.                     else
  2505.                         sprintf(tmpBuffer, "%s\0", ActionToDo[MenuSelection][ItemSelection]);
  2506.  
  2507.                     object = WinQueryObject( tmpBuffer );
  2508.                     if (object==NULLHANDLE) {
  2509.                         WinMessageBox( HWND_DESKTOP, hwndFrame, "Could not locate the specified WPS object!\n\nThe pathname and/or directory you specified may not be correct.", "FileBar Error!", 0,
  2510.                                        MB_MOVEABLE|MB_OK|MB_ERROR);
  2511.                         return 0;
  2512.                         }
  2513.  
  2514.                     WinSetObjectData( object, "OPEN=SETTINGS" );
  2515.                     return 0;
  2516.                     }
  2517.                 //--------------------------------------------------------------
  2518.                 // the user wants to find a file to call as a menu item.  Hook
  2519.                 // into OS/2's file dialog procedure to ease the finding process
  2520.                 // for us to program!  Then once a file is selected, fill in
  2521.                 // the program path, directory and query the application for its
  2522.                 // application type and mark the appropriate radio button
  2523.                 //--------------------------------------------------------------
  2524.                 case FINDFILE: {
  2525.                     CHAR title[] = "FileBar - Find A File To Add";
  2526.                     ULONG s, t;
  2527.                     HWND hwndDialog;
  2528.  
  2529.                     fileDlgInfo.fl = FDS_OPEN_DIALOG|FDS_CENTER;
  2530.                     fileDlgInfo.pszTitle = title;
  2531.                     strcat(fileDlgInfo.szFullFile, "*.*\0");
  2532.  
  2533.                     hwndDialog = WinFileDlg( HWND_DESKTOP, hWnd, &fileDlgInfo );
  2534.                     if (hwndDialog && (fileDlgInfo.lReturn == DID_OK)) {
  2535.  
  2536.                         strcpy( ActionToDo[MenuSelection][ItemSelection], fileDlgInfo.szFullFile );
  2537.  
  2538.                         s=0;
  2539.                         while(fileDlgInfo.szFullFile[s]!='\0')
  2540.                             s++;
  2541.                         while((fileDlgInfo.szFullFile[s]!='\\') && (s>=0))
  2542.                             s--;
  2543.  
  2544.                         t = 0;
  2545.                         while (t<s)
  2546.                             Directory[MenuSelection][ItemSelection][t] = fileDlgInfo.szFullFile[t++];
  2547.                         Directory[MenuSelection][ItemSelection][t] = '\0';
  2548.  
  2549.                         DosQueryAppType( ActionToDo[MenuSelection][ItemSelection], &t);
  2550.                         ProgType[MenuSelection][ItemSelection] = OS2 + WINDOWED;
  2551.                         if (t == FAPPTYP_WINDOWAPI)
  2552.                             ProgType[MenuSelection][ItemSelection] = PM;
  2553.                         if (t == FAPPTYP_WINDOWCOMPAT)
  2554.                             ProgType[MenuSelection][ItemSelection] = OS2 + WINDOWED;
  2555.                         if (t == FAPPTYP_NOTWINDOWCOMPAT)
  2556.                             ProgType[MenuSelection][ItemSelection] = OS2 + FULLSCREEN;
  2557.                         if (t == FAPPTYP_DOS)
  2558.                             ProgType[MenuSelection][ItemSelection] = DOS + WINDOWED;
  2559.                         if ((t == FAPPTYP_WINDOWSREAL) || (t == FAPPTYP_WINDOWSPROT))
  2560.                             ProgType[MenuSelection][ItemSelection] = WINOS2 + FULLSCREEN;
  2561.  
  2562.                         updateEditItemData( hWnd );
  2563.                         updateEditItemWindow( hWnd );
  2564.  
  2565.                         if (fileDlgInfo.szFullFile[s]=='\\')
  2566.                             fileDlgInfo.szFullFile[s+1]='\0';
  2567.                         else
  2568.                             fileDlgInfo.szFullFile[0]='\0';
  2569.                         }
  2570.                     else
  2571.                         fileDlgInfo.szFullFile[0]='\0';
  2572.                     return 0;
  2573.                     }
  2574.                 //--------------------------------------------------------------
  2575.                 // user pressed Reset, restore old settings and continue
  2576.                 //--------------------------------------------------------------
  2577.                 case RESETBUTTON: {
  2578.                     ProgType[MenuSelection][ItemSelection] = oldProgType;
  2579.                     strcpy( ItemName[MenuSelection][ItemSelection], oldItemName );
  2580.                     strcpy( Directory[MenuSelection][ItemSelection], oldDirectory );
  2581.                     strcpy( ActionToDo[MenuSelection][ItemSelection], oldAction );
  2582.                     strcpy( CmdLnArgs[MenuSelection][ItemSelection], oldCmdLn );
  2583.                     updateEditItemData( hWnd );
  2584.                     return 0;
  2585.                     }
  2586.                 //--------------------------------------------------------------
  2587.                 // user pressed CANCEL, restore old item data
  2588.                 //--------------------------------------------------------------
  2589.                 case DID_CANCEL: {
  2590.                     ProgType[MenuSelection][ItemSelection] = oldProgType;
  2591.                     strcpy( ItemName[MenuSelection][ItemSelection], oldItemName );
  2592.                     strcpy( Directory[MenuSelection][ItemSelection], oldDirectory );
  2593.                     strcpy( ActionToDo[MenuSelection][ItemSelection], oldAction );
  2594.                     strcpy( CmdLnArgs[MenuSelection][ItemSelection], oldCmdLn );
  2595.                     WinDismissDlg( hWnd, TRUE );
  2596.                     return 0;
  2597.                     }
  2598.                 //--------------------------------------------------------------
  2599.                 // user pressed OK, save current information for this item
  2600.                 //--------------------------------------------------------------
  2601.                 case DID_OK: {
  2602.                     // save program type and max/min startup status
  2603.                     ProgType[MenuSelection][ItemSelection] = 0;
  2604.                     if (WinQueryButtonCheckstate( hWnd, FOLDER ))
  2605.                         ProgType[MenuSelection][ItemSelection] = WPSFOLDER;
  2606.                     if (WinQueryButtonCheckstate( hWnd, OS2WIN ))
  2607.                         ProgType[MenuSelection][ItemSelection] = OS2 + WINDOWED;
  2608.                     if (WinQueryButtonCheckstate( hWnd, OS2FS ))
  2609.                         ProgType[MenuSelection][ItemSelection] = OS2 + FULLSCREEN;
  2610.                     if (WinQueryButtonCheckstate( hWnd, DOSWIN ))
  2611.                         ProgType[MenuSelection][ItemSelection] = DOS + WINDOWED;
  2612.                     if (WinQueryButtonCheckstate( hWnd, DOSFS ))
  2613.                         ProgType[MenuSelection][ItemSelection] = DOS + FULLSCREEN;
  2614.                     if (WinQueryButtonCheckstate( hWnd, WINOS2WIN ))
  2615.                         ProgType[MenuSelection][ItemSelection] = WINOS2 + WINDOWED;
  2616.                     if (WinQueryButtonCheckstate( hWnd, WINOS2FS ))
  2617.                         ProgType[MenuSelection][ItemSelection] = WINOS2 + FULLSCREEN;
  2618.                     if (WinQueryButtonCheckstate( hWnd, PMAPP ))
  2619.                         ProgType[MenuSelection][ItemSelection] = PM;
  2620.                     if (WinQueryButtonCheckstate( hWnd, MAXIMIZED ))
  2621.                         ProgType[MenuSelection][ItemSelection] = ProgType[MenuSelection][ItemSelection] | STARTMAX;
  2622.                     if (WinQueryButtonCheckstate( hWnd, MINIMIZED ))
  2623.                         ProgType[MenuSelection][ItemSelection] = ProgType[MenuSelection][ItemSelection] | STARTMIN;
  2624.                     if (WinQueryButtonCheckstate( hWnd, STARTWPS ))
  2625.                         ProgType[MenuSelection][ItemSelection] = ProgType[MenuSelection][ItemSelection] | STARTASWPS;
  2626.  
  2627.                     // save name, path, directory, command line args
  2628.                     WinQueryDlgItemText( hWnd, ITEMNAME, MAXITEMNAMELENGTH,
  2629.                                          ItemName[MenuSelection][ItemSelection]);
  2630.                     WinQueryDlgItemText( hWnd, PATHNAME, MAXACTIONSTRINGLENGTH,
  2631.                                          ActionToDo[MenuSelection][ItemSelection]);
  2632.                     WinQueryDlgItemText( hWnd, ARGUMENTS, MAXARGSTRINGLENGTH,
  2633.                                          CmdLnArgs[MenuSelection][ItemSelection]);
  2634.                     WinQueryDlgItemText( hWnd, DIRECTORY, MAXDIRSTRINGLENGTH,
  2635.                                          Directory[MenuSelection][ItemSelection]);
  2636.                     UpdateMenu[MenuSelection] = TRUE;
  2637.                     WinDismissDlg( hWnd, TRUE );
  2638.                     return 0;
  2639.                     }
  2640.             default:
  2641.                 return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2642.             }
  2643.         }
  2644.         //----------------------------------------------------------------------
  2645.         // if nothing further we want to intercept, pass message onto system
  2646.         //----------------------------------------------------------------------
  2647.         default:
  2648.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2649.     }
  2650. }
  2651.  
  2652.  
  2653. ////////////////////////////////////////////////////////////////////////////////
  2654. // AddAnItemProc - the message handler for the "add an item to a menu" dialog
  2655. ////////////////////////////////////////////////////////////////////////////////
  2656. MRESULT EXPENTRY AddAnItemProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  2657. {
  2658.    switch( msg )
  2659.     {
  2660.         //----------------------------------------------------------------------
  2661.         // when the dialog is being initialized, center it on desktop and put
  2662.         // the current data into control fields
  2663.         //----------------------------------------------------------------------
  2664.         case WM_INITDLG: {
  2665.             SWP swp;
  2666.             WinSendDlgItemMsg( hWnd, ITEMNAME, EM_SETTEXTLIMIT,
  2667.                                MPFROM2SHORT( MAXITEMNAMELENGTH-1, 0 ), 0 );
  2668.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  2669.             WinSetWindowPos( hWnd, (HWND)0,
  2670.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  2671.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  2672.                              0, 0, SWP_MOVE);
  2673.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2674.             }
  2675.         //----------------------------------------------------------------------
  2676.         // process a command message received from the system
  2677.         //----------------------------------------------------------------------
  2678.         case WM_COMMAND:
  2679.         {
  2680.             USHORT command = SHORT1FROMMP(mp1);
  2681.             switch( command )
  2682.                 {
  2683.                 //--------------------------------------------------------------
  2684.                 // if they pressed OK, then save the data in the dialog as an
  2685.                 // item that we can now launch from the fileBar.
  2686.                 //--------------------------------------------------------------
  2687.                 case DID_OK: {
  2688.                     WinQueryDlgItemText( hWnd, ITEMNAME, MAXMENUNAMELENGTH, ItemName[MenuSelection][ (NumItems[MenuSelection]) ]);
  2689.                     ActionToDo[MenuSelection][ (NumItems[MenuSelection]) ][0] = '\0';
  2690.                     CmdLnArgs[MenuSelection][ (NumItems[MenuSelection]) ][0] = '\0';
  2691.                     Directory[MenuSelection][ (NumItems[MenuSelection]) ][0] = '\0';
  2692.                     ProgType[MenuSelection][ (NumItems[MenuSelection]) ] = PM;
  2693.                     UpdateMenu[MenuSelection] = TRUE;
  2694.                     WinDismissDlg( hWnd, TRUE );
  2695.                     ItemSelection = NumItems[MenuSelection];
  2696.                     NumItems[MenuSelection]++;
  2697.                     WinDlgBox(HWND_DESKTOP,
  2698.                               hWnd,
  2699.                               (PFNWP)EditItemDataProc,
  2700.                               0,
  2701.                               EDITITEMDATA,
  2702.                               (PVOID)NULL);
  2703.                     return 0;
  2704.                     }
  2705.                 //--------------------------------------------------------------
  2706.                 // if they pressed cancel, save no data and return
  2707.                 //--------------------------------------------------------------
  2708.                 case DID_CANCEL: {
  2709.                     WinDismissDlg( hWnd, TRUE );
  2710.                     return 0;
  2711.                     }
  2712.                 //--------------------------------------------------------------
  2713.                 // nothing further we care about, pass on for default processing
  2714.                 //--------------------------------------------------------------
  2715.                 default:
  2716.                     return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2717.                 }
  2718.         }
  2719.         //----------------------------------------------------------------------
  2720.         // if nothing further we want to intercept, pass message onto system
  2721.         //----------------------------------------------------------------------
  2722.         default:
  2723.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2724.     }
  2725. }
  2726.  
  2727.  
  2728. ////////////////////////////////////////////////////////////////////////////////
  2729. // Message handler for entering a runtime parameter
  2730. ////////////////////////////////////////////////////////////////////////////////
  2731. MRESULT EXPENTRY EnterParamProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  2732. {
  2733.    switch( msg )
  2734.     {
  2735.         //----------------------------------------------------------------------
  2736.         // when the dialog is being initialized, center it on desktop
  2737.         //----------------------------------------------------------------------
  2738.         case WM_INITDLG: {
  2739.             SWP swp;
  2740.  
  2741.             WinSetWindowText( hWnd, parameterTitle );
  2742.             WinSetDlgItemText( hWnd, PARAMETER_TEXT, ParameterTextPtr );
  2743.             WinSendDlgItemMsg( hWnd, PARAMETER_TEXT, EM_SETTEXTLIMIT, MPFROMSHORT( sizeof(variableText) ), 0 );
  2744.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  2745.             WinSetWindowPos( hWnd, (HWND)0,
  2746.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  2747.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  2748.                              0, 0, SWP_MOVE);
  2749.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2750.             }
  2751.         //----------------------------------------------------------------------
  2752.         // if we receive any system message, dismiss the dialog box
  2753.         //----------------------------------------------------------------------
  2754.         case WM_COMMAND:
  2755.         {
  2756.             WinQueryDlgItemText( hWnd, PARAMETER_EDIT, sizeof(variableText), (PSZ)variableText );
  2757.             WinDismissDlg( hWnd, TRUE );
  2758.             return 0;
  2759.         }
  2760.         //----------------------------------------------------------------------
  2761.         // if nothing further we want to intercept, pass message onto system
  2762.         //----------------------------------------------------------------------
  2763.         default:
  2764.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2765.     }
  2766. }
  2767.  
  2768.  
  2769. ////////////////////////////////////////////////////////////////////////////////
  2770. // startApplication uses DosStartSession to start a batch file to start an
  2771. // application pointed to in one of the user menus by menu and item variables.
  2772. ////////////////////////////////////////////////////////////////////////////////
  2773. SHORT startApplication( SHORT menu, SHORT item )
  2774. {
  2775.     CHAR parameters[MAXARGSTRINGLENGTH*2];
  2776.     CHAR itemName[MAXITEMNAMELENGTH];
  2777.     APIRET rc;
  2778.     STARTDATA startData;
  2779.     ULONG sessionId;
  2780.     PID ppId;
  2781.     UCHAR ObjBuf[2];
  2782.     SHORT y1 = 0;
  2783.     SHORT y2 = 0;
  2784.     SHORT i = 0;
  2785.     SHORT h = 0;
  2786.  
  2787.     // remove tilde from title window
  2788.     while (ItemName[menu][item][y1]!='\0') {
  2789.         if (ItemName[menu][item][y1]!='~')
  2790.             itemName[y2++] = ItemName[menu][item][y1];
  2791.         y1++;
  2792.         }
  2793.     itemName[y2] = '\0';
  2794.  
  2795.     // get command line arguments via user input if necessary
  2796.     while ( CmdLnArgs[menu][item][i] != '\0' ) {
  2797.         if (CmdLnArgs[menu][item][i] == STARTINPUT) {
  2798.             short j = 0;
  2799.             CHAR tmp[MAXARGSTRINGLENGTH];
  2800.  
  2801.             i++;
  2802.             while ( (CmdLnArgs[menu][item][i] != '\0') &&
  2803.                     (CmdLnArgs[menu][item][i] != ENDINPUT ))
  2804.                 tmp[j++] = CmdLnArgs[menu][item][i++];
  2805.             tmp[j] = '\0';
  2806.  
  2807.             if (CmdLnArgs[menu][item][i] != '\0')
  2808.                 i++;
  2809.  
  2810.             {
  2811.                 CHAR mesg[18+MAXARGSTRINGLENGTH];
  2812.                 SHORT k = 0;
  2813.  
  2814.                 sprintf( parameterTitle, "%s parameter...", ItemName[menu][item] );
  2815.                 sprintf( mesg, "Please enter '%s'", tmp);
  2816.                 ParameterTextPtr = mesg;
  2817.                 (VOID*)WinDlgBox(HWND_DESKTOP,
  2818.                                  hwndFrame,
  2819.                                  (PFNWP)EnterParamProc,
  2820.                                  0,
  2821.                                  ENTERPARAMETER,
  2822.                                  (PVOID)NULL);
  2823.  
  2824.                 while ( variableText[k] != '\0')
  2825.                     parameters[h++] = variableText[k++];
  2826.             }
  2827.  
  2828.             }
  2829.         else
  2830.             parameters[h++] = CmdLnArgs[menu][item][i++];
  2831.         }
  2832.     parameters[h] = '\0';
  2833.  
  2834.     //--------------------------------------------------------------------------
  2835.     // open a WPS folder/object
  2836.     //--------------------------------------------------------------------------
  2837.     if ((ProgType[menu][item] & WPSFOLDER) || (ProgType[menu][item] & STARTASWPS)) {
  2838.         CHAR string[MAXACTIONSTRINGLENGTH+MAXDIRSTRINGLENGTH+2];
  2839.         ULONG numItems;
  2840.         ULONG Buffer;
  2841.         PSWBLOCK SwitchBlockPtr;
  2842.         HSWITCH hSwitch;
  2843.         HOBJECT object;
  2844.  
  2845.         if (ProgType[menu][item] & WPSFOLDER)
  2846.             sprintf(string, "%s%s\0", Directory[menu][item],ActionToDo[menu][item]);
  2847.         else
  2848.             sprintf(string, "%s\0", ActionToDo[menu][item]);
  2849.  
  2850.         object = WinQueryObject( string );
  2851.         if (object==NULLHANDLE) {
  2852.             WinMessageBox( HWND_DESKTOP, hwndFrame, "Could not locate the specified WPS object!\n\nThe pathname and/or directory you specified may not be correct.", "FileBar Error!", 0,
  2853.                            MB_MOVEABLE|MB_OK|MB_ERROR);
  2854.             return 0;
  2855.             }
  2856.  
  2857.         WinSetObjectData(object, "OPEN=DEFAULT");
  2858.         numItems = WinQuerySwitchList( hab, NULL, 0 );
  2859.         Buffer = (numItems * sizeof(SWENTRY)) + sizeof(HSWITCH);
  2860.         PVOID my = new BYTE[Buffer];
  2861.         WinQuerySwitchList( hab, (SWBLOCK*)my, Buffer );
  2862.         SwitchBlockPtr = (PSWBLOCK)(my);
  2863.  
  2864.         hSwitch = WinQuerySwitchHandle( SwitchBlockPtr->aswentry[numItems-1].swctl.hwnd,
  2865.                                         SwitchBlockPtr->aswentry[numItems-1].swctl.idProcess);
  2866.         delete( my );
  2867.         return WinSwitchToProgram( hSwitch );
  2868.         }
  2869.  
  2870.     //--------------------------------------------------------------------------
  2871.     // launch a windows app
  2872.     //--------------------------------------------------------------------------
  2873.     if (ProgType[menu][item] & WINOS2) {
  2874.         FILE* outputFile;
  2875.         STARTDATA startData;
  2876.  
  2877.         outputFile = fopen(LAUNCHFILE, "wt");
  2878.         if (!outputFile) {
  2879.             char title[] = "Launch an application";
  2880.             char text[] = "Could not start the application due to an error accessing the drive";
  2881.             WinMessageBox( HWND_DESKTOP, hwndFrame, text, title, 0,
  2882.                            MB_MOVEABLE|MB_ERROR|MB_OK);
  2883.             return 0;
  2884.             }
  2885.  
  2886.         if (Directory[menu][item][0] != '\0') {
  2887.             if ((isalpha( Directory[menu][item][0] )) && ( Directory[menu][item][1]==':'))
  2888.                 fprintf( outputFile, "%c:\n", Directory[menu][item][0]);
  2889.             fprintf( outputFile, "cd %s\n", Directory[menu][item]);
  2890.             }
  2891.  
  2892.         fprintf( outputFile, "start /K " );
  2893.         if (ProgType[menu][item] & STARTMAX)
  2894.             fprintf( outputFile, "/MAX ");
  2895.         else if (ProgType[menu][item] & STARTMIN)
  2896.             fprintf( outputFile, "/MIN ");
  2897.         if (ProgType[menu][item] & FULLSCREEN)
  2898.             fprintf( outputFile, "/FS ");
  2899.         else
  2900.             fprintf( outputFile, "/WIN ");
  2901.  
  2902.         fprintf( outputFile, "%s %s", ActionToDo[menu][item], parameters );
  2903.         fclose( outputFile );
  2904.  
  2905.         {
  2906.         CHAR title[] = "FileBar\nWIN-OS/2 Launch";
  2907.         CHAR program[] = OS2SHELL;
  2908.         CHAR inputs[] = LAUNCHINPUTS;
  2909.  
  2910.         memset( &startData, 0, sizeof(STARTDATA) );
  2911.         startData.Related = SSF_RELATED_INDEPENDENT;
  2912.         startData.FgBg = SSF_FGBG_FORE;
  2913.         startData.TraceOpt = SSF_TRACEOPT_NONE;
  2914.         startData.InheritOpt = SSF_INHERTOPT_PARENT;
  2915.         startData.SessionType = SSF_TYPE_WINDOWABLEVIO;
  2916.         startData.PgmControl = SSF_CONTROL_INVISIBLE | SSF_CONTROL_MINIMIZE;
  2917.         startData.PgmTitle = title;
  2918.         startData.PgmName = program;
  2919.         startData.PgmInputs = inputs;
  2920.         startData.ObjectBuffer = ObjBuf;
  2921.         startData.ObjectBuffLen = sizeof(ObjBuf);
  2922.         startData.Length = sizeof(STARTDATA);
  2923.  
  2924.         return DosStartSession( (STARTDATA*) &startData, (ULONG*)&sessionId,
  2925.                                 (PID*) &ppId );
  2926.         }
  2927.     }
  2928.     //--------------------------------------------------------------------------
  2929.     /*
  2930.     //// this doesn't work to start a seamless app and I don't know why!!  :(
  2931.     //--------------------------------------------------------------------------
  2932.  
  2933.     if ((ProgType[menu][item] & WINOS2) && (ProgType[menu][item] & WINDOWED)) {
  2934.         APIRET rc;
  2935.         PROGDETAILS pDetails;
  2936.  
  2937.         memset( &pDetails, 0, sizeof(PROGDETAILS) );
  2938.         pDetails.Length = sizeof(PROGDETAILS);
  2939.         pDetails.progt.progc = PROG_WINDOWABLEVIO;
  2940.         pDetails.progt.fbVisible = SHE_VISIBLE;
  2941.         pDetails.pszTitle = 0;  //ItemName[menu][item];
  2942.         pDetails.pszExecutable = "\\os2\\te2\\te2.exe";  //ActionToDo[menu][item];
  2943.  
  2944.         //pDetails.pszParameters = "";
  2945.         //pDetails.pszIcon = "C:\\OS2\\FILEBAR\\FILEBAR.ICO";
  2946.         //pDetails.pszEnvironment = "WORKPLACE\0\0";
  2947.  
  2948.         //pDetails.pszParameters = CmdLnArgs[menu][item];
  2949.         //pDetails.pszStartupDir = "d:\os2\mdos\winos2";   //Directory[menu][item];
  2950.         pDetails.swpInitial.fl = SWP_ACTIVATE;
  2951.  
  2952.         if (ProgType[menu][item] & STARTMAX)
  2953.             rc = WinStartApp(NULLHANDLE, &pDetails, CmdLnArgs[menu][item], NULL, 4 );
  2954.         else if (ProgType[menu][item] & STARTMIN)
  2955.             rc = WinStartApp(NULLHANDLE, &pDetails, CmdLnArgs[menu][item], NULL, 8 );
  2956.         else rc = WinStartApp(NULLHANDLE, &pDetails, CmdLnArgs[menu][item], NULL, 0 );
  2957.  
  2958.         if (rc==0) {
  2959.            ERRORID errorID = WinGetLastError( hab );
  2960.            char text[1024];
  2961.            sprintf(text, "error code %lu\0", errorID);
  2962.            WinMessageBox( HWND_DESKTOP, hwndFrame, text, NULL, 0,
  2963.                           MB_MOVEABLE|MB_ERROR|MB_OK);
  2964.            }
  2965.  
  2966.         return 0;
  2967.         }
  2968.     */
  2969.     //--------------------------------------------------------------------------
  2970.     // this launches a command shell (DOS or OS2 (Windowed or FS session))
  2971.     //--------------------------------------------------------------------------
  2972.     if (ActionToDo[menu][item][0] == '\0') {
  2973.         ULONG currentDrive;
  2974.         ULONG driveMap;
  2975.         CHAR InputDir[MAXPATH + 9];
  2976.  
  2977.         DosQueryCurrentDisk( ¤tDrive, &driveMap );
  2978.         DosSetDefaultDisk( (ULONG)(toupper(Directory[menu][item][0])-'A' + 1) );
  2979.  
  2980.         memset( &startData, 0, sizeof(STARTDATA) );
  2981.         startData.Related = SSF_RELATED_INDEPENDENT;
  2982.         startData.FgBg = SSF_FGBG_FORE;
  2983.         startData.TraceOpt = SSF_TRACEOPT_NONE;
  2984.         startData.InheritOpt = SSF_INHERTOPT_PARENT;
  2985.         startData.ObjectBuffer = ObjBuf;
  2986.         startData.ObjectBuffLen = sizeof(ObjBuf);
  2987.         startData.Length = sizeof(STARTDATA);
  2988.         startData.PgmTitle = itemName;
  2989.         strcpy( InputDir, "/K cd  \0");
  2990.         strcpy( InputDir+6, Directory[menu][item] );
  2991.         startData.PgmInputs = InputDir;
  2992.  
  2993.         startData.PgmControl = SSF_CONTROL_VISIBLE;
  2994.         if (ProgType[menu][item] & MAXIMIZED)
  2995.             startData.PgmControl = SSF_CONTROL_VISIBLE | SSF_CONTROL_MAXIMIZE;
  2996.         else if (ProgType[menu][item] & MINIMIZED)
  2997.             startData.PgmControl = SSF_CONTROL_VISIBLE | SSF_CONTROL_MINIMIZE;
  2998.  
  2999.         if (ProgType[menu][item] & DOS) {
  3000.             if (ProgType[menu][item] & WINDOWED)
  3001.                 startData.SessionType = SSF_TYPE_WINDOWEDVDM;
  3002.             else
  3003.                 startData.SessionType = SSF_TYPE_VDM;
  3004.             rc = DosStartSession( (STARTDATA*) &startData, (ULONG*)&sessionId,
  3005.                                   (PID*) &ppId );
  3006.             DosSetDefaultDisk( currentDrive );
  3007.             return rc;
  3008.             }
  3009.         else if (ProgType[menu][item] & OS2) {
  3010.             if (ProgType[menu][item] & WINDOWED)
  3011.                 startData.SessionType = SSF_TYPE_WINDOWABLEVIO;
  3012.             else
  3013.                 startData.SessionType = SSF_TYPE_FULLSCREEN;
  3014.             rc = DosStartSession( (STARTDATA*) &startData, (ULONG*)&sessionId,
  3015.                                   (PID*) &ppId );
  3016.             DosSetDefaultDisk( currentDrive );
  3017.             return rc;
  3018.             }
  3019.         WinMessageBox( HWND_DESKTOP, hwndFrame, "Error opening command shell!", NULL, 0,
  3020.                        MB_MOVEABLE|MB_ERROR|MB_OK);
  3021.         return 0;
  3022.         }
  3023.  
  3024.     //--------------------------------------------------------------------------
  3025.     // this section of code launches a program (non-command shell application)
  3026.     //--------------------------------------------------------------------------
  3027.     {
  3028.     CHAR SettingsBuffer[WPSBUFFER];
  3029.     ULONG currentDrive;
  3030.     ULONG driveMap;
  3031.     UCHAR defaultDirectory[MAXPATH];
  3032.     //CHAR program[MAXPATH];
  3033.     CHAR inputs[MAXARGSTRINGLENGTH];
  3034.  
  3035.     memset( &startData, 0, sizeof(STARTDATA) );
  3036.     startData.Length = sizeof(STARTDATA);
  3037.     startData.Related = SSF_RELATED_INDEPENDENT;
  3038.     startData.FgBg = SSF_FGBG_FORE;
  3039.     startData.TraceOpt = SSF_TRACEOPT_NONE;
  3040.     startData.PgmTitle = itemName;
  3041.     startData.InheritOpt = SSF_INHERTOPT_PARENT;
  3042.     startData.SessionType = SSF_TYPE_WINDOWABLEVIO;
  3043.     startData.PgmControl = SSF_CONTROL_VISIBLE;
  3044.     startData.SessionType = SSF_TYPE_PM;
  3045.     startData.PgmName = ActionToDo[menu][item];
  3046.     startData.PgmInputs = parameters;
  3047.  
  3048.     if (ProgType[menu][item] & DOS) {
  3049.         if (ProgType[menu][item] & FULLSCREEN)
  3050.             startData.SessionType = SSF_TYPE_VDM;
  3051.         else if (ProgType[menu][item] & WINDOWED)
  3052.             startData.SessionType = SSF_TYPE_WINDOWEDVDM;
  3053.         }
  3054.     else if (ProgType[menu][item] & OS2) {
  3055.         if (ProgType[menu][item] & FULLSCREEN)
  3056.             startData.SessionType = SSF_TYPE_FULLSCREEN;
  3057.         else if (ProgType[menu][item] & WINDOWED)
  3058.             startData.SessionType = SSF_TYPE_WINDOWABLEVIO;
  3059.         }
  3060.     else if (ProgType[menu][item] & WINOS2)
  3061.         startData.SessionType = PROG_WINDOW_AUTO;
  3062.  
  3063.     if (ProgType[menu][item] & STARTMAX)
  3064.         startData.PgmControl |= SSF_CONTROL_MAXIMIZE;
  3065.     else if (ProgType[menu][item] & STARTMIN)
  3066.         startData.PgmControl |= SSF_CONTROL_MINIMIZE;
  3067.  
  3068.     if ((startData.PgmName != NULL) && (startData.SessionType != SSF_TYPE_PM)) {
  3069.         CHAR temp[MAXPATH+MAXARGSTRINGLENGTH+6];
  3070.         sprintf(temp, "/c %s %s\0", ActionToDo[menu][item], parameters);
  3071.         startData.PgmName = 0;
  3072.         strcpy(inputs, temp);
  3073.         startData.PgmInputs = inputs;
  3074.         }
  3075.  
  3076.     // save current drive and directory
  3077.     DosQueryCurrentDisk( ¤tDrive, &driveMap );
  3078.     {
  3079.         CHAR temp[MAXPATH+5];
  3080.         ULONG tempSize = MAXPATH;
  3081.         defaultDirectory[0]= (currentDrive+'A'-1);
  3082.         defaultDirectory[1]= ':';
  3083.         defaultDirectory[2]= '\\';
  3084.         defaultDirectory[3]= '\0';
  3085.         DosQueryCurrentDir( currentDrive, (CHAR*)&temp, &tempSize );
  3086.         strcat( defaultDirectory, temp );
  3087.     }
  3088.  
  3089.     // point to working directory of program to execute
  3090.     if (((toupper(Directory[menu][item][0]))>='A') && ((toupper(Directory[menu][item][0]))<='Z'))
  3091.         DosSetDefaultDisk( (ULONG)(toupper(Directory[menu][item][0])-'A' + 1) );
  3092.     DosSetCurrentDir( Directory[menu][item] );
  3093.  
  3094.  
  3095.     // try and locate a settings file
  3096.     {
  3097.     FILE *FileHandle;
  3098.  
  3099.     memset( &SettingsBuffer, 0, sizeof(SettingsBuffer) );
  3100.     if ((FileHandle = fopen("SETTINGS.INI","rt")) != NULL) {
  3101.         SHORT offset = 0;
  3102.         CHAR ch;
  3103.  
  3104.         while (fscanf(FileHandle, "%c", &ch) != EOF) {
  3105.             if ( ch == '\n' )
  3106.                 SettingsBuffer[ offset++ ] = '\0';
  3107.             else
  3108.                 SettingsBuffer[ offset++ ] = ch;
  3109.             }
  3110.         SettingsBuffer[ offset++ ] = '\0';
  3111.         SettingsBuffer[ offset++ ] = '\x1A';
  3112.         fclose(FileHandle);
  3113.         startData.Environment = SettingsBuffer;
  3114.         }
  3115.  
  3116.     }
  3117.  
  3118.     // launch application
  3119.     rc = DosStartSession( (STARTDATA*) &startData, (ULONG*)&sessionId,
  3120.                           (PID*) &ppId );
  3121.  
  3122.     // restore current drive and directory
  3123.     DosSetDefaultDisk( currentDrive );
  3124.     DosSetCurrentDir( defaultDirectory );
  3125.  
  3126.     if ((rc != 0) && (rc != ERROR_SMG_START_IN_BACKGROUND) && (!startUp)) {
  3127.         char text[] = "Could not open the specified item.  Path and directory information may not be correct.";
  3128.         char title[28];
  3129.  
  3130.         sprintf(title, "FileBar Error code #%d", rc );
  3131.         WinMessageBox( HWND_DESKTOP, hwndFrame, text, title, 0,
  3132.                        MB_MOVEABLE|MB_ERROR|MB_OK);
  3133.         }
  3134.  
  3135.     return rc;
  3136.     }
  3137. }
  3138.  
  3139.  
  3140. ////////////////////////////////////////////////////////////////////////////////
  3141. // display a background bitmap
  3142. ////////////////////////////////////////////////////////////////////////////////
  3143. VOID displayBackground( VOID )
  3144. {
  3145.     DESKTOP desktop;
  3146.  
  3147.     if ((showBackground) || (isBackgroundDisplayed)) {
  3148.         desktop.cbSize = sizeof( DESKTOP );
  3149.         desktop.hbm = 0;
  3150.         desktop.x = 0;
  3151.         desktop.y = 0;
  3152.         desktop.fl = SDT_DESTROY;
  3153.         if (isBackgroundDisplayed)
  3154.             WinSetDesktopBkgnd( HWND_DESKTOP, &desktop );
  3155.  
  3156.         desktop.fl = SDT_LOADFILE|SDT_CENTER;
  3157.         if (backgroundAttr & SCALED)
  3158.             desktop.fl = SDT_SCALE|SDT_LOADFILE;
  3159.         if (backgroundAttr & TILED) {
  3160.             desktop.fl = SDT_TILE|SDT_LOADFILE;
  3161.             desktop.lTileCount = backgroundAttr - TILED;
  3162.             }
  3163.         strcpy( desktop.szFile, backgroundBitmap );
  3164.         if (showBackground) {
  3165.             WinSetDesktopBkgnd( HWND_DESKTOP, &desktop );
  3166.             isBackgroundDisplayed = TRUE;
  3167.             }
  3168.         }
  3169. }
  3170.  
  3171.  
  3172. ////////////////////////////////////////////////////////////////////////////////
  3173. // Message handler for a generic information-only dialog box (help & prod info)
  3174. ////////////////////////////////////////////////////////////////////////////////
  3175. MRESULT EXPENTRY backgroundProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  3176. {
  3177.    switch( msg )
  3178.     {
  3179.         //----------------------------------------------------------------------
  3180.         // when the dialog is being initialized, center it on desktop
  3181.         //----------------------------------------------------------------------
  3182.         case WM_INITDLG: {
  3183.             SWP swp;
  3184.             char temp[12];
  3185.  
  3186.             WinCheckButton( hWnd, BKGND_NORMAL, TRUE );
  3187.             if (backgroundAttr & SCALED)
  3188.                 WinCheckButton( hWnd, BKGND_SCALED, TRUE );
  3189.             else if (backgroundAttr & TILED) {
  3190.                 WinCheckButton( hWnd, BKGND_TILED, TRUE );
  3191.                 WinEnableControl( hWnd, BKGND_TILENUMBER, TRUE );
  3192.                 WinEnableControl( hWnd, BKGND_TILENUMBERTEXT, TRUE );
  3193.                 WinEnableControl( hWnd, BKGND_LESS, TRUE );
  3194.                 WinEnableControl( hWnd, BKGND_MORE, TRUE );
  3195.                 }
  3196.  
  3197.             if (backgroundAttr & SCALED)
  3198.                 backgroundAttr = backgroundAttr - SCALED;
  3199.             if (backgroundAttr & TILED)
  3200.                 backgroundAttr = backgroundAttr - TILED;
  3201.  
  3202.             sprintf(temp,"%d x %d", backgroundAttr, backgroundAttr);
  3203.             WinSetDlgItemText( hWnd, BKGND_TILENUMBER, temp );
  3204.  
  3205.             WinSendDlgItemMsg( hWnd, BKGND_BITMAPNAME, EM_SETTEXTLIMIT, MPFROMSHORT( sizeof(backgroundBitmap) ), 0 );
  3206.             WinSetDlgItemText( hWnd, BKGND_BITMAPNAME, backgroundBitmap );
  3207.  
  3208.             WinCheckButton( hWnd, BKGND_SHOW, showBackground );
  3209.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  3210.             WinSetWindowPos( hWnd, (HWND)0,
  3211.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  3212.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  3213.                              0, 0, SWP_MOVE);
  3214.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  3215.             }
  3216.         //----------------------------------------------------------------------
  3217.         //----------------------------------------------------------------------
  3218.         case WM_CONTROL:
  3219.         {
  3220.             if (SHORT2FROMMP(mp1)==BN_CLICKED) {
  3221.                 BOOLEAN option = FALSE;
  3222.                 if (WinQueryButtonCheckstate( hWnd, BKGND_TILED))
  3223.                     option = TRUE;
  3224.                 WinEnableControl( hWnd, BKGND_TILENUMBER, option );
  3225.                 WinEnableControl( hWnd, BKGND_TILENUMBERTEXT, option );
  3226.                 WinEnableControl( hWnd, BKGND_LESS, option );
  3227.                 WinEnableControl( hWnd, BKGND_MORE, option );
  3228.                 }
  3229.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  3230.         }
  3231.         //----------------------------------------------------------------------
  3232.         //----------------------------------------------------------------------
  3233.         case WM_COMMAND:
  3234.         {
  3235.             USHORT command = SHORT1FROMMP(mp1);
  3236.             switch( command )
  3237.                 {
  3238.                 //--------------------------------------------------------------
  3239.                 // if they pressed OK, then save the data in the dialog as an
  3240.                 // item that we can now launch from the fileBar.
  3241.                 //--------------------------------------------------------------
  3242.                 case DID_OK: {
  3243.                     WinQueryDlgItemText( hWnd, BKGND_BITMAPNAME, sizeof(backgroundBitmap), (PSZ)backgroundBitmap );
  3244.                     showBackground = WinQueryButtonCheckstate( hWnd, BKGND_SHOW );
  3245.                     if (WinQueryButtonCheckstate( hWnd, BKGND_SCALED))
  3246.                         backgroundAttr = backgroundAttr + SCALED;
  3247.                     if (WinQueryButtonCheckstate( hWnd, BKGND_TILED))
  3248.                         backgroundAttr = backgroundAttr + TILED;
  3249.                     WinDismissDlg( hWnd, TRUE );
  3250.                     return 0;
  3251.                     }
  3252.                 //--------------------------------------------------------------
  3253.                 //--------------------------------------------------------------
  3254.                 case BKGND_LESS: {
  3255.                     char temp[12];
  3256.  
  3257.                     if (backgroundAttr > 1)
  3258.                         backgroundAttr--;
  3259.                     sprintf(temp,"%d x %d", backgroundAttr, backgroundAttr);
  3260.                     WinSetDlgItemText( hWnd, BKGND_TILENUMBER, temp );
  3261.                     return 0;
  3262.                     }
  3263.                 //--------------------------------------------------------------
  3264.                 //--------------------------------------------------------------
  3265.                 case BKGND_MORE: {
  3266.                     char temp[12];
  3267.  
  3268.                     if (backgroundAttr < 32)
  3269.                         backgroundAttr++;
  3270.                     sprintf(temp,"%d x %d", backgroundAttr, backgroundAttr);
  3271.                     WinSetDlgItemText( hWnd, BKGND_TILENUMBER, temp );
  3272.                     return 0;
  3273.                     }
  3274.                 //--------------------------------------------------------------
  3275.                 //--------------------------------------------------------------
  3276.                 case BKGND_FINDFILE: {
  3277.                     CHAR title[] = "FileBar - Find A Background Image";
  3278.                     ULONG s;
  3279.                     HWND hwndDialog;
  3280.                     CHAR oldDir[MAXPATH];
  3281.  
  3282.                     fileDlgInfo.fl = FDS_OPEN_DIALOG|FDS_CENTER;
  3283.                     fileDlgInfo.pszTitle = title;
  3284.                     strcpy( oldDir, fileDlgInfo.szFullFile );
  3285.                     strcat(fileDlgInfo.szFullFile, "*.BMP\0");
  3286.  
  3287.                     hwndDialog = WinFileDlg( HWND_DESKTOP, hWnd, &fileDlgInfo );
  3288.                     if (hwndDialog && (fileDlgInfo.lReturn == DID_OK)) {
  3289.                         strcpy( backgroundBitmap, fileDlgInfo.szFullFile );
  3290.  
  3291.                         s=0;
  3292.                         while(fileDlgInfo.szFullFile[s]!='\0')
  3293.                             s++;
  3294.                         while((fileDlgInfo.szFullFile[s]!='\\') && (s>=0))
  3295.                             s--;
  3296.  
  3297.                         if (fileDlgInfo.szFullFile[s]=='\\')
  3298.                             fileDlgInfo.szFullFile[s+1]='\0';
  3299.                         else
  3300.                             fileDlgInfo.szFullFile[0]='\0';
  3301.  
  3302.                         WinSetDlgItemText( hWnd, BKGND_BITMAPNAME, backgroundBitmap );
  3303.                         }
  3304.                     else
  3305.                         strcpy( fileDlgInfo.szFullFile, oldDir );
  3306.                     return 0;
  3307.                     }
  3308.             }
  3309.         }
  3310.         //----------------------------------------------------------------------
  3311.         // if nothing further we want to intercept, pass message onto system
  3312.         //----------------------------------------------------------------------
  3313.         default:
  3314.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  3315.     }
  3316. }
  3317.  
  3318.  
  3319. ////////////////////////////////////////////////////////////////////////////////
  3320. // Message handler for a generic information-only dialog box (help & prod info)
  3321. ////////////////////////////////////////////////////////////////////////////////
  3322. MRESULT EXPENTRY startupProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  3323. {
  3324.    switch( msg )
  3325.     {
  3326.         //----------------------------------------------------------------------
  3327.         // when the dialog is being initialized, center it on desktop
  3328.         //----------------------------------------------------------------------
  3329.         case WM_INITDLG: {
  3330.             SWP swp;
  3331.             short i,j;
  3332.             char temp[MAXITEMNAMELENGTH+8];
  3333.  
  3334.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  3335.             WinSetWindowPos( hWnd, (HWND)0,
  3336.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  3337.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  3338.                              0, 0, SWP_MOVE);
  3339.             WinSendDlgItemMsg( hWnd, STARTUP_ITEMLIST, LM_DELETEALL, 0, 0);
  3340.             temp[0] = ' ';
  3341.             temp[1] = ' ';
  3342.             temp[2] = '-';
  3343.             temp[3] = ' ';
  3344.             for (i=0; i<NumMenus; i++) {
  3345.                 WinSendDlgItemMsg( hWnd, STARTUP_ITEMLIST, LM_INSERTITEM, MPFROMSHORT( LIT_END ), MenuName[i] );
  3346.                 for (j=0; j<NumItems[i]; j++)
  3347.                     if (ItemName[i][j][0] != '\0') {
  3348.                         temp[4] = '\0';
  3349.                         strcat(temp, ItemName[i][j]);
  3350.                         WinSendDlgItemMsg( hWnd, STARTUP_ITEMLIST, LM_INSERTITEM, MPFROMSHORT( LIT_END ), temp );
  3351.                         }
  3352.                 }
  3353.  
  3354.             WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_DELETEALL, 0, 0);
  3355.             for( i = 0; i< numStartItems; i++)
  3356.                 WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_INSERTITEM, MPFROMSHORT( LIT_END ), ItemName[(StartUpMenu[i])][(StartUpItem[i])] );
  3357.  
  3358.             WinCheckButton( hWnd, STARTUP_LAUNCH, DoStartUpList );
  3359.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  3360.             }
  3361.         //----------------------------------------------------------------------
  3362.         //----------------------------------------------------------------------
  3363.         case WM_CONTROL:
  3364.         {
  3365.             if (SHORT2FROMMP(mp1)==BN_CLICKED) {
  3366.                 BOOLEAN option = FALSE;
  3367.                 if (WinQueryButtonCheckstate( hWnd, BKGND_TILED))
  3368.                     option = TRUE;
  3369.                 WinEnableControl( hWnd, BKGND_TILENUMBER, option );
  3370.                 WinEnableControl( hWnd, BKGND_TILENUMBERTEXT, option );
  3371.                 WinEnableControl( hWnd, BKGND_LESS, option );
  3372.                 WinEnableControl( hWnd, BKGND_MORE, option );
  3373.                 }
  3374.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  3375.         }
  3376.         //----------------------------------------------------------------------
  3377.         //----------------------------------------------------------------------
  3378.         case WM_COMMAND:
  3379.         {
  3380.             USHORT command = SHORT1FROMMP(mp1);
  3381.             switch( command )
  3382.                 {
  3383.                 //--------------------------------------------------------------
  3384.                 //--------------------------------------------------------------
  3385.                 case STARTUP_ADD: {
  3386.  
  3387.                     if (numStartItems == MAXSTARTITEMS)
  3388.                         WinMessageBox( HWND_DESKTOP, hwndFrame, "No room to add an additional task!", "Add a start up item", 0,
  3389.                                        MB_MOVEABLE|MB_ERROR|MB_OK);
  3390.                     else {
  3391.                         SHORT itemSelected = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, STARTUP_ITEMLIST,
  3392.                                                                               LM_QUERYSELECTION,
  3393.                                                                               MPFROM2SHORT( LIT_FIRST, 0 ),
  3394.                                                                               0 ) );
  3395.                         if (itemSelected == LIT_NONE) {
  3396.                             WinMessageBox( HWND_DESKTOP, hwndFrame, "You must first select an item to add!", "Add a start up item", 0,
  3397.                                            MB_MOVEABLE|MB_ERROR|MB_OK);
  3398.                             return 0;
  3399.                             }
  3400.  
  3401.                         {
  3402.                         char buffer[MAXITEMNAMELENGTH + 8];
  3403.                         SHORT i,j;
  3404.                         BOOL found = FALSE;
  3405.  
  3406.                         for( i=0; i<NumMenus; i++)
  3407.                             for( j=0; j<NumItems[i]; j++) {
  3408.                                 SHORT1FROMMP( WinSendDlgItemMsg( hWnd, STARTUP_ITEMLIST,
  3409.                                                          LM_QUERYITEMTEXT,
  3410.                                                          MPFROM2SHORT( itemSelected, sizeof(buffer) ),
  3411.                                                          &buffer ) );
  3412.                                 if (strcmp(&(buffer[4]),ItemName[i][j])==0) {
  3413.                                     StartUpMenu[ numStartItems ] = i;
  3414.                                     StartUpItem[ numStartItems ] = j;
  3415.                                     numStartItems++;
  3416.                                     WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_INSERTITEM, MPFROMSHORT( LIT_END ), ItemName[i][j] );
  3417.                                     found = TRUE;
  3418.                                     }
  3419.                                 }
  3420.                             if (!found)
  3421.                                 WinMessageBox( HWND_DESKTOP, hwndFrame, "You need to select an item -- not a menu!", "Add a start up item", 0,
  3422.                                                MB_MOVEABLE|MB_ERROR|MB_OK);
  3423.                         }
  3424.  
  3425.  
  3426.                         }
  3427.  
  3428.                     return 0;
  3429.                     }
  3430.                 //--------------------------------------------------------------
  3431.                 //--------------------------------------------------------------
  3432.                 case STARTUP_REMOVE: {
  3433.                     SHORT itemSelected = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS,
  3434.                                                                      LM_QUERYSELECTION,
  3435.                                                                      MPFROM2SHORT( LIT_FIRST, 0 ),
  3436.                                                                      0 ) );
  3437.                     SHORT i;
  3438.  
  3439.                     if (itemSelected != LIT_NONE) {
  3440.                         for (i=itemSelected+1; i<numStartItems; i++) {
  3441.                             StartUpMenu[i-1] = StartUpMenu[i];
  3442.                             StartUpItem[i-1] = StartUpItem[i];
  3443.                             }
  3444.                         numStartItems--;
  3445.                         WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_DELETEALL, 0, 0);
  3446.                         for( i = 0; i< numStartItems; i++)
  3447.                             WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_INSERTITEM, MPFROMSHORT( LIT_END ), ItemName[(StartUpMenu[i])][(StartUpItem[i])] );
  3448.  
  3449.                         if (itemSelected == numStartItems)
  3450.                             WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_SELECTITEM,
  3451.                                                MPFROM2SHORT( numStartItems-1, 0 ),
  3452.                                                MPFROM2SHORT( TRUE, 0 ) );
  3453.                         else
  3454.                             WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_SELECTITEM,
  3455.                                                MPFROM2SHORT( itemSelected, 0 ),
  3456.                                                MPFROM2SHORT( TRUE, 0 ) );
  3457.                         }
  3458.  
  3459.                     return 0;
  3460.                     }
  3461.                 //--------------------------------------------------------------
  3462.                 //--------------------------------------------------------------
  3463.                 case STARTUP_CLEARALL: {
  3464.                     WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_DELETEALL, 0, 0);
  3465.                     numStartItems = 0;
  3466.                     return 0;
  3467.                     }
  3468.                 //--------------------------------------------------------------
  3469.                 //--------------------------------------------------------------
  3470.                 case STARTUP_MOVEDOWN: {
  3471.                     SHORT itemSelected = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS,
  3472.                                                                      LM_QUERYSELECTION,
  3473.                                                                      MPFROM2SHORT( LIT_FIRST, 0 ),
  3474.                                                                      0 ) );
  3475.                     if ((itemSelected < (numStartItems-1)) && (itemSelected != LIT_NONE)) {
  3476.                         SHORT z;
  3477.                         SHORT i;
  3478.  
  3479.                         z = StartUpMenu[itemSelected+1];
  3480.                         StartUpMenu[itemSelected+1] = StartUpMenu[itemSelected];
  3481.                         StartUpMenu[itemSelected] = z;
  3482.  
  3483.                         z = StartUpItem[itemSelected+1];
  3484.                         StartUpItem[itemSelected+1] = StartUpItem[itemSelected];
  3485.                         StartUpItem[itemSelected] = z;
  3486.  
  3487.                         WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_DELETEALL, 0, 0);
  3488.                         for( i = 0; i< numStartItems; i++)
  3489.                             WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_INSERTITEM, MPFROMSHORT( LIT_END ), ItemName[(StartUpMenu[i])][(StartUpItem[i])] );
  3490.  
  3491.                         WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_SELECTITEM,
  3492.                                            MPFROM2SHORT( itemSelected+1, 0 ),
  3493.                                            MPFROM2SHORT( TRUE, 0 ) );
  3494.                         }
  3495.                     return 0;
  3496.                     }
  3497.                 //--------------------------------------------------------------
  3498.                 //--------------------------------------------------------------
  3499.                 case STARTUP_MOVEUP: {
  3500.                     SHORT itemSelected = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS,
  3501.                                                                      LM_QUERYSELECTION,
  3502.                                                                      MPFROM2SHORT( LIT_FIRST, 0 ),
  3503.                                                                      0 ) );
  3504.                     if ((itemSelected > 0) && (itemSelected != LIT_NONE)) {
  3505.                         SHORT z;
  3506.                         SHORT i;
  3507.  
  3508.                         z = StartUpMenu[itemSelected-1];
  3509.                         StartUpMenu[itemSelected-1] = StartUpMenu[itemSelected];
  3510.                         StartUpMenu[itemSelected] = z;
  3511.  
  3512.                         z = StartUpItem[itemSelected-1];
  3513.                         StartUpItem[itemSelected-1] = StartUpItem[itemSelected];
  3514.                         StartUpItem[itemSelected] = z;
  3515.  
  3516.                         WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_DELETEALL, 0, 0);
  3517.                         for( i = 0; i< numStartItems; i++)
  3518.                             WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_INSERTITEM, MPFROMSHORT( LIT_END ), ItemName[(StartUpMenu[i])][(StartUpItem[i])] );
  3519.  
  3520.                         WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_SELECTITEM,
  3521.                                            MPFROM2SHORT( itemSelected-1, 0 ),
  3522.                                            MPFROM2SHORT( TRUE, 0 ) );
  3523.                         }
  3524.                     return 0;
  3525.                     }
  3526.                 //--------------------------------------------------------------
  3527.                 // if they pressed OK, then save the data in the dialog as an
  3528.                 // item that we can now launch from the fileBar.
  3529.                 //--------------------------------------------------------------
  3530.                 case DID_OK: {
  3531.                     DoStartUpList = WinQueryButtonCheckstate( hWnd, STARTUP_LAUNCH);
  3532.                     WinDismissDlg( hWnd, TRUE );
  3533.                     return 0;
  3534.                     }
  3535.             }
  3536.         }
  3537.         //----------------------------------------------------------------------
  3538.         // if nothing further we want to intercept, pass message onto system
  3539.         //----------------------------------------------------------------------
  3540.         default:
  3541.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  3542.     }
  3543. }
  3544.  
  3545.  
  3546. ////////////////////////////////////////////////////////////////////////////////
  3547. // execute start up list of applications
  3548. ////////////////////////////////////////////////////////////////////////////////
  3549. VOID ExecuteStartUpList( VOID )
  3550. {
  3551.      SHORT i;
  3552.  
  3553.      if (DoStartUpList)
  3554.          for (i=0; i<numStartItems; i++)
  3555.              startApplication( StartUpMenu[i], StartUpItem[i] );
  3556.  
  3557.      startUp = FALSE;
  3558. }
  3559.  
  3560.  
  3561. ////////////////////////////////////////////////////////////////////////////////
  3562. // update the buttons of the calendar to reflect current month structure
  3563. ////////////////////////////////////////////////////////////////////////////////
  3564. VOID updateCalendar( HWND hWnd )
  3565. {
  3566.     CHAR temp[50];
  3567.     struct tm *time_now;
  3568.     time_t currentTime;
  3569.     short i;
  3570.     short numDaysInMonth;
  3571.  
  3572.     time(¤tTime);
  3573.     time_now = localtime( ¤tTime );
  3574.  
  3575.     numDaysInMonth = numberOfDaysInMonth(month, year);
  3576.     time_now->tm_mon = month;
  3577.     time_now->tm_year= year;
  3578.  
  3579.     strftime( temp, sizeof(temp), " %B - %Y ", time_now);
  3580.     WinSetDlgItemText( hWnd, 550, temp );
  3581.  
  3582.     for( i=0; i<startDay; i++) {
  3583.         WinSetDlgItemText( hWnd, i+500, "" );
  3584.         WinEnableControl( hWnd, i+500, FALSE );
  3585.         }
  3586.     for( i=1; i<=numDaysInMonth; i++) {
  3587.         sprintf(temp, "%d", i);
  3588.         WinEnableControl( hWnd, i+startDay+500-1, TRUE );
  3589.         WinSetDlgItemText( hWnd, i+startDay+500-1, temp );
  3590.         }
  3591.     for( i=numDaysInMonth+startDay+500; i<543; i++) {
  3592.         WinSetDlgItemText( hWnd, i, "" );
  3593.         WinEnableControl( hWnd, i, FALSE );
  3594.         }
  3595. }
  3596.  
  3597.  
  3598. ////////////////////////////////////////////////////////////////////////////////
  3599. // return # of days in # (even checking for leap year)
  3600. ////////////////////////////////////////////////////////////////////////////////
  3601. BYTE numberOfDaysInMonth(int month, int year)
  3602. {
  3603.     if (((1900+year) % 4) || (month != 1))
  3604.         return daysInMonth[month];
  3605.     else
  3606.         return daysInMonth[month]+1;    //handle leap year
  3607. }
  3608.  
  3609.  
  3610. ////////////////////////////////////////////////////////////////////////////////
  3611. // display scheduling calendar and let user schedule and revise tasks
  3612. ////////////////////////////////////////////////////////////////////////////////
  3613. MRESULT EXPENTRY schedulerProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  3614. {
  3615.    switch( msg )
  3616.     {
  3617.         //----------------------------------------------------------------------
  3618.         // when the dialog is being initialized, center it on desktop
  3619.         //----------------------------------------------------------------------
  3620.         case WM_INITDLG: {
  3621.             struct tm *time_now;
  3622.             CHAR mesg[24];
  3623.             time_t currentTime;
  3624.             SWP swp;
  3625.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  3626.             WinSetWindowPos( hWnd, (HWND)0,
  3627.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  3628.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  3629.                              0, 0, SWP_MOVE);
  3630.  
  3631.             time(¤tTime);
  3632.             time_now = localtime( ¤tTime );
  3633.             month = time_now->tm_mon;
  3634.             year = time_now->tm_year;
  3635.  
  3636.             startDay = (time_now->tm_wday - (time_now->tm_mday % 7 - 1));
  3637.             if (startDay > 6)
  3638.                 startDay = startDay - 7;
  3639.             else if (startDay < 0)
  3640.                 startDay = startDay + 7;
  3641.             updateCalendar( hWnd );
  3642.  
  3643.             sprintf( mesg, "Every %d Seconds", repeatTime );
  3644.             WinSetDlgItemText( hWnd, REMINDERTIME, mesg );
  3645.  
  3646.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  3647.             }
  3648.         //----------------------------------------------------------------------
  3649.         // process a command message from the dialog box
  3650.         //----------------------------------------------------------------------
  3651.         case WM_COMMAND:
  3652.         {
  3653.             USHORT command = SHORT1FROMMP(mp1);
  3654.  
  3655.             //------------------------------------------------------------------
  3656.             // if the user pressed a day button, show daily schedule window
  3657.             //------------------------------------------------------------------
  3658.             if ((command>=500) && (command<=542)) {
  3659.                 day = command - 500 - startDay;
  3660.                 WinDlgBox(HWND_DESKTOP,
  3661.                           hWnd,
  3662.                           (PFNWP)scheduleProc,
  3663.                           0,
  3664.                           SCHEDULEITEM,
  3665.                           (PVOID)NULL);
  3666.                 return 0;
  3667.                 }
  3668.             //------------------------------------------------------------------
  3669.             // handle user commands
  3670.             //------------------------------------------------------------------
  3671.             switch( command ) {
  3672.                 //------------------------------------------------------------------
  3673.                 // show all currently scheduled tasks
  3674.                 //------------------------------------------------------------------
  3675.                 case SHOWALL: {
  3676.                     WinDlgBox(HWND_DESKTOP,
  3677.                               hWnd,
  3678.                               (PFNWP)showAllItemsProc,
  3679.                               0,
  3680.                               SHOWALLITEMS,
  3681.                               (PVOID)NULL);
  3682.                     return 0;
  3683.                     }
  3684.                 //--------------------------------------------------------------
  3685.                 // reduce amount of time between reminder sounds
  3686.                 //--------------------------------------------------------------
  3687.                 case LESSTIME: {
  3688.                     char mesg[24];
  3689.                     if (repeatTime>0)
  3690.                         repeatTime--;
  3691.                     sprintf( mesg, "Every %d Seconds", repeatTime );
  3692.                     WinSetDlgItemText( hWnd, REMINDERTIME, mesg );
  3693.                     return 0;
  3694.                     }
  3695.                 //--------------------------------------------------------------
  3696.                 // increase amount of time between reminder sounds
  3697.                 //--------------------------------------------------------------
  3698.                 case MORETIME: {
  3699.                     char mesg[24];
  3700.                     if (repeatTime<32767)
  3701.                         repeatTime++;
  3702.                     sprintf( mesg, "Every %d Seconds", repeatTime );
  3703.                     WinSetDlgItemText( hWnd, REMINDERTIME, mesg );
  3704.                     return 0;
  3705.                     }
  3706.                 //--------------------------------------------------------------
  3707.                 // go back 1 month
  3708.                 //--------------------------------------------------------------
  3709.                 case 551: {
  3710.                     month--;
  3711.                     if (month < 0) {
  3712.                         month = 11;
  3713.                         year--;
  3714.                         }
  3715.  
  3716.                     startDay = startDay - numberOfDaysInMonth(month, year) % 7;
  3717.  
  3718.                     if (startDay > 6)
  3719.                         startDay = startDay - 7;
  3720.                     if (startDay < 0)
  3721.                         startDay = startDay + 7;
  3722.  
  3723.                     updateCalendar( hWnd );
  3724.                     return 0;
  3725.                     }
  3726.                 //--------------------------------------------------------------
  3727.                 // advance 1 month
  3728.                 //--------------------------------------------------------------
  3729.                 case 553: {
  3730.                     SHORT oldMonth = month;
  3731.                     SHORT oldYear = year;
  3732.  
  3733.                     month++;
  3734.                     if (month > 11) {
  3735.                         month = 0;
  3736.                         year++;
  3737.                         }
  3738.  
  3739.                     startDay = (startDay + numberOfDaysInMonth(oldMonth, oldYear)) % 7;
  3740.                     if (startDay > 6)
  3741.                         startDay = startDay - 7;
  3742.                     if (startDay < 0)
  3743.                         startDay = startDay + 7;
  3744.  
  3745.                     updateCalendar( hWnd );
  3746.                     return 0;
  3747.                     }
  3748.                 //--------------------------------------------------------------
  3749.                 // go back to current month
  3750.                 //--------------------------------------------------------------
  3751.                 case 552: {
  3752.                     time_t currentTime;
  3753.                     struct tm *time_now;
  3754.  
  3755.                     time(¤tTime);
  3756.                     time_now = localtime( ¤tTime );
  3757.                     month = time_now->tm_mon;
  3758.                     year = time_now->tm_year;
  3759.  
  3760.                     startDay = time_now->tm_wday - (time_now->tm_mday % 7 - 1);
  3761.                     if (startDay > 6)
  3762.                         startDay = startDay - 7;
  3763.                     if (startDay < 0)
  3764.                         startDay = startDay + 7;
  3765.  
  3766.                     updateCalendar( hWnd );
  3767.                     return 0;
  3768.                     }
  3769.                 //--------------------------------------------------------------
  3770.                 // user pressed OK, cancel dialog
  3771.                 //--------------------------------------------------------------
  3772.                 case DID_OK: {
  3773.                     WinDismissDlg( hWnd, TRUE );
  3774.                     return 0;
  3775.                 }
  3776.             }
  3777.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  3778.         }
  3779.         //----------------------------------------------------------------------
  3780.         // if nothing further we want to intercept, pass message onto system
  3781.         //----------------------------------------------------------------------
  3782.         default:
  3783.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  3784.     }
  3785. }
  3786.  
  3787.  
  3788. ////////////////////////////////////////////////////////////////////////////////
  3789. ////////////////////////////////////////////////////////////////////////////////
  3790. MRESULT EXPENTRY showAllItemsProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  3791. {
  3792.    switch( msg )
  3793.     {
  3794.         //----------------------------------------------------------------------
  3795.         // when the dialog is being initialized, center it on desktop
  3796.         //----------------------------------------------------------------------
  3797.         case WM_INITDLG: {
  3798.             CHAR temp[64+MAXACTIONSTRINGLENGTH];
  3799.             CHAR s[MAXACTIONSTRINGLENGTH+11];
  3800.             SWP swp;
  3801.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  3802.             WinSetWindowPos( hWnd, (HWND)0,
  3803.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  3804.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  3805.                              0, 0, SWP_MOVE);
  3806.  
  3807.             sprintf(temp, "%d tasks currently scheduled (out of %d possible)", numAlarms, MAXALARMS );
  3808.             WinSetWindowText( hWnd, temp );
  3809.  
  3810.             WinSendDlgItemMsg( hWnd, SHOWITEMS, LM_DELETEALL, MPFROMSHORT( LIT_END ), temp );
  3811.             for( short i = 0; i< numAlarms; i++) {
  3812.                 CHAR c = 'a';
  3813.                 BYTE hour = alarm[i].AlarmHour;
  3814.  
  3815.                 if (alarm[i].options & SCHEDULE_LAUNCHAPP) {
  3816.                     short j = 10;
  3817.                     short k = 0;
  3818.                     strcpy(s, "Launch >> ");
  3819.                     while ((ItemName[((int)alarm[i].ActionToDo[0])][((int)alarm[i].ActionToDo[1])][k])!='\0')
  3820.                         if ((ItemName[((int)alarm[i].ActionToDo[0])][((int)alarm[i].ActionToDo[1])][k])=='~')
  3821.                             k++;
  3822.                         else
  3823.                             s[j++] = ItemName[((int)alarm[i].ActionToDo[0])][((int)alarm[i].ActionToDo[1])][k++];
  3824.                         s[j] = '\0';
  3825.                     }
  3826.                 else
  3827.                     strcpy(s, alarm[i].ActionToDo);
  3828.  
  3829.                 if (alarm[i].AlarmHour>11)
  3830.                     c='p';
  3831.                 if (!(hour = hour % 12))
  3832.                     hour = 12;
  3833.  
  3834.                 sprintf( temp, "%2d:%2d%cm (%2d:%2d) -- %d/%d/%d (%d/%d/%d) -- %s", hour,
  3835.                                                                     alarm[i].AlarmMinute,
  3836.                                                                     c,
  3837.                                                                     alarm[i].AlarmHour,
  3838.                                                                     alarm[i].AlarmMinute,
  3839.                                                                     alarm[i].AlarmMonth+1,
  3840.                                                                     alarm[i].AlarmDay+1,
  3841.                                                                     alarm[i].AlarmYear,
  3842.                                                                     alarm[i].AlarmDay+1,
  3843.                                                                     alarm[i].AlarmMonth+1,
  3844.                                                                     alarm[i].AlarmYear,
  3845.                                                                     s );
  3846.                 if (temp[3]==' ') {
  3847.                     temp[3] = '0';
  3848.                     temp[12]= '0';
  3849.                     }
  3850.  
  3851.                 WinSendDlgItemMsg( hWnd, SHOWITEMS, LM_INSERTITEM, MPFROMSHORT( LIT_END ), temp );
  3852.                 }
  3853.  
  3854.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  3855.             }
  3856.         //----------------------------------------------------------------------
  3857.         //----------------------------------------------------------------------
  3858.         case WM_CONTROL:
  3859.         {
  3860.             if (SHORT2FROMMP(mp1)==LN_ENTER) {
  3861.                 SHORT itemSelected = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, SHOWITEMS,
  3862.                                                                       LM_QUERYSELECTION,
  3863.                                                                       MPFROM2SHORT( LIT_FIRST, 0 ),
  3864.                                                                       0 ) );
  3865.  
  3866.                 oldProgType = numAlarms;
  3867.                 numAlarms = 0;
  3868.  
  3869.                 reviseScheduledItem( itemSelected );
  3870.                 sortTimeEntries( oldProgType );
  3871.                 numAlarms = oldProgType;
  3872.                 WinSendMsg( hWnd, WM_INITDLG, 0, 0 );
  3873.                 WinSendDlgItemMsg( hWnd, SHOWITEMS, LM_SELECTITEM,
  3874.                                    MPFROM2SHORT( itemSelected, 0 ),
  3875.                                    MPFROM2SHORT( TRUE, 0 ) );
  3876.                 return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  3877.                 }
  3878.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  3879.         }
  3880.         //----------------------------------------------------------------------
  3881.         // if we receive any system message, dismiss the dialog box
  3882.         //----------------------------------------------------------------------
  3883.         case WM_COMMAND:
  3884.         {
  3885.             if (SHORT1FROMMP(mp1)==DID_OK)
  3886.                 WinDismissDlg( hWnd, TRUE );
  3887.             return 0;
  3888.         }
  3889.         //----------------------------------------------------------------------
  3890.         // if nothing further we want to intercept, pass message onto system
  3891.         //----------------------------------------------------------------------
  3892.         default:
  3893.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  3894.     }
  3895. }
  3896.  
  3897.  
  3898. ////////////////////////////////////////////////////////////////////////////////
  3899. ////////////////////////////////////////////////////////////////////////////////
  3900. MRESULT EXPENTRY scheduleProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  3901. {
  3902.     switch( msg )
  3903.     {
  3904.         //----------------------------------------------------------------------
  3905.         // when the dialog is being initialized, center it on desktop
  3906.         //----------------------------------------------------------------------
  3907.         case WM_INITDLG: {
  3908.             CHAR temp[MAXACTIONSTRINGLENGTH+32];
  3909.             SWP swp;
  3910.             SHORT i;
  3911.  
  3912.             // disable alarms while editing calendar
  3913.             oldProgType = numAlarms;
  3914.             numAlarms = 0;
  3915.  
  3916.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  3917.             WinSetWindowPos( hWnd, (HWND)0,
  3918.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  3919.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  3920.                              0, 0, SWP_MOVE);
  3921.  
  3922.             sprintf( temp, "Schedule for %d/%d/%4d...", month+1, day+1, 1900+year);
  3923.             WinSetWindowText( hWnd, temp );
  3924.  
  3925.             WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS, LM_DELETEALL, MPFROMSHORT( LIT_END ), temp );
  3926.             for( i = 0; i< oldProgType; i++)
  3927.                 if (alarm[i].AlarmDay == day)
  3928.                   if (alarm[i].AlarmMonth == month)
  3929.                     if (alarm[i].AlarmYear == year) {
  3930.                         CHAR c = 'a';
  3931.                         CHAR s[11+MAXACTIONSTRINGLENGTH];
  3932.                         BYTE hour = alarm[i].AlarmHour;
  3933.  
  3934.                         if (alarm[i].options & SCHEDULE_LAUNCHAPP) {
  3935.                             short j = 10;
  3936.                             short k = 0;
  3937.                             strcpy(s, "Launch >> ");
  3938.                             while ((ItemName[((int)alarm[i].ActionToDo[0])][((int)alarm[i].ActionToDo[1])][k])!='\0')
  3939.                                 if ((ItemName[((int)alarm[i].ActionToDo[0])][((int)alarm[i].ActionToDo[1])][k])=='~')
  3940.                                     k++;
  3941.                                 else
  3942.                                     s[j++] = ItemName[((int)alarm[i].ActionToDo[0])][((int)alarm[i].ActionToDo[1])][k++];
  3943.                             s[j] = '\0';
  3944.                             }
  3945.                         else
  3946.                             strcpy(s, alarm[i].ActionToDo);
  3947.  
  3948.                         if (alarm[i].AlarmHour>11)
  3949.                             c='p';
  3950.                         if (!(hour = hour % 12))
  3951.                             hour = 12;
  3952.  
  3953.                         sprintf( temp, "%2d:%2d%cm (%2d:%2d) -- %s", hour,
  3954.                                                                     alarm[i].AlarmMinute,
  3955.                                                                     c,
  3956.                                                                     alarm[i].AlarmHour,
  3957.                                                                     alarm[i].AlarmMinute,
  3958.                                                                     s );
  3959.                         if (temp[3]==' ') {
  3960.                             temp[3] = '0';
  3961.                             temp[12]= '0';
  3962.                             }
  3963.  
  3964.  
  3965.                         WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS, LM_INSERTITEM, MPFROMSHORT( LIT_END ), temp );
  3966.                         }
  3967.  
  3968.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  3969.             }
  3970.         //----------------------------------------------------------------------
  3971.         //----------------------------------------------------------------------
  3972.         case WM_CONTROL:
  3973.         {
  3974.             if ((SHORT1FROMMP(mp1)==SCHEDULEDITEMS) && (SHORT2FROMMP(mp1)==LN_ENTER))
  3975.                 return WinSendMsg( hWnd, WM_COMMAND, MPFROM2SHORT( REVISEITEM, 0 ), mp2 );
  3976.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  3977.         }
  3978.         //----------------------------------------------------------------------
  3979.         //----------------------------------------------------------------------
  3980.         case WM_COMMAND:
  3981.         {
  3982.             USHORT command = SHORT1FROMMP(mp1);
  3983.  
  3984.             //------------------------------------------------------------------
  3985.             //------------------------------------------------------------------
  3986.             if ( command==DELETEITEM ) {
  3987.                 BOOL continueOn = TRUE;
  3988.                 SHORT index = 0;
  3989.                 SHORT item = 0;
  3990.                 SHORT itemSelected = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS,
  3991.                                                                       LM_QUERYSELECTION,
  3992.                                                                       MPFROM2SHORT( LIT_FIRST, 0 ),
  3993.                                                                       0 ) );
  3994.                 if (itemSelected==LIT_NONE) {
  3995.                     WinMessageBox( HWND_DESKTOP, hwndFrame,
  3996.                                    "You must select an item!",
  3997.                                    "Delete an item", 0,
  3998.                                    MB_MOVEABLE|MB_ERROR|MB_OK);
  3999.                     return 0;
  4000.                     }
  4001.  
  4002.                 if (WinMessageBox( HWND_DESKTOP, hwndFrame,
  4003.                                    "Are you sure you want to permanently delete this item?",
  4004.                                    "Delete an item", 0,
  4005.                                    MB_MOVEABLE|MB_ICONQUESTION|MB_YESNO) == MBID_NO)
  4006.                     return 0;
  4007.  
  4008.                 itemSelected++;
  4009.                 while (continueOn) {
  4010.                     if ((alarm[index].AlarmYear  == (BYTE)(year%100)) &&
  4011.                         (alarm[index].AlarmMonth == (BYTE)(month%14)) &&
  4012.                         (alarm[index].AlarmDay   == (BYTE)(day%40))) {
  4013.                             item++;
  4014.                             if (item == itemSelected)
  4015.                                 continueOn = FALSE;
  4016.                             }
  4017.                     index++;
  4018.                     }
  4019.                 {
  4020.                     struct ALARMS tmp;
  4021.                     for ( item=index-1; item<MAXALARMS-1; item++) {
  4022.                         tmp = alarm[item];
  4023.                         alarm[item]   = alarm[item+1];
  4024.                         alarm[item+1] = tmp;
  4025.                         }
  4026.                 }
  4027.                 numAlarms = oldProgType-1;
  4028.                 sortTimeEntries( numAlarms );
  4029.                 WinSendMsg( hWnd, WM_INITDLG, 0, 0 );
  4030.                 if (index-1 >= oldProgType)
  4031.                     WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS, LM_SELECTITEM,
  4032.                                        MPFROM2SHORT( oldProgType-1, 0 ),
  4033.                                        MPFROM2SHORT( TRUE, 0 ) );
  4034.                 else
  4035.                     WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS, LM_SELECTITEM,
  4036.                                        MPFROM2SHORT( index-1, 0 ),
  4037.                                        MPFROM2SHORT( TRUE, 0 ) );
  4038.                 return 0;
  4039.                 }
  4040.             //------------------------------------------------------------------
  4041.             //------------------------------------------------------------------
  4042.             if ( command==ADDITEM ) {
  4043.                 SHORT itemSelected = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS,
  4044.                                                                       LM_QUERYSELECTION,
  4045.                                                                       MPFROM2SHORT( LIT_FIRST, 0 ),
  4046.                                                                       0 ) );
  4047.                 if (oldProgType == MAXALARMS) {
  4048.                     WinMessageBox( HWND_DESKTOP, hwndFrame,
  4049.                                    "There is no room for an additional task entry!",
  4050.                                    "Task Scheduler", 0,
  4051.                                    MB_MOVEABLE|MB_ERROR|MB_OK);
  4052.                     return 0;
  4053.                     }
  4054.                 alarm[oldProgType].AlarmYear = (BYTE)(year%100);
  4055.                 alarm[oldProgType].AlarmMonth = (BYTE)(month%14);
  4056.                 alarm[oldProgType].AlarmDay = (BYTE)(day%40);
  4057.                 alarm[oldProgType].AlarmHour = 0;
  4058.                 alarm[oldProgType].AlarmMinute = 0;
  4059.                 alarm[oldProgType].options = SCHEDULE_USEWAVFILE | SCHEDULE_USEWAVFILE;
  4060.                 alarm[oldProgType].ActionToDo[0] = 0;
  4061.                 alarm[oldProgType].ReminderWAV[0] = 0;
  4062.                 oldProgType++;
  4063.                 reviseScheduledItem( oldProgType-1 );
  4064.                 sortTimeEntries( oldProgType );
  4065.                 numAlarms = oldProgType;
  4066.                 WinSendMsg( hWnd, WM_INITDLG, 0, 0 );
  4067.                 WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS, LM_SELECTITEM,
  4068.                                    MPFROM2SHORT( itemSelected, 0 ),
  4069.                                    MPFROM2SHORT( TRUE, 0 ) );
  4070.                 return 0;
  4071.                 }
  4072.             //------------------------------------------------------------------
  4073.             //------------------------------------------------------------------
  4074.             if (( command==REVISEITEM ) || (command==LN_ENTER)) {
  4075.                 BOOL continueOn = TRUE;
  4076.                 SHORT index = 0;
  4077.                 SHORT item = 0;
  4078.                 SHORT itemSelected = 1 + SHORT1FROMMP( WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS,
  4079.                                                                           LM_QUERYSELECTION,
  4080.                                                                           MPFROM2SHORT( LIT_FIRST, 0 ),
  4081.                                                                           0 ) );
  4082.  
  4083.                 if ( (itemSelected-1) == LIT_NONE ) {
  4084.                     WinMessageBox( HWND_DESKTOP, hwndFrame,
  4085.                                    "You must select an item!",
  4086.                                    "Revise an item", 0,
  4087.                                    MB_MOVEABLE|MB_ERROR|MB_OK);
  4088.                     return 0;
  4089.                     }
  4090.  
  4091.                 while (continueOn) {
  4092.                     if ((alarm[index].AlarmYear  == (BYTE)(year%100)) &&
  4093.                         (alarm[index].AlarmMonth == (BYTE)(month%14)) &&
  4094.                         (alarm[index].AlarmDay   == (BYTE)(day%40))) {
  4095.                             item++;
  4096.                             if (item == itemSelected)
  4097.                                 continueOn = FALSE;
  4098.                             }
  4099.                     index++;
  4100.                     }
  4101.                 reviseScheduledItem( index-1 );
  4102.                 sortTimeEntries( oldProgType );
  4103.                 numAlarms = oldProgType;
  4104.                 WinSendMsg( hWnd, WM_INITDLG, 0, 0 );
  4105.                 WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS, LM_SELECTITEM,
  4106.                                    MPFROM2SHORT( itemSelected-1, 0 ),
  4107.                                    MPFROM2SHORT( TRUE, 0 ) );
  4108.                 return 0;
  4109.                 }
  4110.             //------------------------------------------------------------------
  4111.             //------------------------------------------------------------------
  4112.             if ( command==DID_OK ) {
  4113.                 WinDismissDlg( hWnd, TRUE );
  4114.                 numAlarms = oldProgType;
  4115.                 return 0;
  4116.                 }
  4117.             }
  4118.         default:
  4119.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  4120.     }
  4121. }
  4122.  
  4123.  
  4124. ////////////////////////////////////////////////////////////////////////////////
  4125. ////////////////////////////////////////////////////////////////////////////////
  4126. VOID checkAlarms( SHORT hour, SHORT minute, SHORT month, SHORT day, SHORT year ) {
  4127.     struct tm *time_now;
  4128.     time_t currentTime;
  4129.  
  4130.     day--;
  4131.     if ((numAlarms == 0) || (alarm[0].AlarmYear > year ))
  4132.         return;
  4133.     if ((alarm[0].AlarmYear == year) && (alarm[0].AlarmMonth > month))
  4134.         return;
  4135.     if ((alarm[0].AlarmMonth == month) && (alarm[0].AlarmDay > day))
  4136.         return;
  4137.     if ((alarm[0].AlarmDay == day) && (alarm[0].AlarmHour > hour))
  4138.         return;
  4139.     if ((alarm[0].AlarmHour == hour) && (alarm[0].AlarmMinute > minute))
  4140.         return;
  4141.  
  4142.     if ((alarm[0].options & SCHEDULE_LAUNCHAPP) && (!(alarm[0].options & SCHEDULE_SOUNDONLY)))
  4143.         startApplication( (SHORT)alarm[0].ActionToDo[0], (SHORT)alarm[0].ActionToDo[1] );
  4144.     else {
  4145.         currentReminderWavFile = 0;
  4146.         if (alarm[0].options & SCHEDULE_USEWAVFILE)
  4147.             currentReminderWavFile = alarm[0].ReminderWAV;
  4148.         if (alarm[0].options & SCHEDULE_SOUNDONLY)
  4149.             ringChime( currentReminderWavFile );
  4150.         else {
  4151.             oldItemName[0] = TRUE;
  4152.             WinDlgBox(HWND_DESKTOP,
  4153.             hwndFrame,
  4154.             (PFNWP)reminderNoteProc,
  4155.             0,
  4156.             REMINDER_DIALOG,
  4157.             (PVOID)alarm[0].ActionToDo);
  4158.             if (oldItemName[0]) {
  4159.                 checkAlarms( hour, minute, month, day, year );
  4160.                 return;
  4161.                 }
  4162.             }
  4163.         }
  4164.  
  4165.         // make it so that we reschedule from the current time
  4166.         // and not the time the task was supposed to go off
  4167.         tzset();
  4168.         time(¤tTime);
  4169.         time_now = localtime( ¤tTime );
  4170.  
  4171.         // reschedule or delete note
  4172.         if (alarm[0].options & SCHEDULE_EVERYHOUR) {
  4173.             alarm[0].AlarmHour = time_now->tm_hour;
  4174.             alarm[0].AlarmDay = time_now->tm_mday-1;
  4175.             alarm[0].AlarmMonth = time_now->tm_mon;
  4176.             alarm[0].AlarmYear = time_now->tm_year;
  4177.  
  4178.             alarm[0].AlarmHour++;
  4179.             validateTimeEntry();
  4180.             sortTimeEntries( numAlarms );
  4181.             }
  4182.         else if (alarm[0].options & SCHEDULE_EVERYDAY) {
  4183.             alarm[0].AlarmDay = time_now->tm_mday-1;
  4184.             alarm[0].AlarmMonth = time_now->tm_mon;
  4185.             alarm[0].AlarmYear = time_now->tm_year;
  4186.             alarm[0].AlarmDay++;
  4187.             validateTimeEntry();
  4188.             sortTimeEntries( numAlarms );
  4189.             }
  4190.         else if (alarm[0].options & SCHEDULE_EVERYWEEK) {
  4191.             alarm[0].AlarmDay = time_now->tm_mday-1;
  4192.             alarm[0].AlarmMonth = time_now->tm_mon;
  4193.             alarm[0].AlarmYear = time_now->tm_year;
  4194.             alarm[0].AlarmDay = alarm[0].AlarmDay + 7;
  4195.             validateTimeEntry();
  4196.             sortTimeEntries( numAlarms );
  4197.             }
  4198.         else if (alarm[0].options & SCHEDULE_EVERYMONTH) {
  4199.             alarm[0].AlarmMonth = time_now->tm_mon;
  4200.             alarm[0].AlarmYear = time_now->tm_year;
  4201.             alarm[0].AlarmMonth++;
  4202.             validateTimeEntry();
  4203.             sortTimeEntries( numAlarms );
  4204.             }
  4205.         else if (alarm[0].options & SCHEDULE_EVERYYEAR) {
  4206.             alarm[0].AlarmYear = time_now->tm_year;
  4207.             alarm[0].AlarmYear++;
  4208.             validateTimeEntry();
  4209.             sortTimeEntries( numAlarms );
  4210.             }
  4211.         else {
  4212.         ////// delete the reminder we just performed ///////
  4213.             for (short i=0; i<numAlarms-1; i++) {
  4214.                 alarm[i].AlarmHour = alarm[i+1].AlarmHour;
  4215.                 alarm[i].AlarmMinute = alarm[i+1].AlarmMinute;
  4216.                 alarm[i].AlarmDay = alarm[i+1].AlarmDay;
  4217.                 alarm[i].AlarmMonth = alarm[i+1].AlarmMonth;
  4218.                 alarm[i].AlarmYear = alarm[i+1].AlarmYear;
  4219.                 alarm[i].options = alarm[i+1].options;
  4220.                 strcpy( alarm[i].ReminderWAV, alarm[i+1].ReminderWAV );
  4221.                 strcpy( alarm[i].ActionToDo, alarm[i+1].ActionToDo );
  4222.                 }
  4223.             numAlarms--;
  4224.             }
  4225.         // check to see if another alarm needs to be serviced
  4226.         checkAlarms( hour, minute, month, day, year );
  4227. }
  4228.  
  4229.  
  4230. ////////////////////////////////////////////////////////////////////////////////
  4231. ////////////////////////////////////////////////////////////////////////////////
  4232. VOID validateTimeEntry( VOID )
  4233. {
  4234.     if (alarm[0].AlarmMinute > 59) {
  4235.         alarm[0].AlarmMinute = alarm[0].AlarmMinute - 60;
  4236.         alarm[0].AlarmHour++;
  4237.         }
  4238.     if (alarm[0].AlarmHour > 23) {
  4239.         alarm[0].AlarmMinute = alarm[0].AlarmMinute - 24;
  4240.         alarm[0].AlarmDay++;
  4241.         }
  4242.     if (alarm[0].AlarmDay > daysInMonth[alarm[0].AlarmMonth] ) {
  4243.         alarm[0].AlarmDay = alarm[0].AlarmDay - daysInMonth[alarm[0].AlarmMonth];
  4244.         alarm[0].AlarmMonth++;
  4245.         }
  4246.     if (alarm[0].AlarmMonth > 11) {
  4247.         alarm[0].AlarmMonth = alarm[0].AlarmMonth - 12;
  4248.         alarm[0].AlarmYear++;
  4249.         }
  4250. }
  4251.  
  4252.  
  4253. ////////////////////////////////////////////////////////////////////////////////
  4254. ////////////////////////////////////////////////////////////////////////////////
  4255. VOID sortTimeEntries( INT entries )
  4256. {
  4257.     ALARMS tmp;
  4258.     short i,j;
  4259.  
  4260.     // bubble sort all scheduled events so that closest event tops the list
  4261.     for (i=0; i<entries; i++)
  4262.         for (j=0; j<entries-1; j++) {
  4263.             if ( alarm[j].AlarmMinute > alarm[j+1].AlarmMinute ) {
  4264.                     tmp = alarm[j];
  4265.                     alarm[j] = alarm[j+1];
  4266.                     alarm[j+1] = tmp;
  4267.                     }
  4268.             }
  4269.     for (i=0; i<entries; i++)
  4270.         for (j=0; j<entries-1; j++) {
  4271.             if ( alarm[j].AlarmHour > alarm[j+1].AlarmHour ) {
  4272.                     tmp = alarm[j];
  4273.                     alarm[j] = alarm[j+1];
  4274.                     alarm[j+1] = tmp;
  4275.                     }
  4276.             }
  4277.     for (i=0; i<entries; i++)
  4278.         for (j=0; j<entries-1; j++) {
  4279.             if ( alarm[j].AlarmDay > alarm[j+1].AlarmDay ) {
  4280.                     tmp = alarm[j];
  4281.                     alarm[j] = alarm[j+1];
  4282.                     alarm[j+1] = tmp;
  4283.                     }
  4284.             }
  4285.     for (i=0; i<entries; i++)
  4286.         for (j=0; j<entries-1; j++) {
  4287.             if ( alarm[j].AlarmMonth > alarm[j+1].AlarmMonth ) {
  4288.                     tmp = alarm[j];
  4289.                     alarm[j] = alarm[j+1];
  4290.                     alarm[j+1] = tmp;
  4291.                     }
  4292.             }
  4293.     for (i=0; i<entries; i++)
  4294.         for (j=0; j<entries-1; j++) {
  4295.             if ( alarm[j].AlarmYear > alarm[j+1].AlarmYear ) {
  4296.                     tmp = alarm[j];
  4297.                     alarm[j] = alarm[j+1];
  4298.                     alarm[j+1] = tmp;
  4299.                     }
  4300.             }
  4301. }
  4302.  
  4303.  
  4304. ////////////////////////////////////////////////////////////////////////////////
  4305. // reviseScheduledItem - call dialog box to revise a currently scheduled event
  4306. ////////////////////////////////////////////////////////////////////////////////
  4307. VOID reviseScheduledItem( INT itemToEdit )
  4308. {
  4309.     EditItem = itemToEdit;
  4310.     WinDlgBox(HWND_DESKTOP,
  4311.               hwndFrame,
  4312.               (PFNWP)itemProc,
  4313.               0,
  4314.               SCHEDULEITEMDIALOG,
  4315.               (PVOID)0);
  4316.     return;
  4317. }
  4318.  
  4319.  
  4320. ////////////////////////////////////////////////////////////////////////////////
  4321. // displayReminderTime - update display of time in revision dialog box
  4322. ////////////////////////////////////////////////////////////////////////////////
  4323. VOID displayReminderTime( HWND hWnd, INT offset )
  4324. {
  4325.     SHORT hour;
  4326.     CHAR c;
  4327.     CHAR time[16];
  4328.  
  4329.     c='a';
  4330.     if (alarm[offset].AlarmHour>11)
  4331.         c='p';
  4332.     if (!(hour = alarm[offset].AlarmHour % 12))
  4333.         hour = 12;
  4334.  
  4335.     sprintf( time, "%2d:%2d%cm (%2d:%2d)", hour,
  4336.                                            alarm[offset].AlarmMinute,
  4337.                                            c,
  4338.                                            alarm[offset].AlarmHour,
  4339.                                            alarm[offset].AlarmMinute);
  4340.     if (time[3]==' ') {
  4341.         time[3] = '0';
  4342.         time[12]= '0';
  4343.         }
  4344.     WinSetDlgItemText( hWnd, TIME_TEXT, (CHAR*)time );
  4345. }
  4346.  
  4347.  
  4348. ////////////////////////////////////////////////////////////////////////////////
  4349. // displayReminderDate - update display of date in revision dialog box
  4350. ////////////////////////////////////////////////////////////////////////////////
  4351. VOID displayReminderDate( HWND hWnd, INT offset )
  4352. {
  4353.     CHAR date[24];
  4354.  
  4355.     sprintf( date, " %d/%d/%d (%d/%d/%d) ",  alarm[offset].AlarmMonth+1,
  4356.                                              alarm[offset].AlarmDay+1,
  4357.                                              alarm[offset].AlarmYear,
  4358.                                              alarm[offset].AlarmDay+1,
  4359.                                              alarm[offset].AlarmMonth+1,
  4360.                                              alarm[offset].AlarmYear);
  4361.     WinSetDlgItemText( hWnd, DATETEXT, (CHAR*)date );
  4362. }
  4363.  
  4364.  
  4365. ////////////////////////////////////////////////////////////////////////////////
  4366. ////////////////////////////////////////////////////////////////////////////////
  4367. MRESULT EXPENTRY itemProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  4368. {
  4369.    switch( msg )
  4370.     {
  4371.         //----------------------------------------------------------------------
  4372.         //----------------------------------------------------------------------
  4373.         case WM_INITDLG: {
  4374.             CHAR s[MAXPATH+11];
  4375.             SWP swp;
  4376.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  4377.             WinSetWindowPos( hWnd, (HWND)0,
  4378.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  4379.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  4380.                              0, 0, SWP_MOVE);
  4381.  
  4382.             WinSendDlgItemMsg( hWnd, SOUNDFILE, EM_SETTEXTLIMIT, MPFROMSHORT( sizeof(alarm[EditItem].ReminderWAV) ), 0 );
  4383.             WinSendDlgItemMsg( hWnd, REMINDER, EM_SETTEXTLIMIT, MPFROMSHORT( sizeof(alarm[EditItem].ActionToDo) ), 0 );
  4384.  
  4385.             WinCheckButton( hWnd, DELETEITEM, TRUE );
  4386.             if (alarm[EditItem].options & SCHEDULE_EVERYHOUR)
  4387.                 WinCheckButton( hWnd, EVERYHOUR, TRUE );
  4388.             else if (alarm[EditItem].options & SCHEDULE_EVERYDAY)
  4389.                 WinCheckButton( hWnd, EVERYDAY, TRUE );
  4390.             else if (alarm[EditItem].options & SCHEDULE_EVERYWEEK)
  4391.                 WinCheckButton( hWnd, EVERYWEEK, TRUE );
  4392.             else if (alarm[EditItem].options & SCHEDULE_EVERYMONTH)
  4393.                 WinCheckButton( hWnd, EVERYMONTH, TRUE );
  4394.             else if (alarm[EditItem].options & SCHEDULE_EVERYYEAR)
  4395.                 WinCheckButton( hWnd, EVERYYEAR, TRUE );
  4396.  
  4397.             if ( alarm[EditItem].options & SCHEDULE_USEWAVFILE )
  4398.                 WinCheckButton( hWnd, PLAYSOUND, TRUE );
  4399.             if ( alarm[EditItem].options & SCHEDULE_SOUNDONLY )
  4400.                 WinCheckButton( hWnd, SOUNDONLY, TRUE );
  4401.  
  4402.             WinSetDlgItemText( hWnd, SOUNDFILE, (CHAR*)alarm[EditItem].ReminderWAV );
  4403.             displayReminderTime( hWnd, EditItem );
  4404.             displayReminderDate( hWnd, EditItem );
  4405.  
  4406.             if (alarm[EditItem].options & SCHEDULE_LAUNCHAPP) {
  4407.                 short j = 10;
  4408.                 short k = 0;
  4409.  
  4410.                 strcpy(s, "Launch >> ");
  4411.                 while ((ItemName[((int)alarm[EditItem].ActionToDo[0])][((int)alarm[EditItem].ActionToDo[1])][k])!='\0')
  4412.                     if ((ItemName[((int)alarm[EditItem].ActionToDo[0])][((int)alarm[EditItem].ActionToDo[1])][k])=='~')
  4413.                         k++;
  4414.                     else
  4415.                         s[j++] = ItemName[((int)alarm[EditItem].ActionToDo[0])][((int)alarm[EditItem].ActionToDo[1])][k++];
  4416.                 s[j] = '\0';
  4417.  
  4418.                 WinSetDlgItemText( hWnd, REMINDER, (CHAR*)s );
  4419.                 WinEnableControl( hWnd, REMINDER, FALSE );
  4420.                 }
  4421.             else {
  4422.                 WinEnableControl( hWnd, REMINDER, TRUE );
  4423.                 WinSetDlgItemText( hWnd, REMINDER, (CHAR*)alarm[EditItem].ActionToDo );
  4424.                 }
  4425.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  4426.             }
  4427.         //----------------------------------------------------------------------
  4428.         //----------------------------------------------------------------------
  4429.         case WM_COMMAND:
  4430.         {
  4431.             USHORT command = SHORT1FROMMP(mp1);
  4432.  
  4433.             switch(command) {
  4434.             //------------------------------------------------------------------
  4435.             //------------------------------------------------------------------
  4436.                 case LAUNCHITEM: {
  4437.                     short tmp = 0;
  4438.  
  4439.                     if (WinQueryButtonCheckstate( hWnd, EVERYHOUR ))
  4440.                         tmp += SCHEDULE_EVERYHOUR;
  4441.                     else if (WinQueryButtonCheckstate( hWnd, EVERYDAY ))
  4442.                         tmp += SCHEDULE_EVERYDAY;
  4443.                     else if (WinQueryButtonCheckstate( hWnd, EVERYWEEK ))
  4444.                         tmp += SCHEDULE_EVERYWEEK;
  4445.                     else if (WinQueryButtonCheckstate( hWnd, EVERYMONTH ))
  4446.                         tmp += SCHEDULE_EVERYMONTH;
  4447.                     else if (WinQueryButtonCheckstate( hWnd, EVERYYEAR ))
  4448.                         tmp += SCHEDULE_EVERYYEAR;
  4449.                     if (WinQueryButtonCheckstate( hWnd, PLAYSOUND ))
  4450.                         tmp += SCHEDULE_USEWAVFILE;
  4451.                     if (WinQueryButtonCheckstate( hWnd, SOUNDONLY ))
  4452.                         tmp += SCHEDULE_SOUNDONLY;
  4453.  
  4454.                     WinDlgBox(HWND_DESKTOP,
  4455.                               hWnd,
  4456.                               (PFNWP)LaunchItemProc,
  4457.                               0,
  4458.                               LAUNCHITEMDIALOG,
  4459.                               (PVOID)0);
  4460.  
  4461.                     if (alarm[EditItem].options & SCHEDULE_LAUNCHAPP)
  4462.                         tmp = tmp + SCHEDULE_LAUNCHAPP;
  4463.  
  4464.                     alarm[EditItem].options = tmp;
  4465.                     WinSendMsg( hWnd, WM_INITDLG, 0, 0 );
  4466.                     return 0;
  4467.                     }
  4468.             //------------------------------------------------------------------
  4469.             //------------------------------------------------------------------
  4470.                 case SELECTSOUNDFILE: {
  4471.                     CHAR title[] = "Task Scheduler - Find a Sound File";
  4472.                     ULONG s;
  4473.                     HWND hwndDialog;
  4474.                     CHAR oldDir[MAXPATH];
  4475.  
  4476.                     fileDlgInfo.fl = FDS_OPEN_DIALOG|FDS_CENTER;
  4477.                     fileDlgInfo.pszTitle = title;
  4478.                     strcpy( oldDir, fileDlgInfo.szFullFile );
  4479.                     strcat(fileDlgInfo.szFullFile, "*.WAV\0");
  4480.  
  4481.                     hwndDialog = WinFileDlg( HWND_DESKTOP, hWnd, &fileDlgInfo );
  4482.                     if (hwndDialog && (fileDlgInfo.lReturn == DID_OK)) {
  4483.                         strcpy( alarm[EditItem].ReminderWAV, fileDlgInfo.szFullFile );
  4484.                         strcat( alarm[EditItem].ReminderWAV, "\0" );
  4485.  
  4486.                         s=0;
  4487.                         while(fileDlgInfo.szFullFile[s]!='\0')
  4488.                             s++;
  4489.                         while((fileDlgInfo.szFullFile[s]!='\\') && (s>=0))
  4490.                             s--;
  4491.  
  4492.                         if (fileDlgInfo.szFullFile[s]=='\\')
  4493.                             fileDlgInfo.szFullFile[s+1]='\0';
  4494.                         else
  4495.                             fileDlgInfo.szFullFile[0]='\0';
  4496.  
  4497.                         WinSetDlgItemText( hWnd, SOUNDFILE, alarm[EditItem].ReminderWAV );
  4498.                         }
  4499.                     else
  4500.                         strcpy( fileDlgInfo.szFullFile, oldDir );
  4501.                     return 0;
  4502.                     }
  4503.             //------------------------------------------------------------------
  4504.             //------------------------------------------------------------------
  4505.                 case DAY_MORE: {
  4506.                     alarm[EditItem].AlarmDay = (alarm[EditItem].AlarmDay + 1) % daysInMonth[alarm[EditItem].AlarmMonth];
  4507.                     displayReminderDate( hWnd, EditItem );
  4508.                     return 0;
  4509.                     }
  4510.             //------------------------------------------------------------------
  4511.             //------------------------------------------------------------------
  4512.                 case DAY_LESS: {
  4513.                     if (alarm[EditItem].AlarmDay==0)
  4514.                         alarm[EditItem].AlarmDay = daysInMonth[alarm[EditItem].AlarmMonth] - 1;
  4515.                     else
  4516.                         alarm[EditItem].AlarmDay = (alarm[EditItem].AlarmDay - 1) % daysInMonth[alarm[EditItem].AlarmMonth];
  4517.                     displayReminderDate( hWnd, EditItem );
  4518.                     return 0;
  4519.                     }
  4520.             //------------------------------------------------------------------
  4521.             //------------------------------------------------------------------
  4522.                 case MONTH_MORE: {
  4523.                     alarm[EditItem].AlarmMonth = (alarm[EditItem].AlarmMonth + 1) % 12;
  4524.                     displayReminderDate( hWnd, EditItem );
  4525.                     return 0;
  4526.                     }
  4527.             //------------------------------------------------------------------
  4528.             //------------------------------------------------------------------
  4529.                 case MONTH_LESS: {
  4530.                     if (alarm[EditItem].AlarmMonth == 0)
  4531.                         alarm[EditItem].AlarmMonth = 11;
  4532.                     else
  4533.                         alarm[EditItem].AlarmMonth--;
  4534.                     displayReminderDate( hWnd, EditItem );
  4535.                     return 0;
  4536.                     }
  4537.             //------------------------------------------------------------------
  4538.             //------------------------------------------------------------------
  4539.                 case YEAR_MORE: {
  4540.                     alarm[EditItem].AlarmYear++;
  4541.                     displayReminderDate( hWnd, EditItem );
  4542.                     return 0;
  4543.                     }
  4544.             //------------------------------------------------------------------
  4545.             //------------------------------------------------------------------
  4546.                 case YEAR_LESS: {
  4547.                     alarm[EditItem].AlarmYear--;
  4548.                     displayReminderDate( hWnd, EditItem );
  4549.                     return 0;
  4550.                     }
  4551.             //------------------------------------------------------------------
  4552.             //------------------------------------------------------------------
  4553.                 case MINUTE_MORE: {
  4554.                     alarm[EditItem].AlarmMinute = (alarm[EditItem].AlarmMinute+1) % 60;
  4555.                     displayReminderTime( hWnd, EditItem );
  4556.                     return 0;
  4557.                     }
  4558.             //------------------------------------------------------------------
  4559.             //------------------------------------------------------------------
  4560.                 case MINUTE_LESS: {
  4561.                     if (alarm[EditItem].AlarmMinute == 0)
  4562.                         alarm[EditItem].AlarmMinute = 59;
  4563.                     else
  4564.                         alarm[EditItem].AlarmMinute = (alarm[EditItem].AlarmMinute-1) % 60;
  4565.                     displayReminderTime( hWnd, EditItem );
  4566.                     return 0;
  4567.                     }
  4568.             //------------------------------------------------------------------
  4569.             //------------------------------------------------------------------
  4570.                 case HOUR_MORE: {
  4571.                 alarm[EditItem].AlarmHour = (alarm[EditItem].AlarmHour+1) % 24;
  4572.                 displayReminderTime( hWnd, EditItem );
  4573.                 return 0;
  4574.                 }
  4575.             //------------------------------------------------------------------
  4576.             //------------------------------------------------------------------
  4577.                 case HOUR_LESS: {
  4578.                 if (alarm[EditItem].AlarmHour == 0)
  4579.                     alarm[EditItem].AlarmHour = 23;
  4580.                 else
  4581.                     alarm[EditItem].AlarmHour = (alarm[EditItem].AlarmHour-1) % 24;
  4582.                 displayReminderTime( hWnd, EditItem );
  4583.                 return 0;
  4584.                 }
  4585.             //------------------------------------------------------------------
  4586.             //------------------------------------------------------------------
  4587.                 case DID_OK:  {
  4588.                 if (alarm[EditItem].options & SCHEDULE_LAUNCHAPP)
  4589.                     alarm[EditItem].options = SCHEDULE_LAUNCHAPP;
  4590.                 else {
  4591.                     alarm[EditItem].options = 0;
  4592.                     WinQueryDlgItemText( hWnd, REMINDER,
  4593.                                          sizeof(alarm[EditItem].ActionToDo),
  4594.                                          (PSZ)alarm[EditItem].ActionToDo );
  4595.                     }
  4596.  
  4597.                 if (WinQueryButtonCheckstate( hWnd, EVERYHOUR ))
  4598.                     alarm[EditItem].options += SCHEDULE_EVERYHOUR;
  4599.                 else if (WinQueryButtonCheckstate( hWnd, EVERYDAY ))
  4600.                     alarm[EditItem].options += SCHEDULE_EVERYDAY;
  4601.                 else if (WinQueryButtonCheckstate( hWnd, EVERYWEEK ))
  4602.                     alarm[EditItem].options += SCHEDULE_EVERYWEEK;
  4603.                 else if (WinQueryButtonCheckstate( hWnd, EVERYMONTH ))
  4604.                     alarm[EditItem].options += SCHEDULE_EVERYMONTH;
  4605.                 else if (WinQueryButtonCheckstate( hWnd, EVERYYEAR ))
  4606.                     alarm[EditItem].options += SCHEDULE_EVERYYEAR;
  4607.  
  4608.                 if (WinQueryButtonCheckstate( hWnd, PLAYSOUND ))
  4609.                     alarm[EditItem].options += SCHEDULE_USEWAVFILE;
  4610.                 if (WinQueryButtonCheckstate( hWnd, SOUNDONLY ))
  4611.                     alarm[EditItem].options += SCHEDULE_SOUNDONLY;
  4612.  
  4613.                 WinQueryDlgItemText( hWnd, SOUNDFILE,
  4614.                                      sizeof(alarm[EditItem].ReminderWAV),
  4615.                                      (PSZ)alarm[EditItem].ReminderWAV );
  4616.  
  4617.                 WinDismissDlg( hWnd, TRUE );
  4618.                 return 0;
  4619.                 }
  4620.                 default:
  4621.                     return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  4622.             }
  4623.         }
  4624.         //----------------------------------------------------------------------
  4625.         // if nothing further we want to intercept, pass message onto system
  4626.         //----------------------------------------------------------------------
  4627.         default:
  4628.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  4629.  
  4630.     }
  4631. }
  4632.  
  4633.  
  4634. ////////////////////////////////////////////////////////////////////////////////
  4635. ////////////////////////////////////////////////////////////////////////////////
  4636. MRESULT EXPENTRY reminderNoteProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  4637. {
  4638.    switch( msg )
  4639.     {
  4640.         //----------------------------------------------------------------------
  4641.         //----------------------------------------------------------------------
  4642.         case WM_TIMER: {
  4643.             ringChime( currentReminderWavFile );
  4644.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  4645.             }
  4646.         //----------------------------------------------------------------------
  4647.         // when the dialog is being initialized, center it on desktop
  4648.         //----------------------------------------------------------------------
  4649.         case WM_INITDLG: {
  4650.             SWP swp;
  4651.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  4652.             WinSetWindowPos( hWnd, (HWND)0,
  4653.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  4654.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  4655.                              0, 0, SWP_MOVE);
  4656.             noteTimerNumber = WinStartTimer( hab, hWnd, TIMERID+1, (LONG)repeatTime*1000 );
  4657.             numberOfAlarms = numAlarms;
  4658.             numAlarms = 0;
  4659.             if (mp2 != 0)
  4660.                 WinSetDlgItemText( hWnd, REMINDER, (CHAR*)LONGFROMMP( mp2 ) );
  4661.             WinPostMsg( hWnd, WM_TIMER, mp1, mp2 );
  4662.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  4663.             }
  4664.         //----------------------------------------------------------------------
  4665.         // if we receive any system message, dismiss the dialog box
  4666.         //----------------------------------------------------------------------
  4667.         case WM_COMMAND:
  4668.         {
  4669.             USHORT command = SHORT1FROMMP(mp1);
  4670.  
  4671.             switch(command) {
  4672.             //------------------------------------------------------------------
  4673.             //------------------------------------------------------------------
  4674.             case DID_OK: {
  4675.                 WinStopTimer( hab, TIMERID+1, noteTimerNumber );
  4676.                 WinDismissDlg( hWnd, TRUE );
  4677.                 numAlarms = numberOfAlarms;
  4678.                 oldItemName[0] = FALSE;
  4679.                 return 0;
  4680.                 }
  4681.             //------------------------------------------------------------------
  4682.             //------------------------------------------------------------------
  4683.             case SNOOZE: {
  4684.                 struct tm *time_now;
  4685.                 time_t currentTime;
  4686.  
  4687.                 WinStopTimer( hab, TIMERID+1, noteTimerNumber );
  4688.  
  4689.                 tzset();
  4690.                 time(¤tTime);
  4691.                 time_now = localtime( ¤tTime );
  4692.                 alarm[0].AlarmHour = time_now->tm_hour;
  4693.                 alarm[0].AlarmMinute = time_now->tm_min + 9;
  4694.  
  4695.                 validateTimeEntry();
  4696.                 sortTimeEntries( numberOfAlarms );
  4697.                 WinDismissDlg( hWnd, TRUE );
  4698.                 numAlarms = numberOfAlarms;
  4699.                 return 0;
  4700.                 }
  4701.             //------------------------------------------------------------------
  4702.             //------------------------------------------------------------------
  4703.             case REVISE: {
  4704.                 WinStopTimer( hab, TIMERID+1, noteTimerNumber );
  4705.                 reviseScheduledItem( 0 );
  4706.                 validateTimeEntry();
  4707.                 sortTimeEntries( numberOfAlarms );
  4708.                 WinDismissDlg( hWnd, TRUE );
  4709.                 numAlarms = numberOfAlarms;
  4710.                 return 0;
  4711.                 }
  4712.             //------------------------------------------------------------------
  4713.             //------------------------------------------------------------------
  4714.             case ERASE: {
  4715.                 WinStopTimer( hab, TIMERID+1, noteTimerNumber );
  4716.                 if (WinMessageBox( HWND_DESKTOP, hwndFrame,
  4717.                                    "Are you sure you want to completely erase this reminder?",
  4718.                                    "Erase this reminder", 0,
  4719.                                    MB_MOVEABLE|MB_ICONQUESTION|MB_YESNO)==MBID_YES) {
  4720.                     for (short i=1; i<MAXALARMS; i++)
  4721.                         alarm[ i-1 ] = alarm[ i ];
  4722.                     WinDismissDlg( hWnd, TRUE );
  4723.                     numAlarms = numberOfAlarms-1;
  4724.                     }
  4725.                 noteTimerNumber = WinStartTimer( hab, hWnd, TIMERID+1, (LONG)repeatTime*1000 );
  4726.                 return 0;
  4727.                 }
  4728.             //------------------------------------------------------------------
  4729.             //------------------------------------------------------------------
  4730.             default:
  4731.                 return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  4732.             }
  4733.         }
  4734.         //----------------------------------------------------------------------
  4735.         // if nothing further we want to intercept, pass message onto system
  4736.         //----------------------------------------------------------------------
  4737.         default:
  4738.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  4739.     }
  4740. }
  4741.  
  4742.  
  4743. ////////////////////////////////////////////////////////////////////////////////
  4744. ////////////////////////////////////////////////////////////////////////////////
  4745. MRESULT EXPENTRY LaunchItemProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  4746. {
  4747.    switch( msg )
  4748.     {
  4749.         //----------------------------------------------------------------------
  4750.         // when the dialog is being initialized, center it on desktop
  4751.         //----------------------------------------------------------------------
  4752.         case WM_INITDLG: {
  4753.             SHORT i,j;
  4754.             CHAR temp[MAXACTIONSTRINGLENGTH+5];
  4755.             SWP swp;
  4756.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  4757.             WinSetWindowPos( hWnd, (HWND)0,
  4758.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  4759.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  4760.                              0, 0, SWP_MOVE);
  4761.  
  4762.             oldAction[LAUNCHED] = alarm[EditItem].options & SCHEDULE_LAUNCHAPP;
  4763.             WinSendDlgItemMsg( hWnd, CURITEMLIST, LM_DELETEALL, 0, 0);
  4764.             temp[0] = ' ';
  4765.             temp[1] = ' ';
  4766.             temp[2] = '-';
  4767.             temp[3] = ' ';
  4768.             for (i=0; i<NumMenus; i++) {
  4769.                 WinSendDlgItemMsg( hWnd, CURITEMLIST, LM_INSERTITEM, MPFROMSHORT( LIT_END ), MenuName[i] );
  4770.                 for (j=0; j<NumItems[i]; j++)
  4771.                    if (ItemName[i][j][0] != '\0') {
  4772.                         temp[4] = '\0';
  4773.                         strcat(temp, ItemName[i][j]);
  4774.                         WinSendDlgItemMsg( hWnd, CURITEMLIST, LM_INSERTITEM, MPFROMSHORT( LIT_END ), temp );
  4775.                         }
  4776.                 }
  4777.  
  4778.             // if they had requested to launch an application previously
  4779.             // restore their choice in the dialog box
  4780.             WinCheckButton( hWnd, LAUNCHITEM, FALSE );
  4781.             if (oldAction[LAUNCHED]) {
  4782.                 SHORT item, index;
  4783.                 WinCheckButton( hWnd, LAUNCHITEM, TRUE );
  4784.  
  4785.                 item = 0;
  4786.                 index = alarm[EditItem].ActionToDo[0];
  4787.                 if (index > 0) {
  4788.                     for (i=0; i<index; i++) {
  4789.                         item++;
  4790.                         for (j=0; j<NumItems[i]; j++)
  4791.                             if (ItemName[i][j][0] != '\0')
  4792.                                 item++;
  4793.                         }
  4794.                     }
  4795.  
  4796.                 item += alarm[EditItem].ActionToDo[1]+1;
  4797.  
  4798.                 for (j=0; j<alarm[EditItem].ActionToDo[1]; j++)
  4799.                     if (ItemName[index][j][0] == '\0')
  4800.                         item--;
  4801.  
  4802.                 WinSendDlgItemMsg( hWnd, CURITEMLIST, LM_SELECTITEM,
  4803.                                    MPFROM2SHORT( item, 0 ),
  4804.                                    MPFROM2SHORT( TRUE, 0 ) );
  4805.                 }
  4806.  
  4807.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  4808.             }
  4809.         //----------------------------------------------------------------------
  4810.         //----------------------------------------------------------------------
  4811.         case WM_CONTROL:
  4812.         {
  4813.             if (SHORT1FROMMP(mp1)==CURITEMLIST) {
  4814.                 if (SHORT2FROMMP(mp1)==LN_ENTER) {
  4815.                     WinCheckButton( hWnd, LAUNCHITEM, TRUE );
  4816.                     WinSendMsg( hWnd, WM_COMMAND, MPFROMSHORT(DID_OK), 0 );
  4817.                     }
  4818.                 if (SHORT2FROMMP(mp1)==LN_SELECT)
  4819.                     WinCheckButton( hWnd, LAUNCHITEM, TRUE );
  4820.                 }
  4821.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  4822.         }
  4823.         //----------------------------------------------------------------------
  4824.         //----------------------------------------------------------------------
  4825.         case WM_COMMAND:
  4826.         {
  4827.             if (SHORT1FROMMP(mp1)==DID_OK) {
  4828.                 SHORT itemSelected = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, CURITEMLIST,
  4829.                                                                       LM_QUERYSELECTION,
  4830.                                                                       MPFROM2SHORT( LIT_FIRST, 0 ),
  4831.                                                                       0 ) );
  4832.                 if (WinQueryButtonCheckstate( hWnd, LAUNCHITEM )) {
  4833.                         short i,j;
  4834.                         char temp[MAXPATH];
  4835.  
  4836.                         WinSendDlgItemMsg( hWnd, CURITEMLIST,
  4837.                                                LM_QUERYITEMTEXT,
  4838.                                                MPFROM2SHORT( itemSelected, sizeof(temp) ),
  4839.                                                (PSZ)temp );
  4840.  
  4841.                         if (strncmp(temp, "  - ", 4) != 0) {
  4842.                             WinMessageBox( HWND_DESKTOP, hwndFrame,
  4843.                                            "You must select an item (NOT a menu) from the list!",
  4844.                                            "Task Scheduler: Launch an Application", 0,
  4845.                                            MB_MOVEABLE|MB_ERROR|MB_OK);
  4846.                             return 0;
  4847.                             }
  4848.  
  4849.                         if ( !oldAction[LAUNCHED] )
  4850.                             alarm[EditItem].options += SCHEDULE_LAUNCHAPP;
  4851.  
  4852.                         for (i=0; i<NumMenus; i++)
  4853.                             for (j=0; j<NumItems[i]; j++)
  4854.                                 if (strcmp( temp+4, ItemName[i][j] ) == 0) {
  4855.                                     alarm[EditItem].ActionToDo[0] = i;
  4856.                                     alarm[EditItem].ActionToDo[1] = j;
  4857.                                     }
  4858.                     }
  4859.                 else {
  4860.                     if ( oldAction[LAUNCHED] ) {
  4861.                         alarm[EditItem].options -= SCHEDULE_LAUNCHAPP;
  4862.                         alarm[EditItem].ActionToDo[0] = 0;
  4863.                         }
  4864.                     }
  4865.                 WinDismissDlg( hWnd, TRUE );
  4866.                 return 0;
  4867.                 }
  4868.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  4869.         }
  4870.         //----------------------------------------------------------------------
  4871.         // if nothing further we want to intercept, pass message onto system
  4872.         //----------------------------------------------------------------------
  4873.         default:
  4874.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  4875.     }
  4876. }
  4877.  
  4878.  
  4879.  
  4880.