home *** CD-ROM | disk | FTP | other *** search
Wrap
//////////////////////////////////////////////////////////////////////////////// // // FileBar // // OS/2 Application Launch Facility and WPS Shell Replacement // // Written By Eric A. Wolf // Copyright (C) 1994 - All Rights Reserved // // This source code may be used for reference ONLY! It is provided AS-IS and no // guarantees are made as to its utility, functionality or correctness. It is // provided solely as a guide to aid aspiring OS/2 2.x Presentation Manager // programmers in developing their own PM applications. No modifications are // to be made to this code for re-release as a same or different product. This // code must be distributed (in its original entirety) with the executable // portion of this product. // // -- Please register this shareware product for $10 today -- // See documentation for details // // Project Start Date: December 26, 1993 // Project Completion Date: January 3, 1994 // // Written using Borland C++ for OS/2, version 1.0, Borland Resource Workshop, // and the IBM OS/2 2.1 bitmap/icon editor // // File Last Modified: March 8, 1994 // //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // set compile-time flags for what os/2 header information should be included //////////////////////////////////////////////////////////////////////////////// #define INCL_PM #define INCL_DOSSESMGR #define INCL_DOSERRORS #define INCL_DOSMISC #define INCL_WINPOINTERS #define INCL_WINPROGRAMLIST #define INCL_WINSTDFILE #define INCL_WINWORKPLACE #define INCL_DOSPROCESS //////////////////////////////////////////////////////////////////////////////// // include C, C++, OS/2, application and resource header files //////////////////////////////////////////////////////////////////////////////// #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <time.h> #include "filebar.h" #include "dll/filebar.h" // include DLL function prototypes //////////////////////////////////////////////////////////////////////////////// // MakeHourglassPointer - macro to make the mouse pointer the hourglass //////////////////////////////////////////////////////////////////////////////// #define MakeHourglassPointer() { \ HPOINTER pointer; \ pointer = WinQuerySysPointer( HWND_DESKTOP, SPTR_WAIT, FALSE);\ WinSetPointer( HWND_DESKTOP, pointer ); \ } //////////////////////////////////////////////////////////////////////////////// // MakeArrowPointer - macro to make the mouse pointer the arrow //////////////////////////////////////////////////////////////////////////////// #define MakeArrowPointer() { \ HPOINTER pointer; \ pointer = WinQuerySysPointer( HWND_DESKTOP, SPTR_ARROW, FALSE);\ WinSetPointer( HWND_DESKTOP, pointer ); \ } //////////////////////////////////////////////////////////////////////////////// // writeString - writes a string out with quotes on either side //////////////////////////////////////////////////////////////////////////////// #define writeString(stream, string) fprintf(stream, "\"%s\"\n", string) //////////////////////////////////////////////////////////////////////////////// // define application constants //////////////////////////////////////////////////////////////////////////////// #define EXTERN #define TEMPSTRING 64 #define AT_TOP TRUE #define AT_BOTTOM FALSE #define TIMERID 1 #define MAXTASKS 30 #define MAXMENUS 7 #define MAXITEMS 24 #define MAXPATH CCHMAXPATH+1 #define MAXACTIONSTRINGLENGTH MAXPATH #define MAXITEMNAMELENGTH 24 #define MAXMENUNAMELENGTH 20 #define MAXARGSTRINGLENGTH 32 #define MAXDIRSTRINGLENGTH MAXPATH #define WINDOWED 1 #define FULLSCREEN 2 #define PM 4 #define DOS 8 #define OS2 16 #define WINOS2 32 #define STARTMIN 64 #define STARTMAX 128 #define WPSFOLDER 256 #define STARTASWPS 512 #define SCALED 128 #define TILED 64 #define OS2SHELL "CMD.EXE" #define OPTIONFILE "FILEBAR.INI" #define LAUNCHFILE "STARTPRG.CMD" #define LAUNCHINPUTS "/C STARTPRG.CMD" #define SEPARATOR "────────────────────────" #define WPSDESKTOPNAME "Desktop" #define FILEBARMENUON "~FileBar" #define FILEBARMENUOFF "\x04" #define TASKMENUON "~Task List" #define TASKMENUOFF "~Tasks" #define STARTINPUT '[' #define ENDINPUT ']' #define BITMAPNAME "\\FILEBAR.BMP\0" #define CHIMESOUNDFILE "\\CHIME.WAV\0" #define NOCOLOR 1 #define MAXSTARTITEMS 10 #define WPSBUFFER 4096 #define MAXALARMS 32 #define SCHEDULE_EVERYHOUR 1 #define SCHEDULE_EVERYDAY 2 #define SCHEDULE_EVERYWEEK 4 #define SCHEDULE_EVERYMONTH 8 #define SCHEDULE_EVERYYEAR 16 #define SCHEDULE_USEWAVFILE 32 #define SCHEDULE_SOUNDONLY 64 #define SCHEDULE_LAUNCHAPP 128 #define BOOLEAN INT #define LAUNCHED 0 //////////////////////////////////////////////////////////////////////////////// // define function prototypes //////////////////////////////////////////////////////////////////////////////// VOID validateTimeEntry( VOID ); VOID sortTimeEntries( INT ); VOID displayBackground( VOID ); VOID resizeMenu( VOID ); VOID readOptionFile( VOID ); VOID writeOptionFile( VOID ); VOID readString( FILE*, CHAR* ); VOID restartTimer( VOID ); VOID displayTimeDate( VOID ); VOID SwapTwoMenus( SHORT, SHORT ); VOID SwapTwoItems( SHORT, SHORT, SHORT ); VOID updateItemList( HWND ); VOID updateEditItemData( HWND hWnd ); VOID updateEditItemData( HWND hWnd ); VOID ExecuteStartUpList( VOID ); VOID updateCalendar( HWND ); VOID ringChime( CHAR* ); VOID checkAlarms( SHORT, SHORT, SHORT, SHORT, SHORT ); VOID updateTimeDisplay( VOID ); VOID reviseScheduledItem( INT ); BYTE numberOfDaysInMonth( INT, INT ); SHORT startApplication( SHORT, SHORT ); MRESULT EXPENTRY ClientWndProc( HWND, ULONG, MPARAM, MPARAM ); MRESULT EXPENTRY GenericProc( HWND, ULONG, MPARAM, MPARAM ); MRESULT EXPENTRY TimeDateProc( HWND, ULONG, MPARAM, MPARAM ); MRESULT EXPENTRY EditMenuProc( HWND, ULONG, MPARAM, MPARAM ); MRESULT EXPENTRY AddAMenuProc( HWND, ULONG, MPARAM, MPARAM ); MRESULT EXPENTRY EditItemProc( HWND, ULONG, MPARAM, MPARAM ); MRESULT EXPENTRY EditItemDataProc( HWND, ULONG, MPARAM, MPARAM ); MRESULT EXPENTRY AddAnItemProc( HWND, ULONG, MPARAM, MPARAM ); MRESULT EXPENTRY menuHandler( HWND, ULONG, MPARAM, MPARAM ); MRESULT EXPENTRY EnterParamProc( HWND, ULONG, MPARAM, MPARAM ); MRESULT EXPENTRY backgroundProc( HWND, ULONG, MPARAM, MPARAM ); MRESULT EXPENTRY startupProc( HWND, ULONG, MPARAM, MPARAM ); MRESULT EXPENTRY schedulerProc( HWND, ULONG, MPARAM, MPARAM ); MRESULT EXPENTRY scheduleProc( HWND, ULONG, MPARAM, MPARAM ); MRESULT EXPENTRY reminderNoteProc( HWND, ULONG, MPARAM, MPARAM ); MRESULT EXPENTRY itemProc( HWND, ULONG, MPARAM, MPARAM ); MRESULT EXPENTRY showAllItemsProc( HWND, ULONG, MPARAM, MPARAM ); MRESULT EXPENTRY LaunchItemProc( HWND, ULONG, MPARAM, MPARAM ); extern "C" { #define INCL_REXXSAA #include "rexxsaa.h" RexxStart rexxStart; } //////////////////////////////////////////////////////////////////////////////// // define alarm/task scheduler item structure //////////////////////////////////////////////////////////////////////////////// struct ALARMS { BYTE AlarmYear; BYTE AlarmMonth; BYTE AlarmDay; BYTE AlarmHour; BYTE AlarmMinute; BYTE options; CHAR ReminderWAV[MAXACTIONSTRINGLENGTH]; CHAR ActionToDo[MAXACTIONSTRINGLENGTH]; }; //////////////////////////////////////////////////////////////////////////////// // define global variables //////////////////////////////////////////////////////////////////////////////// const BYTE daysInMonth[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; struct ALARMS alarm[MAXALARMS]; HAB hab; HMQ hmq; PID TaskId[MAXTASKS]; PFNWP menuMessageHandler; FILEDLG fileDlgInfo; MENUITEM menuData[MAXMENUS]; LONG ScreenSizeX = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN) + 2; LONG ScreenSizeY = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN); LONG MenuHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU) + 2; LONG sysMenuHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU) + 2; ULONG noteTimerNumber; ULONG timerNumber; ULONG timeOption = TIMEANDDATE; USHORT year; SHORT day; SHORT month; SHORT startDay; SHORT ItemSelection; SHORT MenuSelection; SHORT ProgType[MAXMENUS][MAXITEMS]; SHORT oldProgType; HWND hwndClient; HWND hwndFrame; HWND hwndMenu; HWND TaskHandle[MAXTASKS]; BYTE NumItems[MAXMENUS]; CHAR MenuName[MAXMENUS][MAXMENUNAMELENGTH]; CHAR ItemName[MAXMENUS][MAXITEMS][MAXITEMNAMELENGTH]; CHAR ActionToDo[MAXMENUS][MAXITEMS][MAXACTIONSTRINGLENGTH]; CHAR CmdLnArgs[MAXMENUS][MAXITEMS][MAXARGSTRINGLENGTH]; CHAR Directory[MAXMENUS][MAXITEMS][MAXACTIONSTRINGLENGTH]; CHAR backgroundBitmap[MAXACTIONSTRINGLENGTH]; CHAR hourlyChimeWavFile[MAXACTIONSTRINGLENGTH]; CHAR variableText[MAXARGSTRINGLENGTH-2]; CHAR oldItemName[MAXITEMNAMELENGTH]; CHAR oldDirectory[MAXACTIONSTRINGLENGTH]; CHAR oldAction[MAXACTIONSTRINGLENGTH]; CHAR oldCmdLn[MAXARGSTRINGLENGTH]; CHAR parameterTitle[MAXITEMNAMELENGTH]; CHAR tmpBuffer[MAXPATH]; INT backgroundAttr = 3 + TILED; INT numAlarms = 0; INT numberOfAlarms; INT repeatTime = 60; INT EditItem; INT NumMenus; INT taskItemSelected; INT numStartItems = 0; INT StartUpMenu[MAXSTARTITEMS]; INT StartUpItem[MAXSTARTITEMS]; PCHAR ParameterTextPtr; PCHAR currentReminderWavFile; BOOLEAN alreadyChimed = FALSE; BOOLEAN BarPosition = AT_TOP; BOOLEAN HourlyChime = TRUE; BOOLEAN FileBarMenuOn = TRUE; BOOLEAN timeSync; BOOLEAN checkBeforeDelete = TRUE; BOOLEAN showBackground = FALSE; BOOLEAN isBackgroundDisplayed = FALSE; BOOLEAN startUp = TRUE; BOOLEAN DoStartUpList = FALSE; BOOLEAN UpdateMenu[MAXMENUS]; BOOLEAN maximizeDesktop = FALSE; BOOLEAN interceptMsg = TRUE; //////////////////////////////////////////////////////////////////////////////// // main function - application entry point //////////////////////////////////////////////////////////////////////////////// main( int argc, char* argv[] ) { hab = WinInitialize(0); // handle: anchor block hmq = WinCreateMsgQueue(hab, 0); // handle: message queue CHAR ClassName[] = "FileBar"; // store a name for our class MENUITEM menuItem; // used to modify menu data //-------------------------------------------------------------------------- // register the window class //-------------------------------------------------------------------------- WinRegisterClass(hab, ClassName, // name of class being registered ClientWndProc, // window procedure for class 0, // class style 0); // extra memory to reserve //-------------------------------------------------------------------------- // create a window with a menu bar added on. Note that the menu bar could // be defined in the WinCreateStdWindow call (set the resource id equal= to // MENUBAR) but is not since I need a handle to the menu (so I can later // modify the menu). Thus, WinLoadMenu is used following WinCreateStdWindow //-------------------------------------------------------------------------- ULONG FrameFlags = FCF_AUTOICON|FCF_TASKLIST|FCF_BORDER|FCF_MENU; hwndFrame = WinCreateStdWindow(HWND_DESKTOP, // parent WS_VISIBLE, // style &FrameFlags, // control data ClassName, // client name "FileBar", // title bar text 0, // client style NULLHANDLE, // resource handle MENUBAR, // resource id &hwndClient); // client pointer //-------------------------------------------------------------------------- // move and size application to span entire top of desktop //-------------------------------------------------------------------------- WinSetWindowPos( hwndFrame, (HWND)0, 0, (ScreenSizeY-MenuHeight), ScreenSizeX, MenuHeight, SWP_MOVE|SWP_SIZE|SWP_MINIMIZE); hwndMenu = WinWindowFromID( hwndFrame, FID_MENU ); MakeHourglassPointer (); // switch to hourglass cursor // during initialization //-------------------------------------------------------------------------- // perform basic initialization //-------------------------------------------------------------------------- NumMenus = 0; MenuSelection = 100; // initialize all actions to do nothing for ( short i = 0; i < MAXMENUS; i++ ) for (short j = 0; j < MAXITEMS; j++) ActionToDo[i][j][0] = '\0'; for ( short k = 0; k < MAXMENUS; k++ ) { WinSendMsg( hwndMenu, MM_QUERYITEM, MPFROM2SHORT(100*(k+1),TRUE),MPFROMP(&menuData[k])); menuItem = menuData[k]; menuItem.afStyle = MIS_STATIC; menuItem.afAttribute = MIA_DISABLED; menuItem.hwndSubMenu = (HWND)0; WinSendMsg( hwndMenu, MM_SETITEM, MPFROM2SHORT(100*(k+1),TRUE),MPFROMP(&menuItem)); WinSetMenuItemText( hwndMenu, 100*(k+1), ""); UpdateMenu[ k ] = FALSE; NumItems[ k ] = 0; } memset( &fileDlgInfo, 0, sizeof(FILEDLG)); fileDlgInfo.cbSize = sizeof(fileDlgInfo); menuMessageHandler = WinSubclassWindow( hwndMenu, menuHandler ); //-------------------------------------------------------------------------- // change to directory that application executable is started from //-------------------------------------------------------------------------- //DosQueryCurrentDisk( &OS2BootDrive, (ULONG*)&tmpBuffer ); if (argc > 0) { strncpy( tmpBuffer, argv[0], sizeof(tmpBuffer) ); if (tmpBuffer[1]==':') DosSetDefaultDisk( (ULONG)(toupper(tmpBuffer[0])-'A' + 1) ); i = strlen(tmpBuffer); while ((tmpBuffer[i]!='\\') && (i>0)) i--; if (i) { tmpBuffer[i]='\0'; if (DosSetCurrentDir( tmpBuffer )!=0) { char mesg[]="Could not switch to the directory holding the application"; WinMessageBox( HWND_DESKTOP, hwndFrame, mesg, tmpBuffer, 0, MB_MOVEABLE|MB_ERROR|MB_OK); } } strcpy( backgroundBitmap, tmpBuffer ); strcat( backgroundBitmap, BITMAPNAME ); strcpy( hourlyChimeWavFile, tmpBuffer ); strcat( hourlyChimeWavFile, CHIMESOUNDFILE ); } //-------------------------------------------------------------------------- // record time and date for scheduler program //-------------------------------------------------------------------------- { struct tm *time_now; time_t currentTime; tzset(); time(¤tTime); time_now = localtime( ¤tTime ); month = time_now->tm_mon; year = time_now->tm_year; } //-------------------------------------------------------------------------- // read in the user option file and set up the menu bar appropriately // check the user time/date option and put it on the menu bar // reset our timer in case they want the current time displayed //-------------------------------------------------------------------------- readOptionFile(); // read in option file sortTimeEntries( numAlarms ); // sort the alarm entries restartTimer(); // resync our clock updateTimeDisplay(); // display current date/time // make FileBar visible WinSetWindowPos( hwndFrame, (HWND)0, 0, 0, 0, 0, SWP_RESTORE); if ((maximizeDesktop) && (BarPosition==AT_TOP)) { ULONG numItems; ULONG Buffer; PSWBLOCK SwitchBlockPtr; // get the # of items and the switch list from the system numItems = WinQuerySwitchList( hab, NULL, 0 ); Buffer = (numItems * sizeof(SWENTRY)) + sizeof(HSWITCH); PVOID my = new BYTE[Buffer]; WinQuerySwitchList( hab, (SWBLOCK*)my, Buffer ); SwitchBlockPtr = (PSWBLOCK)(my); for (short j = 0; j < numItems; j++ ) if (strcmp(SwitchBlockPtr->aswentry[j].swctl.szSwtitle, WPSDESKTOPNAME) == 0) { WinSetWindowPos( SwitchBlockPtr->aswentry[j].swctl.hwnd, (HWND)0, 0, 0, 0, 0, SWP_MAXIMIZE); WinSetWindowPos( SwitchBlockPtr->aswentry[j].swctl.hwnd, (HWND)0, 0, 0, ScreenSizeX, ScreenSizeY-MenuHeight+sysMenuHeight+1, SWP_MOVE|SWP_SIZE); } } displayBackground(); // restore user background bitmap ExecuteStartUpList(); // start execution list MakeArrowPointer (); // switch back to arrow pointer, WinSetParent( hwndFrame, HWND_DESKTOP, FALSE ); WinSetFocus( HWND_DESKTOP, hwndFrame ); //-------------------------------------------------------------------------- // initialize our DLL so that we intercept window sizing messages //-------------------------------------------------------------------------- FileBarInit( hwndFrame ); setFileBarScreen( (BOOL)(BarPosition==AT_TOP), MenuHeight, (interceptMsg==TRUE) ); //-------------------------------------------------------------------------- // create a message queue and then as long as there are messages to get, // get them and dispatch them to our message handlers //-------------------------------------------------------------------------- { QMSG qmsg; // create a message queue while( WinGetMsg( hab, &qmsg, (HWND)0, 0, 0 ) !=FALSE ) WinDispatchMsg( hab, &qmsg ); } //-------------------------------------------------------------------------- // our application is done. Destroy timer, window, the message queue and // release the DLL. Call the system to destroy anchor block and do the // final clean up work //-------------------------------------------------------------------------- if (timerNumber != 0) WinStopTimer( hab, hwndClient, timerNumber ); FileBarQuit(); // release the DLL from memory WinDestroyWindow(hwndFrame); WinDestroyMsgQueue(hmq); WinTerminate(hab); return 0; } //////////////////////////////////////////////////////////////////////////////// // a new font has been selected for our menu, resize and redraw the menubar //////////////////////////////////////////////////////////////////////////////// VOID resizeMenu() { HPS hps; FONTMETRICS fm; hps = WinGetPS( hwndMenu ); GpiQueryFontMetrics(hps, sizeof(FONTMETRICS), &fm); MenuHeight = fm.lLowerCaseDescent + fm.lMaxAscender + 4; if (MenuHeight < (fm.lLowerCaseDescent + fm.lLowerCaseAscent + 2)) MenuHeight = fm.lLowerCaseDescent + fm.lLowerCaseAscent + 2; if (MenuHeight < (WinQuerySysValue(HWND_DESKTOP, SV_CYMENU) + 2)) MenuHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU) + 2; WinReleasePS( hps ); if (BarPosition==AT_BOTTOM) WinSetWindowPos( hwndFrame, (HWND)0, 0, -1, ScreenSizeX, MenuHeight, SWP_MOVE|SWP_SIZE); else WinSetWindowPos( hwndFrame, (HWND)0, 0, (ScreenSizeY-MenuHeight)+1, ScreenSizeX, MenuHeight, SWP_MOVE|SWP_SIZE); setFileBarScreen( (BOOL)(BarPosition==AT_TOP), MenuHeight, (interceptMsg==TRUE) ); } //////////////////////////////////////////////////////////////////////////////// // subclassed menu handler for main application window //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY menuHandler(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch (msg) { //---------------------------------------------------------------------- // if a menu has been highlighted, save which one it is so that we know // which task to affect if something is chosen off cascading menu //---------------------------------------------------------------------- case WM_MENUSELECT: { if ((SHORT1FROMMP(mp1)>TASKLIST_MENU) && (SHORT1FROMMP(mp1)<99)) taskItemSelected = SHORT1FROMMP(mp1); } //---------------------------------------------------------------------- // resize menubar if a font was just dropped on us //---------------------------------------------------------------------- case WM_PRESPARAMCHANGED: { if ( (ULONG)mp1 == PP_FONTNAMESIZE) resizeMenu(); } //---------------------------------------------------------------------- // nothing of interest, pass it onto the system for default processing //---------------------------------------------------------------------- default: break; } return menuMessageHandler(hwnd, msg, mp1, mp2); } ////////////////////////////////////////////////////////////////////////////// // This is the message processing facility for the main application thread //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch (msg) { //---------------------------------------------------------------------- // if the application is terminating, write user settings to a file //---------------------------------------------------------------------- case WM_CLOSE: case WM_SAVEAPPLICATION: case WM_QUIT: { writeOptionFile(); return WinDefWindowProc(hwnd, msg, mp1, mp2); // default processing } //---------------------------------------------------------------------- // the application has been designed such that a WM_TIMER is sent by the // system every minute (so that we can update our time on the menubar // if necessary) //---------------------------------------------------------------------- case WM_TIMER: { if (!timeSync) { WinStopTimer( hab, hwndClient, timerNumber ); timerNumber = WinStartTimer( hab, hwndClient, TIMERID, 60000); timeSync = TRUE; } displayTimeDate(); return WinDefWindowProc(hwnd, msg, mp1, mp2); // default processing } //---------------------------------------------------------------------- // a WM_INITMENU message is sent just prior to any pulldown menu being // displayed. This gives us a chance to change its contents before it // is displayed. If necessary, we update menu contents for user menus //---------------------------------------------------------------------- case WM_INITMENU: { SHORT menuId = SHORT1FROMMP(mp1); //------------------------------------------------------------------ // if the FileBar menu is being readied for display, make sure the // move-bar top/bottom item and check items read appropriately! //------------------------------------------------------------------ if (menuId == FILEBAR_MENU) { if (BarPosition == AT_TOP ) WinSetMenuItemText( HWNDFROMMP( mp2 ), FILEBAR_MOVEBAR, "~Move to Bottom"); else WinSetMenuItemText( HWNDFROMMP( mp2 ), FILEBAR_MOVEBAR, "~Move to Top"); WinCheckMenuItem( hwndMenu, FILEBAR_STARTUP, DoStartUpList); WinCheckMenuItem( hwndMenu, FILEBAR_DISPLAYBACKGROUND, showBackground); WinCheckMenuItem( hwndMenu, FILEBAR_FILEBARMENU, (TRUE - FileBarMenuOn)); WinCheckMenuItem( hwndMenu, FILEBAR_CONFIRMCLOSE, checkBeforeDelete); WinCheckMenuItem( hwndMenu, FILEBAR_RESIZEWPS, maximizeDesktop); WinCheckMenuItem( hwndMenu, FILEBAR_INTERCEPTMSG, interceptMsg ); WinEnableMenuItem( hwndMenu, FILEBAR_RESIZEWPS, (BarPosition==AT_TOP)); return WinDefWindowProc(hwnd, msg, mp1, mp2); // default processing } //------------------------------------------------------------------ // if the user is pulling down the task list, put a current copy of // the task list in the menu and store copies of all the tasks id // numbers and handles just in case they want to jump to one of them //------------------------------------------------------------------ if (menuId == TASKLIST_MENU) { PCHAR text; MENUITEM menuItem; USHORT index; ULONG numItems; ULONG Buffer; PSWBLOCK SwitchBlockPtr; // clear out the menu, get it ready for new task entries for (short i = menuId+1; i <= menuId+MAXITEMS; i++ ) WinSendMsg( HWNDFROMMP( mp2 ), MM_DELETEITEM, MPFROM2SHORT( i, TRUE ), 0 ); // get the # of items and the switch list from the system numItems = WinQuerySwitchList( hab, NULL, 0 ); Buffer = (numItems * sizeof(SWENTRY)) + sizeof(HSWITCH); PVOID my = new BYTE[Buffer]; WinQuerySwitchList( hab, (SWBLOCK*)my, Buffer ); // insert each task as an entry under the task list menu SwitchBlockPtr = (PSWBLOCK)(my); menuItem.iPosition = 0; menuItem.afStyle = MIS_MULTMENU|MIS_SINGLE; menuItem.afAttribute = 0; menuItem.id = TASKLIST_MENU; for (short j = 0; j < numItems; j++ ) { menuItem.id++; if ((SwitchBlockPtr->aswentry[j].swctl.uchVisibility != SWL_GRAYED) && (SwitchBlockPtr->aswentry[j].swctl.uchVisibility != SWL_INVISIBLE) && (SwitchBlockPtr->aswentry[j].swctl.hwnd != hwndFrame)) { // load in the cascading menu for this task entry menuItem.hwndSubMenu = WinLoadMenu(hwndMenu, 0, TASKMENUCLOSE); // remove ctrl characters from task list index = 0; text = SwitchBlockPtr->aswentry[j].swctl.szSwtitle; while (text[++index]!='\0') if (text[index]<' ') text[index]=' '; // enter task into the menu structure WinSendMsg( HWNDFROMMP(mp2), MM_INSERTITEM, (MENUITEM*)&menuItem, &(SwitchBlockPtr->aswentry[j].swctl.szSwtitle) ); TaskId[j] = SwitchBlockPtr->aswentry[j].swctl.idProcess; TaskHandle[j] = SwitchBlockPtr->aswentry[j].swctl.hwnd; WinSetWindowBits(menuItem.hwndSubMenu, QWL_STYLE, MS_CONDITIONALCASCADE, MS_CONDITIONALCASCADE); WinSendMsg(menuItem.hwndSubMenu, MM_SETDEFAULTITEMID, MPFROMSHORT(TASK_SWITCHTO), NULL); } } delete( my ); return WinDefWindowProc(hwnd, msg, mp1, mp2); // default processing } //------------------------------------------------------------------ // one of the user menus is being initialized; if it has been marked // as needing to be updated, fill the menu with the current items // the user has set up //------------------------------------------------------------------ if (menuId >= 100) { int MenuToUpdate = menuId / 100 - 1; if ( UpdateMenu[ MenuToUpdate ] ) { UpdateMenu[ MenuToUpdate ] = FALSE; { MENUITEM menuItem; for (short i = menuId+1; i < menuId+MAXITEMS+1; i++ ) WinSendMsg( HWNDFROMMP( mp2 ), MM_DELETEITEM, MPFROM2SHORT( i, TRUE ), 0 ); menuItem.iPosition = MIT_END; menuItem.afStyle = MIS_TEXT; menuItem.afAttribute = 0; menuItem.hItem = 0; menuItem.hwndSubMenu = (HWND)0; menuItem.id = menuId; for (short j = 0; j < NumItems[ MenuToUpdate ]; j++ ) { menuItem.id++; if (ItemName[MenuToUpdate][j][0] != '\0') WinSendMsg( HWNDFROMMP(mp2), MM_INSERTITEM, (MENUITEM*)&menuItem, ItemName[MenuToUpdate][j] ); else { menuItem.afStyle = MIS_SEPARATOR; WinSendMsg( HWNDFROMMP(mp2), MM_INSERTITEM, (MENUITEM*)&menuItem, ItemName[MenuToUpdate][j] ); menuItem.afStyle = MIS_TEXT; } } } } } } //---------------------------------------------------------------------- //---------------------------------------------------------------------- case WM_COMMAND: { USHORT command = SHORT1FROMMP(mp1); //------------------------------------------------------------------ // uer has altered check state of "resize desktop on boot" item //------------------------------------------------------------------ if ( command == FILEBAR_RESIZEWPS) { maximizeDesktop = TRUE - maximizeDesktop; return 0; } //------------------------------------------------------------------ // user has altered check state of "always on top" item //------------------------------------------------------------------ if ( command == FILEBAR_INTERCEPTMSG) { interceptMsg = TRUE - interceptMsg; setFileBarScreen( (BOOL)(BarPosition==AT_TOP), MenuHeight, (interceptMsg==TRUE) ); return 0; } //------------------------------------------------------------------ // show the display background dialog box //------------------------------------------------------------------ if ( command == FILEBAR_STARTUP) { WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)startupProc, 0, STARTUP_DIALOG, (PVOID)NULL); return 0; } //------------------------------------------------------------------ // user has invoked the scheduler //------------------------------------------------------------------ if ( command == TIMEDATE) { WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)schedulerProc, 0, SCHEDULER, (PVOID)NULL); return 0; } //------------------------------------------------------------------ // expand or shrink FileBar system menus //------------------------------------------------------------------ if ( command == FILEBAR_FILEBARMENU) { CHAR menuOn[] = FILEBARMENUON; CHAR menuOff[] = FILEBARMENUOFF; CHAR taskOn[] = TASKMENUON; CHAR taskOff[] = TASKMENUOFF; FileBarMenuOn = TRUE - FileBarMenuOn; if (FileBarMenuOn) { WinSetMenuItemText( hwndMenu, FILEBAR_MENU, menuOn); WinSetMenuItemText( hwndMenu, TASKLIST_MENU, taskOn); } else { WinSetMenuItemText( hwndMenu, FILEBAR_MENU, menuOff); WinSetMenuItemText( hwndMenu, TASKLIST_MENU, taskOff); } return 0; } //------------------------------------------------------------------ // show the display background dialog box //------------------------------------------------------------------ if ( command == FILEBAR_DISPLAYBACKGROUND) { WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)backgroundProc, 0, BACKGROUNDWIN, (PVOID)NULL); displayBackground(); return 0; } //------------------------------------------------------------------ // user has altered "confirm on task close" check state //------------------------------------------------------------------ if ( command == FILEBAR_CONFIRMCLOSE) { checkBeforeDelete = TRUE - checkBeforeDelete; return 0; } //------------------------------------------------------------------ // close the chosen task //------------------------------------------------------------------ if ( command == TASK_CLOSE) { ULONG numItems; ULONG Buffer; PSWBLOCK SwitchBlockPtr; PID killedTaskId; HWND killedTaskHandle; if (checkBeforeDelete) { if (WinMessageBox( HWND_DESKTOP, hwnd, "Closing may result in the destruction of unsaved data. Are you sure you want to close this task?", "FileBar - Close Task", 0, MB_MOVEABLE|MB_ICONQUESTION|MB_YESNO) == MBID_NO) return 0; } killedTaskId = TaskId[taskItemSelected - TASKLIST_MENU - 1]; killedTaskHandle = TaskHandle[taskItemSelected - TASKLIST_MENU - 1]; WinSendMsg( killedTaskHandle, WM_CLOSE, 0, 0 ); // get the # of items and the switch list from the system numItems = WinQuerySwitchList( hab, NULL, 0 ); Buffer = (numItems * sizeof(SWENTRY)) + sizeof(HSWITCH); PVOID my = new BYTE[Buffer]; WinQuerySwitchList( hab, (SWBLOCK*)my, Buffer ); SwitchBlockPtr = (PSWBLOCK)(my); // if task did not close willingly, kill its process! for (short j = 0; j < numItems; j++ ) if (SwitchBlockPtr->aswentry[j].swctl.hwnd == killedTaskHandle) DosKillProcess( DKP_PROCESS, killedTaskId ); delete( my ); return 0; } //------------------------------------------------------------------ // show the chosen task //------------------------------------------------------------------ if ( command == TASK_SHOW) { WinSetWindowPos( TaskHandle[taskItemSelected - TASKLIST_MENU- 1], (HWND)0, 0, 0, 0, 0, SWP_SHOW); return 0; } //------------------------------------------------------------------ // hide the chosen task //------------------------------------------------------------------ if ( command == TASK_HIDE) { WinSetWindowPos( TaskHandle[taskItemSelected - TASKLIST_MENU- 1], (HWND)0, 0, 0, 0, 0, SWP_HIDE); return 0; } //------------------------------------------------------------------ // maximize the chosen task //------------------------------------------------------------------ if ( command == TASK_MAX) { HSWITCH switchHandle = WinQuerySwitchHandle( TaskHandle[taskItemSelected - TASKLIST_MENU- 1], TaskId[taskItemSelected - TASKLIST_MENU- 1]); WinShowWindow( TaskHandle[taskItemSelected - TASKLIST_MENU- 1], TRUE ); WinSetWindowPos( TaskHandle[taskItemSelected - TASKLIST_MENU- 1], (HWND)0, 0, 0, 0, 0, SWP_MAXIMIZE); WinSwitchToProgram( switchHandle ); return 0; } //------------------------------------------------------------------ // minimize the chosen task //------------------------------------------------------------------ if ( command == TASK_MIN) { WinShowWindow( TaskHandle[taskItemSelected - TASKLIST_MENU- 1], TRUE ); WinSetWindowPos( TaskHandle[taskItemSelected - TASKLIST_MENU- 1], (HWND)0, 0, 0, 0, 0, SWP_MINIMIZE); return 0; } //------------------------------------------------------------------ // the user has selected something from the tasklist menu, switch // control to that task, if possible //------------------------------------------------------------------ if ( command == TASK_SWITCHTO) { CHAR title[] = "FileBar Task Switch Error"; HSWITCH switchHandle; switchHandle = WinQuerySwitchHandle( TaskHandle[taskItemSelected - TASKLIST_MENU-1], TaskId[taskItemSelected - TASKLIST_MENU-1]); if (switchHandle == 0) { CHAR text[] = "ERROR! Could not locate task! The task may have already terminated."; WinMessageBox( HWND_DESKTOP, hwnd, text, title, 0, MB_MOVEABLE|MB_ERROR|MB_OK); return 0; } if (WinSwitchToProgram( switchHandle ) != 0) { CHAR text[] = "ERROR! Could not switch to task!"; WinMessageBox( HWND_DESKTOP, hwnd, text, title, 0, MB_MOVEABLE|MB_ERROR|MB_OK); } WinShowWindow( TaskHandle[taskItemSelected - TASKLIST_MENU - 1], TRUE ); return 0; } //------------------------------------------------------------------ // user wants to shutdown system //------------------------------------------------------------------ if ( command == 99 ) { 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."; if (WinMessageBox( HWND_DESKTOP, hwndFrame, text, "FileBar - Shutdown System", 0, MB_DEFBUTTON2|MB_MOVEABLE|MB_ICONEXCLAMATION|MB_OKCANCEL) == MBID_CANCEL) return 0; writeOptionFile(); WinSetWindowPos( hwndFrame, (HWND)0, 0, 0, 0, 0, SWP_HIDE); WinPostMsg( hwndClient, WM_QUIT, 0, 0 ); WinShutdownSystem( WinQueryAnchorBlock( HWND_DESKTOP ), hmq ); } //------------------------------------------------------------------ // the user has selected an item off the user menus. Activate the // item they have selected //------------------------------------------------------------------ if (( command > 99 ) && (command % 100)) { INT MenuToUpdate = command / 100 - 1; INT ItemToUpdate = command % 100 - 1; if ((ItemToUpdate>=MAXITEMS) || (MenuToUpdate>=MAXMENUS)) return 0; if ((MenuToUpdate >= 0) && (MenuToUpdate<MAXMENUS)) startApplication( MenuToUpdate, ItemToUpdate ); return 0; } //------------------------------------------------------------------ // it was not a tasklist or user item, process now as usual //------------------------------------------------------------------ switch( command ) { //-------------------------------------------------------------- // the user wants to save current options //-------------------------------------------------------------- case FILEBAR_SAVEOPTIONS: { char title[] = "FileBar - Save Menu Configuration"; char message[] = "The current user menu configuration has been successfully saved!"; writeOptionFile(); WinMessageBox( HWND_DESKTOP, hwnd, message, title, 0, MB_MOVEABLE|MB_INFORMATION|MB_OK); return 0; } //-------------------------------------------------------------- // the user wants to edit the menu structure //-------------------------------------------------------------- case FILEBAR_EDITMENU: { return (VOID*)WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)EditMenuProc, 0, EDITMENU, (PVOID)NULL); } //-------------------------------------------------------------- // the user wants to select their time/date display options //-------------------------------------------------------------- case FILEBAR_TIMEOPTION: { return (VOID*)WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)TimeDateProc, 0, TIMEOPTIONS, (PVOID)NULL); } //-------------------------------------------------------------- // the user wants to get general help on filebar //-------------------------------------------------------------- case FILEBAR_GENHELP: { return (VOID*)WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)GenericProc, 0, GENERAL_HELP, (PVOID)NULL); } //-------------------------------------------------------------- // the user wants to see product information for filebar //-------------------------------------------------------------- case FILEBAR_PRODINFO: { return (VOID*)WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)GenericProc, 0, PRODUCT_INFO, (PVOID)NULL); } //-------------------------------------------------------------- // the user wishes to move the filebar from its current position // to either to the top or bottom of the desktop //-------------------------------------------------------------- case FILEBAR_MOVEBAR: { if (BarPosition==AT_TOP) { BarPosition = AT_BOTTOM; WinSetWindowPos( hwndFrame, (HWND)0, 0, -1, ScreenSizeX, MenuHeight, SWP_MOVE); } else { BarPosition = AT_TOP; WinSetWindowPos( hwndFrame, (HWND)0, 0, (ScreenSizeY-MenuHeight)+1, ScreenSizeX, MenuHeight, SWP_MOVE); } setFileBarScreen( (BOOL)(BarPosition==AT_TOP), MenuHeight, (interceptMsg==TRUE) ); return 0; } //-------------------------------------------------------------- // the user wishes to exit the filebar application //-------------------------------------------------------------- case FILEBAR_EXIT: { return (VOID*)WinPostMsg( hwnd, WM_QUIT, 0, 0); } //-------------------------------------------------------------- // something besides our menus sent a message, pass the message // to the system for default processing //-------------------------------------------------------------- default: break; } } //---------------------------------------------------------------------- // we were sent a message that we don't care about, pass it onto system // for default processing //---------------------------------------------------------------------- default: break; }; return WinDefWindowProc(hwnd, msg, mp1, mp2); // default processing } //////////////////////////////////////////////////////////////////////////////// // readOptionFile - will read the option file (generated by the app) from disk, // if it exists and will restore the application to the state in which it was // last left //////////////////////////////////////////////////////////////////////////////// void readOptionFile( void ) { int currentMenu = 100; FILE *optionFile; //-------------------------------------------------------------------------- // if the option file exists on disk, read it in and restore old menu, // otherwise we will return and rely on default values //-------------------------------------------------------------------------- if ((optionFile = fopen(OPTIONFILE,"rt")) != NULL) { RGB2 rgb = {0,0,0,0}; ULONG color; INT a,b,c,d,e,f; MenuHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU) + 2; fscanf(optionFile, "%d %d", &timeOption, &BarPosition); // restore user's desired bar position if (BarPosition==AT_BOTTOM) { WinSetWindowPos( hwndFrame, (HWND)0, 0, 0, 0, 0 , SWP_MOVE|SWP_RESTORE); WinSetWindowPos( hwndFrame, (HWND)0, 0, -1, ScreenSizeX, MenuHeight, SWP_MOVE|SWP_SIZE); WinSetWindowPos( hwndFrame, (HWND)0, 0, 0, 0, 0 , SWP_MOVE|SWP_MINIMIZE); } else { WinSetWindowPos( hwndFrame, (HWND)0, 0, (ScreenSizeY-MenuHeight)+1, ScreenSizeX, MenuHeight, SWP_MOVE|SWP_SIZE); } setFileBarScreen( (BOOL)(BarPosition==AT_TOP), MenuHeight, (interceptMsg==TRUE) ); // restore user's menus and menu choices fscanf(optionFile, "%d", &NumMenus); for (short i = 0; i < NumMenus; i++ ) { UpdateMenu[i] = TRUE; readString( optionFile, (CHAR*)&MenuName[i] ); WinSendMsg( hwndMenu, MM_SETITEM, MPFROM2SHORT(100*i+100,TRUE),MPFROMP(&menuData[i])); WinSetMenuItemText( hwndMenu, 100*i+100, &MenuName[i]); fscanf(optionFile, "%d", &a); NumItems[i] = (BYTE)(a % 256); for (short j = 0; j < NumItems[i]; j++) { readString( optionFile, (CHAR*)&ItemName[i][j] ); readString( optionFile, (CHAR*)&ActionToDo[i][j] ); readString( optionFile, (CHAR*)&CmdLnArgs[i][j] ); readString( optionFile, (CHAR*)&Directory[i][j] ); fscanf( optionFile, "%d", &a ); ProgType[i][j] = a % 1024; } currentMenu = currentMenu + 100; } readString( optionFile, (CHAR*)&tmpBuffer ); if (tmpBuffer[0]!='\0') { WinSetPresParam( hwndMenu, PP_FONTNAMESIZE, sizeof(tmpBuffer), &tmpBuffer ); WinSetWindowPos( hwndFrame, (HWND)0, 0, 0, 0, 0, SWP_RESTORE); resizeMenu(); WinSetWindowPos( hwndFrame, (HWND)0, 0, 0, 0, 0, SWP_MINIMIZE); } fscanf( optionFile, "%d", &checkBeforeDelete ); if (fscanf( optionFile, "%d", &FileBarMenuOn )!=EOF) { CHAR menuOn[] = FILEBARMENUON; CHAR menuOff[] = FILEBARMENUOFF; CHAR taskOn[] = TASKMENUON; CHAR taskOff[] = TASKMENUOFF; if (FileBarMenuOn) { WinSetMenuItemText( hwndMenu, FILEBAR_MENU, menuOn); WinSetMenuItemText( hwndMenu, TASKLIST_MENU, taskOn); } else { WinSetMenuItemText( hwndMenu, FILEBAR_MENU, menuOff); WinSetMenuItemText( hwndMenu, TASKLIST_MENU, taskOff); } } if (fscanf( optionFile, "%d", &showBackground )!=EOF) { fscanf( optionFile, "%d", &backgroundAttr ); readString( optionFile, (CHAR*)&backgroundBitmap ); } for (i=PP_FOREGROUNDCOLOR; i<=PP_BORDERCOLOR; i=i+2) if (fscanf(optionFile, "%ld", &color )!=EOF) if ( color != NOCOLOR) { rgb.bRed = (BYTE)(color/65536); color = color%65536; rgb.bGreen = (BYTE)(color/256); color = color%256; rgb.bBlue = (BYTE)(color); WinSetPresParam( hwndMenu, i, sizeof(rgb), &rgb); } for (i=PP_ACTIVECOLOR; i<=PP_INACTIVETEXTBGNDCOLOR; i=i+2) if (fscanf(optionFile, "%ld", &color )!=EOF) if ( color != NOCOLOR) { rgb.bRed = (BYTE)(color/65536); color = color%65536; rgb.bGreen = (BYTE)(color/256); color = color%256; rgb.bBlue = (BYTE)(color); WinSetPresParam( hwndMenu, i, sizeof(rgb), &rgb); } if (fscanf(optionFile, "%ld", &color )!=EOF) if ( color != NOCOLOR) { rgb.bRed = (BYTE)(color/65536); color = color%65536; rgb.bGreen = (BYTE)(color/256); color = color%256; rgb.bBlue = (BYTE)(color); WinSetPresParam( hwndMenu, PP_SHADOW, sizeof(rgb), &rgb); } for (i=PP_MENUFOREGROUNDCOLOR; i<=PP_MENUDISABLEDBGNDCOLOR; i=i+2) if (fscanf(optionFile, "%ld", &color )!=EOF) if ( color != NOCOLOR) { rgb.bRed = (BYTE)(color/65536); color = color%65536; rgb.bGreen = (BYTE)(color/256); color = color%256; rgb.bBlue = (BYTE)(color); WinSetPresParam( hwndMenu, i, sizeof(rgb), &rgb); } if (fscanf(optionFile, "%d %d", &DoStartUpList, &numStartItems ) != EOF) { for (i=0; i<numStartItems; i++) fscanf(optionFile, "%d %d", &StartUpMenu[i], &StartUpItem[i] ); } if (fscanf(optionFile, "%d", &HourlyChime ) != EOF) readString( optionFile, (CHAR*)&hourlyChimeWavFile ); // read in current task scheduler tasks if (fscanf(optionFile, "%d %d %d %d", &maximizeDesktop, &repeatTime, &interceptMsg, &numAlarms ) != EOF) setFileBarScreen( (BOOL)(BarPosition==AT_TOP), MenuHeight, (interceptMsg==TRUE) ); for (i=0; i<numAlarms; i++) { fscanf(optionFile, "%d %d %d %d %d %d", &a,&b,&c,&d,&e,&f); alarm[i].AlarmHour = a % 256; alarm[i].AlarmMinute = b % 256; alarm[i].AlarmMonth = c % 256; alarm[i].AlarmDay = d % 256; alarm[i].AlarmYear = e % 256; alarm[i].options = f % 256; readString( optionFile, (CHAR*)&alarm[i].ActionToDo ); readString( optionFile, (CHAR*)&alarm[i].ReminderWAV ); } fclose( optionFile ); } } //////////////////////////////////////////////////////////////////////////////// // writeOptionFile - will write the application state to the option file //////////////////////////////////////////////////////////////////////////////// void writeOptionFile( void ) { SHORT currentMenu = 100; FILE *optionFile; //-------------------------------------------------------------------------- // if the option file exists on disk, read it in and restore old menu, // otherwise we will return and rely on default values //-------------------------------------------------------------------------- if ((optionFile = fopen(OPTIONFILE, "wt")) == NULL) // if not able to save, alert the user WinMessageBox( HWND_DESKTOP, hwndClient, "Error writing FileBar configuration file! Application data was NOT saved!", 0, 0, MB_MOVEABLE|MB_ERROR|MB_OK); else { ULONG length; RGB2 rgb; // save user's desired bar position fprintf(optionFile, "%d %d\n", timeOption, BarPosition); // save user's menus and menu choices fprintf(optionFile, "%d\n", NumMenus); for (short i = 0; i < NumMenus; i++ ) { writeString( optionFile, (CHAR*)&MenuName[i] ); fprintf(optionFile, "%d\n", NumItems[i]); for (short j = 0; j < NumItems[i]; j++) { writeString( optionFile, (CHAR*)&ItemName[i][j] ); writeString( optionFile, (CHAR*)&ActionToDo[i][j] ); writeString( optionFile, (CHAR*)&CmdLnArgs[i][j] ); writeString( optionFile, (CHAR*)&Directory[i][j] ); fprintf( optionFile, "%d\n", ProgType[i][j] ); } currentMenu = currentMenu + 100; } if (WinQueryPresParam( hwndMenu, PP_FONTNAMESIZE, 0, &length, sizeof(tmpBuffer), &tmpBuffer, 0)!=FALSE) writeString( optionFile, (CHAR*)&tmpBuffer ); else fprintf( optionFile, "\"\"\n" ); fprintf( optionFile, "%d\n%d\n%d\n%d\n", checkBeforeDelete, FileBarMenuOn, showBackground, backgroundAttr ); writeString( optionFile, (CHAR*)&backgroundBitmap ); // save menu scheme of colors for (i=PP_FOREGROUNDCOLOR; i<=PP_BORDERCOLOR; i=i+2) { if (WinQueryPresParam( hwndMenu, i, 0, 0, sizeof(rgb), &rgb, 0) != 0) fprintf(optionFile, "%ld\n", (ULONG)(rgb.bRed*65536+rgb.bGreen*256+rgb.bBlue) ); else fprintf(optionFile, "%ld\n", NOCOLOR ); } for (i=PP_ACTIVECOLOR; i<=PP_INACTIVETEXTBGNDCOLOR; i=i+2) { if (WinQueryPresParam( hwndMenu, i, 0, 0, sizeof(rgb), &rgb, 0) != 0) fprintf(optionFile, "%ld\n", (ULONG)(rgb.bRed*65536+rgb.bGreen*256+rgb.bBlue) ); else fprintf(optionFile, "%ld\n", NOCOLOR ); } if (WinQueryPresParam( hwndMenu, PP_SHADOW, 0, 0, sizeof(rgb), &rgb, 0) != 0) fprintf(optionFile, "%ld\n", (ULONG)(rgb.bRed*65536+rgb.bGreen*256+rgb.bBlue) ); else fprintf(optionFile, "%ld\n", NOCOLOR ); for (i=PP_MENUFOREGROUNDCOLOR; i<=PP_MENUDISABLEDBGNDCOLOR; i=i+2) { if (WinQueryPresParam( hwndMenu, i, 0, 0, sizeof(rgb), &rgb, 0) != 0) fprintf(optionFile, "%ld\n", (ULONG)(rgb.bRed*65536+rgb.bGreen*256+rgb.bBlue) ); else fprintf(optionFile, "%ld\n", NOCOLOR ); } fprintf(optionFile, "%d\n%d\n", DoStartUpList, numStartItems ); for (i=0; i<numStartItems; i++) fprintf(optionFile, "%d\n%d\n", StartUpMenu[i], StartUpItem[i] ); fprintf(optionFile, "%d\n", HourlyChime ); writeString( optionFile, (CHAR*)&hourlyChimeWavFile ); // save current task scheduler items fprintf(optionFile, "%d %d %d %d\n", maximizeDesktop, repeatTime, interceptMsg, numAlarms ); for (i=0; i<numAlarms; i++) { fprintf(optionFile, "%d %d %d %d %d %d\n", alarm[i].AlarmHour, alarm[i].AlarmMinute, alarm[i].AlarmMonth, alarm[i].AlarmDay, alarm[i].AlarmYear, alarm[i].options ); writeString( optionFile, (CHAR*)&alarm[i].ActionToDo ); writeString( optionFile, (CHAR*)&alarm[i].ReminderWAV ); } fclose( optionFile ); } } //////////////////////////////////////////////////////////////////////////////// // readString will read a sequence of characters that is bounded on both sides // by quote (") characters (We can't use fscanf because it won't read spaces) //////////////////////////////////////////////////////////////////////////////// VOID readString( FILE* stream, CHAR* buffer ) { do { // search for first " character if (fscanf( stream, "%c", buffer)==EOF) break; } while ( (*buffer) !='"'); buffer--; do { // keep putting characters into the buffer buffer++; // " character if (fscanf( stream, "%c", buffer)==EOF) break; } while ( (*buffer) !='"'); *buffer = '\0'; // store a NULL to terminate the string } //////////////////////////////////////////////////////////////////////////////// // Message handler for a generic information-only dialog box (help & prod info) //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY GenericProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch( msg ) { //---------------------------------------------------------------------- // when the dialog is being initialized, center it on desktop //---------------------------------------------------------------------- case WM_INITDLG: { SWP swp; WinQueryWindowPos( hWnd, (PSWP)&swp); WinSetWindowPos( hWnd, (HWND)0, ((SHORT)((ScreenSizeX-swp.cx)/2)), ((SHORT)((ScreenSizeY-swp.cy)/2)), 0, 0, SWP_MOVE); return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- // if we receive any system message, dismiss the dialog box //---------------------------------------------------------------------- case WM_COMMAND: { WinDismissDlg( hWnd, TRUE ); return 0; } //---------------------------------------------------------------------- // if nothing further we want to intercept, pass message onto system //---------------------------------------------------------------------- default: break; } return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //////////////////////////////////////////////////////////////////////////////// // starts or restarts a timer to signal our program when the next minute occurs //////////////////////////////////////////////////////////////////////////////// VOID restartTimer( VOID ) { struct tm *time_now; time_t currentTime; tzset(); time(¤tTime); time_now = localtime( ¤tTime ); timeSync = FALSE; timerNumber = WinStartTimer( hab, hwndClient, TIMERID, (60-(time_now->tm_sec))*1000); } //////////////////////////////////////////////////////////////////////////////// // ringChime - play a .WAV file sent to us as the parameter. //////////////////////////////////////////////////////////////////////////////// VOID ringChime( CHAR* soundFile ) { APIRET rc; char mesg[MAXPATH+384]; RXSTRING INSTORE[2]; RXSTRING retstr; SHORT ReturnCode; LONG offset = 0; if (soundFile == 0) return; if (soundFile[0] == 0) { WinAlarm( HWND_DESKTOP, WA_NOTE ); return; } MakeHourglassPointer (); // switch to hourglass cursor offset = offset + sprintf(mesg+offset, "/* */\r\n"); offset = offset + sprintf(mesg+offset, "rc = call RxFuncAdd('mciRxInit','MCIAPI',,\r\n'mciRxInit')\r\n"); offset = offset + sprintf(mesg+offset, "rc = call mciRxInit()\r\n"); offset = offset + sprintf(mesg+offset, "rc = mciRxSendString('open waveaudio',\r\n'alias wave shareable wait',,\r\n'RetStr','0','0')\r\n"); offset = offset + sprintf(mesg+offset, "rc = mciRxSendString('load wave %s wait',,\r\n'RetStr','0','0')\r\n", soundFile ); offset = offset + sprintf(mesg+offset, "rc = mciRxSendString('play wave wait',,\r\n'RetStr','0','0')\r\n" ); offset = offset + sprintf(mesg+offset, "rc = mciRxSendString('close wave wait',,\r\n'RetStr','0','0')\r\n" ); offset = offset + sprintf(mesg+offset, "call mciRxExit\r\n" ); sprintf(mesg+offset, "exit\r\n\x1A\0" ); INSTORE[0].strptr=mesg; INSTORE[0].strlength=strlen(mesg); INSTORE[1].strptr=NULL; INSTORE[1].strlength=0; rc = rexxStart((LONG)0, (PRXSTRING)0, (PSZ)LAUNCHFILE, (PRXSTRING)INSTORE, (PSZ)"CMD", (LONG)RXCOMMAND, (PRXSYSEXIT)0, (SHORT*)&ReturnCode, (PRXSTRING)&retstr); // if there was an error (ie: no MMPM), make a system beep if (rc) WinAlarm( HWND_DESKTOP, WA_NOTE ); MakeArrowPointer (); // switch back to arrow pointer, } //////////////////////////////////////////////////////////////////////////////// // update the time displayed on the FileBar menubar //////////////////////////////////////////////////////////////////////////////// VOID updateTimeDisplay( VOID ) { char tmp1[24]; char tmp2[24]; CHAR buffer[64] = { '\0' }; struct tm *time_now; time_t currentTime; tzset(); time(¤tTime); time_now = localtime( ¤tTime ); if ((timeOption == TIMEONLY) || (timeOption == TIMEANDDATE)) { strftime( tmp1, sizeof(tmp1), "%I", time_now); strftime( tmp2, sizeof(tmp2), ":%M %p ", time_now); if (tmp1[0] == '0') tmp1[0]=' '; strcat( buffer, tmp1 ); strcat( buffer, tmp2 ); } if (timeOption == TIMEANDDATE) strcat( buffer, " " ); if ((timeOption == DATEONLY) || (timeOption == TIMEANDDATE)) { strftime( tmp1, sizeof(tmp1), "%B", time_now); strftime( tmp2, sizeof(tmp2), "%d, %Y ", time_now); if (tmp2[0] == '0') { tmp2[0] = ' '; strcat( buffer, tmp1 ); strcat( buffer, tmp2 ); } else { strcat( buffer, tmp1 ); strcat( buffer, " \0" ); strcat( buffer, tmp2 ); } } else if (timeOption == OTHERTIMEONLY) strftime( buffer, sizeof(buffer), "%H:%M ", time_now); else if (timeOption == OTHERDATEONLY) strftime( buffer, sizeof(buffer), "%d %B %Y ", time_now); else if (timeOption == OTHERTIMEANDDATE) { strftime( tmp1, sizeof(tmp1), "%H:%M ", time_now ); strftime( tmp2, sizeof(tmp2), "%d %B %Y ", time_now ); if (tmp1[0] == '0') tmp1[0] = ' '; if (tmp2[0] == '0') tmp2[0] = ' '; else strcat( tmp1, " " ); strcat( buffer, tmp1 ); strcat( buffer, tmp2 ); } if (buffer[0]=='0') buffer[0]=' '; WinSetMenuItemText( hwndMenu, TIMEDATE, &buffer ); } //////////////////////////////////////////////////////////////////////////////// // displayTimeDate is used to check to see if time/date on the FileBar menu // needs updateing and also to check to see if any alarms need to be serviced //////////////////////////////////////////////////////////////////////////////// VOID displayTimeDate( VOID ) { struct tm *time_now; time_t currentTime; tzset(); time(¤tTime); time_now = localtime( ¤tTime ); if (timeOption != NONE) if (((timeOption != DATEONLY) && (timeOption != OTHERDATEONLY)) || (time_now->tm_min == 0) ) updateTimeDisplay(); if (time_now->tm_min == 30) alreadyChimed = FALSE; if ((!alreadyChimed) && (time_now->tm_min == 0) && (HourlyChime)) { alreadyChimed = TRUE; ringChime( hourlyChimeWavFile ); } checkAlarms( time_now->tm_hour, time_now->tm_min, time_now->tm_mon, time_now->tm_mday, time_now->tm_year ); } //////////////////////////////////////////////////////////////////////////////// // Message handler for time and date option setting dialog //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY TimeDateProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch( msg ) { //---------------------------------------------------------------------- // when the dialog is being initialized, center it on desktop and check // the appropriate radio button for whatever setting they currently have //---------------------------------------------------------------------- case WM_INITDLG: { SWP swp; WinQueryWindowPos( hWnd, (PSWP)&swp); WinSetWindowPos( hWnd, (HWND)0, ((SHORT)((ScreenSizeX-swp.cx)/2)), ((SHORT)((ScreenSizeY-swp.cy)/2)), 0, 0, SWP_MOVE); WinSendDlgItemMsg( hWnd, timeOption, BM_SETCHECK, MPFROM2SHORT( 1, 0 ), 0); WinCheckButton( hWnd, PLAYCHIME, HourlyChime ); WinSendDlgItemMsg( hWnd, CHIMEWAVFILE, EM_SETTEXTLIMIT, MPFROM2SHORT( MAXACTIONSTRINGLENGTH-1, 0 ), 0 ); WinSetDlgItemText( hWnd, CHIMEWAVFILE, hourlyChimeWavFile); break; } //---------------------------------------------------------------------- // we received a change in control, update menubar time //---------------------------------------------------------------------- case WM_CONTROL: { timeOption = NONE; if (WinQueryButtonCheckstate( hWnd, TIMEONLY )) timeOption = TIMEONLY; else if (WinQueryButtonCheckstate( hWnd, DATEONLY )) timeOption = DATEONLY; else if (WinQueryButtonCheckstate( hWnd, TIMEANDDATE )) timeOption = TIMEANDDATE; else if (WinQueryButtonCheckstate( hWnd, OTHERTIMEONLY )) timeOption = OTHERTIMEONLY; else if (WinQueryButtonCheckstate( hWnd, OTHERDATEONLY )) timeOption = OTHERDATEONLY; else if (WinQueryButtonCheckstate( hWnd, OTHERTIMEANDDATE )) timeOption = OTHERTIMEANDDATE; WinStopTimer( hab, hwndClient, timerNumber ); restartTimer(); updateTimeDisplay(); break; } //---------------------------------------------------------------------- // if we receive any system message, dismiss dialog and store new option //---------------------------------------------------------------------- case WM_COMMAND: { USHORT command = SHORT1FROMMP(mp1); switch( command ) { case TESTWAVEFILE: { WinQueryDlgItemText( hWnd, CHIMEWAVFILE, sizeof(hourlyChimeWavFile), hourlyChimeWavFile); ringChime( hourlyChimeWavFile ); return 0; } case FINDWAVFILE: { CHAR title[] = "FileBar - Find a Hourly Chime .WAV file"; ULONG s; HWND hwndDialog; fileDlgInfo.fl = FDS_OPEN_DIALOG|FDS_CENTER; fileDlgInfo.pszTitle = title; strcpy(oldDirectory, fileDlgInfo.szFullFile); strcat(fileDlgInfo.szFullFile, "*.WAV\0"); hwndDialog = WinFileDlg( HWND_DESKTOP, hWnd, &fileDlgInfo ); if (hwndDialog && (fileDlgInfo.lReturn == DID_OK)) { strcpy( hourlyChimeWavFile, fileDlgInfo.szFullFile ); s=0; while(fileDlgInfo.szFullFile[s]!='\0') s++; while((fileDlgInfo.szFullFile[s]!='\\') && (s>=0)) s--; if (fileDlgInfo.szFullFile[s]=='\\') fileDlgInfo.szFullFile[s+1]='\0'; else fileDlgInfo.szFullFile[0]='\0'; WinSetDlgItemText( hWnd, CHIMEWAVFILE, hourlyChimeWavFile ); } else strcpy(fileDlgInfo.szFullFile, oldDirectory); return 0; } } timeOption = NONE; if (WinQueryButtonCheckstate( hWnd, TIMEONLY )) timeOption = TIMEONLY; else if (WinQueryButtonCheckstate( hWnd, DATEONLY )) timeOption = DATEONLY; else if (WinQueryButtonCheckstate( hWnd, TIMEANDDATE )) timeOption = TIMEANDDATE; else if (WinQueryButtonCheckstate( hWnd, OTHERTIMEONLY )) timeOption = OTHERTIMEONLY; else if (WinQueryButtonCheckstate( hWnd, OTHERDATEONLY )) timeOption = OTHERDATEONLY; else if (WinQueryButtonCheckstate( hWnd, OTHERTIMEANDDATE )) timeOption = OTHERTIMEANDDATE; HourlyChime = WinQueryButtonCheckstate( hWnd, PLAYCHIME ); // stop current timer (if one exists) and start a new one // display new time and date according to new option setting WinStopTimer( hab, hwndClient, timerNumber ); restartTimer(); WinQueryDlgItemText( hWnd, CHIMEWAVFILE, sizeof(hourlyChimeWavFile), hourlyChimeWavFile); WinDismissDlg( hWnd, TRUE ); return 0; } //---------------------------------------------------------------------- // if nothing further we want to intercept, pass message onto system //---------------------------------------------------------------------- default: break; } return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //////////////////////////////////////////////////////////////////////////////// // EditMenuProc - the message handler for editing a menu dialog box //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY EditMenuProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch( msg ) { //---------------------------------------------------------------------- // if double-clicked an entry, allow them to edit it //---------------------------------------------------------------------- case WM_CONTROL: { if ((SHORT1FROMMP(mp1)==CURMENULIST) && (SHORT2FROMMP(mp1)==LN_ENTER)) return WinSendMsg( hWnd, WM_COMMAND, MPFROM2SHORT( EDITMENUBUTTON, 0 ), mp2 ); return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- // when the dialog is being initialized, center it on desktop and put // the current data into appropriate list boxes //---------------------------------------------------------------------- case WM_INITDLG: { SWP swp; for (short i=0; i<NumMenus; i++) WinSendDlgItemMsg( hWnd, CURMENULIST, LM_INSERTITEM, MPFROM2SHORT( LIT_END, 0 ), MenuName[i] ); if (NumMenus > 0) { WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM, MPFROM2SHORT( 0, 0 ), MPFROM2SHORT( TRUE, 0 ) ); } else { WinEnableControl( hWnd, EDITMENUBUTTON, FALSE ); WinEnableControl( hWnd, REMOVEMENU, FALSE ); WinEnableControl( hWnd, MOVEMENULEFT, FALSE ); WinEnableControl( hWnd, MOVEMENURIGHT, FALSE ); } WinQueryWindowPos( hWnd, (PSWP)&swp); WinSetWindowPos( hWnd, (HWND)0, ((SHORT)((ScreenSizeX-swp.cx)/2)), ((SHORT)((ScreenSizeY-swp.cy)/2)), 0, 0, SWP_MOVE); return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- // process a command message received from the system //---------------------------------------------------------------------- case WM_COMMAND: { USHORT command = SHORT1FROMMP(mp1); switch( command ) { //-------------------------------------------------------------- // if they pressed OK button, dismiss dialog and return //-------------------------------------------------------------- case DID_OK: { WinDismissDlg( hWnd, TRUE ); return 0; } //-------------------------------------------------------------- // they want to edit a menu //-------------------------------------------------------------- case EDITMENUBUTTON: { if (NumMenus == 0) { WinAlarm(HWND_DESKTOP, WA_ERROR); return 0; } // find out what menu they've selected in list box MenuSelection = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, CURMENULIST, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); // display edit menu dialog box WinDlgBox(HWND_DESKTOP, hWnd, (PFNWP)EditItemProc, 0, EDITITEM, (PVOID)NULL); // change the item in the list box and select it WinSendDlgItemMsg( hWnd, CURMENULIST, LM_DELETEALL, 0, 0 ); for (short i=0; i<NumMenus; i++) WinSendDlgItemMsg( hWnd, CURMENULIST, LM_INSERTITEM, MPFROM2SHORT( LIT_END, 0 ), MenuName[i] ); WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM, MPFROM2SHORT( MenuSelection, 0 ), MPFROM2SHORT( TRUE, 0 ) ); return 0; } //-------------------------------------------------------------- // the user wants to add another menu to the menubar //-------------------------------------------------------------- case ADDMENU: { MenuSelection = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, CURMENULIST, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); // error if no room for another menu if (NumMenus >= MAXMENUS) { WinMessageBox( HWND_DESKTOP, hWnd, "Error! Maximum number of user-menus already defined!", "Add A Menu", 0, MB_MOVEABLE|MB_ERROR|MB_OK); return 0; } WinDlgBox(HWND_DESKTOP, hWnd, (PFNWP)AddAMenuProc, 0, ADDAMENU, (PVOID)NULL); // if first menu to be added, enable buttons if (NumMenus > 0) { WinEnableControl( hWnd, EDITMENUBUTTON, TRUE ); WinEnableControl( hWnd, REMOVEMENU, TRUE ); WinEnableControl( hWnd, MOVEMENULEFT, TRUE ); WinEnableControl( hWnd, MOVEMENURIGHT, TRUE ); } WinSendDlgItemMsg( hWnd, CURMENULIST, LM_DELETEALL, 0, 0 ); for (short i=0; i<NumMenus; i++) WinSendDlgItemMsg( hWnd, CURMENULIST, LM_INSERTITEM, MPFROM2SHORT( LIT_END, 0 ), MenuName[i] ); WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM, MPFROM2SHORT( MenuSelection, 0 ), MPFROM2SHORT( TRUE, 0 ) ); return 0; } //-------------------------------------------------------------- // the user wants to remove a menu from the menu list box //-------------------------------------------------------------- case REMOVEMENU: { if (NumMenus == 0) { WinAlarm(HWND_DESKTOP, WA_WARNING); return 0; } if (NumMenus > 0) if (WinMessageBox( HWND_DESKTOP, hWnd, "If you remove this menu, there will be no way to recover it. Are you sure you want to remove this menu?", "Remove Menu", 0, MB_MOVEABLE|MB_WARNING|MB_YESNO|MB_DEFBUTTON2) == MBID_YES ) { short index = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, CURMENULIST, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); MENUITEM menuItem; // delete it from the lisr box WinSendDlgItemMsg( hWnd, CURMENULIST, LM_DELETEITEM, MPFROM2SHORT( index, 0 ), 0 ); // delete it from menu structure MakeHourglassPointer (); WinSetMenuItemText( hwndMenu, 100*index+100, "" ); for (short i=index+1; i<MAXMENUS; i++) SwapTwoMenus( i-1, i ); NumItems[MAXMENUS-1] = 0; MenuName[MAXMENUS-1][0] = '\0'; if (NumMenus > 0) { int newIndex = index-1; if (0 > newIndex) newIndex = 0; if (index == NumMenus-1) WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM, MPFROM2SHORT( newIndex, 0 ), MPFROM2SHORT( TRUE, 0 ) ); else WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM, MPFROM2SHORT( index, 0 ), MPFROM2SHORT( TRUE, 0 ) ); } //NumItems[NumMenus] = 0; WinSendMsg( hwndMenu, MM_QUERYITEM, MPFROM2SHORT(NumMenus*100,TRUE),MPFROMP(&menuData[index])); menuItem = menuData[index]; menuItem.afStyle = MIS_STATIC; menuItem.afAttribute = MIA_DISABLED; WinSendMsg( hwndMenu, MM_SETITEM, MPFROM2SHORT(NumMenus*100,TRUE),MPFROMP(&menuItem)); WinSetMenuItemText( hwndMenu, 100*MAXMENUS, "" ); NumItems[ NumMenus ] = 0; UpdateMenu[ NumMenus ] = FALSE; NumMenus--; // if we deleted only menu, disable menu buttons if (NumMenus == 0) { WinEnableControl( hWnd, EDITMENUBUTTON, FALSE ); WinEnableControl( hWnd, REMOVEMENU, FALSE ); WinEnableControl( hWnd, MOVEMENULEFT, FALSE ); WinEnableControl( hWnd, MOVEMENURIGHT, FALSE ); } MakeArrowPointer (); } return 0; } //-------------------------------------------------------------- // move menu left in menu structure //-------------------------------------------------------------- case MOVEMENULEFT: { short index = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, CURMENULIST, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); if ((NumMenus == 0) || (index == 0)) { WinAlarm(HWND_DESKTOP, WA_WARNING); return 0; } MakeHourglassPointer (); SwapTwoMenus( index-1, index ); WinSendDlgItemMsg( hWnd, CURMENULIST, LM_DELETEITEM, MPFROM2SHORT( index, 0 ), 0 ); WinSendDlgItemMsg( hWnd, CURMENULIST, LM_INSERTITEM, MPFROM2SHORT( index-1, 0 ), MenuName[index-1] ); WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM, MPFROM2SHORT( index-1, 0 ), MPFROM2SHORT( TRUE, 0 ) ); MakeArrowPointer (); return 0; } //-------------------------------------------------------------- // move menu right in menu structure //-------------------------------------------------------------- case MOVEMENURIGHT: { short index = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, CURMENULIST, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); if ((NumMenus == 0) || (index == (NumMenus)-1)) { WinAlarm(HWND_DESKTOP, WA_WARNING); return 0; } MakeHourglassPointer (); SwapTwoMenus( index, index+1 ); WinSendDlgItemMsg( hWnd, CURMENULIST, LM_DELETEITEM, MPFROM2SHORT( index, 0 ), 0 ); WinSendDlgItemMsg( hWnd, CURMENULIST, LM_INSERTITEM, MPFROM2SHORT( index+1, 0 ), MenuName[index+1] ); WinSendDlgItemMsg( hWnd, CURMENULIST, LM_SELECTITEM, MPFROM2SHORT( index+1, 0 ), MPFROM2SHORT( TRUE, 0 ) ); MakeArrowPointer (); return 0; } //-------------------------------------------------------------- // nothing we care about, pass it onto the system default proc //-------------------------------------------------------------- default: return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } //---------------------------------------------------------------------- // if nothing further we want to intercept, pass message onto system //---------------------------------------------------------------------- default: return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } //////////////////////////////////////////////////////////////////////////////// // SwapTwoMenus will swap the FileBar stored information entries for two menus // indicated by menu1 and menu2. The text on the displayed menubar will also // be changed to indicate the swap. //////////////////////////////////////////////////////////////////////////////// void SwapTwoMenus( short menu1, short menu2 ) { SHORT t1; BYTE t2; for (short i=0; i<MAXITEMS; i++) { strcpy( tmpBuffer, ItemName[menu1][i] ); strcpy( ItemName[menu1][i], ItemName[menu2][i] ); strcpy( ItemName[menu2][i], tmpBuffer ); strcpy( tmpBuffer, ActionToDo[menu1][i] ); strcpy( ActionToDo[menu1][i], ActionToDo[menu2][i] ); strcpy( ActionToDo[menu2][i], tmpBuffer ); strcpy( tmpBuffer, CmdLnArgs[menu1][i] ); strcpy( CmdLnArgs[menu1][i], CmdLnArgs[menu2][i] ); strcpy( CmdLnArgs[menu2][i], tmpBuffer ); strcpy( tmpBuffer, Directory[menu1][i] ); strcpy( Directory[menu1][i], Directory[menu2][i] ); strcpy( Directory[menu2][i], tmpBuffer ); t1 = ProgType[menu2][i]; ProgType[menu2][i] = ProgType[menu1][i]; ProgType[menu1][i] = t1; } t2 = NumItems[menu2]; NumItems[menu2] = NumItems[menu1]; NumItems[menu1] = t2; strcpy( tmpBuffer, MenuName[menu1] ); strcpy( MenuName[menu1], MenuName[menu2] ); strcpy( MenuName[menu2], tmpBuffer ); UpdateMenu[menu1] = TRUE; UpdateMenu[menu2] = TRUE; WinSetMenuItemText( hwndMenu, 100+menu1*100, MenuName[menu1] ); WinSetMenuItemText( hwndMenu, 100+menu2*100, MenuName[menu2] ); } //////////////////////////////////////////////////////////////////////////////// // AddAMenuProc - message handler for the dialog box that allows the user to // add a menu to the menubar //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY AddAMenuProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch( msg ) { //---------------------------------------------------------------------- // when the dialog is being initialized, center it on desktop and put // the current data into controls //---------------------------------------------------------------------- case WM_INITDLG: { SWP swp; WinSendDlgItemMsg( hWnd, MENUNAME, EM_SETTEXTLIMIT, MPFROM2SHORT( MAXMENUNAMELENGTH-1, 0 ), 0 ); WinQueryWindowPos( hWnd, (PSWP)&swp); WinSetWindowPos( hWnd, (HWND)0, ((SHORT)((ScreenSizeX-swp.cx)/2)), ((SHORT)((ScreenSizeY-swp.cy)/2)), 0, 0, SWP_MOVE); break; // return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- // process a command message received from the system //---------------------------------------------------------------------- case WM_COMMAND: { USHORT command = SHORT1FROMMP(mp1); switch( command ) { //-------------------------------------------------------------- // user press OK button. Add the menu name they entered into // the menu structure and return //-------------------------------------------------------------- case DID_OK: { WinQueryDlgItemText( hWnd, MENUNAME, MAXMENUNAMELENGTH, MenuName[NumMenus]); UpdateMenu[NumMenus] = TRUE; NumItems[NumMenus] = 0; menuData[NumMenus].afStyle = 0; menuData[NumMenus].afAttribute = 0; WinSendMsg( hwndMenu, MM_SETITEM, MPFROM2SHORT(100*NumMenus+100,TRUE),MPFROMP(&menuData[NumMenus])); WinSetMenuItemText( hwndMenu, 100*NumMenus+100, &MenuName[NumMenus]); MenuSelection = NumMenus; NumMenus++; WinDismissDlg( hWnd, TRUE ); return 0; } //-------------------------------------------------------------- // they decided not to add a menu, dismiss dialog and return //-------------------------------------------------------------- case DID_CANCEL: { WinDismissDlg( hWnd, TRUE ); return 0; } //-------------------------------------------------------------- // nothing we care about, pass on for default processing //-------------------------------------------------------------- default: break; // return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } // --------------------------------------------------------------------- // if nothing further we want to intercept, pass message onto system // --------------------------------------------------------------------- default: break; // return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //////////////////////////////////////////////////////////////////////////////// // Swap menu items item1 and item2 on menu Menu in the menu information arrays //////////////////////////////////////////////////////////////////////////////// VOID SwapTwoItems(SHORT Menu, SHORT item1, SHORT item2) { SHORT t1; strcpy( tmpBuffer, ItemName[Menu][item2] ); strcpy( ItemName[Menu][item2], ItemName[Menu][item1] ); strcpy( ItemName[Menu][item1], tmpBuffer ); strcpy( tmpBuffer, ActionToDo[Menu][item2] ); strcpy( ActionToDo[Menu][item2], ActionToDo[Menu][item1] ); strcpy( ActionToDo[Menu][item1], tmpBuffer ); strcpy( tmpBuffer, CmdLnArgs[Menu][item2] ); strcpy( CmdLnArgs[Menu][item2], CmdLnArgs[Menu][item1] ); strcpy( CmdLnArgs[Menu][item1], tmpBuffer ); strcpy( tmpBuffer, Directory[Menu][item2] ); strcpy( Directory[Menu][item2], Directory[Menu][item1] ); strcpy( Directory[Menu][item1], tmpBuffer ); t1 = ProgType[Menu][item2]; ProgType[Menu][item2] = ProgType[Menu][item1]; ProgType[Menu][item1] = t1; } //////////////////////////////////////////////////////////////////////////////// // updateItemList - refreshes the contents of the item list list-box in a dialog //////////////////////////////////////////////////////////////////////////////// VOID updateItemList( HWND hWnd ) { CHAR Separator[] = SEPARATOR; WinSendDlgItemMsg( hWnd, ITEMMENU, LM_DELETEALL, 0, 0 ); for (short i=0; i<NumItems[MenuSelection]; i++) if (ItemName[MenuSelection][i][0] != '\0') WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM, MPFROM2SHORT( LIT_END, 0 ), ItemName[MenuSelection][i] ); else WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM, MPFROM2SHORT( LIT_END, 0 ), Separator ); if (NumItems[MenuSelection] > 0) WinSendDlgItemMsg( hWnd, ITEMMENU, LM_SELECTITEM, MPFROM2SHORT( ItemSelection, 0 ), MPFROM2SHORT( TRUE, 0 ) ); } //////////////////////////////////////////////////////////////////////////////// // EditItemProc - the message handler for the edit menu item dialog box //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY EditItemProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch( msg ) { //---------------------------------------------------------------------- // when the dialog is being initialized, center it on desktop and put // the current data into control fields //---------------------------------------------------------------------- case WM_INITDLG: { SWP swp; WinSendDlgItemMsg( hWnd, MENUNAME, EM_SETTEXTLIMIT, MPFROM2SHORT( MAXMENUNAMELENGTH-1, 0 ), 0 ); WinSetDlgItemText( hWnd, MENUNAME, MenuName[MenuSelection]); ItemSelection = 0; updateItemList( hWnd ); WinQueryWindowPos( hWnd, (PSWP)&swp); WinSetWindowPos( hWnd, (HWND)0, ((SHORT)((ScreenSizeX-swp.cx)/2)), ((SHORT)((ScreenSizeY-swp.cy)/2)), 0, 0, SWP_MOVE); break; // return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- // if there is a control message, update enabled status of buttons //---------------------------------------------------------------------- case WM_CONTROL: { if ((SHORT1FROMMP(mp1)==ITEMMENU) && (SHORT2FROMMP(mp1)==LN_ENTER)) return WinSendMsg( hWnd, WM_COMMAND, MPFROM2SHORT( CHANGEITEM, 0 ), mp2 ); break; // return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- // process a command message received from the system //---------------------------------------------------------------------- case WM_COMMAND: { USHORT command = SHORT1FROMMP(mp1); switch( command ) { //-------------------------------------------------------------- // insert a separator into item list, if there is room //-------------------------------------------------------------- case INSERTSEPARATOR: { ItemSelection = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); if (NumItems[MenuSelection] >= MAXITEMS-1) { // error and return if no room WinMessageBox( HWND_DESKTOP, hWnd, "Error! Maximum number of items for this menu already defined!", "Add A Separator", 0, MB_MOVEABLE|MB_ERROR|MB_OK); return 0; } // since this is a separator, blank out launch information ItemSelection = 0; if (NumItems[MenuSelection] > 0) for (short i=NumItems[MenuSelection]-1; i>=0; i--) SwapTwoItems( MenuSelection, i, i+1 ); ItemName[MenuSelection][ItemSelection][0]='\0'; NumItems[MenuSelection]++; UpdateMenu[MenuSelection] = TRUE; updateItemList( hWnd ); return 0; } //-------------------------------------------------------------- // user wants to add an item to the current menu //-------------------------------------------------------------- case ADDITEM: { ItemSelection = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); // error and return if no room for another item if (NumItems[MenuSelection] >= MAXITEMS) { WinMessageBox( HWND_DESKTOP, hWnd, "Error! Maximum number of items for this menu already defined!", "Add Item", 0, MB_MOVEABLE|MB_ERROR|MB_OK); return 0; } // get new item via add item dialog box WinDlgBox(HWND_DESKTOP, hWnd, (PFNWP)AddAnItemProc, 0, ADDANITEM, (PVOID)NULL); // update item list with possible new item updateItemList( hWnd ); return 0; } //-------------------------------------------------------------- // user wants to change a menu item //-------------------------------------------------------------- case CHANGEITEM: { ItemSelection = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); if ((NumItems[MenuSelection] == 0) || (ItemName[MenuSelection][ItemSelection][0] == '\0')) { WinAlarm(HWND_DESKTOP, WA_WARNING); return 0; } WinDlgBox(HWND_DESKTOP, hWnd, (PFNWP)EditItemDataProc, 0, EDITITEMDATA, (PVOID)NULL); updateItemList( hWnd ); return 0; } //-------------------------------------------------------------- // move item down in menu order //-------------------------------------------------------------- case MOVEITEMDOWN: { CHAR Separator[] = SEPARATOR; short i = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); if ((i == NumItems[MenuSelection]-1) || (NumItems[MenuSelection] == 0)) { WinAlarm(HWND_DESKTOP, WA_WARNING); return 0; } SwapTwoItems( MenuSelection, i, i+1 ); WinSendDlgItemMsg( hWnd, ITEMMENU, LM_DELETEITEM, MPFROM2SHORT( i, 0 ), MPFROM2SHORT( TRUE, 0 ) ); if (ItemName[MenuSelection][i+1][0] == '\0') WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM, MPFROM2SHORT( i+1, 0 ), Separator ); else WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM, MPFROM2SHORT( i+1, 0 ), &ItemName[MenuSelection][i+1] ); WinSendDlgItemMsg( hWnd, ITEMMENU, LM_SELECTITEM, MPFROM2SHORT( i+1, 0 ), MPFROM2SHORT( TRUE, 0 ) ); return 0; } //-------------------------------------------------------------- // move item up in menu order //-------------------------------------------------------------- case MOVEITEMUP: { CHAR Separator[] = SEPARATOR; short i = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); if ((i == 0) || (NumItems[MenuSelection] == 0)) { WinAlarm(HWND_DESKTOP, WA_WARNING); return 0; } SwapTwoItems( MenuSelection, i-1, i ); WinSendDlgItemMsg( hWnd, ITEMMENU, LM_DELETEITEM, MPFROM2SHORT( i, 0 ), MPFROM2SHORT( TRUE, 0 ) ); if (ItemName[MenuSelection][i-1][0] == '\0') WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM, MPFROM2SHORT( i-1, 0 ), Separator ); else WinSendDlgItemMsg( hWnd, ITEMMENU, LM_INSERTITEM, MPFROM2SHORT( i-1, 0 ), &ItemName[MenuSelection][i-1] ); WinSendDlgItemMsg( hWnd, ITEMMENU, LM_SELECTITEM, MPFROM2SHORT( i-1, 0 ), MPFROM2SHORT( TRUE, 0 ) ); return 0; } //-------------------------------------------------------------- // remove a menu item //-------------------------------------------------------------- case REMOVEITEM: { if (NumItems[MenuSelection] == 0) { WinAlarm(HWND_DESKTOP, WA_WARNING); return 0; } if (NumItems[MenuSelection] > 0) if (WinMessageBox( HWND_DESKTOP, hWnd, "If you remove this item, there will be no way to recover it. Are you sure you want to remove this item?", "Remove Item", 0, MB_MOVEABLE|MB_WARNING|MB_YESNO|MB_DEFBUTTON2) == MBID_YES ) { short index = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, ITEMMENU, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); WinSendDlgItemMsg( hWnd, ITEMMENU, LM_DELETEITEM, MPFROM2SHORT( index, 0 ), 0 ); for (short i=index; i<MAXITEMS-1; i++) { strcpy( ItemName[MenuSelection][i], ItemName[MenuSelection][i+1]); strcpy( ActionToDo[MenuSelection][i], ActionToDo[MenuSelection][i+1]); strcpy( CmdLnArgs[MenuSelection][i], CmdLnArgs[MenuSelection][i+1]); strcpy( Directory[MenuSelection][i], Directory[MenuSelection][i+1]); ProgType[MenuSelection][i] = ProgType[MenuSelection][i+1]; } if (NumItems[MenuSelection] > 0) { int newIndex = index-1; if (0 > newIndex) newIndex = 0; if (index == NumItems[MenuSelection]-1) WinSendDlgItemMsg( hWnd, ITEMMENU, LM_SELECTITEM, MPFROM2SHORT( newIndex, 0 ), MPFROM2SHORT( TRUE, 0 ) ); else WinSendDlgItemMsg( hWnd, ITEMMENU, LM_SELECTITEM, MPFROM2SHORT( index, 0 ), MPFROM2SHORT( TRUE, 0 ) ); } NumItems[MenuSelection]--; } return 0; } //-------------------------------------------------------------- // user is done editing a menu, save menu name and return //-------------------------------------------------------------- case DID_OK: { WinQueryDlgItemText( hWnd, MENUNAME, MAXMENUNAMELENGTH, MenuName[MenuSelection]); WinSetMenuItemText( hwndMenu, 100*MenuSelection+100, &MenuName[MenuSelection]); UpdateMenu[MenuSelection] = TRUE; WinDismissDlg( hWnd, TRUE ); return 0; } //-------------------------------------------------------------- // not a message we care about, pass it onto the system //-------------------------------------------------------------- default: break; // return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } //---------------------------------------------------------------------- // if nothing further we want to intercept, pass message onto system //---------------------------------------------------------------------- default: break; // return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //////////////////////////////////////////////////////////////////////////////// // update the enable/disabled state of the program type buttons //////////////////////////////////////////////////////////////////////////////// void updateEditItemWindow( HWND hWnd ) { SHORT value = TRUE; if (WinQueryButtonCheckstate( hWnd, STARTWPS )) value = FALSE; WinEnableControl( hWnd, MAXIMIZED, value ); WinEnableControl( hWnd, MINIMIZED, value ); WinEnableControl( hWnd, FOLDER, value ); WinEnableControl( hWnd, DOSWIN, value ); WinEnableControl( hWnd, DOSFS, value ); WinEnableControl( hWnd, OS2WIN, value ); WinEnableControl( hWnd, OS2FS, value ); WinEnableControl( hWnd, WINOS2WIN, value ); WinEnableControl( hWnd, WINOS2FS, value ); WinEnableControl( hWnd, PMAPP, value ); WinEnableControl( hWnd, SETTINGSBUTTON, TRUE-value ); if (WinQueryButtonCheckstate( hWnd, FOLDER )) { WinEnableControl( hWnd, MAXIMIZED, FALSE ); WinEnableControl( hWnd, MINIMIZED, FALSE ); } if ((WinQueryButtonCheckstate( hWnd, FOLDER )) || (WinQueryButtonCheckstate( hWnd, PMAPP ))) WinEnableControl( hWnd, STARTWPS, FALSE ); else WinEnableControl( hWnd, STARTWPS, TRUE ); if (ActionToDo[MenuSelection][ItemSelection][0]=='\0') WinEnableControl( hWnd, SETTINGSBUTTON, FALSE ); } //////////////////////////////////////////////////////////////////////////////// // updateEditItemData - update the check states of all the buttons for the // program item we are currently editing //////////////////////////////////////////////////////////////////////////////// void updateEditItemData( HWND hWnd ) { // put item name and length of longest possible name in entry field WinSendDlgItemMsg( hWnd, ITEMNAME, EM_SETTEXTLIMIT, MPFROM2SHORT( MAXITEMNAMELENGTH-1, 0 ), 0 ); WinSetDlgItemText( hWnd, ITEMNAME, ItemName[MenuSelection][ItemSelection]); // put path name and length of longest possible name in entry field WinSendDlgItemMsg( hWnd, PATHNAME, EM_SETTEXTLIMIT, MPFROM2SHORT( MAXACTIONSTRINGLENGTH-1, 0 ), 0 ); WinSetDlgItemText( hWnd, PATHNAME, ActionToDo[MenuSelection][ItemSelection]); // put argument and length of longest possible in entry field WinSendDlgItemMsg( hWnd, ARGUMENTS, EM_SETTEXTLIMIT, MPFROM2SHORT( MAXARGSTRINGLENGTH-1, 0 ), 0 ); WinSetDlgItemText( hWnd, ARGUMENTS, CmdLnArgs[MenuSelection][ItemSelection]); // put directory and length of longest possible directory in entry field WinSendDlgItemMsg( hWnd, DIRECTORY, EM_SETTEXTLIMIT, MPFROM2SHORT( MAXDIRSTRINGLENGTH-1, 0 ), 0 ); WinSetDlgItemText( hWnd, DIRECTORY, Directory[MenuSelection][ItemSelection]); // set appropriate radio button for program startup option WinCheckButton( hWnd, MAXIMIZED, FALSE ); WinCheckButton( hWnd, MINIMIZED, FALSE ); if (ProgType[MenuSelection][ItemSelection] & STARTMAX) WinCheckButton( hWnd, MAXIMIZED, TRUE ); else if (ProgType[MenuSelection][ItemSelection] & STARTMIN) WinCheckButton( hWnd, MINIMIZED, TRUE ); // set appropriate radio button for program startup option if (ProgType[MenuSelection][ItemSelection] & PM) WinCheckButton( hWnd, PMAPP, TRUE ); else if (ProgType[MenuSelection][ItemSelection] & WPSFOLDER) WinCheckButton( hWnd, FOLDER, TRUE ); else if ( (ProgType[MenuSelection][ItemSelection] & DOS) && (ProgType[MenuSelection][ItemSelection] & WINDOWED)) WinCheckButton( hWnd, DOSWIN, TRUE ); else if ( (ProgType[MenuSelection][ItemSelection] & DOS) && (ProgType[MenuSelection][ItemSelection] & FULLSCREEN)) WinCheckButton( hWnd, DOSFS, TRUE ); else if ( (ProgType[MenuSelection][ItemSelection] & OS2) && (ProgType[MenuSelection][ItemSelection] & WINDOWED)) WinCheckButton( hWnd, OS2WIN, TRUE ); else if ( (ProgType[MenuSelection][ItemSelection] & OS2) && (ProgType[MenuSelection][ItemSelection] & FULLSCREEN)) WinCheckButton( hWnd, OS2FS, TRUE ); else if ( (ProgType[MenuSelection][ItemSelection] & WINOS2) && (ProgType[MenuSelection][ItemSelection] & WINDOWED)) WinCheckButton( hWnd, WINOS2WIN, TRUE ); else if ( (ProgType[MenuSelection][ItemSelection] & WINOS2) && (ProgType[MenuSelection][ItemSelection] & FULLSCREEN)) WinCheckButton( hWnd, WINOS2FS, TRUE ); if (ProgType[MenuSelection][ItemSelection] & STARTASWPS) WinCheckButton( hWnd, STARTWPS, TRUE ); else WinCheckButton( hWnd, STARTWPS, FALSE ); updateEditItemWindow( hWnd ); } //////////////////////////////////////////////////////////////////////////////// // message handler for the dialog "edit an item's values" //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY EditItemDataProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch( msg ) { //---------------------------------------------------------------------- // if the object being drug over us is a single object, allow drag //---------------------------------------------------------------------- case DM_DRAGOVER: { ULONG cbBuffer; DRAGITEM dragItem; PDRAGINFO dragInfoPtr; INT numObjects; dragInfoPtr = (PDRAGINFO)mp1; DrgAccessDraginfo(dragInfoPtr); numObjects = dragInfoPtr->cditem; cbBuffer = sizeof(DRAGITEM); DrgQueryDragitem( dragInfoPtr, cbBuffer, &dragItem, 0 ); DrgFreeDraginfo(dragInfoPtr); // allow anything, if sent by itself, to be dropped on us if (numObjects == 1) return MPFROM2SHORT( DOR_DROP, DO_UNKNOWN ); return MPFROM2SHORT( DOR_NEVERDROP, DO_UNKNOWN ); } //---------------------------------------------------------------------- // allow the dropping of a WPS object to our window. Once dropped, get // necessary info and fill in dialog with the info we retrieve //---------------------------------------------------------------------- case DM_DROP: { PDRAGINFO dragInfoPtr; ULONG cbBuffer; DRAGITEM dragItem; dragInfoPtr = (PDRAGINFO)mp1; DrgAccessDraginfo(dragInfoPtr); cbBuffer = sizeof(DRAGITEM); DrgQueryDragitem( dragInfoPtr, cbBuffer, &dragItem, 0 ); // get menu item name DrgQueryStrName( dragItem.hstrTargetName, sizeof(ItemName[MenuSelection][ItemSelection]), ItemName[MenuSelection][ItemSelection]); // get default directory DrgQueryStrName( dragItem.hstrContainerName, sizeof(Directory[MenuSelection][ItemSelection]), Directory[MenuSelection][ItemSelection]); // get path name DrgQueryStrName( dragItem.hstrSourceName, sizeof(ActionToDo[MenuSelection][ItemSelection]), ActionToDo[MenuSelection][ItemSelection]); ProgType[MenuSelection][ItemSelection] = WPSFOLDER; WinCheckButton( hWnd, FOLDER, TRUE ); DrgFreeDraginfo(dragInfoPtr); updateEditItemData( hWnd ); WinSetFocus( HWND_DESKTOP, hWnd ); return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- // when the dialog is being initialized, center it on desktop and put // the current data into control fields //---------------------------------------------------------------------- case WM_INITDLG: { SWP swp; // center dialog on screen WinQueryWindowPos( hWnd, (PSWP)&swp); WinSetWindowPos( hWnd, (HWND)0, ((SHORT)((ScreenSizeX-swp.cx)/2)), ((SHORT)((ScreenSizeY-swp.cy)/2)), 0, 0, SWP_MOVE); // save data in case of cancel or restore oldProgType = ProgType[MenuSelection][ItemSelection]; strcpy( oldItemName, ItemName[MenuSelection][ItemSelection] ); strcpy( oldDirectory, Directory[MenuSelection][ItemSelection] ); strcpy( oldAction, ActionToDo[MenuSelection][ItemSelection] ); strcpy( oldCmdLn, CmdLnArgs[MenuSelection][ItemSelection] ); updateEditItemData( hWnd ); return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- // we received a control message, update enabling of buttons //---------------------------------------------------------------------- case WM_CONTROL: { // make sure either maximize -or- minimize is checked, never both if ((SHORT1FROMMP(mp1)==MAXIMIZED) && (SHORT2FROMMP(mp1)==BN_CLICKED)) WinCheckButton( hWnd, MINIMIZED, FALSE ); if ((SHORT1FROMMP(mp1)==MINIMIZED) && (SHORT2FROMMP(mp1)==BN_CLICKED)) WinCheckButton( hWnd, MAXIMIZED, FALSE ); updateEditItemWindow( hWnd ); return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- // process a command message received from the system //---------------------------------------------------------------------- case WM_COMMAND: { USHORT command = SHORT1FROMMP(mp1); switch( command ) { //-------------------------------------------------------------- // open the settings notebook and allow user modifications //-------------------------------------------------------------- case SETTINGSBUTTON: { HOBJECT object; // open settings for current program in dialog controls WinQueryDlgItemText( hWnd, ITEMNAME, MAXITEMNAMELENGTH, ItemName[MenuSelection][ItemSelection]); WinQueryDlgItemText( hWnd, PATHNAME, MAXACTIONSTRINGLENGTH, ActionToDo[MenuSelection][ItemSelection]); WinQueryDlgItemText( hWnd, ARGUMENTS, MAXARGSTRINGLENGTH, CmdLnArgs[MenuSelection][ItemSelection]); WinQueryDlgItemText( hWnd, DIRECTORY, MAXDIRSTRINGLENGTH, Directory[MenuSelection][ItemSelection]); if (ProgType[MenuSelection][ItemSelection] & WPSFOLDER) sprintf(tmpBuffer, "%s%s\0", Directory[MenuSelection][ItemSelection],ActionToDo[MenuSelection][ItemSelection]); else sprintf(tmpBuffer, "%s\0", ActionToDo[MenuSelection][ItemSelection]); object = WinQueryObject( tmpBuffer ); if (object==NULLHANDLE) { WinMessageBox( HWND_DESKTOP, hwndFrame, "Could not locate the specified WPS object!\n\nThe pathname and/or directory you specified may not be correct.", "FileBar Error!", 0, MB_MOVEABLE|MB_OK|MB_ERROR); return 0; } WinSetObjectData( object, "OPEN=SETTINGS" ); return 0; } //-------------------------------------------------------------- // the user wants to find a file to call as a menu item. Hook // into OS/2's file dialog procedure to ease the finding process // for us to program! Then once a file is selected, fill in // the program path, directory and query the application for its // application type and mark the appropriate radio button //-------------------------------------------------------------- case FINDFILE: { CHAR title[] = "FileBar - Find A File To Add"; ULONG s, t; HWND hwndDialog; fileDlgInfo.fl = FDS_OPEN_DIALOG|FDS_CENTER; fileDlgInfo.pszTitle = title; strcat(fileDlgInfo.szFullFile, "*.*\0"); hwndDialog = WinFileDlg( HWND_DESKTOP, hWnd, &fileDlgInfo ); if (hwndDialog && (fileDlgInfo.lReturn == DID_OK)) { strcpy( ActionToDo[MenuSelection][ItemSelection], fileDlgInfo.szFullFile ); s=0; while(fileDlgInfo.szFullFile[s]!='\0') s++; while((fileDlgInfo.szFullFile[s]!='\\') && (s>=0)) s--; t = 0; while (t<s) Directory[MenuSelection][ItemSelection][t] = fileDlgInfo.szFullFile[t++]; Directory[MenuSelection][ItemSelection][t] = '\0'; DosQueryAppType( ActionToDo[MenuSelection][ItemSelection], &t); ProgType[MenuSelection][ItemSelection] = OS2 + WINDOWED; if (t == FAPPTYP_WINDOWAPI) ProgType[MenuSelection][ItemSelection] = PM; if (t == FAPPTYP_WINDOWCOMPAT) ProgType[MenuSelection][ItemSelection] = OS2 + WINDOWED; if (t == FAPPTYP_NOTWINDOWCOMPAT) ProgType[MenuSelection][ItemSelection] = OS2 + FULLSCREEN; if (t == FAPPTYP_DOS) ProgType[MenuSelection][ItemSelection] = DOS + WINDOWED; if ((t == FAPPTYP_WINDOWSREAL) || (t == FAPPTYP_WINDOWSPROT)) ProgType[MenuSelection][ItemSelection] = WINOS2 + FULLSCREEN; updateEditItemData( hWnd ); updateEditItemWindow( hWnd ); if (fileDlgInfo.szFullFile[s]=='\\') fileDlgInfo.szFullFile[s+1]='\0'; else fileDlgInfo.szFullFile[0]='\0'; } else fileDlgInfo.szFullFile[0]='\0'; return 0; } //-------------------------------------------------------------- // user pressed Reset, restore old settings and continue //-------------------------------------------------------------- case RESETBUTTON: { ProgType[MenuSelection][ItemSelection] = oldProgType; strcpy( ItemName[MenuSelection][ItemSelection], oldItemName ); strcpy( Directory[MenuSelection][ItemSelection], oldDirectory ); strcpy( ActionToDo[MenuSelection][ItemSelection], oldAction ); strcpy( CmdLnArgs[MenuSelection][ItemSelection], oldCmdLn ); updateEditItemData( hWnd ); return 0; } //-------------------------------------------------------------- // user pressed CANCEL, restore old item data //-------------------------------------------------------------- case DID_CANCEL: { ProgType[MenuSelection][ItemSelection] = oldProgType; strcpy( ItemName[MenuSelection][ItemSelection], oldItemName ); strcpy( Directory[MenuSelection][ItemSelection], oldDirectory ); strcpy( ActionToDo[MenuSelection][ItemSelection], oldAction ); strcpy( CmdLnArgs[MenuSelection][ItemSelection], oldCmdLn ); WinDismissDlg( hWnd, TRUE ); return 0; } //-------------------------------------------------------------- // user pressed OK, save current information for this item //-------------------------------------------------------------- case DID_OK: { // save program type and max/min startup status ProgType[MenuSelection][ItemSelection] = 0; if (WinQueryButtonCheckstate( hWnd, FOLDER )) ProgType[MenuSelection][ItemSelection] = WPSFOLDER; if (WinQueryButtonCheckstate( hWnd, OS2WIN )) ProgType[MenuSelection][ItemSelection] = OS2 + WINDOWED; if (WinQueryButtonCheckstate( hWnd, OS2FS )) ProgType[MenuSelection][ItemSelection] = OS2 + FULLSCREEN; if (WinQueryButtonCheckstate( hWnd, DOSWIN )) ProgType[MenuSelection][ItemSelection] = DOS + WINDOWED; if (WinQueryButtonCheckstate( hWnd, DOSFS )) ProgType[MenuSelection][ItemSelection] = DOS + FULLSCREEN; if (WinQueryButtonCheckstate( hWnd, WINOS2WIN )) ProgType[MenuSelection][ItemSelection] = WINOS2 + WINDOWED; if (WinQueryButtonCheckstate( hWnd, WINOS2FS )) ProgType[MenuSelection][ItemSelection] = WINOS2 + FULLSCREEN; if (WinQueryButtonCheckstate( hWnd, PMAPP )) ProgType[MenuSelection][ItemSelection] = PM; if (WinQueryButtonCheckstate( hWnd, MAXIMIZED )) ProgType[MenuSelection][ItemSelection] = ProgType[MenuSelection][ItemSelection] | STARTMAX; if (WinQueryButtonCheckstate( hWnd, MINIMIZED )) ProgType[MenuSelection][ItemSelection] = ProgType[MenuSelection][ItemSelection] | STARTMIN; if (WinQueryButtonCheckstate( hWnd, STARTWPS )) ProgType[MenuSelection][ItemSelection] = ProgType[MenuSelection][ItemSelection] | STARTASWPS; // save name, path, directory, command line args WinQueryDlgItemText( hWnd, ITEMNAME, MAXITEMNAMELENGTH, ItemName[MenuSelection][ItemSelection]); WinQueryDlgItemText( hWnd, PATHNAME, MAXACTIONSTRINGLENGTH, ActionToDo[MenuSelection][ItemSelection]); WinQueryDlgItemText( hWnd, ARGUMENTS, MAXARGSTRINGLENGTH, CmdLnArgs[MenuSelection][ItemSelection]); WinQueryDlgItemText( hWnd, DIRECTORY, MAXDIRSTRINGLENGTH, Directory[MenuSelection][ItemSelection]); UpdateMenu[MenuSelection] = TRUE; WinDismissDlg( hWnd, TRUE ); return 0; } default: return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } //---------------------------------------------------------------------- // if nothing further we want to intercept, pass message onto system //---------------------------------------------------------------------- default: return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } //////////////////////////////////////////////////////////////////////////////// // AddAnItemProc - the message handler for the "add an item to a menu" dialog //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY AddAnItemProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch( msg ) { //---------------------------------------------------------------------- // when the dialog is being initialized, center it on desktop and put // the current data into control fields //---------------------------------------------------------------------- case WM_INITDLG: { SWP swp; WinSendDlgItemMsg( hWnd, ITEMNAME, EM_SETTEXTLIMIT, MPFROM2SHORT( MAXITEMNAMELENGTH-1, 0 ), 0 ); WinQueryWindowPos( hWnd, (PSWP)&swp); WinSetWindowPos( hWnd, (HWND)0, ((SHORT)((ScreenSizeX-swp.cx)/2)), ((SHORT)((ScreenSizeY-swp.cy)/2)), 0, 0, SWP_MOVE); return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- // process a command message received from the system //---------------------------------------------------------------------- case WM_COMMAND: { USHORT command = SHORT1FROMMP(mp1); switch( command ) { //-------------------------------------------------------------- // if they pressed OK, then save the data in the dialog as an // item that we can now launch from the fileBar. //-------------------------------------------------------------- case DID_OK: { WinQueryDlgItemText( hWnd, ITEMNAME, MAXMENUNAMELENGTH, ItemName[MenuSelection][ (NumItems[MenuSelection]) ]); ActionToDo[MenuSelection][ (NumItems[MenuSelection]) ][0] = '\0'; CmdLnArgs[MenuSelection][ (NumItems[MenuSelection]) ][0] = '\0'; Directory[MenuSelection][ (NumItems[MenuSelection]) ][0] = '\0'; ProgType[MenuSelection][ (NumItems[MenuSelection]) ] = PM; UpdateMenu[MenuSelection] = TRUE; WinDismissDlg( hWnd, TRUE ); ItemSelection = NumItems[MenuSelection]; NumItems[MenuSelection]++; WinDlgBox(HWND_DESKTOP, hWnd, (PFNWP)EditItemDataProc, 0, EDITITEMDATA, (PVOID)NULL); return 0; } //-------------------------------------------------------------- // if they pressed cancel, save no data and return //-------------------------------------------------------------- case DID_CANCEL: { WinDismissDlg( hWnd, TRUE ); return 0; } //-------------------------------------------------------------- // nothing further we care about, pass on for default processing //-------------------------------------------------------------- default: return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } //---------------------------------------------------------------------- // if nothing further we want to intercept, pass message onto system //---------------------------------------------------------------------- default: return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } //////////////////////////////////////////////////////////////////////////////// // Message handler for entering a runtime parameter //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY EnterParamProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch( msg ) { //---------------------------------------------------------------------- // when the dialog is being initialized, center it on desktop //---------------------------------------------------------------------- case WM_INITDLG: { SWP swp; WinSetWindowText( hWnd, parameterTitle ); WinSetDlgItemText( hWnd, PARAMETER_TEXT, ParameterTextPtr ); WinSendDlgItemMsg( hWnd, PARAMETER_TEXT, EM_SETTEXTLIMIT, MPFROMSHORT( sizeof(variableText) ), 0 ); WinQueryWindowPos( hWnd, (PSWP)&swp); WinSetWindowPos( hWnd, (HWND)0, ((SHORT)((ScreenSizeX-swp.cx)/2)), ((SHORT)((ScreenSizeY-swp.cy)/2)), 0, 0, SWP_MOVE); return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- // if we receive any system message, dismiss the dialog box //---------------------------------------------------------------------- case WM_COMMAND: { WinQueryDlgItemText( hWnd, PARAMETER_EDIT, sizeof(variableText), (PSZ)variableText ); WinDismissDlg( hWnd, TRUE ); return 0; } //---------------------------------------------------------------------- // if nothing further we want to intercept, pass message onto system //---------------------------------------------------------------------- default: return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } //////////////////////////////////////////////////////////////////////////////// // startApplication uses DosStartSession to start a batch file to start an // application pointed to in one of the user menus by menu and item variables. //////////////////////////////////////////////////////////////////////////////// SHORT startApplication( SHORT menu, SHORT item ) { CHAR parameters[MAXARGSTRINGLENGTH*2]; CHAR itemName[MAXITEMNAMELENGTH]; APIRET rc; STARTDATA startData; ULONG sessionId; PID ppId; UCHAR ObjBuf[2]; SHORT y1 = 0; SHORT y2 = 0; SHORT i = 0; SHORT h = 0; // remove tilde from title window while (ItemName[menu][item][y1]!='\0') { if (ItemName[menu][item][y1]!='~') itemName[y2++] = ItemName[menu][item][y1]; y1++; } itemName[y2] = '\0'; // get command line arguments via user input if necessary while ( CmdLnArgs[menu][item][i] != '\0' ) { if (CmdLnArgs[menu][item][i] == STARTINPUT) { short j = 0; CHAR tmp[MAXARGSTRINGLENGTH]; i++; while ( (CmdLnArgs[menu][item][i] != '\0') && (CmdLnArgs[menu][item][i] != ENDINPUT )) tmp[j++] = CmdLnArgs[menu][item][i++]; tmp[j] = '\0'; if (CmdLnArgs[menu][item][i] != '\0') i++; { CHAR mesg[18+MAXARGSTRINGLENGTH]; SHORT k = 0; sprintf( parameterTitle, "%s parameter...", ItemName[menu][item] ); sprintf( mesg, "Please enter '%s'", tmp); ParameterTextPtr = mesg; (VOID*)WinDlgBox(HWND_DESKTOP, hwndFrame, (PFNWP)EnterParamProc, 0, ENTERPARAMETER, (PVOID)NULL); while ( variableText[k] != '\0') parameters[h++] = variableText[k++]; } } else parameters[h++] = CmdLnArgs[menu][item][i++]; } parameters[h] = '\0'; //-------------------------------------------------------------------------- // open a WPS folder/object //-------------------------------------------------------------------------- if ((ProgType[menu][item] & WPSFOLDER) || (ProgType[menu][item] & STARTASWPS)) { CHAR string[MAXACTIONSTRINGLENGTH+MAXDIRSTRINGLENGTH+2]; ULONG numItems; ULONG Buffer; PSWBLOCK SwitchBlockPtr; HSWITCH hSwitch; HOBJECT object; if (ProgType[menu][item] & WPSFOLDER) sprintf(string, "%s%s\0", Directory[menu][item],ActionToDo[menu][item]); else sprintf(string, "%s\0", ActionToDo[menu][item]); object = WinQueryObject( string ); if (object==NULLHANDLE) { WinMessageBox( HWND_DESKTOP, hwndFrame, "Could not locate the specified WPS object!\n\nThe pathname and/or directory you specified may not be correct.", "FileBar Error!", 0, MB_MOVEABLE|MB_OK|MB_ERROR); return 0; } WinSetObjectData(object, "OPEN=DEFAULT"); numItems = WinQuerySwitchList( hab, NULL, 0 ); Buffer = (numItems * sizeof(SWENTRY)) + sizeof(HSWITCH); PVOID my = new BYTE[Buffer]; WinQuerySwitchList( hab, (SWBLOCK*)my, Buffer ); SwitchBlockPtr = (PSWBLOCK)(my); hSwitch = WinQuerySwitchHandle( SwitchBlockPtr->aswentry[numItems-1].swctl.hwnd, SwitchBlockPtr->aswentry[numItems-1].swctl.idProcess); delete( my ); return WinSwitchToProgram( hSwitch ); } //-------------------------------------------------------------------------- // launch a windows app //-------------------------------------------------------------------------- if (ProgType[menu][item] & WINOS2) { FILE* outputFile; STARTDATA startData; outputFile = fopen(LAUNCHFILE, "wt"); if (!outputFile) { char title[] = "Launch an application"; char text[] = "Could not start the application due to an error accessing the drive"; WinMessageBox( HWND_DESKTOP, hwndFrame, text, title, 0, MB_MOVEABLE|MB_ERROR|MB_OK); return 0; } if (Directory[menu][item][0] != '\0') { if ((isalpha( Directory[menu][item][0] )) && ( Directory[menu][item][1]==':')) fprintf( outputFile, "%c:\n", Directory[menu][item][0]); fprintf( outputFile, "cd %s\n", Directory[menu][item]); } fprintf( outputFile, "start /K " ); if (ProgType[menu][item] & STARTMAX) fprintf( outputFile, "/MAX "); else if (ProgType[menu][item] & STARTMIN) fprintf( outputFile, "/MIN "); if (ProgType[menu][item] & FULLSCREEN) fprintf( outputFile, "/FS "); else fprintf( outputFile, "/WIN "); fprintf( outputFile, "%s %s", ActionToDo[menu][item], parameters ); fclose( outputFile ); { CHAR title[] = "FileBar\nWIN-OS/2 Launch"; CHAR program[] = OS2SHELL; CHAR inputs[] = LAUNCHINPUTS; memset( &startData, 0, sizeof(STARTDATA) ); startData.Related = SSF_RELATED_INDEPENDENT; startData.FgBg = SSF_FGBG_FORE; startData.TraceOpt = SSF_TRACEOPT_NONE; startData.InheritOpt = SSF_INHERTOPT_PARENT; startData.SessionType = SSF_TYPE_WINDOWABLEVIO; startData.PgmControl = SSF_CONTROL_INVISIBLE | SSF_CONTROL_MINIMIZE; startData.PgmTitle = title; startData.PgmName = program; startData.PgmInputs = inputs; startData.ObjectBuffer = ObjBuf; startData.ObjectBuffLen = sizeof(ObjBuf); startData.Length = sizeof(STARTDATA); return DosStartSession( (STARTDATA*) &startData, (ULONG*)&sessionId, (PID*) &ppId ); } } //-------------------------------------------------------------------------- /* //// this doesn't work to start a seamless app and I don't know why!! :( //-------------------------------------------------------------------------- if ((ProgType[menu][item] & WINOS2) && (ProgType[menu][item] & WINDOWED)) { APIRET rc; PROGDETAILS pDetails; memset( &pDetails, 0, sizeof(PROGDETAILS) ); pDetails.Length = sizeof(PROGDETAILS); pDetails.progt.progc = PROG_WINDOWABLEVIO; pDetails.progt.fbVisible = SHE_VISIBLE; pDetails.pszTitle = 0; //ItemName[menu][item]; pDetails.pszExecutable = "\\os2\\te2\\te2.exe"; //ActionToDo[menu][item]; //pDetails.pszParameters = ""; //pDetails.pszIcon = "C:\\OS2\\FILEBAR\\FILEBAR.ICO"; //pDetails.pszEnvironment = "WORKPLACE\0\0"; //pDetails.pszParameters = CmdLnArgs[menu][item]; //pDetails.pszStartupDir = "d:\os2\mdos\winos2"; //Directory[menu][item]; pDetails.swpInitial.fl = SWP_ACTIVATE; if (ProgType[menu][item] & STARTMAX) rc = WinStartApp(NULLHANDLE, &pDetails, CmdLnArgs[menu][item], NULL, 4 ); else if (ProgType[menu][item] & STARTMIN) rc = WinStartApp(NULLHANDLE, &pDetails, CmdLnArgs[menu][item], NULL, 8 ); else rc = WinStartApp(NULLHANDLE, &pDetails, CmdLnArgs[menu][item], NULL, 0 ); if (rc==0) { ERRORID errorID = WinGetLastError( hab ); char text[1024]; sprintf(text, "error code %lu\0", errorID); WinMessageBox( HWND_DESKTOP, hwndFrame, text, NULL, 0, MB_MOVEABLE|MB_ERROR|MB_OK); } return 0; } */ //-------------------------------------------------------------------------- // this launches a command shell (DOS or OS2 (Windowed or FS session)) //-------------------------------------------------------------------------- if (ActionToDo[menu][item][0] == '\0') { ULONG currentDrive; ULONG driveMap; CHAR InputDir[MAXPATH + 9]; DosQueryCurrentDisk( ¤tDrive, &driveMap ); DosSetDefaultDisk( (ULONG)(toupper(Directory[menu][item][0])-'A' + 1) ); memset( &startData, 0, sizeof(STARTDATA) ); startData.Related = SSF_RELATED_INDEPENDENT; startData.FgBg = SSF_FGBG_FORE; startData.TraceOpt = SSF_TRACEOPT_NONE; startData.InheritOpt = SSF_INHERTOPT_PARENT; startData.ObjectBuffer = ObjBuf; startData.ObjectBuffLen = sizeof(ObjBuf); startData.Length = sizeof(STARTDATA); startData.PgmTitle = itemName; strcpy( InputDir, "/K cd \0"); strcpy( InputDir+6, Directory[menu][item] ); startData.PgmInputs = InputDir; startData.PgmControl = SSF_CONTROL_VISIBLE; if (ProgType[menu][item] & MAXIMIZED) startData.PgmControl = SSF_CONTROL_VISIBLE | SSF_CONTROL_MAXIMIZE; else if (ProgType[menu][item] & MINIMIZED) startData.PgmControl = SSF_CONTROL_VISIBLE | SSF_CONTROL_MINIMIZE; if (ProgType[menu][item] & DOS) { if (ProgType[menu][item] & WINDOWED) startData.SessionType = SSF_TYPE_WINDOWEDVDM; else startData.SessionType = SSF_TYPE_VDM; rc = DosStartSession( (STARTDATA*) &startData, (ULONG*)&sessionId, (PID*) &ppId ); DosSetDefaultDisk( currentDrive ); return rc; } else if (ProgType[menu][item] & OS2) { if (ProgType[menu][item] & WINDOWED) startData.SessionType = SSF_TYPE_WINDOWABLEVIO; else startData.SessionType = SSF_TYPE_FULLSCREEN; rc = DosStartSession( (STARTDATA*) &startData, (ULONG*)&sessionId, (PID*) &ppId ); DosSetDefaultDisk( currentDrive ); return rc; } WinMessageBox( HWND_DESKTOP, hwndFrame, "Error opening command shell!", NULL, 0, MB_MOVEABLE|MB_ERROR|MB_OK); return 0; } //-------------------------------------------------------------------------- // this section of code launches a program (non-command shell application) //-------------------------------------------------------------------------- { CHAR SettingsBuffer[WPSBUFFER]; ULONG currentDrive; ULONG driveMap; UCHAR defaultDirectory[MAXPATH]; //CHAR program[MAXPATH]; CHAR inputs[MAXARGSTRINGLENGTH]; memset( &startData, 0, sizeof(STARTDATA) ); startData.Length = sizeof(STARTDATA); startData.Related = SSF_RELATED_INDEPENDENT; startData.FgBg = SSF_FGBG_FORE; startData.TraceOpt = SSF_TRACEOPT_NONE; startData.PgmTitle = itemName; startData.InheritOpt = SSF_INHERTOPT_PARENT; startData.SessionType = SSF_TYPE_WINDOWABLEVIO; startData.PgmControl = SSF_CONTROL_VISIBLE; startData.SessionType = SSF_TYPE_PM; startData.PgmName = ActionToDo[menu][item]; startData.PgmInputs = parameters; if (ProgType[menu][item] & DOS) { if (ProgType[menu][item] & FULLSCREEN) startData.SessionType = SSF_TYPE_VDM; else if (ProgType[menu][item] & WINDOWED) startData.SessionType = SSF_TYPE_WINDOWEDVDM; } else if (ProgType[menu][item] & OS2) { if (ProgType[menu][item] & FULLSCREEN) startData.SessionType = SSF_TYPE_FULLSCREEN; else if (ProgType[menu][item] & WINDOWED) startData.SessionType = SSF_TYPE_WINDOWABLEVIO; } else if (ProgType[menu][item] & WINOS2) startData.SessionType = PROG_WINDOW_AUTO; if (ProgType[menu][item] & STARTMAX) startData.PgmControl |= SSF_CONTROL_MAXIMIZE; else if (ProgType[menu][item] & STARTMIN) startData.PgmControl |= SSF_CONTROL_MINIMIZE; if ((startData.PgmName != NULL) && (startData.SessionType != SSF_TYPE_PM)) { CHAR temp[MAXPATH+MAXARGSTRINGLENGTH+6]; sprintf(temp, "/c %s %s\0", ActionToDo[menu][item], parameters); startData.PgmName = 0; strcpy(inputs, temp); startData.PgmInputs = inputs; } // save current drive and directory DosQueryCurrentDisk( ¤tDrive, &driveMap ); { CHAR temp[MAXPATH+5]; ULONG tempSize = MAXPATH; defaultDirectory[0]= (currentDrive+'A'-1); defaultDirectory[1]= ':'; defaultDirectory[2]= '\\'; defaultDirectory[3]= '\0'; DosQueryCurrentDir( currentDrive, (CHAR*)&temp, &tempSize ); strcat( defaultDirectory, temp ); } // point to working directory of program to execute if (((toupper(Directory[menu][item][0]))>='A') && ((toupper(Directory[menu][item][0]))<='Z')) DosSetDefaultDisk( (ULONG)(toupper(Directory[menu][item][0])-'A' + 1) ); DosSetCurrentDir( Directory[menu][item] ); // try and locate a settings file { FILE *FileHandle; memset( &SettingsBuffer, 0, sizeof(SettingsBuffer) ); if ((FileHandle = fopen("SETTINGS.INI","rt")) != NULL) { SHORT offset = 0; CHAR ch; while (fscanf(FileHandle, "%c", &ch) != EOF) { if ( ch == '\n' ) SettingsBuffer[ offset++ ] = '\0'; else SettingsBuffer[ offset++ ] = ch; } SettingsBuffer[ offset++ ] = '\0'; SettingsBuffer[ offset++ ] = '\x1A'; fclose(FileHandle); startData.Environment = SettingsBuffer; } } // launch application rc = DosStartSession( (STARTDATA*) &startData, (ULONG*)&sessionId, (PID*) &ppId ); // restore current drive and directory DosSetDefaultDisk( currentDrive ); DosSetCurrentDir( defaultDirectory ); if ((rc != 0) && (rc != ERROR_SMG_START_IN_BACKGROUND) && (!startUp)) { char text[] = "Could not open the specified item. Path and directory information may not be correct."; char title[28]; sprintf(title, "FileBar Error code #%d", rc ); WinMessageBox( HWND_DESKTOP, hwndFrame, text, title, 0, MB_MOVEABLE|MB_ERROR|MB_OK); } return rc; } } //////////////////////////////////////////////////////////////////////////////// // display a background bitmap //////////////////////////////////////////////////////////////////////////////// VOID displayBackground( VOID ) { DESKTOP desktop; if ((showBackground) || (isBackgroundDisplayed)) { desktop.cbSize = sizeof( DESKTOP ); desktop.hbm = 0; desktop.x = 0; desktop.y = 0; desktop.fl = SDT_DESTROY; if (isBackgroundDisplayed) WinSetDesktopBkgnd( HWND_DESKTOP, &desktop ); desktop.fl = SDT_LOADFILE|SDT_CENTER; if (backgroundAttr & SCALED) desktop.fl = SDT_SCALE|SDT_LOADFILE; if (backgroundAttr & TILED) { desktop.fl = SDT_TILE|SDT_LOADFILE; desktop.lTileCount = backgroundAttr - TILED; } strcpy( desktop.szFile, backgroundBitmap ); if (showBackground) { WinSetDesktopBkgnd( HWND_DESKTOP, &desktop ); isBackgroundDisplayed = TRUE; } } } //////////////////////////////////////////////////////////////////////////////// // Message handler for a generic information-only dialog box (help & prod info) //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY backgroundProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch( msg ) { //---------------------------------------------------------------------- // when the dialog is being initialized, center it on desktop //---------------------------------------------------------------------- case WM_INITDLG: { SWP swp; char temp[12]; WinCheckButton( hWnd, BKGND_NORMAL, TRUE ); if (backgroundAttr & SCALED) WinCheckButton( hWnd, BKGND_SCALED, TRUE ); else if (backgroundAttr & TILED) { WinCheckButton( hWnd, BKGND_TILED, TRUE ); WinEnableControl( hWnd, BKGND_TILENUMBER, TRUE ); WinEnableControl( hWnd, BKGND_TILENUMBERTEXT, TRUE ); WinEnableControl( hWnd, BKGND_LESS, TRUE ); WinEnableControl( hWnd, BKGND_MORE, TRUE ); } if (backgroundAttr & SCALED) backgroundAttr = backgroundAttr - SCALED; if (backgroundAttr & TILED) backgroundAttr = backgroundAttr - TILED; sprintf(temp,"%d x %d", backgroundAttr, backgroundAttr); WinSetDlgItemText( hWnd, BKGND_TILENUMBER, temp ); WinSendDlgItemMsg( hWnd, BKGND_BITMAPNAME, EM_SETTEXTLIMIT, MPFROMSHORT( sizeof(backgroundBitmap) ), 0 ); WinSetDlgItemText( hWnd, BKGND_BITMAPNAME, backgroundBitmap ); WinCheckButton( hWnd, BKGND_SHOW, showBackground ); WinQueryWindowPos( hWnd, (PSWP)&swp); WinSetWindowPos( hWnd, (HWND)0, ((SHORT)((ScreenSizeX-swp.cx)/2)), ((SHORT)((ScreenSizeY-swp.cy)/2)), 0, 0, SWP_MOVE); return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- case WM_CONTROL: { if (SHORT2FROMMP(mp1)==BN_CLICKED) { BOOLEAN option = FALSE; if (WinQueryButtonCheckstate( hWnd, BKGND_TILED)) option = TRUE; WinEnableControl( hWnd, BKGND_TILENUMBER, option ); WinEnableControl( hWnd, BKGND_TILENUMBERTEXT, option ); WinEnableControl( hWnd, BKGND_LESS, option ); WinEnableControl( hWnd, BKGND_MORE, option ); } return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- case WM_COMMAND: { USHORT command = SHORT1FROMMP(mp1); switch( command ) { //-------------------------------------------------------------- // if they pressed OK, then save the data in the dialog as an // item that we can now launch from the fileBar. //-------------------------------------------------------------- case DID_OK: { WinQueryDlgItemText( hWnd, BKGND_BITMAPNAME, sizeof(backgroundBitmap), (PSZ)backgroundBitmap ); showBackground = WinQueryButtonCheckstate( hWnd, BKGND_SHOW ); if (WinQueryButtonCheckstate( hWnd, BKGND_SCALED)) backgroundAttr = backgroundAttr + SCALED; if (WinQueryButtonCheckstate( hWnd, BKGND_TILED)) backgroundAttr = backgroundAttr + TILED; WinDismissDlg( hWnd, TRUE ); return 0; } //-------------------------------------------------------------- //-------------------------------------------------------------- case BKGND_LESS: { char temp[12]; if (backgroundAttr > 1) backgroundAttr--; sprintf(temp,"%d x %d", backgroundAttr, backgroundAttr); WinSetDlgItemText( hWnd, BKGND_TILENUMBER, temp ); return 0; } //-------------------------------------------------------------- //-------------------------------------------------------------- case BKGND_MORE: { char temp[12]; if (backgroundAttr < 32) backgroundAttr++; sprintf(temp,"%d x %d", backgroundAttr, backgroundAttr); WinSetDlgItemText( hWnd, BKGND_TILENUMBER, temp ); return 0; } //-------------------------------------------------------------- //-------------------------------------------------------------- case BKGND_FINDFILE: { CHAR title[] = "FileBar - Find A Background Image"; ULONG s; HWND hwndDialog; CHAR oldDir[MAXPATH]; fileDlgInfo.fl = FDS_OPEN_DIALOG|FDS_CENTER; fileDlgInfo.pszTitle = title; strcpy( oldDir, fileDlgInfo.szFullFile ); strcat(fileDlgInfo.szFullFile, "*.BMP\0"); hwndDialog = WinFileDlg( HWND_DESKTOP, hWnd, &fileDlgInfo ); if (hwndDialog && (fileDlgInfo.lReturn == DID_OK)) { strcpy( backgroundBitmap, fileDlgInfo.szFullFile ); s=0; while(fileDlgInfo.szFullFile[s]!='\0') s++; while((fileDlgInfo.szFullFile[s]!='\\') && (s>=0)) s--; if (fileDlgInfo.szFullFile[s]=='\\') fileDlgInfo.szFullFile[s+1]='\0'; else fileDlgInfo.szFullFile[0]='\0'; WinSetDlgItemText( hWnd, BKGND_BITMAPNAME, backgroundBitmap ); } else strcpy( fileDlgInfo.szFullFile, oldDir ); return 0; } } } //---------------------------------------------------------------------- // if nothing further we want to intercept, pass message onto system //---------------------------------------------------------------------- default: return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } //////////////////////////////////////////////////////////////////////////////// // Message handler for a generic information-only dialog box (help & prod info) //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY startupProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch( msg ) { //---------------------------------------------------------------------- // when the dialog is being initialized, center it on desktop //---------------------------------------------------------------------- case WM_INITDLG: { SWP swp; short i,j; char temp[MAXITEMNAMELENGTH+8]; WinQueryWindowPos( hWnd, (PSWP)&swp); WinSetWindowPos( hWnd, (HWND)0, ((SHORT)((ScreenSizeX-swp.cx)/2)), ((SHORT)((ScreenSizeY-swp.cy)/2)), 0, 0, SWP_MOVE); WinSendDlgItemMsg( hWnd, STARTUP_ITEMLIST, LM_DELETEALL, 0, 0); temp[0] = ' '; temp[1] = ' '; temp[2] = '-'; temp[3] = ' '; for (i=0; i<NumMenus; i++) { WinSendDlgItemMsg( hWnd, STARTUP_ITEMLIST, LM_INSERTITEM, MPFROMSHORT( LIT_END ), MenuName[i] ); for (j=0; j<NumItems[i]; j++) if (ItemName[i][j][0] != '\0') { temp[4] = '\0'; strcat(temp, ItemName[i][j]); WinSendDlgItemMsg( hWnd, STARTUP_ITEMLIST, LM_INSERTITEM, MPFROMSHORT( LIT_END ), temp ); } } WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_DELETEALL, 0, 0); for( i = 0; i< numStartItems; i++) WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_INSERTITEM, MPFROMSHORT( LIT_END ), ItemName[(StartUpMenu[i])][(StartUpItem[i])] ); WinCheckButton( hWnd, STARTUP_LAUNCH, DoStartUpList ); return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- case WM_CONTROL: { if (SHORT2FROMMP(mp1)==BN_CLICKED) { BOOLEAN option = FALSE; if (WinQueryButtonCheckstate( hWnd, BKGND_TILED)) option = TRUE; WinEnableControl( hWnd, BKGND_TILENUMBER, option ); WinEnableControl( hWnd, BKGND_TILENUMBERTEXT, option ); WinEnableControl( hWnd, BKGND_LESS, option ); WinEnableControl( hWnd, BKGND_MORE, option ); } return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- case WM_COMMAND: { USHORT command = SHORT1FROMMP(mp1); switch( command ) { //-------------------------------------------------------------- //-------------------------------------------------------------- case STARTUP_ADD: { if (numStartItems == MAXSTARTITEMS) WinMessageBox( HWND_DESKTOP, hwndFrame, "No room to add an additional task!", "Add a start up item", 0, MB_MOVEABLE|MB_ERROR|MB_OK); else { SHORT itemSelected = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, STARTUP_ITEMLIST, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); if (itemSelected == LIT_NONE) { WinMessageBox( HWND_DESKTOP, hwndFrame, "You must first select an item to add!", "Add a start up item", 0, MB_MOVEABLE|MB_ERROR|MB_OK); return 0; } { char buffer[MAXITEMNAMELENGTH + 8]; SHORT i,j; BOOL found = FALSE; for( i=0; i<NumMenus; i++) for( j=0; j<NumItems[i]; j++) { SHORT1FROMMP( WinSendDlgItemMsg( hWnd, STARTUP_ITEMLIST, LM_QUERYITEMTEXT, MPFROM2SHORT( itemSelected, sizeof(buffer) ), &buffer ) ); if (strcmp(&(buffer[4]),ItemName[i][j])==0) { StartUpMenu[ numStartItems ] = i; StartUpItem[ numStartItems ] = j; numStartItems++; WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_INSERTITEM, MPFROMSHORT( LIT_END ), ItemName[i][j] ); found = TRUE; } } if (!found) WinMessageBox( HWND_DESKTOP, hwndFrame, "You need to select an item -- not a menu!", "Add a start up item", 0, MB_MOVEABLE|MB_ERROR|MB_OK); } } return 0; } //-------------------------------------------------------------- //-------------------------------------------------------------- case STARTUP_REMOVE: { SHORT itemSelected = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); SHORT i; if (itemSelected != LIT_NONE) { for (i=itemSelected+1; i<numStartItems; i++) { StartUpMenu[i-1] = StartUpMenu[i]; StartUpItem[i-1] = StartUpItem[i]; } numStartItems--; WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_DELETEALL, 0, 0); for( i = 0; i< numStartItems; i++) WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_INSERTITEM, MPFROMSHORT( LIT_END ), ItemName[(StartUpMenu[i])][(StartUpItem[i])] ); if (itemSelected == numStartItems) WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_SELECTITEM, MPFROM2SHORT( numStartItems-1, 0 ), MPFROM2SHORT( TRUE, 0 ) ); else WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_SELECTITEM, MPFROM2SHORT( itemSelected, 0 ), MPFROM2SHORT( TRUE, 0 ) ); } return 0; } //-------------------------------------------------------------- //-------------------------------------------------------------- case STARTUP_CLEARALL: { WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_DELETEALL, 0, 0); numStartItems = 0; return 0; } //-------------------------------------------------------------- //-------------------------------------------------------------- case STARTUP_MOVEDOWN: { SHORT itemSelected = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); if ((itemSelected < (numStartItems-1)) && (itemSelected != LIT_NONE)) { SHORT z; SHORT i; z = StartUpMenu[itemSelected+1]; StartUpMenu[itemSelected+1] = StartUpMenu[itemSelected]; StartUpMenu[itemSelected] = z; z = StartUpItem[itemSelected+1]; StartUpItem[itemSelected+1] = StartUpItem[itemSelected]; StartUpItem[itemSelected] = z; WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_DELETEALL, 0, 0); for( i = 0; i< numStartItems; i++) WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_INSERTITEM, MPFROMSHORT( LIT_END ), ItemName[(StartUpMenu[i])][(StartUpItem[i])] ); WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_SELECTITEM, MPFROM2SHORT( itemSelected+1, 0 ), MPFROM2SHORT( TRUE, 0 ) ); } return 0; } //-------------------------------------------------------------- //-------------------------------------------------------------- case STARTUP_MOVEUP: { SHORT itemSelected = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); if ((itemSelected > 0) && (itemSelected != LIT_NONE)) { SHORT z; SHORT i; z = StartUpMenu[itemSelected-1]; StartUpMenu[itemSelected-1] = StartUpMenu[itemSelected]; StartUpMenu[itemSelected] = z; z = StartUpItem[itemSelected-1]; StartUpItem[itemSelected-1] = StartUpItem[itemSelected]; StartUpItem[itemSelected] = z; WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_DELETEALL, 0, 0); for( i = 0; i< numStartItems; i++) WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_INSERTITEM, MPFROMSHORT( LIT_END ), ItemName[(StartUpMenu[i])][(StartUpItem[i])] ); WinSendDlgItemMsg( hWnd, STARTUP_CURRITEMS, LM_SELECTITEM, MPFROM2SHORT( itemSelected-1, 0 ), MPFROM2SHORT( TRUE, 0 ) ); } return 0; } //-------------------------------------------------------------- // if they pressed OK, then save the data in the dialog as an // item that we can now launch from the fileBar. //-------------------------------------------------------------- case DID_OK: { DoStartUpList = WinQueryButtonCheckstate( hWnd, STARTUP_LAUNCH); WinDismissDlg( hWnd, TRUE ); return 0; } } } //---------------------------------------------------------------------- // if nothing further we want to intercept, pass message onto system //---------------------------------------------------------------------- default: return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } //////////////////////////////////////////////////////////////////////////////// // execute start up list of applications //////////////////////////////////////////////////////////////////////////////// VOID ExecuteStartUpList( VOID ) { SHORT i; if (DoStartUpList) for (i=0; i<numStartItems; i++) startApplication( StartUpMenu[i], StartUpItem[i] ); startUp = FALSE; } //////////////////////////////////////////////////////////////////////////////// // update the buttons of the calendar to reflect current month structure //////////////////////////////////////////////////////////////////////////////// VOID updateCalendar( HWND hWnd ) { CHAR temp[50]; struct tm *time_now; time_t currentTime; short i; short numDaysInMonth; time(¤tTime); time_now = localtime( ¤tTime ); numDaysInMonth = numberOfDaysInMonth(month, year); time_now->tm_mon = month; time_now->tm_year= year; strftime( temp, sizeof(temp), " %B - %Y ", time_now); WinSetDlgItemText( hWnd, 550, temp ); for( i=0; i<startDay; i++) { WinSetDlgItemText( hWnd, i+500, "" ); WinEnableControl( hWnd, i+500, FALSE ); } for( i=1; i<=numDaysInMonth; i++) { sprintf(temp, "%d", i); WinEnableControl( hWnd, i+startDay+500-1, TRUE ); WinSetDlgItemText( hWnd, i+startDay+500-1, temp ); } for( i=numDaysInMonth+startDay+500; i<543; i++) { WinSetDlgItemText( hWnd, i, "" ); WinEnableControl( hWnd, i, FALSE ); } } //////////////////////////////////////////////////////////////////////////////// // return # of days in # (even checking for leap year) //////////////////////////////////////////////////////////////////////////////// BYTE numberOfDaysInMonth(int month, int year) { if (((1900+year) % 4) || (month != 1)) return daysInMonth[month]; else return daysInMonth[month]+1; //handle leap year } //////////////////////////////////////////////////////////////////////////////// // display scheduling calendar and let user schedule and revise tasks //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY schedulerProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch( msg ) { //---------------------------------------------------------------------- // when the dialog is being initialized, center it on desktop //---------------------------------------------------------------------- case WM_INITDLG: { struct tm *time_now; CHAR mesg[24]; time_t currentTime; SWP swp; WinQueryWindowPos( hWnd, (PSWP)&swp); WinSetWindowPos( hWnd, (HWND)0, ((SHORT)((ScreenSizeX-swp.cx)/2)), ((SHORT)((ScreenSizeY-swp.cy)/2)), 0, 0, SWP_MOVE); time(¤tTime); time_now = localtime( ¤tTime ); month = time_now->tm_mon; year = time_now->tm_year; startDay = (time_now->tm_wday - (time_now->tm_mday % 7 - 1)); if (startDay > 6) startDay = startDay - 7; else if (startDay < 0) startDay = startDay + 7; updateCalendar( hWnd ); sprintf( mesg, "Every %d Seconds", repeatTime ); WinSetDlgItemText( hWnd, REMINDERTIME, mesg ); return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- // process a command message from the dialog box //---------------------------------------------------------------------- case WM_COMMAND: { USHORT command = SHORT1FROMMP(mp1); //------------------------------------------------------------------ // if the user pressed a day button, show daily schedule window //------------------------------------------------------------------ if ((command>=500) && (command<=542)) { day = command - 500 - startDay; WinDlgBox(HWND_DESKTOP, hWnd, (PFNWP)scheduleProc, 0, SCHEDULEITEM, (PVOID)NULL); return 0; } //------------------------------------------------------------------ // handle user commands //------------------------------------------------------------------ switch( command ) { //------------------------------------------------------------------ // show all currently scheduled tasks //------------------------------------------------------------------ case SHOWALL: { WinDlgBox(HWND_DESKTOP, hWnd, (PFNWP)showAllItemsProc, 0, SHOWALLITEMS, (PVOID)NULL); return 0; } //-------------------------------------------------------------- // reduce amount of time between reminder sounds //-------------------------------------------------------------- case LESSTIME: { char mesg[24]; if (repeatTime>0) repeatTime--; sprintf( mesg, "Every %d Seconds", repeatTime ); WinSetDlgItemText( hWnd, REMINDERTIME, mesg ); return 0; } //-------------------------------------------------------------- // increase amount of time between reminder sounds //-------------------------------------------------------------- case MORETIME: { char mesg[24]; if (repeatTime<32767) repeatTime++; sprintf( mesg, "Every %d Seconds", repeatTime ); WinSetDlgItemText( hWnd, REMINDERTIME, mesg ); return 0; } //-------------------------------------------------------------- // go back 1 month //-------------------------------------------------------------- case 551: { month--; if (month < 0) { month = 11; year--; } startDay = startDay - numberOfDaysInMonth(month, year) % 7; if (startDay > 6) startDay = startDay - 7; if (startDay < 0) startDay = startDay + 7; updateCalendar( hWnd ); return 0; } //-------------------------------------------------------------- // advance 1 month //-------------------------------------------------------------- case 553: { SHORT oldMonth = month; SHORT oldYear = year; month++; if (month > 11) { month = 0; year++; } startDay = (startDay + numberOfDaysInMonth(oldMonth, oldYear)) % 7; if (startDay > 6) startDay = startDay - 7; if (startDay < 0) startDay = startDay + 7; updateCalendar( hWnd ); return 0; } //-------------------------------------------------------------- // go back to current month //-------------------------------------------------------------- case 552: { time_t currentTime; struct tm *time_now; time(¤tTime); time_now = localtime( ¤tTime ); month = time_now->tm_mon; year = time_now->tm_year; startDay = time_now->tm_wday - (time_now->tm_mday % 7 - 1); if (startDay > 6) startDay = startDay - 7; if (startDay < 0) startDay = startDay + 7; updateCalendar( hWnd ); return 0; } //-------------------------------------------------------------- // user pressed OK, cancel dialog //-------------------------------------------------------------- case DID_OK: { WinDismissDlg( hWnd, TRUE ); return 0; } } return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- // if nothing further we want to intercept, pass message onto system //---------------------------------------------------------------------- default: return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY showAllItemsProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch( msg ) { //---------------------------------------------------------------------- // when the dialog is being initialized, center it on desktop //---------------------------------------------------------------------- case WM_INITDLG: { CHAR temp[64+MAXACTIONSTRINGLENGTH]; CHAR s[MAXACTIONSTRINGLENGTH+11]; SWP swp; WinQueryWindowPos( hWnd, (PSWP)&swp); WinSetWindowPos( hWnd, (HWND)0, ((SHORT)((ScreenSizeX-swp.cx)/2)), ((SHORT)((ScreenSizeY-swp.cy)/2)), 0, 0, SWP_MOVE); sprintf(temp, "%d tasks currently scheduled (out of %d possible)", numAlarms, MAXALARMS ); WinSetWindowText( hWnd, temp ); WinSendDlgItemMsg( hWnd, SHOWITEMS, LM_DELETEALL, MPFROMSHORT( LIT_END ), temp ); for( short i = 0; i< numAlarms; i++) { CHAR c = 'a'; BYTE hour = alarm[i].AlarmHour; if (alarm[i].options & SCHEDULE_LAUNCHAPP) { short j = 10; short k = 0; strcpy(s, "Launch >> "); while ((ItemName[((int)alarm[i].ActionToDo[0])][((int)alarm[i].ActionToDo[1])][k])!='\0') if ((ItemName[((int)alarm[i].ActionToDo[0])][((int)alarm[i].ActionToDo[1])][k])=='~') k++; else s[j++] = ItemName[((int)alarm[i].ActionToDo[0])][((int)alarm[i].ActionToDo[1])][k++]; s[j] = '\0'; } else strcpy(s, alarm[i].ActionToDo); if (alarm[i].AlarmHour>11) c='p'; if (!(hour = hour % 12)) hour = 12; sprintf( temp, "%2d:%2d%cm (%2d:%2d) -- %d/%d/%d (%d/%d/%d) -- %s", hour, alarm[i].AlarmMinute, c, alarm[i].AlarmHour, alarm[i].AlarmMinute, alarm[i].AlarmMonth+1, alarm[i].AlarmDay+1, alarm[i].AlarmYear, alarm[i].AlarmDay+1, alarm[i].AlarmMonth+1, alarm[i].AlarmYear, s ); if (temp[3]==' ') { temp[3] = '0'; temp[12]= '0'; } WinSendDlgItemMsg( hWnd, SHOWITEMS, LM_INSERTITEM, MPFROMSHORT( LIT_END ), temp ); } return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- case WM_CONTROL: { if (SHORT2FROMMP(mp1)==LN_ENTER) { SHORT itemSelected = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, SHOWITEMS, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); oldProgType = numAlarms; numAlarms = 0; reviseScheduledItem( itemSelected ); sortTimeEntries( oldProgType ); numAlarms = oldProgType; WinSendMsg( hWnd, WM_INITDLG, 0, 0 ); WinSendDlgItemMsg( hWnd, SHOWITEMS, LM_SELECTITEM, MPFROM2SHORT( itemSelected, 0 ), MPFROM2SHORT( TRUE, 0 ) ); return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- // if we receive any system message, dismiss the dialog box //---------------------------------------------------------------------- case WM_COMMAND: { if (SHORT1FROMMP(mp1)==DID_OK) WinDismissDlg( hWnd, TRUE ); return 0; } //---------------------------------------------------------------------- // if nothing further we want to intercept, pass message onto system //---------------------------------------------------------------------- default: return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY scheduleProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch( msg ) { //---------------------------------------------------------------------- // when the dialog is being initialized, center it on desktop //---------------------------------------------------------------------- case WM_INITDLG: { CHAR temp[MAXACTIONSTRINGLENGTH+32]; SWP swp; SHORT i; // disable alarms while editing calendar oldProgType = numAlarms; numAlarms = 0; WinQueryWindowPos( hWnd, (PSWP)&swp); WinSetWindowPos( hWnd, (HWND)0, ((SHORT)((ScreenSizeX-swp.cx)/2)), ((SHORT)((ScreenSizeY-swp.cy)/2)), 0, 0, SWP_MOVE); sprintf( temp, "Schedule for %d/%d/%4d...", month+1, day+1, 1900+year); WinSetWindowText( hWnd, temp ); WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS, LM_DELETEALL, MPFROMSHORT( LIT_END ), temp ); for( i = 0; i< oldProgType; i++) if (alarm[i].AlarmDay == day) if (alarm[i].AlarmMonth == month) if (alarm[i].AlarmYear == year) { CHAR c = 'a'; CHAR s[11+MAXACTIONSTRINGLENGTH]; BYTE hour = alarm[i].AlarmHour; if (alarm[i].options & SCHEDULE_LAUNCHAPP) { short j = 10; short k = 0; strcpy(s, "Launch >> "); while ((ItemName[((int)alarm[i].ActionToDo[0])][((int)alarm[i].ActionToDo[1])][k])!='\0') if ((ItemName[((int)alarm[i].ActionToDo[0])][((int)alarm[i].ActionToDo[1])][k])=='~') k++; else s[j++] = ItemName[((int)alarm[i].ActionToDo[0])][((int)alarm[i].ActionToDo[1])][k++]; s[j] = '\0'; } else strcpy(s, alarm[i].ActionToDo); if (alarm[i].AlarmHour>11) c='p'; if (!(hour = hour % 12)) hour = 12; sprintf( temp, "%2d:%2d%cm (%2d:%2d) -- %s", hour, alarm[i].AlarmMinute, c, alarm[i].AlarmHour, alarm[i].AlarmMinute, s ); if (temp[3]==' ') { temp[3] = '0'; temp[12]= '0'; } WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS, LM_INSERTITEM, MPFROMSHORT( LIT_END ), temp ); } return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- case WM_CONTROL: { if ((SHORT1FROMMP(mp1)==SCHEDULEDITEMS) && (SHORT2FROMMP(mp1)==LN_ENTER)) return WinSendMsg( hWnd, WM_COMMAND, MPFROM2SHORT( REVISEITEM, 0 ), mp2 ); return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- case WM_COMMAND: { USHORT command = SHORT1FROMMP(mp1); //------------------------------------------------------------------ //------------------------------------------------------------------ if ( command==DELETEITEM ) { BOOL continueOn = TRUE; SHORT index = 0; SHORT item = 0; SHORT itemSelected = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); if (itemSelected==LIT_NONE) { WinMessageBox( HWND_DESKTOP, hwndFrame, "You must select an item!", "Delete an item", 0, MB_MOVEABLE|MB_ERROR|MB_OK); return 0; } if (WinMessageBox( HWND_DESKTOP, hwndFrame, "Are you sure you want to permanently delete this item?", "Delete an item", 0, MB_MOVEABLE|MB_ICONQUESTION|MB_YESNO) == MBID_NO) return 0; itemSelected++; while (continueOn) { if ((alarm[index].AlarmYear == (BYTE)(year%100)) && (alarm[index].AlarmMonth == (BYTE)(month%14)) && (alarm[index].AlarmDay == (BYTE)(day%40))) { item++; if (item == itemSelected) continueOn = FALSE; } index++; } { struct ALARMS tmp; for ( item=index-1; item<MAXALARMS-1; item++) { tmp = alarm[item]; alarm[item] = alarm[item+1]; alarm[item+1] = tmp; } } numAlarms = oldProgType-1; sortTimeEntries( numAlarms ); WinSendMsg( hWnd, WM_INITDLG, 0, 0 ); if (index-1 >= oldProgType) WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS, LM_SELECTITEM, MPFROM2SHORT( oldProgType-1, 0 ), MPFROM2SHORT( TRUE, 0 ) ); else WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS, LM_SELECTITEM, MPFROM2SHORT( index-1, 0 ), MPFROM2SHORT( TRUE, 0 ) ); return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ if ( command==ADDITEM ) { SHORT itemSelected = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); if (oldProgType == MAXALARMS) { WinMessageBox( HWND_DESKTOP, hwndFrame, "There is no room for an additional task entry!", "Task Scheduler", 0, MB_MOVEABLE|MB_ERROR|MB_OK); return 0; } alarm[oldProgType].AlarmYear = (BYTE)(year%100); alarm[oldProgType].AlarmMonth = (BYTE)(month%14); alarm[oldProgType].AlarmDay = (BYTE)(day%40); alarm[oldProgType].AlarmHour = 0; alarm[oldProgType].AlarmMinute = 0; alarm[oldProgType].options = SCHEDULE_USEWAVFILE | SCHEDULE_USEWAVFILE; alarm[oldProgType].ActionToDo[0] = 0; alarm[oldProgType].ReminderWAV[0] = 0; oldProgType++; reviseScheduledItem( oldProgType-1 ); sortTimeEntries( oldProgType ); numAlarms = oldProgType; WinSendMsg( hWnd, WM_INITDLG, 0, 0 ); WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS, LM_SELECTITEM, MPFROM2SHORT( itemSelected, 0 ), MPFROM2SHORT( TRUE, 0 ) ); return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ if (( command==REVISEITEM ) || (command==LN_ENTER)) { BOOL continueOn = TRUE; SHORT index = 0; SHORT item = 0; SHORT itemSelected = 1 + SHORT1FROMMP( WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); if ( (itemSelected-1) == LIT_NONE ) { WinMessageBox( HWND_DESKTOP, hwndFrame, "You must select an item!", "Revise an item", 0, MB_MOVEABLE|MB_ERROR|MB_OK); return 0; } while (continueOn) { if ((alarm[index].AlarmYear == (BYTE)(year%100)) && (alarm[index].AlarmMonth == (BYTE)(month%14)) && (alarm[index].AlarmDay == (BYTE)(day%40))) { item++; if (item == itemSelected) continueOn = FALSE; } index++; } reviseScheduledItem( index-1 ); sortTimeEntries( oldProgType ); numAlarms = oldProgType; WinSendMsg( hWnd, WM_INITDLG, 0, 0 ); WinSendDlgItemMsg( hWnd, SCHEDULEDITEMS, LM_SELECTITEM, MPFROM2SHORT( itemSelected-1, 0 ), MPFROM2SHORT( TRUE, 0 ) ); return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ if ( command==DID_OK ) { WinDismissDlg( hWnd, TRUE ); numAlarms = oldProgType; return 0; } } default: return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// VOID checkAlarms( SHORT hour, SHORT minute, SHORT month, SHORT day, SHORT year ) { struct tm *time_now; time_t currentTime; day--; if ((numAlarms == 0) || (alarm[0].AlarmYear > year )) return; if ((alarm[0].AlarmYear == year) && (alarm[0].AlarmMonth > month)) return; if ((alarm[0].AlarmMonth == month) && (alarm[0].AlarmDay > day)) return; if ((alarm[0].AlarmDay == day) && (alarm[0].AlarmHour > hour)) return; if ((alarm[0].AlarmHour == hour) && (alarm[0].AlarmMinute > minute)) return; if ((alarm[0].options & SCHEDULE_LAUNCHAPP) && (!(alarm[0].options & SCHEDULE_SOUNDONLY))) startApplication( (SHORT)alarm[0].ActionToDo[0], (SHORT)alarm[0].ActionToDo[1] ); else { currentReminderWavFile = 0; if (alarm[0].options & SCHEDULE_USEWAVFILE) currentReminderWavFile = alarm[0].ReminderWAV; if (alarm[0].options & SCHEDULE_SOUNDONLY) ringChime( currentReminderWavFile ); else { oldItemName[0] = TRUE; WinDlgBox(HWND_DESKTOP, hwndFrame, (PFNWP)reminderNoteProc, 0, REMINDER_DIALOG, (PVOID)alarm[0].ActionToDo); if (oldItemName[0]) { checkAlarms( hour, minute, month, day, year ); return; } } } // make it so that we reschedule from the current time // and not the time the task was supposed to go off tzset(); time(¤tTime); time_now = localtime( ¤tTime ); // reschedule or delete note if (alarm[0].options & SCHEDULE_EVERYHOUR) { alarm[0].AlarmHour = time_now->tm_hour; alarm[0].AlarmDay = time_now->tm_mday-1; alarm[0].AlarmMonth = time_now->tm_mon; alarm[0].AlarmYear = time_now->tm_year; alarm[0].AlarmHour++; validateTimeEntry(); sortTimeEntries( numAlarms ); } else if (alarm[0].options & SCHEDULE_EVERYDAY) { alarm[0].AlarmDay = time_now->tm_mday-1; alarm[0].AlarmMonth = time_now->tm_mon; alarm[0].AlarmYear = time_now->tm_year; alarm[0].AlarmDay++; validateTimeEntry(); sortTimeEntries( numAlarms ); } else if (alarm[0].options & SCHEDULE_EVERYWEEK) { alarm[0].AlarmDay = time_now->tm_mday-1; alarm[0].AlarmMonth = time_now->tm_mon; alarm[0].AlarmYear = time_now->tm_year; alarm[0].AlarmDay = alarm[0].AlarmDay + 7; validateTimeEntry(); sortTimeEntries( numAlarms ); } else if (alarm[0].options & SCHEDULE_EVERYMONTH) { alarm[0].AlarmMonth = time_now->tm_mon; alarm[0].AlarmYear = time_now->tm_year; alarm[0].AlarmMonth++; validateTimeEntry(); sortTimeEntries( numAlarms ); } else if (alarm[0].options & SCHEDULE_EVERYYEAR) { alarm[0].AlarmYear = time_now->tm_year; alarm[0].AlarmYear++; validateTimeEntry(); sortTimeEntries( numAlarms ); } else { ////// delete the reminder we just performed /////// for (short i=0; i<numAlarms-1; i++) { alarm[i].AlarmHour = alarm[i+1].AlarmHour; alarm[i].AlarmMinute = alarm[i+1].AlarmMinute; alarm[i].AlarmDay = alarm[i+1].AlarmDay; alarm[i].AlarmMonth = alarm[i+1].AlarmMonth; alarm[i].AlarmYear = alarm[i+1].AlarmYear; alarm[i].options = alarm[i+1].options; strcpy( alarm[i].ReminderWAV, alarm[i+1].ReminderWAV ); strcpy( alarm[i].ActionToDo, alarm[i+1].ActionToDo ); } numAlarms--; } // check to see if another alarm needs to be serviced checkAlarms( hour, minute, month, day, year ); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// VOID validateTimeEntry( VOID ) { if (alarm[0].AlarmMinute > 59) { alarm[0].AlarmMinute = alarm[0].AlarmMinute - 60; alarm[0].AlarmHour++; } if (alarm[0].AlarmHour > 23) { alarm[0].AlarmMinute = alarm[0].AlarmMinute - 24; alarm[0].AlarmDay++; } if (alarm[0].AlarmDay > daysInMonth[alarm[0].AlarmMonth] ) { alarm[0].AlarmDay = alarm[0].AlarmDay - daysInMonth[alarm[0].AlarmMonth]; alarm[0].AlarmMonth++; } if (alarm[0].AlarmMonth > 11) { alarm[0].AlarmMonth = alarm[0].AlarmMonth - 12; alarm[0].AlarmYear++; } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// VOID sortTimeEntries( INT entries ) { ALARMS tmp; short i,j; // bubble sort all scheduled events so that closest event tops the list for (i=0; i<entries; i++) for (j=0; j<entries-1; j++) { if ( alarm[j].AlarmMinute > alarm[j+1].AlarmMinute ) { tmp = alarm[j]; alarm[j] = alarm[j+1]; alarm[j+1] = tmp; } } for (i=0; i<entries; i++) for (j=0; j<entries-1; j++) { if ( alarm[j].AlarmHour > alarm[j+1].AlarmHour ) { tmp = alarm[j]; alarm[j] = alarm[j+1]; alarm[j+1] = tmp; } } for (i=0; i<entries; i++) for (j=0; j<entries-1; j++) { if ( alarm[j].AlarmDay > alarm[j+1].AlarmDay ) { tmp = alarm[j]; alarm[j] = alarm[j+1]; alarm[j+1] = tmp; } } for (i=0; i<entries; i++) for (j=0; j<entries-1; j++) { if ( alarm[j].AlarmMonth > alarm[j+1].AlarmMonth ) { tmp = alarm[j]; alarm[j] = alarm[j+1]; alarm[j+1] = tmp; } } for (i=0; i<entries; i++) for (j=0; j<entries-1; j++) { if ( alarm[j].AlarmYear > alarm[j+1].AlarmYear ) { tmp = alarm[j]; alarm[j] = alarm[j+1]; alarm[j+1] = tmp; } } } //////////////////////////////////////////////////////////////////////////////// // reviseScheduledItem - call dialog box to revise a currently scheduled event //////////////////////////////////////////////////////////////////////////////// VOID reviseScheduledItem( INT itemToEdit ) { EditItem = itemToEdit; WinDlgBox(HWND_DESKTOP, hwndFrame, (PFNWP)itemProc, 0, SCHEDULEITEMDIALOG, (PVOID)0); return; } //////////////////////////////////////////////////////////////////////////////// // displayReminderTime - update display of time in revision dialog box //////////////////////////////////////////////////////////////////////////////// VOID displayReminderTime( HWND hWnd, INT offset ) { SHORT hour; CHAR c; CHAR time[16]; c='a'; if (alarm[offset].AlarmHour>11) c='p'; if (!(hour = alarm[offset].AlarmHour % 12)) hour = 12; sprintf( time, "%2d:%2d%cm (%2d:%2d)", hour, alarm[offset].AlarmMinute, c, alarm[offset].AlarmHour, alarm[offset].AlarmMinute); if (time[3]==' ') { time[3] = '0'; time[12]= '0'; } WinSetDlgItemText( hWnd, TIME_TEXT, (CHAR*)time ); } //////////////////////////////////////////////////////////////////////////////// // displayReminderDate - update display of date in revision dialog box //////////////////////////////////////////////////////////////////////////////// VOID displayReminderDate( HWND hWnd, INT offset ) { CHAR date[24]; sprintf( date, " %d/%d/%d (%d/%d/%d) ", alarm[offset].AlarmMonth+1, alarm[offset].AlarmDay+1, alarm[offset].AlarmYear, alarm[offset].AlarmDay+1, alarm[offset].AlarmMonth+1, alarm[offset].AlarmYear); WinSetDlgItemText( hWnd, DATETEXT, (CHAR*)date ); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY itemProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch( msg ) { //---------------------------------------------------------------------- //---------------------------------------------------------------------- case WM_INITDLG: { CHAR s[MAXPATH+11]; SWP swp; WinQueryWindowPos( hWnd, (PSWP)&swp); WinSetWindowPos( hWnd, (HWND)0, ((SHORT)((ScreenSizeX-swp.cx)/2)), ((SHORT)((ScreenSizeY-swp.cy)/2)), 0, 0, SWP_MOVE); WinSendDlgItemMsg( hWnd, SOUNDFILE, EM_SETTEXTLIMIT, MPFROMSHORT( sizeof(alarm[EditItem].ReminderWAV) ), 0 ); WinSendDlgItemMsg( hWnd, REMINDER, EM_SETTEXTLIMIT, MPFROMSHORT( sizeof(alarm[EditItem].ActionToDo) ), 0 ); WinCheckButton( hWnd, DELETEITEM, TRUE ); if (alarm[EditItem].options & SCHEDULE_EVERYHOUR) WinCheckButton( hWnd, EVERYHOUR, TRUE ); else if (alarm[EditItem].options & SCHEDULE_EVERYDAY) WinCheckButton( hWnd, EVERYDAY, TRUE ); else if (alarm[EditItem].options & SCHEDULE_EVERYWEEK) WinCheckButton( hWnd, EVERYWEEK, TRUE ); else if (alarm[EditItem].options & SCHEDULE_EVERYMONTH) WinCheckButton( hWnd, EVERYMONTH, TRUE ); else if (alarm[EditItem].options & SCHEDULE_EVERYYEAR) WinCheckButton( hWnd, EVERYYEAR, TRUE ); if ( alarm[EditItem].options & SCHEDULE_USEWAVFILE ) WinCheckButton( hWnd, PLAYSOUND, TRUE ); if ( alarm[EditItem].options & SCHEDULE_SOUNDONLY ) WinCheckButton( hWnd, SOUNDONLY, TRUE ); WinSetDlgItemText( hWnd, SOUNDFILE, (CHAR*)alarm[EditItem].ReminderWAV ); displayReminderTime( hWnd, EditItem ); displayReminderDate( hWnd, EditItem ); if (alarm[EditItem].options & SCHEDULE_LAUNCHAPP) { short j = 10; short k = 0; strcpy(s, "Launch >> "); while ((ItemName[((int)alarm[EditItem].ActionToDo[0])][((int)alarm[EditItem].ActionToDo[1])][k])!='\0') if ((ItemName[((int)alarm[EditItem].ActionToDo[0])][((int)alarm[EditItem].ActionToDo[1])][k])=='~') k++; else s[j++] = ItemName[((int)alarm[EditItem].ActionToDo[0])][((int)alarm[EditItem].ActionToDo[1])][k++]; s[j] = '\0'; WinSetDlgItemText( hWnd, REMINDER, (CHAR*)s ); WinEnableControl( hWnd, REMINDER, FALSE ); } else { WinEnableControl( hWnd, REMINDER, TRUE ); WinSetDlgItemText( hWnd, REMINDER, (CHAR*)alarm[EditItem].ActionToDo ); } return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- case WM_COMMAND: { USHORT command = SHORT1FROMMP(mp1); switch(command) { //------------------------------------------------------------------ //------------------------------------------------------------------ case LAUNCHITEM: { short tmp = 0; if (WinQueryButtonCheckstate( hWnd, EVERYHOUR )) tmp += SCHEDULE_EVERYHOUR; else if (WinQueryButtonCheckstate( hWnd, EVERYDAY )) tmp += SCHEDULE_EVERYDAY; else if (WinQueryButtonCheckstate( hWnd, EVERYWEEK )) tmp += SCHEDULE_EVERYWEEK; else if (WinQueryButtonCheckstate( hWnd, EVERYMONTH )) tmp += SCHEDULE_EVERYMONTH; else if (WinQueryButtonCheckstate( hWnd, EVERYYEAR )) tmp += SCHEDULE_EVERYYEAR; if (WinQueryButtonCheckstate( hWnd, PLAYSOUND )) tmp += SCHEDULE_USEWAVFILE; if (WinQueryButtonCheckstate( hWnd, SOUNDONLY )) tmp += SCHEDULE_SOUNDONLY; WinDlgBox(HWND_DESKTOP, hWnd, (PFNWP)LaunchItemProc, 0, LAUNCHITEMDIALOG, (PVOID)0); if (alarm[EditItem].options & SCHEDULE_LAUNCHAPP) tmp = tmp + SCHEDULE_LAUNCHAPP; alarm[EditItem].options = tmp; WinSendMsg( hWnd, WM_INITDLG, 0, 0 ); return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ case SELECTSOUNDFILE: { CHAR title[] = "Task Scheduler - Find a Sound File"; ULONG s; HWND hwndDialog; CHAR oldDir[MAXPATH]; fileDlgInfo.fl = FDS_OPEN_DIALOG|FDS_CENTER; fileDlgInfo.pszTitle = title; strcpy( oldDir, fileDlgInfo.szFullFile ); strcat(fileDlgInfo.szFullFile, "*.WAV\0"); hwndDialog = WinFileDlg( HWND_DESKTOP, hWnd, &fileDlgInfo ); if (hwndDialog && (fileDlgInfo.lReturn == DID_OK)) { strcpy( alarm[EditItem].ReminderWAV, fileDlgInfo.szFullFile ); strcat( alarm[EditItem].ReminderWAV, "\0" ); s=0; while(fileDlgInfo.szFullFile[s]!='\0') s++; while((fileDlgInfo.szFullFile[s]!='\\') && (s>=0)) s--; if (fileDlgInfo.szFullFile[s]=='\\') fileDlgInfo.szFullFile[s+1]='\0'; else fileDlgInfo.szFullFile[0]='\0'; WinSetDlgItemText( hWnd, SOUNDFILE, alarm[EditItem].ReminderWAV ); } else strcpy( fileDlgInfo.szFullFile, oldDir ); return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ case DAY_MORE: { alarm[EditItem].AlarmDay = (alarm[EditItem].AlarmDay + 1) % daysInMonth[alarm[EditItem].AlarmMonth]; displayReminderDate( hWnd, EditItem ); return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ case DAY_LESS: { if (alarm[EditItem].AlarmDay==0) alarm[EditItem].AlarmDay = daysInMonth[alarm[EditItem].AlarmMonth] - 1; else alarm[EditItem].AlarmDay = (alarm[EditItem].AlarmDay - 1) % daysInMonth[alarm[EditItem].AlarmMonth]; displayReminderDate( hWnd, EditItem ); return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ case MONTH_MORE: { alarm[EditItem].AlarmMonth = (alarm[EditItem].AlarmMonth + 1) % 12; displayReminderDate( hWnd, EditItem ); return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ case MONTH_LESS: { if (alarm[EditItem].AlarmMonth == 0) alarm[EditItem].AlarmMonth = 11; else alarm[EditItem].AlarmMonth--; displayReminderDate( hWnd, EditItem ); return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ case YEAR_MORE: { alarm[EditItem].AlarmYear++; displayReminderDate( hWnd, EditItem ); return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ case YEAR_LESS: { alarm[EditItem].AlarmYear--; displayReminderDate( hWnd, EditItem ); return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ case MINUTE_MORE: { alarm[EditItem].AlarmMinute = (alarm[EditItem].AlarmMinute+1) % 60; displayReminderTime( hWnd, EditItem ); return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ case MINUTE_LESS: { if (alarm[EditItem].AlarmMinute == 0) alarm[EditItem].AlarmMinute = 59; else alarm[EditItem].AlarmMinute = (alarm[EditItem].AlarmMinute-1) % 60; displayReminderTime( hWnd, EditItem ); return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ case HOUR_MORE: { alarm[EditItem].AlarmHour = (alarm[EditItem].AlarmHour+1) % 24; displayReminderTime( hWnd, EditItem ); return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ case HOUR_LESS: { if (alarm[EditItem].AlarmHour == 0) alarm[EditItem].AlarmHour = 23; else alarm[EditItem].AlarmHour = (alarm[EditItem].AlarmHour-1) % 24; displayReminderTime( hWnd, EditItem ); return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ case DID_OK: { if (alarm[EditItem].options & SCHEDULE_LAUNCHAPP) alarm[EditItem].options = SCHEDULE_LAUNCHAPP; else { alarm[EditItem].options = 0; WinQueryDlgItemText( hWnd, REMINDER, sizeof(alarm[EditItem].ActionToDo), (PSZ)alarm[EditItem].ActionToDo ); } if (WinQueryButtonCheckstate( hWnd, EVERYHOUR )) alarm[EditItem].options += SCHEDULE_EVERYHOUR; else if (WinQueryButtonCheckstate( hWnd, EVERYDAY )) alarm[EditItem].options += SCHEDULE_EVERYDAY; else if (WinQueryButtonCheckstate( hWnd, EVERYWEEK )) alarm[EditItem].options += SCHEDULE_EVERYWEEK; else if (WinQueryButtonCheckstate( hWnd, EVERYMONTH )) alarm[EditItem].options += SCHEDULE_EVERYMONTH; else if (WinQueryButtonCheckstate( hWnd, EVERYYEAR )) alarm[EditItem].options += SCHEDULE_EVERYYEAR; if (WinQueryButtonCheckstate( hWnd, PLAYSOUND )) alarm[EditItem].options += SCHEDULE_USEWAVFILE; if (WinQueryButtonCheckstate( hWnd, SOUNDONLY )) alarm[EditItem].options += SCHEDULE_SOUNDONLY; WinQueryDlgItemText( hWnd, SOUNDFILE, sizeof(alarm[EditItem].ReminderWAV), (PSZ)alarm[EditItem].ReminderWAV ); WinDismissDlg( hWnd, TRUE ); return 0; } default: return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } //---------------------------------------------------------------------- // if nothing further we want to intercept, pass message onto system //---------------------------------------------------------------------- default: return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY reminderNoteProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch( msg ) { //---------------------------------------------------------------------- //---------------------------------------------------------------------- case WM_TIMER: { ringChime( currentReminderWavFile ); return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- // when the dialog is being initialized, center it on desktop //---------------------------------------------------------------------- case WM_INITDLG: { SWP swp; WinQueryWindowPos( hWnd, (PSWP)&swp); WinSetWindowPos( hWnd, (HWND)0, ((SHORT)((ScreenSizeX-swp.cx)/2)), ((SHORT)((ScreenSizeY-swp.cy)/2)), 0, 0, SWP_MOVE); noteTimerNumber = WinStartTimer( hab, hWnd, TIMERID+1, (LONG)repeatTime*1000 ); numberOfAlarms = numAlarms; numAlarms = 0; if (mp2 != 0) WinSetDlgItemText( hWnd, REMINDER, (CHAR*)LONGFROMMP( mp2 ) ); WinPostMsg( hWnd, WM_TIMER, mp1, mp2 ); return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- // if we receive any system message, dismiss the dialog box //---------------------------------------------------------------------- case WM_COMMAND: { USHORT command = SHORT1FROMMP(mp1); switch(command) { //------------------------------------------------------------------ //------------------------------------------------------------------ case DID_OK: { WinStopTimer( hab, TIMERID+1, noteTimerNumber ); WinDismissDlg( hWnd, TRUE ); numAlarms = numberOfAlarms; oldItemName[0] = FALSE; return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ case SNOOZE: { struct tm *time_now; time_t currentTime; WinStopTimer( hab, TIMERID+1, noteTimerNumber ); tzset(); time(¤tTime); time_now = localtime( ¤tTime ); alarm[0].AlarmHour = time_now->tm_hour; alarm[0].AlarmMinute = time_now->tm_min + 9; validateTimeEntry(); sortTimeEntries( numberOfAlarms ); WinDismissDlg( hWnd, TRUE ); numAlarms = numberOfAlarms; return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ case REVISE: { WinStopTimer( hab, TIMERID+1, noteTimerNumber ); reviseScheduledItem( 0 ); validateTimeEntry(); sortTimeEntries( numberOfAlarms ); WinDismissDlg( hWnd, TRUE ); numAlarms = numberOfAlarms; return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ case ERASE: { WinStopTimer( hab, TIMERID+1, noteTimerNumber ); if (WinMessageBox( HWND_DESKTOP, hwndFrame, "Are you sure you want to completely erase this reminder?", "Erase this reminder", 0, MB_MOVEABLE|MB_ICONQUESTION|MB_YESNO)==MBID_YES) { for (short i=1; i<MAXALARMS; i++) alarm[ i-1 ] = alarm[ i ]; WinDismissDlg( hWnd, TRUE ); numAlarms = numberOfAlarms-1; } noteTimerNumber = WinStartTimer( hab, hWnd, TIMERID+1, (LONG)repeatTime*1000 ); return 0; } //------------------------------------------------------------------ //------------------------------------------------------------------ default: return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } //---------------------------------------------------------------------- // if nothing further we want to intercept, pass message onto system //---------------------------------------------------------------------- default: return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// MRESULT EXPENTRY LaunchItemProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { switch( msg ) { //---------------------------------------------------------------------- // when the dialog is being initialized, center it on desktop //---------------------------------------------------------------------- case WM_INITDLG: { SHORT i,j; CHAR temp[MAXACTIONSTRINGLENGTH+5]; SWP swp; WinQueryWindowPos( hWnd, (PSWP)&swp); WinSetWindowPos( hWnd, (HWND)0, ((SHORT)((ScreenSizeX-swp.cx)/2)), ((SHORT)((ScreenSizeY-swp.cy)/2)), 0, 0, SWP_MOVE); oldAction[LAUNCHED] = alarm[EditItem].options & SCHEDULE_LAUNCHAPP; WinSendDlgItemMsg( hWnd, CURITEMLIST, LM_DELETEALL, 0, 0); temp[0] = ' '; temp[1] = ' '; temp[2] = '-'; temp[3] = ' '; for (i=0; i<NumMenus; i++) { WinSendDlgItemMsg( hWnd, CURITEMLIST, LM_INSERTITEM, MPFROMSHORT( LIT_END ), MenuName[i] ); for (j=0; j<NumItems[i]; j++) if (ItemName[i][j][0] != '\0') { temp[4] = '\0'; strcat(temp, ItemName[i][j]); WinSendDlgItemMsg( hWnd, CURITEMLIST, LM_INSERTITEM, MPFROMSHORT( LIT_END ), temp ); } } // if they had requested to launch an application previously // restore their choice in the dialog box WinCheckButton( hWnd, LAUNCHITEM, FALSE ); if (oldAction[LAUNCHED]) { SHORT item, index; WinCheckButton( hWnd, LAUNCHITEM, TRUE ); item = 0; index = alarm[EditItem].ActionToDo[0]; if (index > 0) { for (i=0; i<index; i++) { item++; for (j=0; j<NumItems[i]; j++) if (ItemName[i][j][0] != '\0') item++; } } item += alarm[EditItem].ActionToDo[1]+1; for (j=0; j<alarm[EditItem].ActionToDo[1]; j++) if (ItemName[index][j][0] == '\0') item--; WinSendDlgItemMsg( hWnd, CURITEMLIST, LM_SELECTITEM, MPFROM2SHORT( item, 0 ), MPFROM2SHORT( TRUE, 0 ) ); } return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- case WM_CONTROL: { if (SHORT1FROMMP(mp1)==CURITEMLIST) { if (SHORT2FROMMP(mp1)==LN_ENTER) { WinCheckButton( hWnd, LAUNCHITEM, TRUE ); WinSendMsg( hWnd, WM_COMMAND, MPFROMSHORT(DID_OK), 0 ); } if (SHORT2FROMMP(mp1)==LN_SELECT) WinCheckButton( hWnd, LAUNCHITEM, TRUE ); } return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- //---------------------------------------------------------------------- case WM_COMMAND: { if (SHORT1FROMMP(mp1)==DID_OK) { SHORT itemSelected = SHORT1FROMMP( WinSendDlgItemMsg( hWnd, CURITEMLIST, LM_QUERYSELECTION, MPFROM2SHORT( LIT_FIRST, 0 ), 0 ) ); if (WinQueryButtonCheckstate( hWnd, LAUNCHITEM )) { short i,j; char temp[MAXPATH]; WinSendDlgItemMsg( hWnd, CURITEMLIST, LM_QUERYITEMTEXT, MPFROM2SHORT( itemSelected, sizeof(temp) ), (PSZ)temp ); if (strncmp(temp, " - ", 4) != 0) { WinMessageBox( HWND_DESKTOP, hwndFrame, "You must select an item (NOT a menu) from the list!", "Task Scheduler: Launch an Application", 0, MB_MOVEABLE|MB_ERROR|MB_OK); return 0; } if ( !oldAction[LAUNCHED] ) alarm[EditItem].options += SCHEDULE_LAUNCHAPP; for (i=0; i<NumMenus; i++) for (j=0; j<NumItems[i]; j++) if (strcmp( temp+4, ItemName[i][j] ) == 0) { alarm[EditItem].ActionToDo[0] = i; alarm[EditItem].ActionToDo[1] = j; } } else { if ( oldAction[LAUNCHED] ) { alarm[EditItem].options -= SCHEDULE_LAUNCHAPP; alarm[EditItem].ActionToDo[0] = 0; } } WinDismissDlg( hWnd, TRUE ); return 0; } return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } //---------------------------------------------------------------------- // if nothing further we want to intercept, pass message onto system //---------------------------------------------------------------------- default: return WinDefDlgProc( hWnd, msg, mp1, mp2 ); } }