home *** CD-ROM | disk | FTP | other *** search
/ HomeWare 14 / HOMEWARE14.bin / os2 / fbar14.arj / FILEBAR.CPP < prev    next >
C/C++ Source or Header  |  1994-02-12  |  149KB  |  3,014 lines

  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. //                                FileBar
  4. //
  5. //         OS/2 Application Launch Facility and WPS Shell Replacement
  6. //                              Version 1.4
  7. //
  8. //                         Written By Eric A. Wolf
  9. //                 Copyright (C) 1994 - All Rights Reserved
  10. //
  11. // This source code may be used for reference ONLY!  It is provided AS-IS and no
  12. // guarantees are made as to its utility, functionality or correctness.  It is
  13. // provided solely as a guide to aid aspiring OS/2 2.x Presentation Manager
  14. // programmers in developing their own PM applications.  No modifications are
  15. // to be made to this code for re-release as a same or different product.  This
  16. // code must be distributed (in its original entirety) with the executable
  17. // portion of this product.
  18. //
  19. //          -- Please register this shareware product for $10 today --
  20. //                          See documentation for details
  21. //
  22. // Project Start Date:      December 26, 1993
  23. // Project Completion Date: January   3, 1994
  24. //
  25. // Written using Borland C++ for OS/2, version 1.0, Borland Resource Workshop,
  26. //               and the IBM OS/2 2.1 bitmap/icon editor
  27. //
  28. // File Last Modified:      February 12, 1994
  29. //
  30. ////////////////////////////////////////////////////////////////////////////////
  31.  
  32.  
  33. ////////////////////////////////////////////////////////////////////////////////
  34. // set compile-time flags for what os/2 header information should be included
  35. ////////////////////////////////////////////////////////////////////////////////
  36. #define INCL_PM
  37. #define INCL_DOSSESMGR
  38. #define INCL_DOSMISC
  39. #define INCL_WINPOINTERS
  40. #define INCL_WINSTDFILE
  41. #define INCL_DOSPROCESS
  42.  
  43. ////////////////////////////////////////////////////////////////////////////////
  44. // include C, C++, OS/2, application and resource header files
  45. ////////////////////////////////////////////////////////////////////////////////
  46. #include <os2.h>
  47. #include <stdio.h>
  48. #include <stdlib.h>
  49. #include <ctype.h>
  50. #include <string.h>
  51. #include <time.h>
  52. #include "filebar.h"
  53.  
  54.  
  55. ////////////////////////////////////////////////////////////////////////////////
  56. // MakeHourglassPointer - macro to make the mouse pointer the hourglass
  57. ////////////////////////////////////////////////////////////////////////////////
  58. #define MakeHourglassPointer() {                                                               \
  59.                                  HPOINTER pointer;                                             \
  60.                                  pointer = WinQuerySysPointer( HWND_DESKTOP, SPTR_WAIT, FALSE);\
  61.                                  WinSetPointer( HWND_DESKTOP, pointer );                       \
  62.                                }
  63.  
  64.  
  65. ////////////////////////////////////////////////////////////////////////////////
  66. // MakeArrowPointer - macro to make the mouse pointer the arrow
  67. ////////////////////////////////////////////////////////////////////////////////
  68. #define MakeArrowPointer() {                                                                \
  69.                              HPOINTER pointer;                                              \
  70.                              pointer = WinQuerySysPointer( HWND_DESKTOP, SPTR_ARROW, FALSE);\
  71.                              WinSetPointer( HWND_DESKTOP, pointer );                        \
  72.                            }
  73.  
  74.  
  75. ////////////////////////////////////////////////////////////////////////////////
  76. // writeString - writes a string out with quotes on either side
  77. ////////////////////////////////////////////////////////////////////////////////
  78. #define writeString(stream, string) fprintf(stream, "\"%s\"\n", string)
  79.  
  80.  
  81. ////////////////////////////////////////////////////////////////////////////////
  82. // define application constants
  83. ////////////////////////////////////////////////////////////////////////////////
  84. #define TEMPSTRING            64
  85. #define AT_TOP                TRUE
  86. #define AT_BOTTOM             FALSE
  87. #define TIMERID               1
  88. #define MAXTASKS              30
  89. #define MAXMENUS              7
  90. #define MAXITEMS              24
  91. #define MAXACTIONSTRINGLENGTH CCHMAXPATH
  92. #define MAXITEMNAMELENGTH     24
  93. #define MAXMENUNAMELENGTH     20
  94. #define MAXARGSTRINGLENGTH    32
  95. #define MAXDIRSTRINGLENGTH    CCHMAXPATH
  96. #define WINDOWED              1
  97. #define FULLSCREEN            2
  98. #define PM                    4
  99. #define DOS                   8
  100. #define OS2                   16
  101. #define WINOS2                32
  102. #define STARTMIN              64
  103. #define STARTMAX              128
  104. #define WPSFOLDER             256
  105. #define STARTASWPS            512
  106. #define SCALED                128
  107. #define TILED                 64
  108. #define OS2SHELL              "CMD.EXE"
  109. #define OPTIONFILE            "FILEBAR.INI"
  110. #define LAUNCHFILE            "STARTPRG.CMD"
  111. #define LAUNCHINPUTS          "/C STARTPRG.CMD"
  112. #define SEPARATOR             "────────────────────────"
  113. #define FILEBARMENUON         "~FileBar"
  114. #define FILEBARMENUOFF        "\x04"
  115. #define TASKMENUON            "~Task List"
  116. #define TASKMENUOFF           "~Tasks"
  117. #define STARTINPUT            '['
  118. #define ENDINPUT              ']'
  119. #define BITMAPNAME            "\\FILEBAR.BMP\0"
  120. #define NOCOLOR               1
  121.  
  122. ////////////////////////////////////////////////////////////////////////////////
  123. // define function prototypes
  124. ////////////////////////////////////////////////////////////////////////////////
  125. VOID displayBackground( VOID );
  126. VOID resizeMenu( VOID );
  127. VOID readOptionFile( VOID );
  128. VOID writeOptionFile( VOID );
  129. VOID readString( FILE* stream, CHAR* buffer );
  130. VOID restartTimer( VOID );
  131. VOID displayTimeDate( VOID );
  132. VOID SwapTwoMenus( SHORT menu1, SHORT menu2 );
  133. VOID SwapTwoItems(SHORT Menu, SHORT item1, SHORT item2);
  134. VOID updateItemList( HWND hWnd );
  135. VOID updateEditItemData( HWND hWnd );
  136. VOID updateEditItemData( HWND hWnd );
  137. SHORT startApplication( SHORT menu, SHORT item );
  138. MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  139. MRESULT EXPENTRY GenericProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  140. MRESULT EXPENTRY TimeDateProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  141. MRESULT EXPENTRY EditMenuProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  142. MRESULT EXPENTRY AddAMenuProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  143. MRESULT EXPENTRY EditItemProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  144. MRESULT EXPENTRY EditItemDataProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  145. MRESULT EXPENTRY AddAnItemProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  146. MRESULT EXPENTRY menuHandler(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  147. MRESULT EXPENTRY EnterParamProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  148. MRESULT EXPENTRY backgroundProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  149.  
  150. extern "C" {
  151.     #define INCL_REXXSAA
  152.     #include "rexxsaa.h"
  153.     RexxStart rexxStart;
  154.     }
  155.  
  156.  
  157. ////////////////////////////////////////////////////////////////////////////////
  158. // define global variables
  159. ////////////////////////////////////////////////////////////////////////////////
  160. HAB      hab;
  161. HMQ      hmq;
  162. PID      TaskId[MAXTASKS];
  163. PFNWP    menuMessageHandler;
  164. FILEDLG  fileDlgInfo;
  165. MENUITEM menuData[MAXMENUS];
  166. LONG     ScreenSizeX = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN) + 2;
  167. LONG     ScreenSizeY = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  168. LONG     MenuHeight  = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU) + 2;
  169. ULONG    timerNumber;
  170. USHORT   ProgType[MAXMENUS][MAXITEMS];
  171. USHORT   oldProgType;
  172. USHORT   timeOption = TIMEANDDATE;
  173. USHORT   MenuSelection;
  174. HWND     hwndClient;
  175. HWND     hwndFrame;
  176. HWND     hwndMenu;
  177. HWND     TaskHandle[MAXTASKS];
  178. HWND     popUpMenu;
  179. BOOL     UpdateMenu[MAXMENUS];
  180. BOOL     FileBarMenuOn = TRUE;
  181. BOOL     BarPosition = AT_TOP;
  182. BOOL     timeSync;
  183. BOOL     checkBeforeDelete = TRUE;
  184. BOOL     showBackground = FALSE;
  185. BOOL     isBackgroundDisplayed = FALSE;
  186. CHAR     MenuName[MAXMENUS][MAXMENUNAMELENGTH];
  187. CHAR     ItemName[MAXMENUS][MAXITEMS][MAXITEMNAMELENGTH];
  188. CHAR     parameterTitle[MAXITEMNAMELENGTH];
  189. CHAR     ActionToDo[MAXMENUS][MAXITEMS][MAXACTIONSTRINGLENGTH];
  190. CHAR     CmdLnArgs[MAXMENUS][MAXITEMS][MAXARGSTRINGLENGTH];
  191. CHAR     Directory[MAXMENUS][MAXITEMS][MAXACTIONSTRINGLENGTH];
  192. CHAR     variableText[MAXARGSTRINGLENGTH-2];
  193. CHAR     oldItemName[MAXITEMNAMELENGTH];
  194. CHAR     oldDirectory[MAXACTIONSTRINGLENGTH];
  195. CHAR     oldAction[MAXACTIONSTRINGLENGTH];
  196. CHAR     oldCmdLn[MAXARGSTRINGLENGTH];
  197. CHAR     tmpBuffer[80];
  198. CHAR     backgroundBitmap[MAXACTIONSTRINGLENGTH];
  199. PCHAR    ParameterTextPtr;
  200. BYTE     backgroundAttr = 3 + TILED;
  201. BYTE     NumMenus;
  202. BYTE     NumItems[MAXMENUS];
  203. USHORT   ItemSelection;
  204. USHORT   taskItemSelected;
  205.  
  206. ////////////////////////////////////////////////////////////////////////////////
  207. // main function - application entry point
  208. ////////////////////////////////////////////////////////////////////////////////
  209. main( int argc, char* argv[] )
  210. {
  211.     hab = WinInitialize(0);                   // handle: anchor block
  212.     hmq = WinCreateMsgQueue(hab, 0);          // handle: message queue
  213.     CHAR ClassName[] = "FileBar";             // store a name for our class
  214.     MENUITEM menuItem;                        // used to modify menu data
  215.  
  216.     //--------------------------------------------------------------------------
  217.     // register the window class
  218.     //--------------------------------------------------------------------------
  219.  
  220.     WinRegisterClass(hab,
  221.                      ClassName,      // name of class being registered
  222.                      ClientWndProc,  // window procedure for class
  223.                      0,              // class style
  224.                      0);             // extra memory to reserve
  225.  
  226.     //--------------------------------------------------------------------------
  227.     // create a window with a menu bar added on.  Note that the menu bar could
  228.     // be defined in the WinCreateStdWindow call (set the resource id equal= to
  229.     // MENUBAR) but is not since I need a handle to the menu (so I can later
  230.     // modify the menu).  Thus, WinLoadMenu is used following WinCreateStdWindow
  231.     //--------------------------------------------------------------------------
  232.     ULONG FrameFlags = FCF_AUTOICON|FCF_TASKLIST|FCF_BORDER;
  233.     hwndFrame = WinCreateStdWindow(HWND_DESKTOP,       // parent
  234.                                         WS_VISIBLE,    // style
  235.                                         &FrameFlags,   // control data
  236.                                         ClassName,     // client name
  237.                                         "FileBar",     // title bar text
  238.                                         0,             // client style
  239.                                         0,             // resource handle
  240.                                         0,             // resource id
  241.                                         &hwndClient);  // client pointer
  242.     hwndMenu = WinLoadMenu( hwndFrame, (HMODULE)0, MENUBAR );
  243.  
  244.     //--------------------------------------------------------------------------
  245.     // move and size application to span entire top of desktop
  246.     //--------------------------------------------------------------------------
  247.     MakeHourglassPointer ();                  // switch to hourglass cursor
  248.                                               // during initialization
  249.     WinSetWindowPos( hwndFrame, (HWND)0, 0, (ScreenSizeY-MenuHeight),
  250.                      ScreenSizeX, MenuHeight, SWP_MOVE|SWP_SIZE);
  251.  
  252.     //--------------------------------------------------------------------------
  253.     // perform basic initialization
  254.     //--------------------------------------------------------------------------
  255.     NumMenus = 0;
  256.     MenuSelection = 100;
  257.  
  258.     for ( short i = 0; i < MAXMENUS; i++ )
  259.         for (short j = 0; j < MAXITEMS; j++)
  260.             ActionToDo[i][j][1] = '\0';
  261.  
  262.     for ( short k = 0; k < MAXMENUS; k++ ) {
  263.         WinSendMsg( hwndMenu, MM_QUERYITEM, MPFROM2SHORT(100*(k+1),TRUE),MPFROMP(&menuData[k]));
  264.         menuItem = menuData[k];
  265.         menuItem.afStyle = MIS_STATIC;
  266.         menuItem.afAttribute = MIA_DISABLED;
  267.         menuItem.hwndSubMenu = (HWND)0;
  268.         WinSendMsg( hwndMenu, MM_SETITEM, MPFROM2SHORT(100*(k+1),TRUE),MPFROMP(&menuItem));
  269.         WinSetMenuItemText( hwndMenu, 100*(k+1), "");
  270.         UpdateMenu[ k ] = FALSE;
  271.         NumItems[ k ] = 0;
  272.         }
  273.  
  274.     memset( &fileDlgInfo, 0, sizeof(FILEDLG));
  275.     fileDlgInfo.cbSize = sizeof(fileDlgInfo);
  276.  
  277.     menuMessageHandler = WinSubclassWindow( hwndMenu, menuHandler );
  278.  
  279.     //--------------------------------------------------------------------------
  280.     // change to directory that application executable is started from
  281.     //--------------------------------------------------------------------------
  282.     if (argc > 0) {
  283.         char temp[CCHMAXPATH];
  284.         short i;
  285.  
  286.         strcpy(temp, argv[0]);
  287.         if (temp[1]==':')
  288.             DosSetDefaultDisk( (ULONG)(toupper(temp[0])-'A' + 1) );
  289.  
  290.         i = strlen(temp);
  291.         while ((temp[i]!='\\') && (i>0))
  292.            i--;
  293.  
  294.         if (i) {
  295.             temp[i]='\0';
  296.             if (DosSetCurrentDir( temp )!=0) {
  297.                 char mesg[]="Could not switch to the directory holding the application";
  298.                 WinMessageBox( HWND_DESKTOP, hwndFrame, mesg, temp, 0,
  299.                                MB_MOVEABLE|MB_ERROR|MB_OK);
  300.                 }
  301.             }
  302.         strcpy( backgroundBitmap, temp );
  303.         strcat( backgroundBitmap, BITMAPNAME );
  304.         }
  305.  
  306.  
  307.     //--------------------------------------------------------------------------
  308.     // read in the user option file and set up the menu bar appropriately
  309.     // check the user time/date option and put it on the menu bar
  310.     // reset our timer in case they want the current time displayed
  311.     //--------------------------------------------------------------------------
  312.     readOptionFile();                         // read in option file
  313.     displayTimeDate();                        // put time/date in menubar
  314.     restartTimer();                           // resync our clock
  315.     displayBackground();                      // restore user background bitmap
  316.     MakeArrowPointer ();                      // switch back to arrow pointer,
  317.                                               // we're done with initialization
  318.  
  319.     WinSetParent( hwndFrame, HWND_DESKTOP, FALSE );
  320.     WinSetFocus( HWND_DESKTOP, hwndFrame );
  321.  
  322.     //--------------------------------------------------------------------------
  323.     // create a message queue and then as long as there are messages to get,
  324.     // get them and dispatch them to our message handlers
  325.     //--------------------------------------------------------------------------
  326.     {
  327.         QMSG qmsg;                             // create a message queue
  328.  
  329.         while( WinGetMsg( hab, &qmsg, (HWND)0, 0, 0 ) !=FALSE )
  330.             WinDispatchMsg( hab, &qmsg );
  331.     }
  332.  
  333.     //--------------------------------------------------------------------------
  334.     // our application is done.  Destroy timer, the window and the message queue
  335.     // call the system to destroy our anchor block and do final clean up work
  336.     //--------------------------------------------------------------------------
  337.     if (timerNumber != 0)
  338.         WinStopTimer( hab, hwndClient, timerNumber );
  339.     WinDestroyWindow(hwndFrame);
  340.     WinDestroyMsgQueue(hmq);
  341.     WinTerminate(hab);
  342.  
  343.     return 0;
  344. }
  345.  
  346.  
  347. ////////////////////////////////////////////////////////////////////////////////
  348. // a new font has been selected for our menu, resize and redraw the menubar
  349. ////////////////////////////////////////////////////////////////////////////////
  350. VOID resizeMenu()
  351. {
  352.     HPS hps;
  353.     FONTMETRICS fm;
  354.  
  355.     hps = WinGetPS( hwndMenu );
  356.     GpiQueryFontMetrics(hps, sizeof(FONTMETRICS), &fm);
  357.     MenuHeight = fm.lLowerCaseDescent + fm.lMaxAscender + 4;
  358.     if (MenuHeight < (fm.lLowerCaseDescent + fm.lLowerCaseAscent + 2))
  359.         MenuHeight = fm.lLowerCaseDescent + fm.lLowerCaseAscent + 2;
  360.     if (MenuHeight < (WinQuerySysValue(HWND_DESKTOP, SV_CYMENU) + 2))
  361.         MenuHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU) + 2;
  362.     WinReleasePS( hps );
  363.  
  364.     if (BarPosition==AT_BOTTOM)
  365.         WinSetWindowPos( hwndFrame, (HWND)0, 0, 0,
  366.                          ScreenSizeX, MenuHeight, SWP_MOVE|SWP_SIZE);
  367.     else
  368.         WinSetWindowPos( hwndFrame, (HWND)0, 0, (ScreenSizeY-MenuHeight),
  369.                          ScreenSizeX, MenuHeight, SWP_MOVE|SWP_SIZE);
  370. }
  371.  
  372.  
  373. ////////////////////////////////////////////////////////////////////////////////
  374. // subclassed menu handler for main application window
  375. ////////////////////////////////////////////////////////////////////////////////
  376. MRESULT EXPENTRY menuHandler(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  377. {
  378.     switch (msg) {
  379.         // if a menu has been highlighted, save which one it is so that we know
  380.         // which task to affect if something is chosen off cascading menu
  381.         case WM_MENUSELECT:
  382.         {
  383.             if ((SHORT1FROMMP(mp1)>TASKLIST_MENU) && (SHORT1FROMMP(mp1)<99)) {
  384.                 taskItemSelected = SHORT1FROMMP(mp1);
  385.                 }
  386.             return menuMessageHandler(hwnd, msg, mp1, mp2);
  387.         }
  388.         // resize menubar if a font was just dropped on us
  389.         case WM_PRESPARAMCHANGED:
  390.         {
  391.             if ( (ULONG)mp1 == PP_FONTNAMESIZE)
  392.                 resizeMenu();
  393.             return menuMessageHandler(hwnd, msg, mp1, mp2);
  394.         }
  395.         default:
  396.             return menuMessageHandler(hwnd, msg, mp1, mp2);
  397.         }
  398. }
  399.  
  400. ////////////////////////////////////////////////////////////////////////////////
  401. // This is the message processing facility for the main application thread
  402. ////////////////////////////////////////////////////////////////////////////////
  403. MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  404. {
  405.     switch (msg) {
  406.         //----------------------------------------------------------------------
  407.         // if the application is terminating, write user settings to a file
  408.         //----------------------------------------------------------------------
  409.         case WM_CLOSE:
  410.         case WM_SAVEAPPLICATION:
  411.         case WM_QUIT: {
  412.             writeOptionFile();
  413.             return WinDefWindowProc(hwnd, msg, mp1, mp2);
  414.             }
  415.         //----------------------------------------------------------------------
  416.         // the application has been designed such that a WM_TIMER is sent by the
  417.         // system every minute (so that we can update our time on the menubar
  418.         // if necessary)
  419.         //----------------------------------------------------------------------
  420.         case WM_TIMER: {
  421.             if (!timeSync) {
  422.                 WinStopTimer( hab, hwndClient, timerNumber );
  423.                 timerNumber = WinStartTimer( hab, hwndClient, TIMERID, 60000);
  424.                 timeSync = TRUE;
  425.                 }
  426.             displayTimeDate();
  427.             return WinDefWindowProc(hwnd, msg, mp1, mp2);
  428.             }
  429.         //----------------------------------------------------------------------
  430.         // a WM_INITMENU message is sent just prior to any pulldown menu being
  431.         // displayed.  This gives us a chance to change its contents before it
  432.         // is displayed.
  433.         //----------------------------------------------------------------------
  434.         case WM_INITMENU: {
  435.             SHORT menuId = SHORT1FROMMP(mp1);
  436.             //------------------------------------------------------------------
  437.             // if the FileBar menu is being readied for display, make sure the
  438.             // move-bar top/bottom item reads appropriately!
  439.             //------------------------------------------------------------------
  440.             if (menuId == FILEBAR_MENU) {
  441.                 if (BarPosition == AT_TOP )
  442.                     WinSetMenuItemText( HWNDFROMMP( mp2 ), FILEBAR_MOVEBAR,
  443.                                         "~Move to Bottom");
  444.                 else
  445.                     WinSetMenuItemText( HWNDFROMMP( mp2 ), FILEBAR_MOVEBAR,
  446.                                         "~Move to Top");
  447.                 WinCheckMenuItem( hwndMenu, FILEBAR_DISPLAYBACKGROUND, showBackground);
  448.                 WinCheckMenuItem( hwndMenu, FILEBAR_FILEBARMENU, (TRUE - FileBarMenuOn));
  449.                 WinCheckMenuItem( hwndMenu, FILEBAR_CONFIRMCLOSE, checkBeforeDelete);
  450.                 return WinDefWindowProc(hwnd, msg, mp1, mp2);
  451.                 }
  452.             //------------------------------------------------------------------
  453.             // if the user is pulling down the task list, put a current copy of
  454.             // the task list in the menu and store copies of all the tasks id
  455.             // numbers and handles just in case they want to jump to one of them
  456.             //------------------------------------------------------------------
  457.             if (menuId == TASKLIST_MENU) {
  458.                 PCHAR text;
  459.                 MENUITEM menuItem;
  460.                 BYTE index;
  461.                 ULONG numItems;
  462.                 ULONG Buffer;
  463.                 PSWBLOCK SwitchBlockPtr;
  464.  
  465.                 // clear out the menu, get it ready for new task entries
  466.                 // for (short i = menuId+1; i < menuId+MAXITEMS+1; i++ )
  467.                 for (short i = menuId+1; i < menuId+MAXITEMS+1; i++ )
  468.                     WinSendMsg( HWNDFROMMP( mp2 ), MM_DELETEITEM,
  469.                                 MPFROM2SHORT( i, TRUE ), 0 );
  470.  
  471.                 // get the # of items and the switch list from the system
  472.                 numItems = WinQuerySwitchList( hab, NULL, 0 );
  473.                 Buffer = (numItems * sizeof(SWENTRY)) + sizeof(HSWITCH);
  474.                 PVOID my = new BYTE[Buffer];
  475.                 WinQuerySwitchList( hab, (SWBLOCK*)my, Buffer );
  476.  
  477.                 // insert each task as an entry under the task list menu
  478.                 SwitchBlockPtr = (PSWBLOCK)(my);
  479.                 menuItem.iPosition = 0;
  480.                 menuItem.afStyle = MIS_MULTMENU|MIS_SINGLE;
  481.                 menuItem.afAttribute = 0;
  482.                 menuItem.hItem = 0;
  483.                 menuItem.id = TASKLIST_MENU;
  484.                 WinSendMsg(menuItem.hwndSubMenu , MM_SETDEFAULTITEMID, MPFROMSHORT(TASK_SWITCHTO), NULL);
  485.  
  486.                 //for (short j = 1; j < numItems-1; j++ ) {
  487.                 for (short j = 0; j < numItems; j++ ) {
  488.                     menuItem.id++;
  489.                     if ((SwitchBlockPtr->aswentry[j].swctl.uchVisibility != SWL_GRAYED) &&
  490.                         (strcmp(SwitchBlockPtr->aswentry[j].swctl.szSwtitle,"Workplace Shell")) &&
  491.                         (SwitchBlockPtr->aswentry[j].swctl.uchVisibility != SWL_INVISIBLE) &&
  492.                         (SwitchBlockPtr->aswentry[j].swctl.hwnd != hwndFrame)) {
  493.                         menuItem.hwndSubMenu = WinLoadMenu(hwndMenu, 0, TASKMENUCLOSE);
  494.  
  495.                         // remove ctrl characters from task list
  496.                         index = 0;
  497.                         text = SwitchBlockPtr->aswentry[j].swctl.szSwtitle;
  498.                         while (text[++index]!='\0')
  499.                             if (text[index]<' ')
  500.                                 text[index]=' ';
  501.  
  502.                         WinSendMsg( HWNDFROMMP(mp2), MM_INSERTITEM,
  503.                                    (MENUITEM*)&menuItem,
  504.                                   &(SwitchBlockPtr->aswentry[j].swctl.szSwtitle) );
  505.  
  506.                         TaskId[j] = SwitchBlockPtr->aswentry[j].swctl.idProcess;
  507.                         TaskHandle[j] = SwitchBlockPtr->aswentry[j].swctl.hwnd;
  508.                         WinSendMsg(menuItem.hwndSubMenu, MM_SETDEFAULTITEMID, MPFROMSHORT(TASK_SWITCHTO), NULL);
  509.                         WinSetWindowBits(menuItem.hwndSubMenu , QWL_STYLE, MS_CONDITIONALCASCADE, MS_CONDITIONALCASCADE);
  510.                         }
  511.                     }
  512.                 delete( my );
  513.                 return WinDefWindowProc(hwnd, msg, mp1, mp2);
  514.                 }
  515.             //------------------------------------------------------------------
  516.             // one of the user menus is being initialized; if it has been marked
  517.             // as needing to be updated, fill the menu with the current items
  518.             // the user has set up
  519.             //------------------------------------------------------------------
  520.             if (menuId >= 100) {
  521.                 int MenuToUpdate = menuId / 100 - 1;
  522.  
  523.                 if ( UpdateMenu[ MenuToUpdate ] ) {
  524.                     UpdateMenu[ MenuToUpdate ] = FALSE;
  525.                         {
  526.                         MENUITEM menuItem;
  527.  
  528.                         for (short i = menuId+1; i < menuId+MAXITEMS+1; i++ )
  529.                             WinSendMsg( HWNDFROMMP( mp2 ), MM_DELETEITEM,
  530.                                         MPFROM2SHORT( i, TRUE ), 0 );
  531.                         menuItem.iPosition = MIT_END;
  532.                         menuItem.afStyle = MIS_TEXT;
  533.                         menuItem.afAttribute = 0;
  534.                         menuItem.hItem = 0;
  535.                         menuItem.hwndSubMenu = (HWND)0;
  536.                         menuItem.id = menuId;
  537.                         for (short j = 0; j < NumItems[ MenuToUpdate ]; j++ ) {
  538.                             menuItem.id++;
  539.                             if (ItemName[MenuToUpdate][j][0] != '\0')
  540.                                 WinSendMsg( HWNDFROMMP(mp2), MM_INSERTITEM,
  541.                                             (MENUITEM*)&menuItem,
  542.                                             ItemName[MenuToUpdate][j] );
  543.                             else {
  544.                                 menuItem.afStyle = MIS_SEPARATOR;
  545.                                 WinSendMsg( HWNDFROMMP(mp2), MM_INSERTITEM,
  546.                                             (MENUITEM*)&menuItem,
  547.                                             ItemName[MenuToUpdate][j] );
  548.                                 menuItem.afStyle = MIS_TEXT;
  549.                                 }
  550.                             }
  551.                         }
  552.                     }
  553.                 return WinDefWindowProc(hwnd, msg, mp1, mp2);
  554.                 }
  555.             }
  556.  
  557.         //----------------------------------------------------------------------
  558.         //----------------------------------------------------------------------
  559.         case WM_COMMAND: {
  560.             USHORT command = SHORT1FROMMP(mp1);
  561.  
  562.             //------------------------------------------------------------------
  563.             // expand or shrink FileBar system menus
  564.             //------------------------------------------------------------------
  565.             if ( command == FILEBAR_FILEBARMENU) {
  566.                 CHAR menuOn[] = FILEBARMENUON;
  567.                 CHAR menuOff[] = FILEBARMENUOFF;
  568.                 CHAR taskOn[] = TASKMENUON;
  569.                 CHAR taskOff[] = TASKMENUOFF;
  570.  
  571.                 FileBarMenuOn = TRUE - FileBarMenuOn;
  572.                 if (FileBarMenuOn) {
  573.                     WinSetMenuItemText( hwndMenu, FILEBAR_MENU, menuOn);
  574.                     WinSetMenuItemText( hwndMenu, TASKLIST_MENU, taskOn);
  575.                     }
  576.                 else {
  577.                     WinSetMenuItemText( hwndMenu, FILEBAR_MENU, menuOff);
  578.                     WinSetMenuItemText( hwndMenu, TASKLIST_MENU, taskOff);
  579.                     }
  580.                 return 0;
  581.                 }
  582.             //------------------------------------------------------------------
  583.             // show the display background dialog box
  584.             //------------------------------------------------------------------
  585.             if ( command == FILEBAR_DISPLAYBACKGROUND) {
  586.                 WinDlgBox(HWND_DESKTOP,
  587.                           hwnd,
  588.                           (PFNWP)backgroundProc,
  589.                           0,
  590.                           BACKGROUNDWIN,
  591.                           (PVOID)NULL);
  592.                 displayBackground();
  593.                 return 0;
  594.                 }
  595.             //------------------------------------------------------------------
  596.             // close the chosen task
  597.             //------------------------------------------------------------------
  598.             if ( command == FILEBAR_CONFIRMCLOSE) {
  599.                 checkBeforeDelete = TRUE - checkBeforeDelete;
  600.                 return 0;
  601.                 }
  602.             //------------------------------------------------------------------
  603.             // close the chosen task
  604.             //------------------------------------------------------------------
  605.             if ( command == TASK_CLOSE) {
  606.                 ULONG numItems;
  607.                 ULONG Buffer;
  608.                 PSWBLOCK SwitchBlockPtr;
  609.                 PID killedTaskId;
  610.                 HWND killedTaskHandle;
  611.  
  612.                 if (checkBeforeDelete) {
  613.                     CHAR title[] = "FileBar - Close Task";
  614.                     CHAR text[] = "Closing may result in the destruction of unsaved data.  Are you sure you want to close this task?";
  615.                     if (WinMessageBox( HWND_DESKTOP, hwnd, text, title, 0,
  616.                                        MB_MOVEABLE|MB_ICONQUESTION|MB_YESNO) == MBID_NO)
  617.                         return 0;
  618.                     }
  619.  
  620.                 killedTaskId = TaskId[taskItemSelected - TASKLIST_MENU - 1];
  621.                 killedTaskHandle = TaskHandle[taskItemSelected - TASKLIST_MENU - 1];
  622.                 WinSendMsg( killedTaskHandle, WM_CLOSE, 0, 0 );
  623.  
  624.                 // get the # of items and the switch list from the system
  625.                 numItems = WinQuerySwitchList( hab, NULL, 0 );
  626.                 Buffer = (numItems * sizeof(SWENTRY)) + sizeof(HSWITCH);
  627.                 PVOID my = new BYTE[Buffer];
  628.                 WinQuerySwitchList( hab, (SWBLOCK*)my, Buffer );
  629.                 SwitchBlockPtr = (PSWBLOCK)(my);
  630.  
  631.                 // if task did not close willingly, kill its process!
  632.                 for (short j = 0; j < numItems; j++ )
  633.                     if (SwitchBlockPtr->aswentry[j].swctl.hwnd == killedTaskHandle)
  634.                         DosKillProcess( DKP_PROCESS, killedTaskId );
  635.                 delete( my );
  636.  
  637.                 return 0;
  638.                 }
  639.             //------------------------------------------------------------------
  640.             // show the chosen task
  641.             //------------------------------------------------------------------
  642.             if ( command == TASK_SHOW) {
  643.                 WinSetWindowPos( TaskHandle[taskItemSelected - TASKLIST_MENU- 1],
  644.                                  (HWND)0, 0, 0, 0, 0, SWP_SHOW);
  645.                 return 0;
  646.                 }
  647.             //------------------------------------------------------------------
  648.             // hide the chosen task
  649.             //------------------------------------------------------------------
  650.             if ( command == TASK_HIDE) {
  651.                 WinSetWindowPos( TaskHandle[taskItemSelected - TASKLIST_MENU- 1],
  652.                                  (HWND)0, 0, 0, 0, 0, SWP_HIDE);
  653.                 return 0;
  654.                 }
  655.             //------------------------------------------------------------------
  656.             // maximize the chosen task
  657.             //------------------------------------------------------------------
  658.             if ( command == TASK_MAX) {
  659.                 HSWITCH switchHandle = WinQuerySwitchHandle( TaskHandle[taskItemSelected - TASKLIST_MENU- 1],
  660.                                                              TaskId[taskItemSelected - TASKLIST_MENU- 1]);
  661.  
  662.                 WinShowWindow( TaskHandle[taskItemSelected - TASKLIST_MENU- 1], TRUE );
  663.                 WinSetWindowPos( TaskHandle[taskItemSelected - TASKLIST_MENU- 1],
  664.                                  (HWND)0, 0, 0, 0, 0, SWP_MAXIMIZE);
  665.                 WinSwitchToProgram( switchHandle );
  666.                 return 0;
  667.                 }
  668.             //------------------------------------------------------------------
  669.             // minimize the chosen task
  670.             //------------------------------------------------------------------
  671.             if ( command == TASK_MIN) {
  672.                 WinShowWindow( TaskHandle[taskItemSelected - TASKLIST_MENU- 1], TRUE );
  673.                 WinSetWindowPos( TaskHandle[taskItemSelected - TASKLIST_MENU- 1],
  674.                                  (HWND)0, 0, 0, 0, 0, SWP_MINIMIZE);
  675.                 return 0;
  676.                 }
  677.             //------------------------------------------------------------------
  678.             // the user has selected something from the tasklist menu, switch
  679.             // control to that task, if possible
  680.             //------------------------------------------------------------------
  681.             if ( command == TASK_SWITCHTO) {
  682.                 HSWITCH switchHandle;
  683.  
  684.                 switchHandle = WinQuerySwitchHandle( TaskHandle[taskItemSelected - TASKLIST_MENU-1],
  685.                                                      TaskId[taskItemSelected - TASKLIST_MENU-1]);
  686.  
  687.                 if (switchHandle == 0) {
  688.                     CHAR title[] = "FileBar Task Switch Error";
  689.                     CHAR text[] = "ERROR!  Could not locate task!  The task may have already terminated.";
  690.                     WinMessageBox( HWND_DESKTOP, hwnd, text, title, 0,
  691.                                    MB_MOVEABLE|MB_ERROR|MB_OK);
  692.                     return 0;
  693.                     }
  694.                 if (WinSwitchToProgram( switchHandle ) != 0) {
  695.                     CHAR title[] = "FileBar Task Switch Error";
  696.                     CHAR text[] = "ERROR!  Could not switch to task!";
  697.                     WinMessageBox( HWND_DESKTOP, hwnd, text, title, 0,
  698.                                    MB_MOVEABLE|MB_ERROR|MB_OK);
  699.                     }
  700.                 WinShowWindow( TaskHandle[taskItemSelected - TASKLIST_MENU], TRUE );
  701.                 return 0;
  702.                 }
  703.             //------------------------------------------------------------------
  704.             //  user wants to shutdown system
  705.             //------------------------------------------------------------------
  706.             if ( command == 99 ) {
  707.                 char title[] = "FileBar - Shutdown System";
  708.                 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.";
  709.                 if (WinMessageBox( HWND_DESKTOP, hwndFrame, text, title, 0,
  710.                                    MB_DEFBUTTON2|MB_MOVEABLE|MB_ICONEXCLAMATION|MB_OKCANCEL) == MBID_CANCEL)
  711.                     return 0;
  712.  
  713.                 writeOptionFile();
  714.                 WinSetWindowPos( hwndFrame, (HWND)0, 0, 0, 0, 0, SWP_HIDE);
  715.                 //WinBroadcastMsg( HWND_DESKTOP, WM_QUIT, 0, 0 );
  716.                 WinPostMsg( hwndClient, WM_QUIT, 0, 0 );
  717.                 WinShutdownSystem( WinQueryAnchorBlock( HWND_DESKTOP ), hmq );
  718.                 }
  719.             //------------------------------------------------------------------
  720.             // the user has selected an option off the user menus.  Activate the
  721.             // item they have selected
  722.             //------------------------------------------------------------------
  723.             if (( command > 99 ) && (command % 100)) {
  724.                 INT MenuToUpdate = command / 100 - 1;
  725.                 INT ItemToUpdate = command % 100 - 1;
  726.  
  727.                 if ((ItemToUpdate>=MAXITEMS) || (MenuToUpdate>=MAXMENUS))
  728.                     return 0;
  729.  
  730.                 if ((MenuToUpdate >= 0) && (MenuToUpdate<MAXMENUS))
  731.                     //errorCode = startApplication( MenuToUpdate, ItemToUpdate );
  732.                     startApplication( MenuToUpdate, ItemToUpdate );
  733.  
  734. /*
  735.                 if (errorCode != 0) {
  736.                     CHAR title[34];
  737.                     char message[500];
  738.                     ULONG MessageLength;
  739.  
  740.                     memset( &message, 0, sizeof(message));
  741.                     DosGetMessage(NULL,0,message,sizeof(message),errorCode,"OSO001.MSG",&MessageLength);
  742.  
  743.                     sprintf(title, "FileBar (Menu %d, Item %d) - Application Launch Error", MenuToUpdate, ItemToUpdate);
  744.                     WinMessageBox( HWND_DESKTOP, hwnd, message, title, 0,
  745.                                    MB_MOVEABLE|MB_ERROR|MB_OK);
  746.                     }
  747. */
  748.  
  749.                 return 0;
  750.                 }
  751.             //------------------------------------------------------------------
  752.             // it was not a tasklist or user item, process now as usual
  753.             //------------------------------------------------------------------
  754.             switch( command ) {
  755.                 //--------------------------------------------------------------
  756.                 // the user wants to save current options
  757.                 //--------------------------------------------------------------
  758.                 case FILEBAR_SAVEOPTIONS: {
  759.                     char title[] = "FileBar - Save Menu Configuration";
  760.                     char message[] = "The current user menu configuration has been successfully saved!";
  761.  
  762.                     writeOptionFile();
  763.                     WinMessageBox( HWND_DESKTOP, hwnd, message, title, 0,
  764.                                    MB_MOVEABLE|MB_INFORMATION|MB_OK);
  765.                     return 0;
  766.                 }
  767.                 //--------------------------------------------------------------
  768.                 // the user wants to edit the menu structure
  769.                 //--------------------------------------------------------------
  770.                 case FILEBAR_EDITMENU: {
  771.                     return (VOID*)WinDlgBox(HWND_DESKTOP,
  772.                                             hwnd,
  773.                                             (PFNWP)EditMenuProc,
  774.                                             0,
  775.                                             EDITMENU,
  776.                                             (PVOID)NULL);
  777.                     }
  778.                 //--------------------------------------------------------------
  779.                 // the user wants to select their time/date display options
  780.                 //--------------------------------------------------------------
  781.                 case FILEBAR_TIMEOPTION: {
  782.                     return (VOID*)WinDlgBox(HWND_DESKTOP,
  783.                                             hwnd,
  784.                                             (PFNWP)TimeDateProc,
  785.                                             0,
  786.                                             TIMEOPTIONS,
  787.                                             (PVOID)NULL);
  788.                     }
  789.                 //--------------------------------------------------------------
  790.                 // the user wants to get general help on filebar
  791.                 //--------------------------------------------------------------
  792.                 case FILEBAR_GENHELP: {
  793.                     return (VOID*)WinDlgBox(HWND_DESKTOP,
  794.                                             hwnd,
  795.                                             (PFNWP)GenericProc,
  796.                                             0,
  797.                                             GENERAL_HELP,
  798.                                             (PVOID)NULL);
  799.                     }
  800.                 //--------------------------------------------------------------
  801.                 // the user wants to see product information for filebar
  802.                 //--------------------------------------------------------------
  803.                 case FILEBAR_PRODINFO: {
  804.                     return (VOID*)WinDlgBox(HWND_DESKTOP,
  805.                                             hwnd,
  806.                                             (PFNWP)GenericProc,
  807.                                             0,
  808.                                             PRODUCT_INFO,
  809.                                             (PVOID)NULL);
  810.                     }
  811.                 //--------------------------------------------------------------
  812.                 // the user wishes to move the filebar from its current position
  813.                 // to either to the top or bottom of the desktop
  814.                 //--------------------------------------------------------------
  815.                 case FILEBAR_MOVEBAR: {
  816.                     if (BarPosition==AT_TOP) {
  817.                         BarPosition = AT_BOTTOM;
  818.                         WinSetWindowPos( hwndFrame, (HWND)0, 0, 0,
  819.                                          ScreenSizeX, MenuHeight, SWP_MOVE);
  820.                         }
  821.                     else {
  822.                         BarPosition = AT_TOP;
  823.                         WinSetWindowPos( hwndFrame, (HWND)0, 0, (ScreenSizeY-MenuHeight),
  824.                                          ScreenSizeX, MenuHeight, SWP_MOVE);
  825.                         }
  826.                     return 0;
  827.                     }
  828.                 //--------------------------------------------------------------
  829.                 // the user wishes to exit the filebar application
  830.                 //--------------------------------------------------------------
  831.                 case FILEBAR_EXIT: {
  832.                     return (VOID*)WinPostMsg( hwnd, WM_QUIT, 0, 0);
  833.                     }
  834.                 //--------------------------------------------------------------
  835.                 // something besides our menus sent a message, pass the message
  836.                 // to the system for default processing
  837.                 //--------------------------------------------------------------
  838.                 default:
  839.                     return WinDefWindowProc(hwnd, msg, mp1, mp2);  // default processing
  840.                 }
  841.             }
  842.         //----------------------------------------------------------------------
  843.         // we were sent a message that we don't care about, pass it onto system
  844.         // for default processing
  845.         //----------------------------------------------------------------------
  846.         default:
  847.             return WinDefWindowProc(hwnd, msg, mp1, mp2);  // default processing
  848.         };
  849. }
  850.  
  851.  
  852. ////////////////////////////////////////////////////////////////////////////////
  853. // readOptionFile - will read the option file (generated by the app) from disk,
  854. // if it exists and will restore the application to the state in which it was
  855. // last left
  856. ////////////////////////////////////////////////////////////////////////////////
  857. void readOptionFile( void )
  858. {
  859.     int currentMenu = 100;
  860.     FILE *optionFile;
  861.  
  862.     //--------------------------------------------------------------------------
  863.     // if the option file exists on disk, read it in and restore old menu,
  864.     // otherwise we will return and rely on default values
  865.     //--------------------------------------------------------------------------
  866.     if ((optionFile = fopen(OPTIONFILE,"rt")) != NULL) {
  867.         RGB2 rgb = {0,0,0,0};
  868.         ULONG color;
  869.         CHAR temp[200];
  870.  
  871.         ScreenSizeX = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN) + 2;
  872.         ScreenSizeY = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  873.         MenuHeight  = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU) + 2;
  874.  
  875.         fscanf(optionFile, "%d %d", &timeOption, &BarPosition);
  876.         // restore user's desired bar position
  877.         if (BarPosition==AT_BOTTOM) {
  878.             WinSetWindowPos( hwndFrame, (HWND)0, 0, 0,
  879.                              ScreenSizeX, MenuHeight, SWP_MOVE|SWP_SIZE);
  880.             }
  881.         else {
  882.             WinSetWindowPos( hwndFrame, (HWND)0, 0, (ScreenSizeY-MenuHeight),
  883.                              ScreenSizeX, MenuHeight, SWP_MOVE|SWP_SIZE);
  884.             }
  885.  
  886.         // restore user's menus and menu choices
  887.         fscanf(optionFile, "%d", &NumMenus);
  888.         for (short i = 0; i < NumMenus; i++ ) {
  889.             UpdateMenu[i] = TRUE;
  890.             readString( optionFile, (CHAR*)&MenuName[i] );
  891.  
  892.             WinSendMsg( hwndMenu, MM_SETITEM, MPFROM2SHORT(100*i+100,TRUE),MPFROMP(&menuData[i]));
  893.             WinSetMenuItemText( hwndMenu, 100*i+100, &MenuName[i]);
  894.  
  895.             fscanf(optionFile, "%d", &NumItems[i]);
  896.             for (short j = 0; j < NumItems[i]; j++) {
  897.                 readString( optionFile, (CHAR*)&ItemName[i][j] );
  898.                 readString( optionFile, (CHAR*)&ActionToDo[i][j] );
  899.                 readString( optionFile, (CHAR*)&CmdLnArgs[i][j] );
  900.                 readString( optionFile, (CHAR*)&Directory[i][j] );
  901.                 fscanf( optionFile, "%d", &ProgType[i][j] );
  902.                 }
  903.             currentMenu = currentMenu + 100;
  904.             }
  905.  
  906.         readString( optionFile, (CHAR*)&temp );
  907.         if (temp[0]!='\0') {
  908.             WinSetPresParam( hwndMenu, PP_FONTNAMESIZE, sizeof(temp), &temp );
  909.             resizeMenu();
  910.             }
  911.         fscanf( optionFile, "%d", &checkBeforeDelete );
  912.         if (fscanf( optionFile, "%d", &FileBarMenuOn )!=EOF) {
  913.             CHAR menuOn[] = FILEBARMENUON;
  914.             CHAR menuOff[] = FILEBARMENUOFF;
  915.             CHAR taskOn[] = TASKMENUON;
  916.             CHAR taskOff[] = TASKMENUOFF;
  917.  
  918.             if (FileBarMenuOn) {
  919.                 WinSetMenuItemText( hwndMenu, FILEBAR_MENU, menuOn);
  920.                 WinSetMenuItemText( hwndMenu, TASKLIST_MENU, taskOn);
  921.                 }
  922.             else {
  923.                 WinSetMenuItemText( hwndMenu, FILEBAR_MENU, menuOff);
  924.                 WinSetMenuItemText( hwndMenu, TASKLIST_MENU, taskOff);
  925.                 }
  926.             }
  927.  
  928.         if (fscanf( optionFile, "%d", &showBackground )!=EOF) {
  929.             fscanf( optionFile, "%d", &backgroundAttr );
  930.             readString( optionFile, (CHAR*)&backgroundBitmap );
  931.             }
  932.  
  933.         for (i=PP_FOREGROUNDCOLOR; i<=PP_BORDERCOLOR; i=i+2)
  934.             if (fscanf(optionFile, "%ld", &color )!=EOF)
  935.                 if ( color != NOCOLOR) {
  936.                     rgb.bRed = (BYTE)(color/65536);
  937.                     color = color%65536;
  938.                     rgb.bGreen = (BYTE)(color/256);
  939.                     color = color%256;
  940.                     rgb.bBlue = (BYTE)(color);
  941.                     WinSetPresParam( hwndMenu, i, sizeof(rgb), &rgb);
  942.                     }
  943.  
  944.         for (i=PP_ACTIVECOLOR; i<=PP_INACTIVETEXTBGNDCOLOR; i=i+2)
  945.             if (fscanf(optionFile, "%ld", &color )!=EOF)
  946.                 if ( color != NOCOLOR) {
  947.                     rgb.bRed = (BYTE)(color/65536);
  948.                     color = color%65536;
  949.                     rgb.bGreen = (BYTE)(color/256);
  950.                     color = color%256;
  951.                     rgb.bBlue = (BYTE)(color);
  952.                     WinSetPresParam( hwndMenu, i, sizeof(rgb), &rgb);
  953.                     }
  954.  
  955.         if (fscanf(optionFile, "%ld", &color )!=EOF)
  956.             if ( color != NOCOLOR) {
  957.                 rgb.bRed = (BYTE)(color/65536);
  958.                 color = color%65536;
  959.                 rgb.bGreen = (BYTE)(color/256);
  960.                 color = color%256;
  961.                 rgb.bBlue = (BYTE)(color);
  962.                 WinSetPresParam( hwndMenu, PP_SHADOW, sizeof(rgb), &rgb);
  963.                 }
  964.  
  965.         for (i=PP_MENUFOREGROUNDCOLOR; i<=PP_MENUDISABLEDBGNDCOLOR; i=i+2)
  966.             if (fscanf(optionFile, "%ld", &color )!=EOF)
  967.                 if ( color != NOCOLOR) {
  968.                     rgb.bRed = (BYTE)(color/65536);
  969.                     color = color%65536;
  970.                     rgb.bGreen = (BYTE)(color/256);
  971.                     color = color%256;
  972.                     rgb.bBlue = (BYTE)(color);
  973.                     WinSetPresParam( hwndMenu, i, sizeof(rgb), &rgb);
  974.                     }
  975.  
  976.         fclose( optionFile );
  977.         }
  978. }
  979.  
  980.  
  981. ////////////////////////////////////////////////////////////////////////////////
  982. // writeOptionFile - will write the application state to the option file
  983. ////////////////////////////////////////////////////////////////////////////////
  984. void writeOptionFile( void )
  985. {
  986.     SHORT currentMenu = 100;
  987.     FILE *optionFile;
  988.  
  989.     //--------------------------------------------------------------------------
  990.     // if the option file exists on disk, read it in and restore old menu,
  991.     // otherwise we will return and rely on default values
  992.     //--------------------------------------------------------------------------
  993.     if ((optionFile = fopen(OPTIONFILE, "wt")) == NULL) {
  994.         // if not able to save, alert the user
  995.         CHAR title[] = "FileBar Error";
  996.         CHAR text[] = "Error writing application configuration file!  Application data was NOT saved!";
  997.         WinMessageBox( HWND_DESKTOP, hwndClient, text, title, 0,
  998.                        MB_MOVEABLE|MB_ERROR|MB_OK);
  999.         }
  1000.     else {
  1001.         char mesg[TEMPSTRING];
  1002.         ULONG length;
  1003.         RGB2 rgb;
  1004.  
  1005.         // save user's desired bar position
  1006.         fprintf(optionFile, "%d %d\n", timeOption, BarPosition);
  1007.         // save user's menus and menu choices
  1008.         fprintf(optionFile, "%d\n", NumMenus);
  1009.         for (short i = 0; i < NumMenus; i++ ) {
  1010.             writeString( optionFile, (CHAR*)&MenuName[i] );
  1011.             fprintf(optionFile, "%d\n", NumItems[i]);
  1012.             for (short j = 0; j < NumItems[i]; j++) {
  1013.                 writeString( optionFile, (CHAR*)&ItemName[i][j] );
  1014.                 writeString( optionFile, (CHAR*)&ActionToDo[i][j] );
  1015.                 writeString( optionFile, (CHAR*)&CmdLnArgs[i][j] );
  1016.                 writeString( optionFile, (CHAR*)&Directory[i][j] );
  1017.                 fprintf( optionFile, "%d\n", ProgType[i][j] );
  1018.                 }
  1019.             currentMenu = currentMenu + 100;
  1020.             }
  1021.  
  1022.         if (WinQueryPresParam( hwndMenu, PP_FONTNAMESIZE, 0, &length, sizeof(mesg), &mesg, 0)!=FALSE)
  1023.             writeString( optionFile, (CHAR*)&mesg );
  1024.         else
  1025.             fprintf( optionFile, "\"\"\n" );
  1026.         fprintf( optionFile, "%d\n%d\n%d\n%d\n", checkBeforeDelete, FileBarMenuOn, showBackground, backgroundAttr );
  1027.         writeString( optionFile, (CHAR*)&backgroundBitmap );
  1028.  
  1029.         // save menu scheme of colors
  1030.         for (i=PP_FOREGROUNDCOLOR; i<=PP_BORDERCOLOR; i=i+2) {
  1031.             if (WinQueryPresParam( hwndMenu, i, 0, 0, sizeof(rgb), &rgb, 0) != 0)
  1032.                 fprintf(optionFile, "%ld\n", (ULONG)(rgb.bRed*65536+rgb.bGreen*256+rgb.bBlue) );
  1033.             else fprintf(optionFile, "%ld\n", NOCOLOR );
  1034.             }
  1035.  
  1036.         for (i=PP_ACTIVECOLOR; i<=PP_INACTIVETEXTBGNDCOLOR; i=i+2) {
  1037.             if (WinQueryPresParam( hwndMenu, i, 0, 0, sizeof(rgb), &rgb, 0) != 0)
  1038.                 fprintf(optionFile, "%ld\n", (ULONG)(rgb.bRed*65536+rgb.bGreen*256+rgb.bBlue) );
  1039.             else fprintf(optionFile, "%ld\n", NOCOLOR );
  1040.             }
  1041.  
  1042.         if (WinQueryPresParam( hwndMenu, PP_SHADOW, 0, 0, sizeof(rgb), &rgb, 0) != 0)
  1043.             fprintf(optionFile, "%ld\n", (ULONG)(rgb.bRed*65536+rgb.bGreen*256+rgb.bBlue) );
  1044.         else fprintf(optionFile, "%ld\n", NOCOLOR );
  1045.  
  1046.         for (i=PP_MENUFOREGROUNDCOLOR; i<=PP_MENUDISABLEDBGNDCOLOR; i=i+2) {
  1047.             if (WinQueryPresParam( hwndMenu, i, 0, 0, sizeof(rgb), &rgb, 0) != 0)
  1048.                 fprintf(optionFile, "%ld\n", (ULONG)(rgb.bRed*65536+rgb.bGreen*256+rgb.bBlue) );
  1049.             else fprintf(optionFile, "%ld\n", NOCOLOR );
  1050.             }
  1051.  
  1052.         fclose( optionFile );
  1053.         }
  1054. }
  1055.  
  1056.  
  1057. ////////////////////////////////////////////////////////////////////////////////
  1058. // readString will read a sequence of characters that is bounded on both sides
  1059. // by quote (") characters (We can't use fscanf because it won't read spaces)
  1060. ////////////////////////////////////////////////////////////////////////////////
  1061. VOID readString( FILE* stream, CHAR* buffer )
  1062. {
  1063.     do {                               // search for first " character
  1064.         if (fscanf( stream, "%c", buffer)==EOF) break;
  1065.     } while ( (*buffer) !='"');
  1066.     buffer--;
  1067.     do {                               // keep putting characters into the buffer
  1068.         buffer++;                      // " character
  1069.         if (fscanf( stream, "%c", buffer)==EOF) break;
  1070.         //fscanf( stream, "%c", buffer); // until we hit the 2nd and terminating
  1071.     } while ( (*buffer) !='"');
  1072.     *buffer = '\0';                    // store a NULL to terminate the string
  1073. }
  1074.  
  1075.  
  1076. ////////////////////////////////////////////////////////////////////////////////
  1077. // Message handler for a generic information-only dialog box (help & prod info)
  1078. ////////////////////////////////////////////////////////////////////////////////
  1079. MRESULT EXPENTRY GenericProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1080. {
  1081.    switch( msg )
  1082.     {
  1083.         //----------------------------------------------------------------------
  1084.         // when the dialog is being initialized, center it on desktop
  1085.         //----------------------------------------------------------------------
  1086.         case WM_INITDLG: {
  1087.             SWP swp;
  1088.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  1089.             WinSetWindowPos( hWnd, (HWND)0,
  1090.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  1091.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  1092.                              0, 0, SWP_MOVE);
  1093.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1094.             }
  1095.         //----------------------------------------------------------------------
  1096.         // if we receive any system message, dismiss the dialog box
  1097.         //----------------------------------------------------------------------
  1098.         case WM_COMMAND:
  1099.         {
  1100.             WinDismissDlg( hWnd, TRUE );
  1101.             return 0;
  1102.         }
  1103.         //----------------------------------------------------------------------
  1104.         // if nothing further we want to intercept, pass message onto system
  1105.         //----------------------------------------------------------------------
  1106.         default:
  1107.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1108.     }
  1109. }
  1110.  
  1111.  
  1112. ////////////////////////////////////////////////////////////////////////////////
  1113. // starts or restarts a timer to signal our program when the next minute occurs
  1114. ////////////////////////////////////////////////////////////////////////////////
  1115. VOID restartTimer( VOID )
  1116. {
  1117.     if ((timeOption == TIMEONLY) || (timeOption==TIMEANDDATE) ||
  1118.         (timeOption == OTHERTIMEONLY) || (timeOption==OTHERTIMEANDDATE)) {
  1119.         // only do this if the user needs to see the current time
  1120.         struct tm *time_now;
  1121.         time_t currentTime;
  1122.  
  1123.         tzset();
  1124.         time(¤tTime);
  1125.         time_now = localtime( ¤tTime );
  1126.         timeSync = FALSE;
  1127.         timerNumber = WinStartTimer( hab, hwndClient, TIMERID, (60-(time_now->tm_sec))*1000);
  1128.         }
  1129. }
  1130.  
  1131.  
  1132. ////////////////////////////////////////////////////////////////////////////////
  1133. // displayTimeDate is used to place current date and/or time on the FileBar
  1134. ////////////////////////////////////////////////////////////////////////////////
  1135. VOID displayTimeDate( VOID )
  1136. {
  1137.     char tmp1[32];
  1138.     char tmp2[32];
  1139.     CHAR buffer[50] = { '\0' };
  1140.     struct tm *time_now;
  1141.     time_t currentTime;
  1142.  
  1143.     tzset();
  1144.     time(¤tTime);
  1145.     time_now = localtime( ¤tTime );
  1146.  
  1147.     if ((timeOption == TIMEONLY) || (timeOption == TIMEANDDATE)) {
  1148.         strftime( tmp1, sizeof(tmp1), "%I", time_now);
  1149.         strftime( tmp2, sizeof(tmp2), ":%M %p  ", time_now);
  1150.         if (tmp1[0] == '0')
  1151.             tmp1[0]=' ';
  1152.         strcat( buffer, tmp1 );
  1153.         strcat( buffer, tmp2 );
  1154.         }
  1155.     if (timeOption == TIMEANDDATE)
  1156.         strcat( buffer, " " );
  1157.     if ((timeOption == DATEONLY) || (timeOption == TIMEANDDATE)) {
  1158.         strftime( tmp1, sizeof(tmp1), "%B", time_now);
  1159.         strftime( tmp2, sizeof(tmp2), "%d, %Y  ", time_now);
  1160.  
  1161.         if (tmp2[0] == '0') {
  1162.             tmp2[0] = ' ';
  1163.             strcat( buffer, tmp1 );
  1164.             strcat( buffer, tmp2 );
  1165.             }
  1166.         else {
  1167.             strcat( buffer, tmp1 );
  1168.             strcat( buffer, " \0" );
  1169.             strcat( buffer, tmp2 );
  1170.             }
  1171.         }
  1172.     else if (timeOption == OTHERTIMEONLY)
  1173.         strftime( buffer, sizeof(buffer), "%H:%M  ", time_now);
  1174.     else if (timeOption == OTHERDATEONLY)
  1175.         strftime( buffer, sizeof(buffer), "%d %B %Y  ", time_now);
  1176.     else if (timeOption == OTHERTIMEANDDATE) {
  1177.         strftime( tmp1, sizeof(tmp1), "%H:%M ", time_now );
  1178.         strftime( tmp2, sizeof(tmp2), "%d %B %Y  ", time_now );
  1179.         if (tmp1[0] == '0')
  1180.             tmp1[0] = ' ';
  1181.         if (tmp2[0] == '0')
  1182.             tmp2[0] = ' ';
  1183.         else
  1184.             strcat( tmp1, " " );
  1185.         strcat( buffer, tmp1 );
  1186.         strcat( buffer, tmp2 );
  1187.         }
  1188.     if (buffer[0]=='0')
  1189.         buffer[0]=' ';
  1190.     WinSetMenuItemText( hwndMenu, TIMEDATE, &buffer );
  1191. }
  1192.  
  1193.  
  1194. ////////////////////////////////////////////////////////////////////////////////
  1195. // Message handler for time and date option setting dialog
  1196. ////////////////////////////////////////////////////////////////////////////////
  1197. MRESULT EXPENTRY TimeDateProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1198. {
  1199.    switch( msg )
  1200.     {
  1201.         //----------------------------------------------------------------------
  1202.         // when the dialog is being initialized, center it on desktop and check
  1203.         // the appropriate radio button for whatever setting they currently have
  1204.         //----------------------------------------------------------------------
  1205.         case WM_INITDLG: {
  1206.             SWP swp;
  1207.  
  1208.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  1209.             WinSetWindowPos( hWnd, (HWND)0,
  1210.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  1211.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  1212.                              0, 0, SWP_MOVE);
  1213.             WinSendDlgItemMsg( hWnd, timeOption, BM_SETCHECK,
  1214.                                MPFROM2SHORT( 1, 0 ), 0);
  1215.  
  1216.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1217.             }
  1218.         //----------------------------------------------------------------------
  1219.         // we received a change in control, update menubar time
  1220.         //----------------------------------------------------------------------
  1221.         case WM_CONTROL:
  1222.         {
  1223.             timeOption = NONE;
  1224.             if (WinQueryButtonCheckstate( hWnd, TIMEONLY ))
  1225.                 timeOption = TIMEONLY;
  1226.             else if (WinQueryButtonCheckstate( hWnd, DATEONLY ))
  1227.                 timeOption = DATEONLY;
  1228.             else if (WinQueryButtonCheckstate( hWnd, TIMEANDDATE ))
  1229.                 timeOption = TIMEANDDATE;
  1230.             else if (WinQueryButtonCheckstate( hWnd, OTHERTIMEONLY ))
  1231.                 timeOption = OTHERTIMEONLY;
  1232.             else if (WinQueryButtonCheckstate( hWnd, OTHERDATEONLY ))
  1233.                 timeOption = OTHERDATEONLY;
  1234.             else if (WinQueryButtonCheckstate( hWnd, OTHERTIMEANDDATE ))
  1235.                 timeOption = OTHERTIMEANDDATE;
  1236.  
  1237.             WinStopTimer( hab, hwndClient, timerNumber );
  1238.             restartTimer();
  1239.             displayTimeDate();
  1240.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1241.         }
  1242.  
  1243.         //----------------------------------------------------------------------
  1244.         // if we receive any system message, dismiss dialog and store new option
  1245.         //----------------------------------------------------------------------
  1246.         case WM_COMMAND:
  1247.         {
  1248.             timeOption = NONE;
  1249.             if (WinQueryButtonCheckstate( hWnd, TIMEONLY ))
  1250.                 timeOption = TIMEONLY;
  1251.             else if (WinQueryButtonCheckstate( hWnd, DATEONLY ))
  1252.                 timeOption = DATEONLY;
  1253.             else if (WinQueryButtonCheckstate( hWnd, TIMEANDDATE ))
  1254.                 timeOption = TIMEANDDATE;
  1255.             else if (WinQueryButtonCheckstate( hWnd, OTHERTIMEONLY ))
  1256.                 timeOption = OTHERTIMEONLY;
  1257.             else if (WinQueryButtonCheckstate( hWnd, OTHERDATEONLY ))
  1258.                 timeOption = OTHERDATEONLY;
  1259.             else if (WinQueryButtonCheckstate( hWnd, OTHERTIMEANDDATE ))
  1260.                 timeOption = OTHERTIMEANDDATE;
  1261.  
  1262.             // stop current timer (if one exists) and start a new one
  1263.             // display new time and date according to new option setting
  1264.             WinStopTimer( hab, hwndClient, timerNumber );
  1265.             restartTimer();
  1266.             displayTimeDate();
  1267.             WinDismissDlg( hWnd, TRUE );
  1268.             return 0;
  1269.         }
  1270.         //----------------------------------------------------------------------
  1271.         // if nothing further we want to intercept, pass message onto system
  1272.         //----------------------------------------------------------------------
  1273.         default:
  1274.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1275.     }
  1276. }
  1277.  
  1278.  
  1279. ////////////////////////////////////////////////////////////////////////////////
  1280. // EditMenuProc - the message handler for editing a menu dialog box
  1281. ////////////////////////////////////////////////////////////////////////////////
  1282. MRESULT EXPENTRY EditMenuProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1283. {
  1284.     switch( msg )
  1285.     {
  1286.         //----------------------------------------------------------------------
  1287.         // if double-clicked an entry, allow them to edit it
  1288.         //----------------------------------------------------------------------
  1289.         case WM_CONTROL:
  1290.         {
  1291.             if ((SHORT1FROMMP(mp1)==CURMENULIST) && (SHORT2FROMMP(mp1)==LN_ENTER))
  1292.                 return WinSendMsg( hWnd, WM_COMMAND, MPFROM2SHORT( EDITMENUBUTTON, 0 ), mp2 );
  1293.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1294.         }
  1295.         //----------------------------------------------------------------------
  1296.         // when the dialog is being initialized, center it on desktop and put
  1297.         // the current data into appropriate list boxes
  1298.         //----------------------------------------------------------------------
  1299.         case WM_INITDLG: {
  1300.             SWP swp;
  1301.  
  1302.             for (short i=0; i<NumMenus; i++)
  1303.                 WinSendDlgItemMsg( hWnd, CURMENULIST, LM_INSERTITEM,
  1304.                                    MPFROM2SHORT( LIT_END, 0 ),
  1305.                                    MenuName[i] );
  1306.             if (NumMenus > 0) {
  1307.                 WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM,
  1308.                                    MPFROM2SHORT( 0, 0 ),
  1309.                                    MPFROM2SHORT( TRUE, 0 ) );
  1310.                 }
  1311.             else {
  1312.                 WinEnableControl( hWnd, EDITMENUBUTTON, FALSE );
  1313.                 WinEnableControl( hWnd, REMOVEMENU, FALSE );
  1314.                 WinEnableControl( hWnd, MOVEMENULEFT, FALSE );
  1315.                 WinEnableControl( hWnd, MOVEMENURIGHT, FALSE );
  1316.                 }
  1317.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  1318.             WinSetWindowPos( hWnd, (HWND)0,
  1319.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  1320.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  1321.                              0, 0, SWP_MOVE);
  1322.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1323.             }
  1324.         //----------------------------------------------------------------------
  1325.         // process a command message received from the system
  1326.         //----------------------------------------------------------------------
  1327.         case WM_COMMAND: {
  1328.             USHORT command = SHORT1FROMMP(mp1);
  1329.             switch( command )
  1330.                 {
  1331.                 //--------------------------------------------------------------
  1332.                 // if they pressed OK button, dismiss dialog and return
  1333.                 //--------------------------------------------------------------
  1334.                 case DID_OK: {
  1335.                     WinDismissDlg( hWnd, TRUE );
  1336.                     return 0;
  1337.                     }
  1338.                 //--------------------------------------------------------------
  1339.                 // they want to edit a menu
  1340.                 //--------------------------------------------------------------
  1341.                 case EDITMENUBUTTON: {
  1342.                     if (NumMenus == 0) {
  1343.                         WinAlarm(HWND_DESKTOP, WA_ERROR);
  1344.                         return 0;
  1345.                         }
  1346.                     // find out what menu they've selected in list box
  1347.                     MenuSelection = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, CURMENULIST,
  1348.                                                                      LM_QUERYSELECTION,
  1349.                                                                      MPFROM2SHORT( LIT_FIRST, 0 ),
  1350.                                                                      0 ) );
  1351.                     // display edit menu dialog box
  1352.                     WinDlgBox(HWND_DESKTOP,
  1353.                               hWnd,
  1354.                               (PFNWP)EditItemProc,
  1355.                               0,
  1356.                               EDITITEM,
  1357.                               (PVOID)NULL);
  1358.                     // change the item in the list box and select it
  1359.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_DELETEALL, 0, 0 );
  1360.                     for (short i=0; i<NumMenus; i++)
  1361.                         WinSendDlgItemMsg( hWnd, CURMENULIST, LM_INSERTITEM,
  1362.                                            MPFROM2SHORT( LIT_END, 0 ),
  1363.                                            MenuName[i] );
  1364.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM,
  1365.                                        MPFROM2SHORT( MenuSelection, 0 ),
  1366.                                        MPFROM2SHORT( TRUE, 0 ) );
  1367.                     return 0;
  1368.                     }
  1369.                 //--------------------------------------------------------------
  1370.                 // the user wants to add another menu to the menubar
  1371.                 //--------------------------------------------------------------
  1372.                 case ADDMENU: {
  1373.                     MenuSelection = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, CURMENULIST,
  1374.                                                                      LM_QUERYSELECTION,
  1375.                                                                      MPFROM2SHORT( LIT_FIRST, 0 ),
  1376.                                                                      0 ) );
  1377.                     // error if no room for another menu
  1378.                     if (NumMenus >= MAXMENUS) {
  1379.                         char text[]="Error!  Maximum number of user-menus already defined!";
  1380.                         char title[]="Add A Menu";
  1381.                         WinMessageBox( HWND_DESKTOP, hWnd, text, title, 0,
  1382.                                        MB_MOVEABLE|MB_ERROR|MB_OK);
  1383.                         return 0;
  1384.                         }
  1385.                     WinDlgBox(HWND_DESKTOP,
  1386.                               hWnd,
  1387.                               (PFNWP)AddAMenuProc,
  1388.                               0,
  1389.                               ADDAMENU,
  1390.                               (PVOID)NULL);
  1391.                     // if first menu to be added, enable buttons
  1392.                     if (NumMenus > 0) {
  1393.                         WinEnableControl( hWnd, EDITMENUBUTTON, TRUE );
  1394.                         WinEnableControl( hWnd, REMOVEMENU, TRUE );
  1395.                         WinEnableControl( hWnd, MOVEMENULEFT, TRUE );
  1396.                         WinEnableControl( hWnd, MOVEMENURIGHT, TRUE );
  1397.                         }
  1398.  
  1399.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_DELETEALL, 0, 0 );
  1400.                     for (short i=0; i<NumMenus; i++)
  1401.                         WinSendDlgItemMsg( hWnd, CURMENULIST, LM_INSERTITEM,
  1402.                                            MPFROM2SHORT( LIT_END, 0 ),
  1403.                                            MenuName[i] );
  1404.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM,
  1405.                                        MPFROM2SHORT( MenuSelection, 0 ),
  1406.                                        MPFROM2SHORT( TRUE, 0 ) );
  1407.                     return 0;
  1408.                     }
  1409.                 //--------------------------------------------------------------
  1410.                 // the user wants to remove a menu from the menu list box
  1411.                 //--------------------------------------------------------------
  1412.                 case REMOVEMENU: {
  1413.                     char text[]="If you remove this menu, there will be no way to recover it.  Are you sure you want to remove this menu?";
  1414.                     char title[]="Remove Menu";
  1415.  
  1416.                     if (NumMenus == 0) {
  1417.                         WinAlarm(HWND_DESKTOP, WA_WARNING);
  1418.                         return 0;
  1419.                         }
  1420.  
  1421.                     if (NumMenus > 0)
  1422.                         if (WinMessageBox( HWND_DESKTOP, hWnd, text, title, 0,
  1423.                                            MB_MOVEABLE|MB_WARNING|MB_YESNO|MB_DEFBUTTON2) == MBID_YES ) {
  1424.                             short index = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, CURMENULIST,
  1425.                                                                            LM_QUERYSELECTION,
  1426.                                                                            MPFROM2SHORT( LIT_FIRST, 0 ),
  1427.                                                                            0 ) );
  1428.                             CHAR noName[]="";
  1429.                             MENUITEM menuItem;
  1430.  
  1431.                             // delete it from the lisr box
  1432.                             WinSendDlgItemMsg( hWnd, CURMENULIST, LM_DELETEITEM,
  1433.                                                MPFROM2SHORT( index, 0 ), 0 );
  1434.  
  1435.                             // delete it from menu structure
  1436.                             MakeHourglassPointer ();
  1437.                             WinSetMenuItemText( hwndMenu, 100*index+100, noName);
  1438.                             for (short i=index+1; i<MAXMENUS; i++) {
  1439.                                 SwapTwoMenus( i-1, i );
  1440.                                 }
  1441.                             NumItems[MAXMENUS-1] = 0;
  1442.                             MenuName[MAXMENUS-1][0] = '\0';
  1443.                             if (NumMenus > 0) {
  1444.                                 int newIndex = index-1;
  1445.                                 if (0 > newIndex)
  1446.                                     newIndex = 0;
  1447.  
  1448.                                 if (index == NumMenus-1)
  1449.                                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM,
  1450.                                                        MPFROM2SHORT( newIndex, 0 ),
  1451.                                                        MPFROM2SHORT( TRUE, 0 ) );
  1452.                                 else
  1453.                                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM,
  1454.                                                        MPFROM2SHORT( index, 0 ),
  1455.                                                        MPFROM2SHORT( TRUE, 0 ) );
  1456.                                 }
  1457.                             NumItems[NumMenus] = 0;
  1458.                             WinSendMsg( hwndMenu, MM_QUERYITEM, MPFROM2SHORT(NumMenus*100,TRUE),MPFROMP(&menuData[index]));
  1459.                             menuItem = menuData[index];
  1460.                             menuItem.afStyle = MIS_STATIC;
  1461.                             menuItem.afAttribute = MIA_DISABLED;
  1462.                             menuItem.hwndSubMenu = (HWND)0;
  1463.                             WinSendMsg( hwndMenu, MM_SETITEM, MPFROM2SHORT(NumMenus*100,TRUE),MPFROMP(&menuItem));
  1464.                             WinSetMenuItemText( hwndMenu, 100*MAXMENUS, noName);
  1465.                             NumItems[ NumMenus ] = 0;
  1466.                             UpdateMenu[ NumMenus ] = FALSE;
  1467.                             NumMenus--;
  1468.  
  1469.                             // if we deleted only menu, disable menu buttons
  1470.                             if (NumMenus == 0) {
  1471.                                 WinEnableControl( hWnd, EDITMENUBUTTON, FALSE );
  1472.                                 WinEnableControl( hWnd, REMOVEMENU, FALSE );
  1473.                                 WinEnableControl( hWnd, MOVEMENULEFT, FALSE );
  1474.                                 WinEnableControl( hWnd, MOVEMENURIGHT, FALSE );
  1475.                                 }
  1476.                             MakeArrowPointer ();
  1477.                             }
  1478.                     return 0;
  1479.                     }
  1480.                 //--------------------------------------------------------------
  1481.                 // move menu left in menu structure
  1482.                 //--------------------------------------------------------------
  1483.                 case MOVEMENULEFT: {
  1484.                     short index = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, CURMENULIST,
  1485.                                                              LM_QUERYSELECTION,
  1486.                                                              MPFROM2SHORT( LIT_FIRST, 0 ),
  1487.                                                              0 ) );
  1488.                     if ((NumMenus == 0) || (index == 0)) {
  1489.                         WinAlarm(HWND_DESKTOP, WA_WARNING);
  1490.                         return 0;
  1491.                         }
  1492.                     MakeHourglassPointer ();
  1493.                     SwapTwoMenus( index-1, index );
  1494.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_DELETEITEM,
  1495.                                        MPFROM2SHORT( index, 0 ), 0 );
  1496.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_INSERTITEM,
  1497.                                        MPFROM2SHORT( index-1, 0 ), MenuName[index-1] );
  1498.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM,
  1499.                                        MPFROM2SHORT( index-1, 0 ),
  1500.                                        MPFROM2SHORT( TRUE, 0 ) );
  1501.                     MakeArrowPointer ();
  1502.                     return 0;
  1503.                     }
  1504.                 //--------------------------------------------------------------
  1505.                 // move menu right in menu structure
  1506.                 //--------------------------------------------------------------
  1507.                 case MOVEMENURIGHT: {
  1508.                     short index = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, CURMENULIST,
  1509.                                                              LM_QUERYSELECTION,
  1510.                                                              MPFROM2SHORT( LIT_FIRST, 0 ),
  1511.                                                              0 ) );
  1512.                     if ((NumMenus == 0) || (index == (NumMenus)-1)) {
  1513.                         WinAlarm(HWND_DESKTOP, WA_WARNING);
  1514.                         return 0;
  1515.                         }
  1516.                     MakeHourglassPointer ();
  1517.                     SwapTwoMenus( index, index+1 );
  1518.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_DELETEITEM,
  1519.                                        MPFROM2SHORT( index, 0 ), 0 );
  1520.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_INSERTITEM,
  1521.                                        MPFROM2SHORT( index+1, 0 ), MenuName[index+1] );
  1522.                     WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM,
  1523.                                        MPFROM2SHORT( index+1, 0 ),
  1524.                                        MPFROM2SHORT( TRUE, 0 ) );
  1525.                     MakeArrowPointer ();
  1526.                     return 0;
  1527.                     }
  1528.                 //--------------------------------------------------------------
  1529.                 // nothing we care about, pass it onto the system default proc
  1530.                 //--------------------------------------------------------------
  1531.                 default:
  1532.                     return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1533.                 }
  1534.             }
  1535.         //----------------------------------------------------------------------
  1536.         // if nothing further we want to intercept, pass message onto system
  1537.         //----------------------------------------------------------------------
  1538.         default:
  1539.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1540.     }
  1541. }
  1542.  
  1543.  
  1544. ////////////////////////////////////////////////////////////////////////////////
  1545. // SwapTwoMenus will swap the FileBar stored information entries for two menus
  1546. // indicated by menu1 and menu2.  The text on the displayed menubar will also
  1547. // be changed to indicate the swap.
  1548. ////////////////////////////////////////////////////////////////////////////////
  1549. void SwapTwoMenus( short menu1, short menu2 )
  1550. {
  1551.     SHORT t1;
  1552.     for (short i=0; i<MAXITEMS; i++) {
  1553.         strcpy( tmpBuffer, ItemName[menu1][i] );
  1554.         strcpy( ItemName[menu1][i], ItemName[menu2][i] );
  1555.         strcpy( ItemName[menu2][i], tmpBuffer );
  1556.         strcpy( tmpBuffer, ActionToDo[menu1][i] );
  1557.         strcpy( ActionToDo[menu1][i], ActionToDo[menu2][i] );
  1558.         strcpy( ActionToDo[menu2][i], tmpBuffer );
  1559.         strcpy( tmpBuffer, CmdLnArgs[menu1][i] );
  1560.         strcpy( CmdLnArgs[menu1][i], CmdLnArgs[menu2][i] );
  1561.         strcpy( CmdLnArgs[menu2][i], tmpBuffer );
  1562.         strcpy( tmpBuffer, Directory[menu1][i] );
  1563.         strcpy( Directory[menu1][i], Directory[menu2][i] );
  1564.         strcpy( Directory[menu2][i], tmpBuffer );
  1565.         t1 = ProgType[menu2][i];
  1566.         ProgType[menu2][i] = ProgType[menu1][i];
  1567.         ProgType[menu1][i] = t1;
  1568.         }
  1569.     t1 = NumItems[menu2];
  1570.     NumItems[menu2] = NumItems[menu1];
  1571.     NumItems[menu1] = t1;
  1572.     strcpy( tmpBuffer, MenuName[menu1] );
  1573.     strcpy( MenuName[menu1], MenuName[menu2] );
  1574.     strcpy( MenuName[menu2], tmpBuffer );
  1575.     UpdateMenu[menu1] = TRUE;
  1576.     UpdateMenu[menu2] = TRUE;
  1577.     WinSetMenuItemText( hwndMenu, 100+menu1*100, MenuName[menu1] );
  1578.     WinSetMenuItemText( hwndMenu, 100+menu2*100, MenuName[menu2] );
  1579. }
  1580.  
  1581.  
  1582. ////////////////////////////////////////////////////////////////////////////////
  1583. // AddAMenuProc - message handler for the dialog box that allows the user to
  1584. // add a menu to the menubar
  1585. ////////////////////////////////////////////////////////////////////////////////
  1586. MRESULT EXPENTRY AddAMenuProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1587. {
  1588.    switch( msg )
  1589.     {
  1590.         //----------------------------------------------------------------------
  1591.         // when the dialog is being initialized, center it on desktop and put
  1592.         // the current data into controls
  1593.         //----------------------------------------------------------------------
  1594.         case WM_INITDLG: {
  1595.             SWP swp;
  1596.             WinSendDlgItemMsg( hWnd, MENUNAME, EM_SETTEXTLIMIT,
  1597.                                MPFROM2SHORT( MAXMENUNAMELENGTH-1, 0 ), 0 );
  1598.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  1599.             WinSetWindowPos( hWnd, (HWND)0,
  1600.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  1601.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  1602.                              0, 0, SWP_MOVE);
  1603.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1604.             }
  1605.         //----------------------------------------------------------------------
  1606.         // process a command message received from the system
  1607.         //----------------------------------------------------------------------
  1608.         case WM_COMMAND:
  1609.         {
  1610.             USHORT command = SHORT1FROMMP(mp1);
  1611.             switch( command )
  1612.                 {
  1613.                 //--------------------------------------------------------------
  1614.                 // user press OK button.  Add the menu name they entered into
  1615.                 // the menu structure and return
  1616.                 //--------------------------------------------------------------
  1617.                 case DID_OK: {
  1618.                     WinQueryDlgItemText( hWnd, MENUNAME, MAXMENUNAMELENGTH, MenuName[NumMenus]);
  1619.                     UpdateMenu[NumMenus] = TRUE;
  1620.                     NumItems[NumMenus] = 0;
  1621.                     menuData[NumMenus].afStyle = 0;
  1622.                     menuData[NumMenus].afAttribute = 0;
  1623.                     WinSendMsg( hwndMenu, MM_SETITEM, MPFROM2SHORT(100*NumMenus+100,TRUE),MPFROMP(&menuData[NumMenus]));
  1624.                     WinSetMenuItemText( hwndMenu, 100*NumMenus+100, &MenuName[NumMenus]);
  1625.                     MenuSelection = NumMenus;
  1626.                     NumMenus++;
  1627.                     WinDismissDlg( hWnd, TRUE );
  1628.                     return 0;
  1629.                     }
  1630.                 //--------------------------------------------------------------
  1631.                 // they decided not to add a menu, dismiss dialog and return
  1632.                 //--------------------------------------------------------------
  1633.                 case DID_CANCEL: {
  1634.                     WinDismissDlg( hWnd, TRUE );
  1635.                     return 0;
  1636.                     }
  1637.                 //--------------------------------------------------------------
  1638.                 // nothing we care about, pass on for default processing
  1639.                 //--------------------------------------------------------------
  1640.                 default:
  1641.                     return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1642.                 }
  1643.         }
  1644.         // ---------------------------------------------------------------------
  1645.         // if nothing further we want to intercept, pass message onto system
  1646.         // ---------------------------------------------------------------------
  1647.         default:
  1648.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1649.     }
  1650. }
  1651.  
  1652.  
  1653. ////////////////////////////////////////////////////////////////////////////////
  1654. // Swap menu items item1 and item2 on menu Menu in the menu information arrays
  1655. ////////////////////////////////////////////////////////////////////////////////
  1656. VOID SwapTwoItems(SHORT Menu, SHORT item1, SHORT item2)
  1657. {
  1658.     strcpy( tmpBuffer, ItemName[Menu][item2] );
  1659.     strcpy( ItemName[Menu][item2], ItemName[Menu][item1] );
  1660.     strcpy( ItemName[Menu][item1], tmpBuffer );
  1661.     strcpy( tmpBuffer, ActionToDo[Menu][item2] );
  1662.     strcpy( ActionToDo[Menu][item2], ActionToDo[Menu][item1] );
  1663.     strcpy( ActionToDo[Menu][item1], tmpBuffer );
  1664.     strcpy( tmpBuffer, CmdLnArgs[Menu][item2] );
  1665.     strcpy( CmdLnArgs[Menu][item2], CmdLnArgs[Menu][item1] );
  1666.     strcpy( CmdLnArgs[Menu][item1], tmpBuffer );
  1667.     strcpy( tmpBuffer, Directory[Menu][item2] );
  1668.     strcpy( Directory[Menu][item2], Directory[Menu][item1] );
  1669.     strcpy( Directory[Menu][item1], tmpBuffer );
  1670.     short t1 = ProgType[Menu][item2];
  1671.     ProgType[Menu][item2] = ProgType[Menu][item1];
  1672.     ProgType[Menu][item1] = t1;
  1673. }
  1674.  
  1675.  
  1676. ////////////////////////////////////////////////////////////////////////////////
  1677. // updateItemList - refreshes the contents of the item list list-box in a dialog
  1678. ////////////////////////////////////////////////////////////////////////////////
  1679. VOID updateItemList( HWND hWnd )
  1680. {
  1681.     CHAR Separator[] = SEPARATOR;
  1682.     WinSendDlgItemMsg( hWnd, ITEMMENU, LM_DELETEALL, 0, 0 );
  1683.     for (short i=0; i<NumItems[MenuSelection]; i++)
  1684.         if (ItemName[MenuSelection][i][0] != '\0')
  1685.             WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM,
  1686.                                MPFROM2SHORT( LIT_END, 0 ),
  1687.                                ItemName[MenuSelection][i] );
  1688.         else
  1689.             WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM,
  1690.                                MPFROM2SHORT( LIT_END, 0 ),
  1691.                                Separator );
  1692.     if (NumItems[MenuSelection] > 0)
  1693.         WinSendDlgItemMsg( hWnd, ITEMMENU, LM_SELECTITEM,
  1694.                            MPFROM2SHORT( ItemSelection, 0 ),
  1695.                            MPFROM2SHORT( TRUE, 0 ) );
  1696. }
  1697.  
  1698.  
  1699. ////////////////////////////////////////////////////////////////////////////////
  1700. // EditItemProc - the message handler for the edit menu item dialog box
  1701. ////////////////////////////////////////////////////////////////////////////////
  1702. MRESULT EXPENTRY EditItemProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1703. {
  1704.     switch( msg )
  1705.     {
  1706.         //----------------------------------------------------------------------
  1707.         // when the dialog is being initialized, center it on desktop and put
  1708.         // the current data into control fields
  1709.         //----------------------------------------------------------------------
  1710.         case WM_INITDLG: {
  1711.             SWP swp;
  1712.             WinSendDlgItemMsg( hWnd, MENUNAME, EM_SETTEXTLIMIT,
  1713.                                MPFROM2SHORT( MAXMENUNAMELENGTH-1, 0 ), 0 );
  1714.             WinSetDlgItemText( hWnd, MENUNAME, MenuName[MenuSelection]);
  1715.             ItemSelection = 0;
  1716.             updateItemList( hWnd );
  1717.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  1718.             WinSetWindowPos( hWnd, (HWND)0,
  1719.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  1720.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  1721.                              0, 0, SWP_MOVE);
  1722.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1723.             }
  1724.         //----------------------------------------------------------------------
  1725.         // if there is a control message, update enabled status of buttons
  1726.         //----------------------------------------------------------------------
  1727.         case WM_CONTROL:
  1728.         {
  1729.             if ((SHORT1FROMMP(mp1)==ITEMMENU) && (SHORT2FROMMP(mp1)==LN_ENTER))
  1730.                 return WinSendMsg( hWnd, WM_COMMAND, MPFROM2SHORT( CHANGEITEM, 0 ), mp2 );
  1731.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1732.         }
  1733.         //----------------------------------------------------------------------
  1734.         // process a command message received from the system
  1735.         //----------------------------------------------------------------------
  1736.         case WM_COMMAND:
  1737.         {
  1738.             USHORT command = SHORT1FROMMP(mp1);
  1739.             switch( command )
  1740.                 {
  1741.                 //--------------------------------------------------------------
  1742.                 // insert a separator into item list, if there is room
  1743.                 //--------------------------------------------------------------
  1744.                 case INSERTSEPARATOR: {
  1745.                     ItemSelection = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU,
  1746.                                                                      LM_QUERYSELECTION,
  1747.                                                                      MPFROM2SHORT( LIT_FIRST, 0 ),
  1748.                                                                      0 ) );
  1749.                     if (NumItems[MenuSelection] >= MAXITEMS-1) {
  1750.                         // error and return if no room
  1751.                         char text[]="Error!  Maximum number of items for this menu already defined!";
  1752.                         char title[]="Add A Separator";
  1753.                         WinMessageBox( HWND_DESKTOP, hWnd, text, title, 0,
  1754.                                        MB_MOVEABLE|MB_ERROR|MB_OK);
  1755.                         return 0;
  1756.                         }
  1757.                     // since this is a separator, blank out launch information
  1758.                     for (short i=NumItems[MenuSelection]-1; i>=ItemSelection; i--)
  1759.                         SwapTwoItems( MenuSelection, i, i+1 );
  1760.                     ItemName[MenuSelection][ItemSelection][0]='\0';
  1761.                     ActionToDo[MenuSelection][ItemSelection][0]='\0';
  1762.                     CmdLnArgs[MenuSelection][ItemSelection][0]='\0';
  1763.                     Directory[MenuSelection][ItemSelection][0]='\0';
  1764.                     ProgType[MenuSelection][ItemSelection]=0;
  1765.                     if (NumItems[MenuSelection]==0)
  1766.                         ItemSelection = 0;
  1767.                     NumItems[MenuSelection]++;
  1768.                     UpdateMenu[MenuSelection] = TRUE;
  1769.                     updateItemList( hWnd );
  1770.                     return 0;
  1771.                     }
  1772.                 //--------------------------------------------------------------
  1773.                 // user wants to add an item to the current menu
  1774.                 //--------------------------------------------------------------
  1775.                 case ADDITEM: {
  1776.                     ItemSelection = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU,
  1777.                                                                      LM_QUERYSELECTION,
  1778.                                                                      MPFROM2SHORT( LIT_FIRST, 0 ),
  1779.                                                                      0 ) );
  1780.                     // error and return if no room for another item
  1781.                     if (NumItems[MenuSelection] >= MAXITEMS) {
  1782.                         char text[]="Error!  Maximum number of items for this menu already defined!";
  1783.                         char title[]="Add An Item";
  1784.                         WinMessageBox( HWND_DESKTOP, hWnd, text, title, 0,
  1785.                                        MB_MOVEABLE|MB_ERROR|MB_OK);
  1786.                         return 0;
  1787.                         }
  1788.                     // get new item via add item dialog box
  1789.                     WinDlgBox(HWND_DESKTOP,
  1790.                               hWnd,
  1791.                               (PFNWP)AddAnItemProc,
  1792.                               0,
  1793.                               ADDANITEM,
  1794.                               (PVOID)NULL);
  1795.                     // update item list with possible new item
  1796.                     updateItemList( hWnd );
  1797.                     return 0;
  1798.                     }
  1799.                 //--------------------------------------------------------------
  1800.                 // user wants to change a menu item
  1801.                 //--------------------------------------------------------------
  1802.                 case CHANGEITEM: {
  1803.                     ItemSelection = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU,
  1804.                                                                      LM_QUERYSELECTION,
  1805.                                                                      MPFROM2SHORT( LIT_FIRST, 0 ),
  1806.                                                                      0 ) );
  1807.                     if ((NumItems[MenuSelection] == 0) || (ItemName[MenuSelection][ItemSelection][0] == '\0')) {
  1808.                         WinAlarm(HWND_DESKTOP, WA_WARNING);
  1809.                         return 0;
  1810.                         }
  1811.                     WinDlgBox(HWND_DESKTOP,
  1812.                               hWnd,
  1813.                               (PFNWP)EditItemDataProc,
  1814.                               0,
  1815.                               EDITITEMDATA,
  1816.                               (PVOID)NULL);
  1817.                     updateItemList( hWnd );
  1818.                     return 0;
  1819.                     }
  1820.                 //--------------------------------------------------------------
  1821.                 // move item down in menu order
  1822.                 //--------------------------------------------------------------
  1823.                 case MOVEITEMDOWN: {
  1824.                     CHAR Separator[] = SEPARATOR;
  1825.                     short i = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU,
  1826.                                                                LM_QUERYSELECTION,
  1827.                                                                MPFROM2SHORT( LIT_FIRST, 0 ),
  1828.                                                                0 ) );
  1829.                     if ((i == NumItems[MenuSelection]-1) || (NumItems[MenuSelection] == 0)) {
  1830.                         WinAlarm(HWND_DESKTOP, WA_WARNING);
  1831.                         return 0;
  1832.                         }
  1833.                     SwapTwoItems( MenuSelection, i, i+1 );
  1834.                     WinSendDlgItemMsg( hWnd, ITEMMENU, LM_DELETEITEM,
  1835.                                        MPFROM2SHORT( i, 0 ),
  1836.                                        MPFROM2SHORT( TRUE, 0 ) );
  1837.                     if (ItemName[MenuSelection][i+1][0] == '\0')
  1838.                         WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM,
  1839.                                            MPFROM2SHORT( i+1, 0 ),
  1840.                                            Separator );
  1841.                     else WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM,
  1842.                                             MPFROM2SHORT( i+1, 0 ),
  1843.                                             &ItemName[MenuSelection][i+1] );
  1844.                     WinSendDlgItemMsg( hWnd, ITEMMENU, LM_SELECTITEM,
  1845.                                        MPFROM2SHORT( i+1, 0 ),
  1846.                                        MPFROM2SHORT( TRUE, 0 ) );
  1847.                     return 0;
  1848.                     }
  1849.                 //--------------------------------------------------------------
  1850.                 // move item up in menu order
  1851.                 //--------------------------------------------------------------
  1852.                 case MOVEITEMUP: {
  1853.                     CHAR Separator[] = SEPARATOR;
  1854.                     short i = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU,
  1855.                                                                LM_QUERYSELECTION,
  1856.                                                                MPFROM2SHORT( LIT_FIRST, 0 ),
  1857.                                                                0 ) );
  1858.                     if ((i == 0) || (NumItems[MenuSelection] == 0)) {
  1859.                         WinAlarm(HWND_DESKTOP, WA_WARNING);
  1860.                         return 0;
  1861.                         }
  1862.                     SwapTwoItems( MenuSelection, i-1, i );
  1863.                     WinSendDlgItemMsg( hWnd, ITEMMENU, LM_DELETEITEM,
  1864.                                        MPFROM2SHORT( i, 0 ),
  1865.                                        MPFROM2SHORT( TRUE, 0 ) );
  1866.                     if (ItemName[MenuSelection][i-1][0] == '\0')
  1867.                         WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM,
  1868.                                            MPFROM2SHORT( i-1, 0 ),
  1869.                                            Separator );
  1870.                     else WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM,
  1871.                                             MPFROM2SHORT( i-1, 0 ),
  1872.                                             &ItemName[MenuSelection][i-1] );
  1873.                     WinSendDlgItemMsg( hWnd, ITEMMENU, LM_SELECTITEM,
  1874.                                        MPFROM2SHORT( i-1, 0 ),
  1875.                                        MPFROM2SHORT( TRUE, 0 ) );
  1876.                     return 0;
  1877.                     }
  1878.                 //--------------------------------------------------------------
  1879.                 // remove a menu item
  1880.                 //--------------------------------------------------------------
  1881.                 case REMOVEITEM: {
  1882.                     char text[]="If you remove this item, there will be no way to recover it.  Are you sure you want to remove this item?";
  1883.                     char title[]="Remove Menu Item";
  1884.  
  1885.                     if (NumItems[MenuSelection] == 0) {
  1886.                         WinAlarm(HWND_DESKTOP, WA_WARNING);
  1887.                         return 0;
  1888.                         }
  1889.  
  1890.                     if (NumItems[MenuSelection] > 0)
  1891.                         if (WinMessageBox( HWND_DESKTOP, hWnd, text, title, 0,
  1892.                                            MB_MOVEABLE|MB_WARNING|MB_YESNO|MB_DEFBUTTON2) == MBID_YES ) {
  1893.                             short index = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU,
  1894.                                                                            LM_QUERYSELECTION,
  1895.                                                                            MPFROM2SHORT( LIT_FIRST, 0 ),
  1896.                                                                            0 ) );
  1897.                             WinSendDlgItemMsg( hWnd, ITEMMENU, LM_DELETEITEM,
  1898.                                                MPFROM2SHORT( index, 0 ), 0 );
  1899.  
  1900.                             for (short i=index; i<MAXITEMS-1; i++) {
  1901.                                 strcpy( ItemName[MenuSelection][i], ItemName[MenuSelection][i+1]);
  1902.                                 strcpy( ActionToDo[MenuSelection][i], ActionToDo[MenuSelection][i+1]);
  1903.                                 strcpy( CmdLnArgs[MenuSelection][i], CmdLnArgs[MenuSelection][i+1]);
  1904.                                 strcpy( Directory[MenuSelection][i], Directory[MenuSelection][i+1]);
  1905.                                 ProgType[MenuSelection][i] = ProgType[MenuSelection][i+1];
  1906.                                 }
  1907.  
  1908.                             if (NumItems[MenuSelection] > 0) {
  1909.                                 int newIndex = index-1;
  1910.                                 if (0 > newIndex)
  1911.                                     newIndex = 0;
  1912.  
  1913.                                 if (index == NumItems[MenuSelection]-1)
  1914.                                     WinSendDlgItemMsg( hWnd, ITEMMENU, LM_SELECTITEM,
  1915.                                                        MPFROM2SHORT( newIndex, 0 ),
  1916.                                                        MPFROM2SHORT( TRUE, 0 ) );
  1917.                                 else
  1918.                                     WinSendDlgItemMsg( hWnd, ITEMMENU, LM_SELECTITEM,
  1919.                                                        MPFROM2SHORT( index, 0 ),
  1920.                                                        MPFROM2SHORT( TRUE, 0 ) );
  1921.                                 }
  1922.  
  1923.                             NumItems[MenuSelection]--;
  1924.                             }
  1925.                     return 0;
  1926.                     }
  1927.                 //--------------------------------------------------------------
  1928.                 // user is done editing a menu, save menu name and return
  1929.                 //--------------------------------------------------------------
  1930.                 case DID_OK: {
  1931.                     WinQueryDlgItemText( hWnd, MENUNAME, MAXMENUNAMELENGTH, MenuName[MenuSelection]);
  1932.                     WinSetMenuItemText( hwndMenu, 100*MenuSelection+100, &MenuName[MenuSelection]);
  1933.                     UpdateMenu[MenuSelection] = TRUE;
  1934.                     WinDismissDlg( hWnd, TRUE );
  1935.                     return 0;
  1936.                     }
  1937.                 //--------------------------------------------------------------
  1938.                 // no message we care about, pass it onto the system
  1939.                 //--------------------------------------------------------------
  1940.                 default:
  1941.                     return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1942.                 }
  1943.         }
  1944.         //----------------------------------------------------------------------
  1945.         // if nothing further we want to intercept, pass message onto system
  1946.         //----------------------------------------------------------------------
  1947.         default:
  1948.            return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  1949.         }
  1950. }
  1951.  
  1952.  
  1953. ////////////////////////////////////////////////////////////////////////////////
  1954. // update the enable/disabled state of the program type buttons
  1955. ////////////////////////////////////////////////////////////////////////////////
  1956. void updateEditItemWindow( HWND hWnd )
  1957. {
  1958.     int value = TRUE;
  1959.  
  1960.     if (WinQueryButtonCheckstate( hWnd, STARTWPS ))
  1961.         value = FALSE;
  1962.  
  1963.     WinEnableControl( hWnd, MAXIMIZED, value );
  1964.     WinEnableControl( hWnd, MINIMIZED, value );
  1965.     WinEnableControl( hWnd, FOLDER, value );
  1966.     WinEnableControl( hWnd, DOSWIN, value );
  1967.     WinEnableControl( hWnd, DOSFS, value );
  1968.     WinEnableControl( hWnd, OS2WIN, value );
  1969.     WinEnableControl( hWnd, OS2FS, value );
  1970.     WinEnableControl( hWnd, WINOS2WIN, value );
  1971.     WinEnableControl( hWnd, WINOS2FS, value );
  1972.     WinEnableControl( hWnd, PMAPP, value );
  1973.     WinEnableControl( hWnd, SETTINGSBUTTON, TRUE-value );
  1974.  
  1975.     if (WinQueryButtonCheckstate( hWnd, FOLDER )) {
  1976.         WinEnableControl( hWnd, MAXIMIZED, FALSE );
  1977.         WinEnableControl( hWnd, MINIMIZED, FALSE );
  1978.         }
  1979.  
  1980.     if ((WinQueryButtonCheckstate( hWnd, FOLDER )) || (WinQueryButtonCheckstate( hWnd, PMAPP )))
  1981.         WinEnableControl( hWnd, STARTWPS, FALSE );
  1982.     else
  1983.         WinEnableControl( hWnd, STARTWPS, TRUE );
  1984.  
  1985.     if (ActionToDo[MenuSelection][ItemSelection][0]=='\0')
  1986.         WinEnableControl( hWnd, SETTINGSBUTTON, FALSE );
  1987. }
  1988.  
  1989.  
  1990. ////////////////////////////////////////////////////////////////////////////////
  1991. //
  1992. ////////////////////////////////////////////////////////////////////////////////
  1993. void updateEditItemData( HWND hWnd )
  1994. {
  1995.             // put item name and length of longest possible name in entry field
  1996.             WinSendDlgItemMsg( hWnd, ITEMNAME, EM_SETTEXTLIMIT,
  1997.                                MPFROM2SHORT( MAXITEMNAMELENGTH-1, 0 ), 0 );
  1998.             WinSetDlgItemText( hWnd, ITEMNAME, ItemName[MenuSelection][ItemSelection]);
  1999.             // put path name and length of longest possible name in entry field
  2000.             WinSendDlgItemMsg( hWnd, PATHNAME, EM_SETTEXTLIMIT,
  2001.                                MPFROM2SHORT( MAXACTIONSTRINGLENGTH-1, 0 ), 0 );
  2002.             WinSetDlgItemText( hWnd, PATHNAME, ActionToDo[MenuSelection][ItemSelection]);
  2003.             // put argument and length of longest possible in entry field
  2004.             WinSendDlgItemMsg( hWnd, ARGUMENTS, EM_SETTEXTLIMIT,
  2005.                                MPFROM2SHORT( MAXARGSTRINGLENGTH-1, 0 ), 0 );
  2006.             WinSetDlgItemText( hWnd, ARGUMENTS, CmdLnArgs[MenuSelection][ItemSelection]);
  2007.             // put directory and length of longest possible directory in entry field
  2008.             WinSendDlgItemMsg( hWnd, DIRECTORY, EM_SETTEXTLIMIT,
  2009.                                MPFROM2SHORT( MAXDIRSTRINGLENGTH-1, 0 ), 0 );
  2010.             WinSetDlgItemText( hWnd, DIRECTORY, Directory[MenuSelection][ItemSelection]);
  2011.             // set appropriate radio button for program startup option
  2012.             WinCheckButton( hWnd, MAXIMIZED, FALSE );
  2013.             WinCheckButton( hWnd, MINIMIZED, FALSE );
  2014.             if (ProgType[MenuSelection][ItemSelection] & STARTMAX)
  2015.                 WinCheckButton( hWnd, MAXIMIZED, TRUE );
  2016.             else if (ProgType[MenuSelection][ItemSelection] & STARTMIN)
  2017.                 WinCheckButton( hWnd, MINIMIZED, TRUE );
  2018.             // set appropriate radio button for program startup option
  2019.             if (ProgType[MenuSelection][ItemSelection] & PM)
  2020.                 WinCheckButton( hWnd, PMAPP, TRUE );
  2021.             else if (ProgType[MenuSelection][ItemSelection] & WPSFOLDER)
  2022.                 WinCheckButton( hWnd, FOLDER, TRUE );
  2023.             else if ( (ProgType[MenuSelection][ItemSelection] & DOS) &&
  2024.                     (ProgType[MenuSelection][ItemSelection] & WINDOWED))
  2025.                 WinCheckButton( hWnd, DOSWIN, TRUE );
  2026.             else if ( (ProgType[MenuSelection][ItemSelection] & DOS) &&
  2027.                     (ProgType[MenuSelection][ItemSelection] & FULLSCREEN))
  2028.                 WinCheckButton( hWnd, DOSFS, TRUE );
  2029.             else if ( (ProgType[MenuSelection][ItemSelection] & OS2) &&
  2030.                     (ProgType[MenuSelection][ItemSelection] & WINDOWED))
  2031.                 WinCheckButton( hWnd, OS2WIN, TRUE );
  2032.             else if ( (ProgType[MenuSelection][ItemSelection] & OS2) &&
  2033.                     (ProgType[MenuSelection][ItemSelection] & FULLSCREEN))
  2034.                 WinCheckButton( hWnd, OS2FS, TRUE );
  2035.             else if ( (ProgType[MenuSelection][ItemSelection] & WINOS2) &&
  2036.                     (ProgType[MenuSelection][ItemSelection] & WINDOWED))
  2037.                 WinCheckButton( hWnd, WINOS2WIN, TRUE );
  2038.             else if ( (ProgType[MenuSelection][ItemSelection] & WINOS2) &&
  2039.                     (ProgType[MenuSelection][ItemSelection] & FULLSCREEN))
  2040.                 WinCheckButton( hWnd, WINOS2FS, TRUE );
  2041.             if (ProgType[MenuSelection][ItemSelection] & STARTASWPS)
  2042.                 WinCheckButton( hWnd, STARTWPS, TRUE );
  2043.             else
  2044.                 WinCheckButton( hWnd, STARTWPS, FALSE );
  2045.             updateEditItemWindow( hWnd );
  2046. }
  2047.  
  2048. ////////////////////////////////////////////////////////////////////////////////
  2049. // message handler for the dialog "edit an item's values"
  2050. ////////////////////////////////////////////////////////////////////////////////
  2051. MRESULT EXPENTRY EditItemDataProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  2052. {
  2053.     switch( msg )
  2054.     {
  2055.         //----------------------------------------------------------------------
  2056.         // if the object being drug over us is a single folder, allow drag
  2057.         //----------------------------------------------------------------------
  2058.         case DM_DRAGOVER: {
  2059.             ULONG cbBuffer;
  2060.             DRAGITEM dragItem;
  2061.             PDRAGINFO dragInfoPtr;
  2062.             int numObjects;
  2063.  
  2064.             dragInfoPtr = (PDRAGINFO)mp1;
  2065.             DrgAccessDraginfo(dragInfoPtr);
  2066.             numObjects = dragInfoPtr->cditem;
  2067.             cbBuffer = sizeof(DRAGITEM);
  2068.             DrgQueryDragitem( dragInfoPtr, cbBuffer, &dragItem, 0 );
  2069.             DrgFreeDraginfo(dragInfoPtr);
  2070.  
  2071.             if ((numObjects == 1) && (dragItem.fsControl & DC_CONTAINER))
  2072.                 return MPFROM2SHORT( DOR_DROP, DO_UNKNOWN );
  2073.             return MPFROM2SHORT( DOR_NEVERDROP, DO_UNKNOWN );
  2074.             }
  2075.         //----------------------------------------------------------------------
  2076.         // allow the dropping of a WPS folder to our window.  Once dropped, get
  2077.         // necessary info and fill in dialog with the info we retrieve
  2078.         //----------------------------------------------------------------------
  2079.         case DM_DROP: {
  2080.             PDRAGINFO dragInfoPtr;
  2081.             ULONG cbBuffer;
  2082.             DRAGITEM dragItem;
  2083.  
  2084.             dragInfoPtr = (PDRAGINFO)mp1;
  2085.             DrgAccessDraginfo(dragInfoPtr);
  2086.  
  2087.             cbBuffer = sizeof(DRAGITEM);
  2088.             DrgQueryDragitem( dragInfoPtr, cbBuffer, &dragItem, 0 );
  2089.  
  2090.             // get menu item name
  2091.             DrgQueryStrName( dragItem.hstrTargetName, sizeof(ItemName[MenuSelection][ItemSelection]), ItemName[MenuSelection][ItemSelection]);
  2092.             // get default directory
  2093.             DrgQueryStrName( dragItem.hstrContainerName, sizeof(Directory[MenuSelection][ItemSelection]), Directory[MenuSelection][ItemSelection]);
  2094.             // get path name
  2095.             DrgQueryStrName( dragItem.hstrSourceName, sizeof(ActionToDo[MenuSelection][ItemSelection]), ActionToDo[MenuSelection][ItemSelection]);
  2096.  
  2097.             ProgType[MenuSelection][ItemSelection] = WPSFOLDER;
  2098.             WinCheckButton( hWnd, FOLDER, TRUE );
  2099.  
  2100.             DrgFreeDraginfo(dragInfoPtr);
  2101.             updateEditItemData( hWnd );
  2102.             WinSetFocus( HWND_DESKTOP, hWnd );
  2103.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2104.             }
  2105.         //----------------------------------------------------------------------
  2106.         // when the dialog is being initialized, center it on desktop and put
  2107.         // the current data into control fields
  2108.         //----------------------------------------------------------------------
  2109.         case WM_INITDLG: {
  2110.             SWP swp;
  2111.  
  2112.             // center dialog on screen
  2113.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  2114.             WinSetWindowPos( hWnd, (HWND)0,
  2115.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  2116.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  2117.                              0, 0, SWP_MOVE);
  2118.  
  2119.             // save data in case of cancel or restore
  2120.             oldProgType = ProgType[MenuSelection][ItemSelection];
  2121.             strcpy( oldItemName, ItemName[MenuSelection][ItemSelection] );
  2122.             strcpy( oldDirectory, Directory[MenuSelection][ItemSelection] );
  2123.             strcpy( oldAction, ActionToDo[MenuSelection][ItemSelection] );
  2124.             strcpy( oldCmdLn, CmdLnArgs[MenuSelection][ItemSelection] );
  2125.  
  2126.             updateEditItemData( hWnd );
  2127.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2128.             }
  2129.         //----------------------------------------------------------------------
  2130.         // we received a control message, update enabling of buttons
  2131.         //----------------------------------------------------------------------
  2132.         case WM_CONTROL:
  2133.         {
  2134.             if ((SHORT1FROMMP(mp1)==MAXIMIZED) && (SHORT2FROMMP(mp1)==BN_CLICKED))
  2135.                 WinCheckButton( hWnd, MINIMIZED, FALSE );
  2136.             if ((SHORT1FROMMP(mp1)==MINIMIZED) && (SHORT2FROMMP(mp1)==BN_CLICKED))
  2137.                 WinCheckButton( hWnd, MAXIMIZED, FALSE );
  2138.             updateEditItemWindow( hWnd );            return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2139.         }
  2140.         //----------------------------------------------------------------------
  2141.         // process a command message received from the system
  2142.         //----------------------------------------------------------------------
  2143.         case WM_COMMAND:
  2144.         {
  2145.             USHORT command = SHORT1FROMMP(mp1);
  2146.             switch( command )
  2147.                 {
  2148.                 //--------------------------------------------------------------
  2149.                 // open the settings notebook and allow user modifications
  2150.                 //--------------------------------------------------------------
  2151.                 case SETTINGSBUTTON: {
  2152.                     RXSTRING  retstr;
  2153.                     RXSTRING  INSTORE[2];
  2154.                     SHORT returnCode;
  2155.                     char mesg[1024];
  2156.                     int offset;
  2157.                     short rc;
  2158.  
  2159.                     // open settings for current program in dialog controls
  2160.                     WinQueryDlgItemText( hWnd, ITEMNAME, MAXITEMNAMELENGTH,
  2161.                                          ItemName[MenuSelection][ItemSelection]);
  2162.                     WinQueryDlgItemText( hWnd, PATHNAME, MAXACTIONSTRINGLENGTH,
  2163.                                          ActionToDo[MenuSelection][ItemSelection]);
  2164.                     WinQueryDlgItemText( hWnd, ARGUMENTS, MAXARGSTRINGLENGTH,
  2165.                                          CmdLnArgs[MenuSelection][ItemSelection]);
  2166.                     WinQueryDlgItemText( hWnd, DIRECTORY, MAXDIRSTRINGLENGTH,
  2167.                                          Directory[MenuSelection][ItemSelection]);
  2168.  
  2169.                     offset = 0;
  2170.                     offset = offset + sprintf(mesg+offset, "/* */\r\n");
  2171.                     offset = offset + sprintf(mesg+offset, "call RxFuncAdd 'SysSetObjectData', 'RexxUtil', 'SysSetObjectData'\r\n");
  2172.  
  2173.                     if (ProgType[MenuSelection][ItemSelection] & WPSFOLDER)
  2174.                         offset = offset + sprintf(mesg+offset, "result = SysSetObjectData(\"%s%s\",\"OPEN=SETTINGS\")\r\n\x1A\0", Directory[MenuSelection][ItemSelection],ActionToDo[MenuSelection][ItemSelection]);
  2175.                     else
  2176.                         offset = offset + sprintf(mesg+offset, "result = SysSetObjectData(\"%s\",\"OPEN=SETTINGS\")\r\n\x1A\0", ActionToDo[MenuSelection][ItemSelection]);
  2177.  
  2178.                     INSTORE[0].strptr=mesg;
  2179.                     INSTORE[0].strlength=strlen(mesg);
  2180.                     INSTORE[1].strptr=NULL;
  2181.                     INSTORE[1].strlength=0;
  2182.  
  2183.                     rc = rexxStart((LONG)0,
  2184.                               (PRXSTRING)0,
  2185.                               (PSZ)LAUNCHFILE,
  2186.                               (PRXSTRING)INSTORE,
  2187.                               (PSZ)"CMD",
  2188.                               (LONG)RXCOMMAND,
  2189.                               (PRXSYSEXIT)0,
  2190.                               (SHORT*)&returnCode,
  2191.                               (PRXSTRING)&retstr);
  2192.  
  2193.                     if ((rc) || (returnCode)) {
  2194.                         char title[]="Open Settings for Object";
  2195.                         char mesg[]="Could not locate the settings for this object.  You may consider fully qualifying (adding drive and path) the program and trying again.";
  2196.  
  2197.                         WinMessageBox( HWND_DESKTOP, hWnd, mesg, title, 0,
  2198.                                        MB_MOVEABLE|MB_ERROR|MB_OK);
  2199.                         }
  2200.  
  2201.                     return 0;
  2202.                     }
  2203.                 //--------------------------------------------------------------
  2204.                 // the user wants to find a file to call as a menu item.  Hook
  2205.                 // into OS/2's file dialog procedure to ease the finding process
  2206.                 // for us to program!  Then once a file is selected, fill in
  2207.                 // the program path, directory and query the application for its
  2208.                 // application type and mark the appropriate radio button
  2209.                 //--------------------------------------------------------------
  2210.                 case FINDFILE: {
  2211.                     CHAR title[] = "FileBar - Find A File To Add";
  2212.                     ULONG s, t;
  2213.                     HWND hwndDialog;
  2214.  
  2215.                     fileDlgInfo.fl = FDS_OPEN_DIALOG|FDS_CENTER;
  2216.                     fileDlgInfo.pszTitle = title;
  2217.                     strcat(fileDlgInfo.szFullFile, "*.*\0");
  2218.  
  2219.                     hwndDialog = WinFileDlg( HWND_DESKTOP, hWnd, &fileDlgInfo );
  2220.                     if (hwndDialog && (fileDlgInfo.lReturn == DID_OK)) {
  2221.  
  2222.                         strcpy( ActionToDo[MenuSelection][ItemSelection], fileDlgInfo.szFullFile );
  2223.  
  2224.                         s=0;
  2225.                         while(fileDlgInfo.szFullFile[s]!='\0')
  2226.                             s++;
  2227.                         while((fileDlgInfo.szFullFile[s]!='\\') && (s>=0))
  2228.                             s--;
  2229.  
  2230.                         t = 0;
  2231.                         while (t<s)
  2232.                             Directory[MenuSelection][ItemSelection][t] = fileDlgInfo.szFullFile[t++];
  2233.                         Directory[MenuSelection][ItemSelection][t] = '\0';
  2234.  
  2235.                         DosQueryAppType( ActionToDo[MenuSelection][ItemSelection], &t);
  2236.                         ProgType[MenuSelection][ItemSelection] = OS2 + WINDOWED;
  2237.                         if (t == FAPPTYP_WINDOWAPI)
  2238.                             ProgType[MenuSelection][ItemSelection] = PM;
  2239.                         if (t == FAPPTYP_WINDOWCOMPAT)
  2240.                             ProgType[MenuSelection][ItemSelection] = OS2 + WINDOWED;
  2241.                         if (t == FAPPTYP_NOTWINDOWCOMPAT)
  2242.                             ProgType[MenuSelection][ItemSelection] = OS2 + FULLSCREEN;
  2243.                         if (t == FAPPTYP_DOS)
  2244.                             ProgType[MenuSelection][ItemSelection] = DOS + WINDOWED;
  2245.                         if ((t == FAPPTYP_WINDOWSREAL) || (t == FAPPTYP_WINDOWSPROT))
  2246.                             ProgType[MenuSelection][ItemSelection] = WINOS2 + FULLSCREEN;
  2247.  
  2248.                         updateEditItemData( hWnd );
  2249.                         updateEditItemWindow( hWnd );
  2250.  
  2251.                         if (fileDlgInfo.szFullFile[s]=='\\')
  2252.                             fileDlgInfo.szFullFile[s+1]='\0';
  2253.                         else
  2254.                             fileDlgInfo.szFullFile[0]='\0';
  2255.                         }
  2256.                     else
  2257.                         fileDlgInfo.szFullFile[0]='\0';
  2258.                     return 0;
  2259.                     }
  2260.                 //--------------------------------------------------------------
  2261.                 // user pressed Reset, restore old settings and continue
  2262.                 //--------------------------------------------------------------
  2263.                 case RESETBUTTON: {
  2264.                     ProgType[MenuSelection][ItemSelection] = oldProgType;
  2265.                     strcpy( ItemName[MenuSelection][ItemSelection], oldItemName );
  2266.                     strcpy( Directory[MenuSelection][ItemSelection], oldDirectory );
  2267.                     strcpy( ActionToDo[MenuSelection][ItemSelection], oldAction );
  2268.                     strcpy( CmdLnArgs[MenuSelection][ItemSelection], oldCmdLn );
  2269.                     updateEditItemData( hWnd );
  2270.                     return 0;
  2271.                     }
  2272.                 //--------------------------------------------------------------
  2273.                 // user pressed CANCEL, restore old item data
  2274.                 //--------------------------------------------------------------
  2275.                 case DID_CANCEL: {
  2276.                     ProgType[MenuSelection][ItemSelection] = oldProgType;
  2277.                     strcpy( ItemName[MenuSelection][ItemSelection], oldItemName );
  2278.                     strcpy( Directory[MenuSelection][ItemSelection], oldDirectory );
  2279.                     strcpy( ActionToDo[MenuSelection][ItemSelection], oldAction );
  2280.                     strcpy( CmdLnArgs[MenuSelection][ItemSelection], oldCmdLn );
  2281.                     WinDismissDlg( hWnd, TRUE );
  2282.                     return 0;
  2283.                     }
  2284.                 //--------------------------------------------------------------
  2285.                 // user pressed OK, save current information for this item
  2286.                 //--------------------------------------------------------------
  2287.                 case DID_OK: {
  2288.                     if ( WinQueryButtonCheckstate( hWnd, MAXIMIZED ) &&
  2289.                          WinQueryButtonCheckstate( hWnd, MINIMIZED ) ) {
  2290.                         char text[]="Cannot have the item start both as minimized AND maximized!";
  2291.                         WinMessageBox( HWND_DESKTOP, hWnd, text, NULL, 0,
  2292.                                        MB_MOVEABLE|MB_ERROR|MB_OK);
  2293.                         return 0;
  2294.                         }
  2295.  
  2296.                     // save program type and max/min startup status
  2297.                     ProgType[MenuSelection][ItemSelection] = 0;
  2298.                     if (WinQueryButtonCheckstate( hWnd, FOLDER ))
  2299.                         ProgType[MenuSelection][ItemSelection] = WPSFOLDER;
  2300.                     if (WinQueryButtonCheckstate( hWnd, OS2WIN ))
  2301.                         ProgType[MenuSelection][ItemSelection] = OS2 + WINDOWED;
  2302.                     if (WinQueryButtonCheckstate( hWnd, OS2FS ))
  2303.                         ProgType[MenuSelection][ItemSelection] = OS2 + FULLSCREEN;
  2304.                     if (WinQueryButtonCheckstate( hWnd, DOSWIN ))
  2305.                         ProgType[MenuSelection][ItemSelection] = DOS + WINDOWED;
  2306.                     if (WinQueryButtonCheckstate( hWnd, DOSFS ))
  2307.                         ProgType[MenuSelection][ItemSelection] = DOS + FULLSCREEN;
  2308.                     if (WinQueryButtonCheckstate( hWnd, WINOS2WIN ))
  2309.                         ProgType[MenuSelection][ItemSelection] = WINOS2 + WINDOWED;
  2310.                     if (WinQueryButtonCheckstate( hWnd, WINOS2FS ))
  2311.                         ProgType[MenuSelection][ItemSelection] = WINOS2 + FULLSCREEN;
  2312.                     if (WinQueryButtonCheckstate( hWnd, PMAPP ))
  2313.                         ProgType[MenuSelection][ItemSelection] = PM;
  2314.                     if (WinQueryButtonCheckstate( hWnd, MAXIMIZED ))
  2315.                         ProgType[MenuSelection][ItemSelection] = ProgType[MenuSelection][ItemSelection] | STARTMAX;
  2316.                     if (WinQueryButtonCheckstate( hWnd, MINIMIZED ))
  2317.                         ProgType[MenuSelection][ItemSelection] = ProgType[MenuSelection][ItemSelection] | STARTMIN;
  2318.                     if (WinQueryButtonCheckstate( hWnd, STARTWPS ))
  2319.                         ProgType[MenuSelection][ItemSelection] = ProgType[MenuSelection][ItemSelection] | STARTASWPS;
  2320.  
  2321.                     // save name, path, directory, command line args
  2322.                     WinQueryDlgItemText( hWnd, ITEMNAME, MAXITEMNAMELENGTH,
  2323.                                          ItemName[MenuSelection][ItemSelection]);
  2324.                     WinQueryDlgItemText( hWnd, PATHNAME, MAXACTIONSTRINGLENGTH,
  2325.                                          ActionToDo[MenuSelection][ItemSelection]);
  2326.                     WinQueryDlgItemText( hWnd, ARGUMENTS, MAXARGSTRINGLENGTH,
  2327.                                          CmdLnArgs[MenuSelection][ItemSelection]);
  2328.                     WinQueryDlgItemText( hWnd, DIRECTORY, MAXDIRSTRINGLENGTH,
  2329.                                          Directory[MenuSelection][ItemSelection]);
  2330.                     UpdateMenu[MenuSelection] = TRUE;
  2331.                     WinDismissDlg( hWnd, TRUE );
  2332.                     return 0;
  2333.                     }
  2334.             default:
  2335.                 return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2336.             }
  2337.         }
  2338.         //----------------------------------------------------------------------
  2339.         // if nothing further we want to intercept, pass message onto system
  2340.         //----------------------------------------------------------------------
  2341.         default:
  2342.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2343.     }
  2344. }
  2345.  
  2346.  
  2347. ////////////////////////////////////////////////////////////////////////////////
  2348. // AddAnItemProc - the message handler for the "add an item to a menu" dialog
  2349. ////////////////////////////////////////////////////////////////////////////////
  2350. MRESULT EXPENTRY AddAnItemProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  2351. {
  2352.    switch( msg )
  2353.     {
  2354.         //----------------------------------------------------------------------
  2355.         // when the dialog is being initialized, center it on desktop and put
  2356.         // the current data into control fields
  2357.         //----------------------------------------------------------------------
  2358.         case WM_INITDLG: {
  2359.             SWP swp;
  2360.             WinSendDlgItemMsg( hWnd, ITEMNAME, EM_SETTEXTLIMIT,
  2361.                                MPFROM2SHORT( MAXITEMNAMELENGTH-1, 0 ), 0 );
  2362.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  2363.             WinSetWindowPos( hWnd, (HWND)0,
  2364.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  2365.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  2366.                              0, 0, SWP_MOVE);
  2367.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2368.             }
  2369.         //----------------------------------------------------------------------
  2370.         // process a command message received from the system
  2371.         //----------------------------------------------------------------------
  2372.         case WM_COMMAND:
  2373.         {
  2374.             USHORT command = SHORT1FROMMP(mp1);
  2375.             switch( command )
  2376.                 {
  2377.                 //--------------------------------------------------------------
  2378.                 // if they pressed OK, then save the data in the dialog as an
  2379.                 // item that we can now launch from the fileBar.
  2380.                 //--------------------------------------------------------------
  2381.                 case DID_OK: {
  2382.                     WinQueryDlgItemText( hWnd, ITEMNAME, MAXMENUNAMELENGTH, ItemName[MenuSelection][ (NumItems[MenuSelection]) ]);
  2383.                     ActionToDo[MenuSelection][ (NumItems[MenuSelection]) ][0] = '\0';
  2384.                     CmdLnArgs[MenuSelection][ (NumItems[MenuSelection]) ][0] = '\0';
  2385.                     Directory[MenuSelection][ (NumItems[MenuSelection]) ][0] = '\0';
  2386.                     ProgType[MenuSelection][ (NumItems[MenuSelection]) ] = PM;
  2387.                     UpdateMenu[MenuSelection] = TRUE;
  2388.                     WinDismissDlg( hWnd, TRUE );
  2389.                     ItemSelection = NumItems[MenuSelection];
  2390.                     NumItems[MenuSelection]++;
  2391.                     WinDlgBox(HWND_DESKTOP,
  2392.                               hWnd,
  2393.                               (PFNWP)EditItemDataProc,
  2394.                               0,
  2395.                               EDITITEMDATA,
  2396.                               (PVOID)NULL);
  2397.                     return 0;
  2398.                     }
  2399.                 //--------------------------------------------------------------
  2400.                 // if they pressed cancel, save no data and return
  2401.                 //--------------------------------------------------------------
  2402.                 case DID_CANCEL: {
  2403.                     WinDismissDlg( hWnd, TRUE );
  2404.                     return 0;
  2405.                     }
  2406.                 //--------------------------------------------------------------
  2407.                 // nothing further we care about, pass on for default processing
  2408.                 //--------------------------------------------------------------
  2409.                 default:
  2410.                     return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2411.                 }
  2412.         }
  2413.         //----------------------------------------------------------------------
  2414.         // if nothing further we want to intercept, pass message onto system
  2415.         //----------------------------------------------------------------------
  2416.         default:
  2417.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2418.     }
  2419. }
  2420.  
  2421.  
  2422. ////////////////////////////////////////////////////////////////////////////////
  2423. // Message handler for a generic information-only dialog box (help & prod info)
  2424. ////////////////////////////////////////////////////////////////////////////////
  2425. MRESULT EXPENTRY EnterParamProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  2426. {
  2427.    switch( msg )
  2428.     {
  2429.         //----------------------------------------------------------------------
  2430.         // when the dialog is being initialized, center it on desktop
  2431.         //----------------------------------------------------------------------
  2432.         case WM_INITDLG: {
  2433.             SWP swp;
  2434.  
  2435.             WinSetWindowText( hWnd, parameterTitle );
  2436.             WinSetDlgItemText( hWnd, PARAMETER_TEXT, ParameterTextPtr );
  2437.             WinSendDlgItemMsg( hWnd, PARAMETER_TEXT, EM_SETTEXTLIMIT, MPFROMSHORT( sizeof(variableText) ), 0 );
  2438.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  2439.             WinSetWindowPos( hWnd, (HWND)0,
  2440.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  2441.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  2442.                              0, 0, SWP_MOVE);
  2443.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2444.             }
  2445.         //----------------------------------------------------------------------
  2446.         // if we receive any system message, dismiss the dialog box
  2447.         //----------------------------------------------------------------------
  2448.         case WM_COMMAND:
  2449.         {
  2450.             WinQueryDlgItemText( hWnd, PARAMETER_EDIT, sizeof(variableText), (PSZ)variableText );
  2451.             WinDismissDlg( hWnd, TRUE );
  2452.             return 0;
  2453.         }
  2454.         //----------------------------------------------------------------------
  2455.         // if nothing further we want to intercept, pass message onto system
  2456.         //----------------------------------------------------------------------
  2457.         default:
  2458.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2459.     }
  2460. }
  2461.  
  2462.  
  2463. ////////////////////////////////////////////////////////////////////////////////
  2464. // startApplication uses DosStartSession to start a batch file to start an
  2465. // application pointed to in one of the user menus by menu and item variables.
  2466. ////////////////////////////////////////////////////////////////////////////////
  2467. SHORT startApplication( SHORT menu, SHORT item )
  2468. {
  2469.     CHAR parameters[MAXARGSTRINGLENGTH];
  2470.     CHAR itemName[MAXITEMNAMELENGTH];
  2471.     RXSTRING  INSTORE[2];
  2472.     RXSTRING  retstr;
  2473.     APIRET rc;
  2474.     STARTDATA startData;
  2475.     ULONG sessionId;
  2476.     PID ppId;
  2477.     UCHAR ObjBuf[2];
  2478.     SHORT ReturnCode;
  2479.     LONG offset;
  2480.  
  2481.     {
  2482.     short y1=0;
  2483.     short y2=0;
  2484.  
  2485.     while (ItemName[menu][item][y1]!='\0') {
  2486.         if (ItemName[menu][item][y1]!='~')
  2487.             itemName[y2++] = ItemName[menu][item][y1];
  2488.         y1++;
  2489.         }
  2490.     itemName[y2] = '\0';
  2491.     }
  2492.  
  2493.  
  2494.     {
  2495.     short i = 0;
  2496.     short h = 0;
  2497.  
  2498.     while ( CmdLnArgs[menu][item][i] != '\0' ) {
  2499.         if (CmdLnArgs[menu][item][i] == STARTINPUT) {
  2500.             short j = 0;
  2501.             CHAR tmp[MAXARGSTRINGLENGTH];
  2502.  
  2503.             i++;
  2504.             while ( (CmdLnArgs[menu][item][i] != '\0') &&
  2505.                     (CmdLnArgs[menu][item][i] != ENDINPUT ))
  2506.                 tmp[j++] = CmdLnArgs[menu][item][i++];
  2507.             tmp[j] = '\0';
  2508.  
  2509.             if (CmdLnArgs[menu][item][i] != '\0')
  2510.                 i++;
  2511.  
  2512.             parameters[h++] = '*';
  2513.             {
  2514.                 CHAR mesg[512];
  2515.                 SHORT k = 0;
  2516.  
  2517.                 sprintf( parameterTitle, "%s parameter...", ItemName[menu][item] );
  2518.                 sprintf( mesg, "Please enter '%s'", tmp);
  2519.                 ParameterTextPtr = mesg;
  2520.                 (VOID*)WinDlgBox(HWND_DESKTOP,
  2521.                                  hwndFrame,
  2522.                                  (PFNWP)EnterParamProc,
  2523.                                  0,
  2524.                                  ENTERPARAMETER,
  2525.                                  (PVOID)NULL);
  2526.  
  2527.                 while ( variableText[k] != '\0')
  2528.                     parameters[h++] = variableText[k++];
  2529.             }
  2530.             parameters[h++] = '*';
  2531.  
  2532.             }
  2533.         else
  2534.             parameters[h++] = CmdLnArgs[menu][item][i++];
  2535.         }
  2536.         parameters[h] = '\0';
  2537.     }
  2538.  
  2539.     //--------------------------------------------------------------------------
  2540.     // open a WPS folder/object
  2541.     //--------------------------------------------------------------------------
  2542.     if ((ProgType[menu][item] & WPSFOLDER) || (ProgType[menu][item] & STARTASWPS)) {
  2543.         char mesg[CCHMAXPATH+CCHMAXPATH+256];
  2544.  
  2545.         offset = 0;
  2546.         offset = offset + sprintf(mesg+offset, "/* */\r\n");
  2547.         offset = offset + sprintf(mesg+offset, "call RxFuncAdd 'SysSetObjectData', 'RexxUtil', 'SysSetObjectData'\r\n");
  2548.  
  2549.         if (ProgType[menu][item] & WPSFOLDER)
  2550.             offset = offset + sprintf(mesg+offset, "result = SysSetObjectData(\"%s%s\",\"OPEN=DEFAULT\")\r\n", Directory[menu][item],ActionToDo[menu][item]);
  2551.         else
  2552.             offset = offset + sprintf(mesg+offset, "result = SysSetObjectData(\"%s\",\"OPEN=DEFAULT\")\r\n", ActionToDo[menu][item]);
  2553.  
  2554.         offset = offset + sprintf(mesg+offset, "\x1A\0");
  2555.  
  2556.         INSTORE[0].strptr=mesg;
  2557.         INSTORE[0].strlength=strlen(mesg);
  2558.         INSTORE[1].strptr=NULL;
  2559.         INSTORE[1].strlength=0;
  2560.  
  2561.         rc = rexxStart((LONG)0,
  2562.                   (PRXSTRING)0,
  2563.                   (PSZ)LAUNCHFILE,
  2564.                   (PRXSTRING)INSTORE,
  2565.                   (PSZ)"CMD",
  2566.                   (LONG)RXCOMMAND,
  2567.                   (PRXSYSEXIT)0,
  2568.                   (SHORT*)&ReturnCode,
  2569.                   (PRXSTRING)&retstr);
  2570.  
  2571.         if (!rc) {
  2572.                 ULONG numItems;
  2573.                 ULONG Buffer;
  2574.                 PSWBLOCK SwitchBlockPtr;
  2575.                 HSWITCH hSwitch;
  2576.  
  2577.                 numItems = WinQuerySwitchList( hab, NULL, 0 );
  2578.                 Buffer = (numItems * sizeof(SWENTRY)) + sizeof(HSWITCH);
  2579.                 PVOID my = new BYTE[Buffer];
  2580.                 WinQuerySwitchList( hab, (SWBLOCK*)my, Buffer );
  2581.                 SwitchBlockPtr = (PSWBLOCK)(my);
  2582.  
  2583.                 hSwitch = WinQuerySwitchHandle( SwitchBlockPtr->aswentry[numItems-1].swctl.hwnd,
  2584.                                                 SwitchBlockPtr->aswentry[numItems-1].swctl.idProcess);
  2585.                 delete( my );
  2586.                 rc = WinSwitchToProgram( hSwitch );
  2587.                 }
  2588.  
  2589.         return rc;
  2590.         }
  2591.  
  2592.     //--------------------------------------------------------------------------
  2593.     // launch a windows app
  2594.     //--------------------------------------------------------------------------
  2595.     // if ((ProgType[menu][item] & WINOS2) && (ProgType[menu][item] & WINDOWED)) {
  2596.     if (ProgType[menu][item] & WINOS2) {
  2597.         FILE* outputFile;
  2598.         STARTDATA startData;
  2599.  
  2600.         outputFile = fopen(LAUNCHFILE, "wt");
  2601.         if (!outputFile) {
  2602.             char title[] = "Launch an application";
  2603.             char text[] = "Could not start the application due to an error accessing the drive";
  2604.             WinMessageBox( HWND_DESKTOP, hwndFrame, text, title, 0,
  2605.                            MB_MOVEABLE|MB_ERROR|MB_OK);
  2606.             return 0;
  2607.             }
  2608.  
  2609.         if (Directory[menu][item][0] != '\0') {
  2610.             if ((isalpha( Directory[menu][item][0] )) && ( Directory[menu][item][1]==':'))
  2611.                 fprintf( outputFile, "%c:\n", Directory[menu][item][0]);
  2612.             fprintf( outputFile, "cd %s\n", Directory[menu][item]);
  2613.             }
  2614.  
  2615.         fprintf( outputFile, "start /C " );
  2616.         if (ProgType[menu][item] & STARTMAX)
  2617.             fprintf( outputFile, "/MAX ");
  2618.         else if (ProgType[menu][item] & STARTMIN)
  2619.             fprintf( outputFile, "/MIN ");
  2620.         if (ProgType[menu][item] & WINDOWED)
  2621.             fprintf( outputFile, "/WIN ");
  2622.         else if (ProgType[menu][item] & FULLSCREEN)
  2623.             fprintf( outputFile, "/FS ");
  2624.  
  2625.         fprintf( outputFile, "%s %s", ActionToDo[menu][item], parameters );
  2626.         fclose( outputFile );
  2627.  
  2628.         {
  2629.         CHAR title[] = "FileBar -\nWIN-OS/2 Launch";
  2630.         CHAR program[] = OS2SHELL;
  2631.         CHAR inputs[] = LAUNCHINPUTS;
  2632.  
  2633.         memset( &startData, 0, sizeof(STARTDATA) );
  2634.         startData.Related = SSF_RELATED_INDEPENDENT;
  2635.         startData.FgBg = SSF_FGBG_FORE;
  2636.         startData.TraceOpt = SSF_TRACEOPT_NONE;
  2637.         startData.InheritOpt = SSF_INHERTOPT_PARENT;
  2638.         startData.SessionType = SSF_TYPE_WINDOWABLEVIO;
  2639.         startData.PgmControl = SSF_CONTROL_INVISIBLE | SSF_CONTROL_MINIMIZE;
  2640.         startData.PgmTitle = title;
  2641.         startData.PgmName = program;
  2642.         startData.PgmInputs = inputs;
  2643.         startData.ObjectBuffer = ObjBuf;
  2644.         startData.ObjectBuffLen = sizeof(ObjBuf);
  2645.         startData.Length = sizeof(STARTDATA);
  2646.  
  2647.         return DosStartSession( (STARTDATA*) &startData, (ULONG*)&sessionId,
  2648.                                 (PID*) &ppId );
  2649.         }
  2650.     }
  2651.     //--------------------------------------------------------------------------
  2652.     /*
  2653.     //// this doesn't work to start a seamless app and I don't know why!!  :(
  2654.  
  2655.     if ((ProgType[menu][item] & WINOS2) && (ProgType[menu][item] & WINDOWED)) {
  2656.         APIRET rc;
  2657.         PROGDETAILS pDetails;
  2658.  
  2659.         memset( &pDetails, 0, sizeof(PROGDETAILS) );
  2660.         pDetails.Length = sizeof(PROGDETAILS);
  2661.         pDetails.progt.progc = PROG_WINDOWABLEVIO;
  2662.         pDetails.progt.fbVisible = SHE_VISIBLE;
  2663.         pDetails.pszTitle = 0;  //ItemName[menu][item];
  2664.         pDetails.pszExecutable = "\\os2\\te2\\te2.exe";  //ActionToDo[menu][item];
  2665.  
  2666.         //pDetails.pszParameters = "";
  2667.         //pDetails.pszIcon = "C:\\OS2\\FILEBAR\\FILEBAR.ICO";
  2668.         //pDetails.pszEnvironment = "WORKPLACE\0\0";
  2669.  
  2670.         //pDetails.pszParameters = CmdLnArgs[menu][item];
  2671.         //pDetails.pszStartupDir = "d:\os2\mdos\winos2";   //Directory[menu][item];
  2672.         pDetails.swpInitial.fl = SWP_ACTIVATE;
  2673.  
  2674.         if (ProgType[menu][item] & STARTMAX)
  2675.             rc = WinStartApp(NULLHANDLE, &pDetails, CmdLnArgs[menu][item], NULL, 4 );
  2676.         else if (ProgType[menu][item] & STARTMIN)
  2677.             rc = WinStartApp(NULLHANDLE, &pDetails, CmdLnArgs[menu][item], NULL, 8 );
  2678.         else rc = WinStartApp(NULLHANDLE, &pDetails, CmdLnArgs[menu][item], NULL, 0 );
  2679.  
  2680.         if (rc==0) {
  2681.            ERRORID errorID = WinGetLastError( hab );
  2682.            char text[1024];
  2683.            sprintf(text, "error code %lu\0", errorID);
  2684.            WinMessageBox( HWND_DESKTOP, hwndFrame, text, NULL, 0,
  2685.                           MB_MOVEABLE|MB_ERROR|MB_OK);
  2686.            }
  2687.  
  2688.         return 0;
  2689.         }
  2690.     */
  2691.     //--------------------------------------------------------------------------
  2692.     // this launches a command shell (DOS or OS2 (Windowed or FS session))
  2693.     //--------------------------------------------------------------------------
  2694.     if (ActionToDo[menu][item][0] == '\0') {
  2695.         ULONG currentDrive;
  2696.         ULONG driveMap;
  2697.         CHAR InputDir[CCHMAXPATH + 16];
  2698.  
  2699.         DosQueryCurrentDisk( ¤tDrive, &driveMap );
  2700.         DosSetDefaultDisk( (ULONG)(toupper(Directory[menu][item][0])-'A' + 1) );
  2701.  
  2702.         memset( &startData, 0, sizeof(STARTDATA) );
  2703.         startData.Related = SSF_RELATED_INDEPENDENT;
  2704.         startData.FgBg = SSF_FGBG_FORE;
  2705.         startData.TraceOpt = SSF_TRACEOPT_NONE;
  2706.         startData.InheritOpt = SSF_INHERTOPT_PARENT;
  2707.         startData.ObjectBuffer = ObjBuf;
  2708.         startData.ObjectBuffLen = sizeof(ObjBuf);
  2709.         startData.Length = sizeof(STARTDATA);
  2710.         startData.PgmTitle = itemName;
  2711.         strcpy( InputDir, "/K cd  \0");
  2712.         strcpy( InputDir+6, Directory[menu][item] );
  2713.         startData.PgmInputs = InputDir;
  2714.  
  2715.         startData.PgmControl = SSF_CONTROL_VISIBLE;
  2716.         if (ProgType[menu][item] & MAXIMIZED)
  2717.             startData.PgmControl = SSF_CONTROL_VISIBLE | SSF_CONTROL_MAXIMIZE;
  2718.         else if (ProgType[menu][item] & MINIMIZED)
  2719.             startData.PgmControl = SSF_CONTROL_VISIBLE | SSF_CONTROL_MINIMIZE;
  2720.  
  2721.         if (ProgType[menu][item] & DOS) {
  2722.             if (ProgType[menu][item] & WINDOWED)
  2723.                 startData.SessionType = SSF_TYPE_WINDOWEDVDM;
  2724.             else
  2725.                 startData.SessionType = SSF_TYPE_VDM;
  2726.             rc = DosStartSession( (STARTDATA*) &startData, (ULONG*)&sessionId,
  2727.                                   (PID*) &ppId );
  2728.             DosSetDefaultDisk( currentDrive );
  2729.             return rc;
  2730.             }
  2731.         else if (ProgType[menu][item] & OS2) {
  2732.             if (ProgType[menu][item] & WINDOWED)
  2733.                 startData.SessionType = SSF_TYPE_WINDOWABLEVIO;
  2734.             else
  2735.                 startData.SessionType = SSF_TYPE_FULLSCREEN;
  2736.             rc = DosStartSession( (STARTDATA*) &startData, (ULONG*)&sessionId,
  2737.                                   (PID*) &ppId );
  2738.             DosSetDefaultDisk( currentDrive );
  2739.             return rc;
  2740.             }
  2741.         DosBeep(100,200);
  2742.         return 0;
  2743.         }
  2744.  
  2745.     //--------------------------------------------------------------------------
  2746.     // this section of code launches a program (non-command shell application)
  2747.     //--------------------------------------------------------------------------
  2748.     {
  2749.     APIRET rc;
  2750.     ULONG currentDrive;
  2751.     ULONG driveMap;
  2752.     UCHAR defaultDirectory[CCHMAXPATH];
  2753.     CHAR title[MAXITEMNAMELENGTH];
  2754.     CHAR program[CCHMAXPATH];
  2755.     CHAR inputs[MAXARGSTRINGLENGTH];
  2756.  
  2757.     strcpy(program, ActionToDo[menu][item]);
  2758.     strcpy(inputs, parameters );
  2759.     strcpy(title, ItemName[menu][item]);
  2760.  
  2761.     memset( &startData, 0, sizeof(STARTDATA) );
  2762.     startData.Length = sizeof(STARTDATA);
  2763.     startData.Related = SSF_RELATED_INDEPENDENT;
  2764.     startData.FgBg = SSF_FGBG_FORE;
  2765.     startData.TraceOpt = SSF_TRACEOPT_NONE;
  2766.     startData.PgmTitle = itemName;
  2767.     startData.InheritOpt = SSF_INHERTOPT_PARENT;
  2768.     startData.SessionType = SSF_TYPE_WINDOWABLEVIO;
  2769.     startData.PgmControl = SSF_CONTROL_VISIBLE;
  2770.     startData.SessionType = SSF_TYPE_PM;
  2771.     startData.PgmName = program;
  2772.     startData.PgmInputs = inputs;
  2773.  
  2774.     if (ProgType[menu][item] & DOS) {
  2775.         if (ProgType[menu][item] & FULLSCREEN)
  2776.             startData.SessionType = SSF_TYPE_VDM;
  2777.         else if (ProgType[menu][item] & WINDOWED)
  2778.             startData.SessionType = SSF_TYPE_WINDOWEDVDM;
  2779.         }
  2780.     else if (ProgType[menu][item] & OS2) {
  2781.         if (ProgType[menu][item] & FULLSCREEN)
  2782.             startData.SessionType = SSF_TYPE_FULLSCREEN;
  2783.         else if (ProgType[menu][item] & WINDOWED)
  2784.             startData.SessionType = SSF_TYPE_WINDOWABLEVIO;
  2785.         }
  2786.     else if (ProgType[menu][item] & WINOS2)
  2787.         startData.SessionType = SSF_TYPE_FULLSCREEN;
  2788.  
  2789.  
  2790.     if (ProgType[menu][item] & STARTMAX)
  2791.         startData.PgmControl |= SSF_CONTROL_MAXIMIZE;
  2792.     else if (ProgType[menu][item] & STARTMIN)
  2793.         startData.PgmControl |= SSF_CONTROL_MINIMIZE;
  2794.  
  2795.     if ((startData.PgmName != NULL) && (startData.SessionType != SSF_TYPE_PM)) {
  2796.         CHAR temp[CCHMAXPATH*2+5];
  2797.         sprintf(temp, "/c %s %s\0", program, inputs);
  2798.         startData.PgmName = 0;
  2799.         strcpy(inputs, temp);
  2800.         startData.PgmInputs = inputs;
  2801.         }
  2802.  
  2803.     // save current drive and directory
  2804.     DosQueryCurrentDisk( ¤tDrive, &driveMap );
  2805.     {
  2806.         CHAR temp[CCHMAXPATH+5];
  2807.         ULONG tempSize = CCHMAXPATH;
  2808.         defaultDirectory[0]= (currentDrive+'A'-1);
  2809.         defaultDirectory[1]= ':';
  2810.         defaultDirectory[2]= '\\';
  2811.         defaultDirectory[3]= '\0';
  2812.         DosQueryCurrentDir( currentDrive, (CHAR*)&temp, &tempSize );
  2813.         strcat( defaultDirectory, temp );
  2814.     }
  2815.  
  2816.     // point to working directory of program to execute
  2817.     if (((toupper(Directory[menu][item][0]))>='A') && ((toupper(Directory[menu][item][0]))<='Z'))
  2818.         DosSetDefaultDisk( (ULONG)(toupper(Directory[menu][item][0])-'A' + 1) );
  2819.     DosSetCurrentDir( Directory[menu][item] );
  2820.  
  2821.     rc = DosStartSession( (STARTDATA*) &startData, (ULONG*)&sessionId,
  2822.                      (PID*) &ppId );
  2823.  
  2824.     // restore current drive and directory
  2825.     DosSetDefaultDisk( currentDrive );
  2826.     DosSetCurrentDir( defaultDirectory );
  2827.  
  2828.     if (rc != 0) {
  2829.         char text[] = "Could not open the specified item.  Path and directory information may not be correct.";
  2830.         char title[32];
  2831.  
  2832.         sprintf( title, "FileBar Launch Error");
  2833.         WinMessageBox( HWND_DESKTOP, hwndFrame, text, title, 0,
  2834.                        MB_MOVEABLE|MB_ERROR|MB_OK);
  2835.         }
  2836.  
  2837.     return rc;
  2838.     }
  2839. }
  2840.  
  2841.  
  2842. ////////////////////////////////////////////////////////////////////////////////
  2843. // display a background bitmap
  2844. ////////////////////////////////////////////////////////////////////////////////
  2845. VOID displayBackground( VOID )
  2846. {
  2847.     DESKTOP desktop;
  2848.  
  2849.     if ((showBackground) || (isBackgroundDisplayed)) {
  2850.         desktop.cbSize = sizeof( DESKTOP );
  2851.         desktop.hbm = 0;
  2852.         desktop.x = 0;
  2853.         desktop.y = 0;
  2854.         desktop.fl = SDT_DESTROY;
  2855.         if (isBackgroundDisplayed)
  2856.             WinSetDesktopBkgnd( HWND_DESKTOP, &desktop );
  2857.  
  2858.         desktop.fl = SDT_LOADFILE;
  2859.         if (backgroundAttr & SCALED)
  2860.             desktop.fl = SDT_SCALE|SDT_LOADFILE;
  2861.         if (backgroundAttr & TILED) {
  2862.             desktop.fl = SDT_TILE|SDT_LOADFILE;
  2863.             desktop.lTileCount = backgroundAttr - TILED;
  2864.             }
  2865.         strcpy( desktop.szFile, backgroundBitmap );
  2866.         if (showBackground) {
  2867.             WinSetDesktopBkgnd( HWND_DESKTOP, &desktop );
  2868.             isBackgroundDisplayed = TRUE;
  2869.             }
  2870.         }
  2871. }
  2872.  
  2873.  
  2874. ////////////////////////////////////////////////////////////////////////////////
  2875. // Message handler for a generic information-only dialog box (help & prod info)
  2876. ////////////////////////////////////////////////////////////////////////////////
  2877. MRESULT EXPENTRY backgroundProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  2878. {
  2879.    switch( msg )
  2880.     {
  2881.         //----------------------------------------------------------------------
  2882.         // when the dialog is being initialized, center it on desktop
  2883.         //----------------------------------------------------------------------
  2884.         case WM_INITDLG: {
  2885.             SWP swp;
  2886.             char temp[12];
  2887.  
  2888.             WinCheckButton( hWnd, BKGND_NORMAL, TRUE );
  2889.             if (backgroundAttr & SCALED)
  2890.                 WinCheckButton( hWnd, BKGND_SCALED, TRUE );
  2891.             else if (backgroundAttr & TILED) {
  2892.                 WinCheckButton( hWnd, BKGND_TILED, TRUE );
  2893.                 WinEnableControl( hWnd, BKGND_TILENUMBER, TRUE );
  2894.                 WinEnableControl( hWnd, BKGND_TILENUMBERTEXT, TRUE );
  2895.                 WinEnableControl( hWnd, BKGND_LESS, TRUE );
  2896.                 WinEnableControl( hWnd, BKGND_MORE, TRUE );
  2897.                 }
  2898.  
  2899.             if (backgroundAttr & SCALED)
  2900.                 backgroundAttr = backgroundAttr - SCALED;
  2901.             if (backgroundAttr & TILED)
  2902.                 backgroundAttr = backgroundAttr - TILED;
  2903.  
  2904.             sprintf(temp,"%d x %d", backgroundAttr, backgroundAttr);
  2905.             WinSetDlgItemText( hWnd, BKGND_TILENUMBER, temp );
  2906.  
  2907.             WinSendDlgItemMsg( hWnd, BKGND_BITMAPNAME, EM_SETTEXTLIMIT, MPFROMSHORT( sizeof(backgroundBitmap) ), 0 );
  2908.             WinSetDlgItemText( hWnd, BKGND_BITMAPNAME, backgroundBitmap );
  2909.  
  2910.             WinCheckButton( hWnd, BKGND_SHOW, showBackground );
  2911.             WinQueryWindowPos( hWnd, (PSWP)&swp);
  2912.             WinSetWindowPos( hWnd, (HWND)0,
  2913.                              ((SHORT)((ScreenSizeX-swp.cx)/2)),
  2914.                              ((SHORT)((ScreenSizeY-swp.cy)/2)),
  2915.                              0, 0, SWP_MOVE);
  2916.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2917.             }
  2918.         //----------------------------------------------------------------------
  2919.         //----------------------------------------------------------------------
  2920.         case WM_CONTROL:
  2921.         {
  2922.             if (SHORT2FROMMP(mp1)==BN_CLICKED) {
  2923.                 BOOL option = FALSE;
  2924.                 if (WinQueryButtonCheckstate( hWnd, BKGND_TILED))
  2925.                     option = TRUE;
  2926.                 WinEnableControl( hWnd, BKGND_TILENUMBER, option );
  2927.                 WinEnableControl( hWnd, BKGND_TILENUMBERTEXT, option );
  2928.                 WinEnableControl( hWnd, BKGND_LESS, option );
  2929.                 WinEnableControl( hWnd, BKGND_MORE, option );
  2930.                 }
  2931.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  2932.         }
  2933.         //----------------------------------------------------------------------
  2934.         //----------------------------------------------------------------------
  2935.         case WM_COMMAND:
  2936.         {
  2937.             USHORT command = SHORT1FROMMP(mp1);
  2938.             switch( command )
  2939.                 {
  2940.                 //--------------------------------------------------------------
  2941.                 // if they pressed OK, then save the data in the dialog as an
  2942.                 // item that we can now launch from the fileBar.
  2943.                 //--------------------------------------------------------------
  2944.                 case DID_OK: {
  2945.                     WinQueryDlgItemText( hWnd, BKGND_BITMAPNAME, sizeof(backgroundBitmap), (PSZ)backgroundBitmap );
  2946.                     showBackground = WinQueryButtonCheckstate( hWnd, BKGND_SHOW );
  2947.                     if (WinQueryButtonCheckstate( hWnd, BKGND_SCALED))
  2948.                         backgroundAttr = backgroundAttr + SCALED;
  2949.                     if (WinQueryButtonCheckstate( hWnd, BKGND_TILED))
  2950.                         backgroundAttr = backgroundAttr + TILED;
  2951.                     WinDismissDlg( hWnd, TRUE );
  2952.                     return 0;
  2953.                     }
  2954.                 case BKGND_LESS: {
  2955.                     char temp[12];
  2956.  
  2957.                     if (backgroundAttr > 1)
  2958.                         backgroundAttr--;
  2959.                     sprintf(temp,"%d x %d", backgroundAttr, backgroundAttr);
  2960.                     WinSetDlgItemText( hWnd, BKGND_TILENUMBER, temp );
  2961.                     return 0;
  2962.                     }
  2963.                 case BKGND_MORE: {
  2964.                     char temp[12];
  2965.  
  2966.                     if (backgroundAttr < 32)
  2967.                         backgroundAttr++;
  2968.                     sprintf(temp,"%d x %d", backgroundAttr, backgroundAttr);
  2969.                     WinSetDlgItemText( hWnd, BKGND_TILENUMBER, temp );
  2970.                     return 0;
  2971.                     }
  2972.                 case BKGND_FINDFILE: {
  2973.                     CHAR title[] = "FileBar - Find A Background Image";
  2974.                     ULONG s;
  2975.                     HWND hwndDialog;
  2976.  
  2977.                     fileDlgInfo.fl = FDS_OPEN_DIALOG|FDS_CENTER;
  2978.                     fileDlgInfo.pszTitle = title;
  2979.                     strcat(fileDlgInfo.szFullFile, "*.BMP\0");
  2980.  
  2981.                     hwndDialog = WinFileDlg( HWND_DESKTOP, hWnd, &fileDlgInfo );
  2982.                     if (hwndDialog && (fileDlgInfo.lReturn == DID_OK)) {
  2983.  
  2984.                         strcpy( backgroundBitmap, fileDlgInfo.szFullFile );
  2985.  
  2986.                         s=0;
  2987.                         while(fileDlgInfo.szFullFile[s]!='\0')
  2988.                             s++;
  2989.                         while((fileDlgInfo.szFullFile[s]!='\\') && (s>=0))
  2990.                             s--;
  2991.  
  2992.                         if (fileDlgInfo.szFullFile[s]=='\\')
  2993.                             fileDlgInfo.szFullFile[s+1]='\0';
  2994.                         else
  2995.                             fileDlgInfo.szFullFile[0]='\0';
  2996.                         WinSetDlgItemText( hWnd, BKGND_BITMAPNAME, backgroundBitmap );
  2997.                         }
  2998.                     else
  2999.                         fileDlgInfo.szFullFile[0]='\0';
  3000.                     return 0;
  3001.                     }
  3002.             }
  3003.         }
  3004.         //----------------------------------------------------------------------
  3005.         // if nothing further we want to intercept, pass message onto system
  3006.         //----------------------------------------------------------------------
  3007.         default:
  3008.             return WinDefDlgProc( hWnd, msg, mp1, mp2 );
  3009.     }
  3010. }
  3011.  
  3012.  
  3013.  
  3014.