/* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Program : SLPM.C � ** � � ** � Description : OS/2 PM Shopping List Utility � ** � � ** � (C) Copyright 1989, 1990 by Steve Blunden. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 */ /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Description : Includes and global variables used by � ** � multiple procedures. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ #define INCL_WIN #define INCL_GPI #include #include #include #include #include #include #include "slpm.h" MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ; MRESULT EXPENTRY AboutDlgProc (HWND, USHORT, MPARAM, MPARAM) ; void cdecl SetMenuAttr (HWND, USHORT, USHORT, BOOL ) ; MRESULT EXPENTRY RunAddCopyDlg (HWND, PCHAR, PCHAR ) ; MRESULT EXPENTRY AddCopyDlgProc(HWND, USHORT, MPARAM, MPARAM) ; int cdecl SLPMNameSort (PSLPMSLIST, PSLPMSLIST ) ; int cdecl SLPMStoreSort (PSLPMSLIST, PSLPMSLIST ) ; HAB hab; /* Anchor block */ BOOL fFileHasChanged = FALSE ; /* TRUE when file has changed */ PSLPMSLIST pSlist ; /* Pointer to shopping list */ PSLPMSTORES pStoreList ; /* Pointer to store list */ HPOINTER hptr; /* Handle for current pointer icon */ CHAR *pchAddCopyLocation, *pchAddCopyDesc ; /* Used in Add/Copy dlg */ /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Function : main � ** � � ** � Description : Main routine for SLPM. Dispatches messages � ** � and displays a message box when SLPM is � ** � about to terminate. Cancels termination � ** � if the user decides to do so. � ** � � ** � Called by : Start Programs in OS/2. � ** � � ** � Calls : Win... functions. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ int main (void) { static CHAR szClientClass [] = "SLPM" ; static ULONG flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_SIZEBORDER | FCF_MINMAX | FCF_SHELLPOSITION | FCF_TASKLIST| FCF_MINMAX | FCF_ICON | FCF_MENU | FCF_ACCELTABLE | FCF_VERTSCROLL ; HMQ hmq; HWND hwndFrame, hwndClient; QMSG qmsg; RECTL rcl ; hab = WinInitialize (0); hmq = WinCreateMsgQueue (hab, 0); WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW , 0) ; hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE, &flFrameFlags, szClientClass, NULL, 0L, NULL, ID_WINDOW, &hwndClient) ; rcl.xLeft = WinQuerySysValue (HWND_DESKTOP, SV_CXSCREEN) / 4 ; rcl.xRight = rcl.xLeft * 3 ; rcl.yBottom = WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN) / 16 ; rcl.yTop = rcl.yBottom * 14 ; WinCalcFrameRect (hwndFrame, &rcl, FALSE) ; WinSetWindowPos (hwndFrame, NULL, /* position window in middle of */ (SHORT) rcl.xLeft, (SHORT) rcl.yBottom, /* screen */ (SHORT) (rcl.xRight - rcl.xLeft), (SHORT) (rcl.yTop - rcl.yBottom), SWP_SIZE | SWP_MOVE | SWP_ACTIVATE) ; while (TRUE) { while (WinGetMsg(hab, &qmsg, NULL, 0, 0)) WinDispatchMsg (hab, &qmsg); if (MBID_YES == WinMessageBox (HWND_DESKTOP, hwndClient, "Do you really want to exit SLPM?", szClientClass, 0, MB_YESNO | MB_ICONQUESTION)) break; WinCancelShutdown (hmq, FALSE); } WinDestroyWindow (hwndFrame); WinDestroyMsgQueue (hmq); WinTerminate (hab); return 0; } /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Function : ClientWndProc � ** � � ** � Description : Client window procedure. Maintains screen � ** � and files, and allows user to print a � ** � shopping list. � ** � � ** � Called by : WinDispatchMsg � ** � � ** � Calls : Win... functions, also calls itself. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2) { static HWND hwndVscroll ; static SHORT sVscrollMax, sVscrollPos, sCurrentLine, sCurrentItem, cxChar, cxCaps, cyChar, cyDesc, cxClient, cyClient, sMouseYPosition, sListMax ; static SHORT sPrevItemIndex = 0, sCompOffset ; static ULONG ulPrevCharTime = 0 ; /* used to time keystroke arrival */ static BOOL fHaveFocus ; CHAR szWork [80], cWork, szPreviousAisle[3], szHelp[255], cPreviousStore ; FONTMETRICS fm; HPS hps; POINTL ptl, aptl[4] ; SHORT sLine, sPaintBeg, sPaintEnd, sVscrollInc, sLineCount ; RECTL rclInvalid; SIZEL sizel; FILE *fileList, *filePrint ; static HBITMAP hbmSLPMCHK, hbmSLPMCPN ; /* bitmap information for */ static HPS hpsSLPMCHK, hpsSLPMCPN ; /* the checkmark and coupon */ static HDC hdcSLPMCHK, hdcSLPMCPN ; /* bit maps */ static BITMAPINFOHEADER bmpSLPMCHK, bmpSLPMCPN ; SHORT sI, sJ ; static CHAR szStoreFile[64] = "STORE.TXT" ; /* name of store file */ static CHAR szListFile[64] = "SLPM.TXT" ; /* name of list file */ switch (msg) { /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : WM_CREATE � ** � � ** � Description : Handles creation of standard window. Gets � ** � infomation on the system fontand the scroll � ** � bar. Loads the bitmaps for the checkmark � ** � and the coupon image. � ** � � ** � Called by : WinDispatchMessage. � ** � � ** � Calls : Sends WM_COMMAND(ID_OPEN) when done. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case WM_CREATE: hps = WinGetPS (hwnd) ; GpiQueryFontMetrics (hps, (LONG) sizeof fm, &fm) ; cxChar = (SHORT) fm.lAveCharWidth ; cxCaps = (SHORT) fm.lEmInc ; cyChar = (SHORT) fm.lMaxBaselineExt ; cyDesc = (SHORT) fm.lMaxDescender ; sCurrentLine = 0; sCurrentItem = 0; hptr = WinQuerySysPointer (HWND_DESKTOP, SPTR_ARROW, FALSE) ; hwndVscroll = WinWindowFromID ( WinQueryWindow (hwnd, QW_PARENT, FALSE), FID_VERTSCROLL) ; hdcSLPMCHK = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ; sizel.cx = 0 ; sizel.cy = 0 ; hpsSLPMCHK = GpiCreatePS (hab, hdcSLPMCHK, &sizel, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC) ; hbmSLPMCHK = GpiLoadBitmap (hps, NULL, IDB_SLPMCHK, 0L, 0L) ; GpiQueryBitmapParameters (hbmSLPMCHK, &bmpSLPMCHK) ; GpiSetBitmap (hpsSLPMCHK, hbmSLPMCHK) ; hdcSLPMCPN = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ; sizel.cx = 0 ; sizel.cy = 0 ; hpsSLPMCPN = GpiCreatePS (hab, hdcSLPMCPN, &sizel, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC) ; hbmSLPMCPN = GpiLoadBitmap (hps, NULL, IDB_SLPMCPN, 0L, 0L) ; GpiQueryBitmapParameters (hbmSLPMCPN, &bmpSLPMCPN) ; GpiSetBitmap (hpsSLPMCPN, hbmSLPMCPN) ; WinReleasePS (hps); WinPostMsg (hwnd, WM_COMMAND, MPFROMSHORT (ID_OPEN), MPFROMSHORT (0) ) ; return 0; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : WM_SIZE � ** � � ** � Description : Called for window resize or initial size. � ** � Sets up Vertical Scroll Bar parameters and � ** � if we have the input focus sizes and shows � ** � the "cursor". � ** � � ** � Calls : WinSendMsg, Win...Cursor. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case WM_SIZE : cxClient = SHORT1FROMMP (mp2); cyClient = SHORT2FROMMP (mp2); sVscrollMax = max (0, sListMax - cyClient / cyChar) ; sVscrollPos = min (sVscrollPos, sVscrollMax) ; WinSendMsg (hwndVscroll, SBM_SETSCROLLBAR, MPFROM2SHORT (sVscrollPos, 0), MPFROM2SHORT (0, sVscrollMax)); WinSendMsg (hwndVscroll, SBM_SETTHUMBSIZE, MPFROM2SHORT (cyClient / cyChar, sListMax), MPFROMSHORT (0)) ; WinEnableWindow (hwndVscroll, sVscrollMax ? TRUE : FALSE) ; if (fHaveFocus) { WinDestroyCursor (hwnd) ; CREATE_CURSOR_MACRO; WinShowCursor (hwnd, TRUE) ; } return 0; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : WM_SETFOCUS � ** � � ** � Description : Handles changes in the input focus. Sets � ** � (BOOL)fHaveFocus and either creates or � ** � destroys the "cursor", which is the black � ** � bar marking the current selection. � ** � � ** � Calls : Win...Cursor. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case WM_SETFOCUS : if (fHaveFocus = SHORT1FROMMP(mp2)) { CREATE_CURSOR_MACRO; WinShowCursor (hwnd, TRUE); } else { WinDestroyCursor (hwnd) ; } return 0; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : WM_MOUSEMOVE � ** � � ** � Description : Tracks mouse movement. Only the y-axis � ** � movement is tracked. X-position is not � ** � used in SLPM. Sets sMouseYPosition and � ** � displays the current pointer. � ** � � ** � Calls : WinSetPointer. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case WM_MOUSEMOVE : sMouseYPosition = MOUSEMSG (&msg) -> y ; WinSetPointer (HWND_DESKTOP, hptr) ; break ; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : WM_BUTTON... � ** � � ** � Description : Handles mouse buttons. If this is just a � ** � focus change, return default WndProc, which � ** � effects a focus change. If we have the � ** � focus both the previous cursor line and the � ** � new cursor line are invalidated in order � ** � to force a redraw. � ** � Next a WM_COMMAND message with either � ** � ID_SELECT_COUPON or ID_TOGGLE_SELECT is � ** � send to ourselves. � ** � � ** � Calls : Win... functions. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case WM_BUTTON1DOWN : case WM_BUTTON1DBLCLK : case WM_BUTTON2DOWN : case WM_BUTTON2DBLCLK : if (!fHaveFocus) break ; rclInvalid.xLeft = 0 ; rclInvalid.xRight = cxClient ; rclInvalid.yBottom = cyClient - (sCurrentLine + 1) * cyChar ; rclInvalid.yTop = cyClient - sCurrentLine * cyChar ; sCurrentItem = min (sVscrollPos + ((cyClient - sMouseYPosition) / cyChar) , sListMax - 1) ; sCurrentLine = sCurrentItem - sVscrollPos ; WinInvalidateRect (hwnd, &rclInvalid, FALSE) ; rclInvalid.yBottom = cyClient - (sCurrentLine + 1) * cyChar ; rclInvalid.yTop = cyClient - sCurrentLine * cyChar ; WinInvalidateRect (hwnd, &rclInvalid, FALSE) ; WinUpdateWindow (hwnd) ; WinSendMsg (hwnd, WM_COMMAND, MPFROMSHORT ((msg == WM_BUTTON2DOWN) || (msg == WM_BUTTON2DBLCLK) ? ID_SELECT_COUPON : ID_TOGGLE_SELECT), MPFROM2SHORT (CMDSRC_OTHER, TRUE) ) ; break; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : WM_VSCROLL � ** � � ** � Description : Handles keyboard or slider bar scrolling. � ** � � ** � Called by : Slider Bar or WM_CHAR case for arrow keys. � ** � � ** � Calls : Win... functions. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case WM_VSCROLL : switch (SHORT2FROMMP (mp2)) { case SB_LINEUP : sVscrollInc = -1 ; break; case SB_LINEDOWN : sVscrollInc = 1; break; case SB_PAGEUP : sVscrollInc = min (-1, -cyClient / cyChar) ; break; case SB_PAGEDOWN : sVscrollInc = max (1, cyClient / cyChar) ; break; case SB_SLIDERTRACK : sVscrollInc = SHORT1FROMMP (mp2) - sVscrollPos ; break; case SB_SLIDERPOSITION : sVscrollInc = SHORT1FROMMP (mp2) - sVscrollPos ; break; default: sVscrollInc = 0; break ; } sVscrollInc = max (-sVscrollPos, min (sVscrollInc, sVscrollMax - sVscrollPos)) ; if (sVscrollInc != 0 || (SHORT2FROMMP (mp2) == SB_SLIDERPOSITION)) { WinDestroyCursor (hwnd) ; sVscrollPos += sVscrollInc ; WinScrollWindow (hwnd, 0, cyChar * sVscrollInc, NULL, NULL, NULL, NULL, SW_INVALIDATERGN) ; if (SHORT2FROMMP (mp2) != SB_SLIDERTRACK) WinSendMsg (hwndVscroll, SBM_SETPOS, MPFROMSHORT (sVscrollPos), NULL) ; CREATE_CURSOR_MACRO; WinShowCursor (hwnd, TRUE) ; WinUpdateWindow (hwnd) ; } return 0 ; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : WM_USER_REBUILD � ** � � ** � Description : Called by any routine which changes the � ** � vertical scroll value sVscrollMax or � ** � sListMax. Sets new vertical scroll range � ** � and invalidates the whole client area. � ** � � ** � Called by : WinSendMsg, as mentioned above. � ** � � ** � Calls : Win... functions. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case WM_USER_REBUILD : sVscrollMax = max (0, sListMax - cyClient / cyChar) ; sVscrollPos = min (sVscrollPos, sVscrollMax) ; WinSendMsg (hwndVscroll, SBM_SETSCROLLBAR, MPFROM2SHORT (sVscrollPos, 0), MPFROM2SHORT (0, sVscrollMax)); WinSendMsg (hwndVscroll, SBM_SETTHUMBSIZE, MPFROM2SHORT (cyClient / cyChar, sListMax), MPFROMSHORT (0)) ; WinEnableWindow (hwndVscroll, sVscrollMax ? TRUE : FALSE) ; WinSendMsg (hwndVscroll, SBM_SETPOS, MPFROMSHORT (sVscrollPos), NULL) ; WinInvalidateRect (hwnd, NULL, FALSE) ; WinUpdateWindow (hwnd) ; return 0 ; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : WM_CHAR � ** � � ** � Description : Handles character messages. For VK_... � ** � scroll keys sends the message to the scroll � ** � bar. For VK_END or VK_HOME sets up new � ** � scroll positions and sends a WM_USER_REBUILD � ** � to ourselves. � ** � For numeric keys, sets the select count for � ** � the current item to the numeric value. � ** � For alpha keys, searches for the first list � ** � entry starting with that letter. If another � ** � keystroke arrives during the time interval � ** � defined by CHAR_DELAY in slpm.h the search � ** � offset is shifted one character to the � ** � right, allowing the user to move directly � ** � to a list entry by typing the entry. � ** � When the current entry is changed, a � ** � WM_USER_REBUILD is sent to ourselves. � ** � � ** � Calls : Win... functions, WM_USER_REBUILD � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case WM_CHAR : if (SHORT1FROMMP(mp1) & (KC_KEYUP)) return (MRESULT) (FALSE) ; sCurrentItem = sVscrollPos + sCurrentLine ; if (CHARMSG (&msg) -> fs & KC_VIRTUALKEY) switch (CHARMSG (&msg)-> vkey) { case VK_UP: if (--sCurrentLine < 0) { sCurrentLine = 0; return WinSendMsg (hwndVscroll, msg, mp1, mp2); } MOVE_CURSOR_MACRO; return (MRESULT) (TRUE) ; case VK_DOWN: if (++sCurrentLine >= (cyClient / cyChar)) { sCurrentLine -= 1 ; return WinSendMsg (hwndVscroll, msg, mp1, mp2); } MOVE_CURSOR_MACRO; return (MRESULT) (TRUE) ; case VK_PAGEUP: case VK_PAGEDOWN: return WinSendMsg (hwndVscroll, msg, mp1, mp2 ) ; case VK_HOME : sCurrentItem = 0 ; if ((sListMax - sCurrentItem) < ((cyClient / cyChar) / 2)) sCurrentLine = (cyClient / cyChar) - (sListMax - sCurrentItem) - 1 ; else sCurrentLine = min (sCurrentItem, (cyClient / cyChar) /2 ) ; sVscrollPos = max (sCurrentItem - sCurrentLine, 0) ; WinSendMsg (hwnd, WM_USER_REBUILD, 0, 0) ; WinUpdateWindow (hwnd) ; return (MRESULT) (TRUE) ; case VK_END : sCurrentItem = sListMax ; if ((sListMax - sCurrentItem) < ((cyClient / cyChar) / 2)) sCurrentLine = (cyClient / cyChar) - (sListMax - sCurrentItem) - 1 ; else sCurrentLine = min (sCurrentItem, (cyClient / cyChar) /2 ) ; sVscrollPos = max (sCurrentItem - sCurrentLine, 0) ; WinSendMsg (hwnd, WM_USER_REBUILD, 0, 0) ; WinUpdateWindow (hwnd) ; return (MRESULT) (TRUE) ; } else if (CHARMSG (&msg) -> fs & KC_CHAR) switch (cWork = (CHAR) (CHARMSG (&msg) -> chr)) { case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : pSlist[sCurrentItem].cSelected = (UCHAR) (CHARMSG (&msg) -> chr & 0x0f) | (pSlist[sCurrentItem].cSelected & COUPON) ; rclInvalid.xLeft = 0 ; rclInvalid.xRight = cxClient ; rclInvalid.yBottom = cyClient - (sCurrentLine + 1) * cyChar ; rclInvalid.yTop = cyClient - sCurrentLine * cyChar ; WinInvalidateRect (hwnd, &rclInvalid, FALSE) ; WinUpdateWindow (hwnd) ; return (MRESULT) (TRUE) ; default : if (isalpha(cWork)) { if ((WinGetCurrentTime(hab) - ulPrevCharTime) < CHAR_DELAY) sCompOffset += 1 ; else sPrevItemIndex = sCompOffset = 0 ; ulPrevCharTime = WinGetCurrentTime (hab) ; while ((toupper ( pSlist[sPrevItemIndex].szDescription[sCompOffset]) < toupper (cWork)) && (sPrevItemIndex < sListMax)) sPrevItemIndex++ ; sCurrentItem = min (sPrevItemIndex, sListMax - 1) ; if ((sListMax - sCurrentItem) < ((cyClient / cyChar) / 2)) sCurrentLine = (cyClient / cyChar) - (sListMax - sCurrentItem) ; else sCurrentLine = min (sCurrentItem, (cyClient / cyChar) /2 ) ; sVscrollPos = max (sCurrentItem - sCurrentLine, 0) ; WinSendMsg (hwnd, WM_USER_REBUILD, 0, 0) ; WinUpdateWindow (hwnd) ; return (MRESULT) (TRUE) ; } break ; } break; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : WM_CLOSE � ** � � ** � Description : Handles frame window close. If the file � ** � has been changed and not saved, the user � ** � has the option to save it, in which case � ** � a WM_COMMAND(ID_SAVE) message is sent to � ** � ourselves. The shopping list and store list � ** � memory blocks are freed, and a WM_QUIT is � ** � posted to the client window. � ** � � ** � Calls : Win... functions, ID_SAVE case. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case WM_CLOSE: if (fFileHasChanged) if (MBID_YES == WinMessageBox (HWND_DESKTOP, hwnd, "File has changed! Do you wish to save it ?", "SLPM", 0, MB_YESNO | MB_HELP | MB_ICONQUESTION)) WinSendMsg (hwnd, WM_COMMAND, MPFROMSHORT (ID_SAVE), MPFROM2SHORT (CMDSRC_OTHER, TRUE)) ; _ffree (pSlist); free (pStoreList) ; WinPostMsg(hwnd,WM_QUIT,0L,0L); break; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : WM_DESTROY � ** � � ** � Description : Handles destroy case. The checkmark and � ** � coupon bitmaps are cleaned up. � ** � � ** � Called by : WinDestroyWindow � ** � � ** � Calls : Gpi... and Dev... functions. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case WM_DESTROY : GpiDestroyPS (hpsSLPMCHK) ; DevCloseDC (hdcSLPMCHK) ; GpiDeleteBitmap (hbmSLPMCHK) ; GpiDestroyPS (hpsSLPMCPN) ; DevCloseDC (hdcSLPMCPN) ; GpiDeleteBitmap (hbmSLPMCPN) ; return 0; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : WM_PAINT � ** � � ** � Description : Paints the client window. Draws the coupon � ** � and checkmark symbols using GpiBitBlt and � ** � displays the item names using Gpi... calls. � ** � The cursor is moved back to the proper place � ** � when done. � ** � � ** � Calls : Win... and Gpi... functions. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case WM_PAINT : hps = WinBeginPaint (hwnd, NULL, &rclInvalid) ; GpiErase (hps) ; sPaintBeg = max (0, sVscrollPos + (cyClient - (SHORT) rclInvalid.yTop) / cyChar) ; sPaintEnd = min (sListMax, sVscrollPos + (cyClient - (SHORT) rclInvalid.yBottom) / cyChar +1 ) ; for (sLine = sPaintBeg; sLine cmd) { case ID_MENU_EXIT : case ID_EXITPROG : WinPostMsg(hwnd, WM_CLOSE, 0L, 0L); break; case ID_RESUME: break; case ID_ABOUT: WinDlgBox (HWND_DESKTOP, hwnd, AboutDlgProc, NULL, ID_ABOUT, NULL) ; return 0 ; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : ID_TOGGLE_SELECT � ** � � ** � Description : Toggles the cSelected flag between one and � ** � zero. The COUPON indicator is ignored and � ** � reset. The selected line is invalidated � ** � and redrawn in the client window. � ** � � ** � Called by : Accelerator (VK_SPACE) or left mouse button � ** � from WM_BUTTON... case handling. � ** � � ** � Calls : Win... functions. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case ID_TOGGLE_SELECT : sCurrentItem = sVscrollPos + sCurrentLine ; if (pSlist[sCurrentItem].cSelected == '\0') pSlist[sCurrentItem].cSelected = '\x01' ; else pSlist[sCurrentItem].cSelected = '\0' ; rclInvalid.xLeft = 0 ; rclInvalid.xRight = cxClient ; rclInvalid.yBottom = cyClient - (sCurrentLine + 1) * cyChar ; rclInvalid.yTop = cyClient - sCurrentLine * cyChar ; WinInvalidateRect (hwnd, &rclInvalid, FALSE) ; WinUpdateWindow (hwnd) ; return 0 ; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : ID_SELECT_COUPON � ** � � ** � Description : The select count in the current item is � ** � incremented by one, and the COUPON flag � ** � is set on. The current line is invalidated. � ** � � ** � Called by : Accelerator (VK_SPACE+SHIFT) or right mouse � ** � button from WM_BUTTON... case. � ** � � ** � Calls : Win... functions. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case ID_SELECT_COUPON : sCurrentItem = sVscrollPos + sCurrentLine ; pSlist[sCurrentItem].cSelected = ((pSlist[sCurrentItem].cSelected & ~COUPON) + 1) | COUPON ; rclInvalid.xLeft = 0 ; rclInvalid.xRight = cxClient ; rclInvalid.yBottom = cyClient - (sCurrentLine + 1) * cyChar ; rclInvalid.yTop = cyClient - sCurrentLine * cyChar ; WinInvalidateRect (hwnd, &rclInvalid, FALSE) ; WinUpdateWindow (hwnd) ; return 0 ; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : ID_OPEN � ** � � ** � Description : Opens the store and shopping lists and � ** � loads them into memory. The shopping list � ** � is sorted by name and the client window � ** � is invalidated. � ** � � ** � Called by : Menu selection or WM_CREATE case. � ** � � ** � Calls : Win... and Gpi... functions, � ** � WM_USER_REBUILD, WM_COMMAND(ID_SORT_NAME). � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case ID_OPEN : hps = WinGetPS (hwnd) ; GpiErase (hps) ; WinReleasePS (hps) ; fFileHasChanged = FALSE ; SetMenuAttr (hwnd, ID_MENU_FILE, MIA_DISABLED, TRUE) ; SetMenuAttr (hwnd, ID_MENU_ITEM, MIA_DISABLED, TRUE) ; SetMenuAttr (hwnd, ID_MENU_SORT, MIA_DISABLED, TRUE) ; hptr = WinQuerySysPointer (HWND_DESKTOP, SPTR_WAIT, FALSE) ; WinSetPointer (HWND_DESKTOP, hptr) ; if (NULL != pSlist) _ffree (pSlist) ; if (NULL != pStoreList) free (pStoreList) ; if ((NULL == (pSlist = _fmalloc (512 * sizeof (SLPMslist) ))) || (NULL == (pStoreList = malloc (16 * sizeof (SLPMstores) )))) { WinMessageBox (HWND_DESKTOP, hwnd, "Can't Allocate Memory for Files - Hit F3", "SLPM", 0, MB_OK | MB_ICONEXCLAMATION) ; } else { if ((fileList = fopen (szStoreFile, "r")) == NULL) { WinAlarm (HWND_DESKTOP, WA_ERROR) ; break ; } for (sI = 0; fgets (&pStoreList[sI].cStore, sizeof (SLPMstores), fileList) != NULL; sI++); pStoreList[sI].cStore = '\0'; fclose (fileList); /* close store file */ cPreviousStore = '\0'; if ((fileList = fopen (szListFile, "r")) == NULL) { WinAlarm (HWND_DESKTOP, WA_ERROR) ; break ; } for (sListMax = 0; fgets (&pSlist[sListMax].cStore, sizeof(SLPMslist), fileList) != NULL; sListMax++) { pSlist[sListMax].szAisle[2] = '\0' ; pSlist[sListMax].szDescription[ strlen(pSlist[sListMax]. szDescription) - 1] = '\0' ; pSlist[sListMax].cSelected = NOT_SELECTED ; } fclose (fileList); /* free the file */ } SetMenuAttr (hwnd, ID_MENU_FILE, MIA_DISABLED, FALSE) ; SetMenuAttr (hwnd, ID_MENU_ITEM, MIA_DISABLED, FALSE) ; SetMenuAttr (hwnd, ID_MENU_SORT, MIA_DISABLED, FALSE) ; hptr = WinQuerySysPointer (HWND_DESKTOP, SPTR_ARROW, FALSE) ; WinSetPointer (HWND_DESKTOP, hptr) ; WinSendMsg (hwnd, WM_COMMAND, MPFROMSHORT (ID_SORT_NAME), MPFROM2SHORT (CMDSRC_OTHER, TRUE) ) ; WinSendMsg (hwnd, WM_USER_REBUILD, 0, 0) ; return 0 ; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : ID_SAVE � ** � � ** � Description : Saves the shopping list file. � ** � (BOOL)fFileHasChanged is reset. � ** � � ** � Called by : Menu selection or WM_CLOSE case. � ** � � ** � Calls : Win... and C functions. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case ID_SAVE : fFileHasChanged = FALSE ; SetMenuAttr (hwnd, ID_MENU_FILE, MIA_DISABLED, TRUE) ; SetMenuAttr (hwnd, ID_MENU_ITEM, MIA_DISABLED, TRUE) ; SetMenuAttr (hwnd, ID_MENU_SORT, MIA_DISABLED, TRUE) ; hptr = WinQuerySysPointer (HWND_DESKTOP, SPTR_WAIT, FALSE) ; WinSetPointer (HWND_DESKTOP, hptr) ; if ((fileList = fopen (szListFile, "w")) == NULL) { WinAlarm (HWND_DESKTOP, WA_ERROR) ; break ; } for (sI = 0; sI < sListMax; sI++) { pSlist[sI].szAisle[2] = ' ' ; pSlist[sI].cSelected = ' ' ; pSlist[sI].szDescription[sJ = strlen(pSlist[sI].szDescription)] = '\n' ; pSlist[sI].szDescription[sJ+1] = '\0' ; fputs (&pSlist[sI].cStore, fileList) ; } fclose (fileList); /* free the file */ SetMenuAttr (hwnd, ID_MENU_FILE, MIA_DISABLED, FALSE) ; SetMenuAttr (hwnd, ID_MENU_ITEM, MIA_DISABLED, FALSE) ; SetMenuAttr (hwnd, ID_MENU_SORT, MIA_DISABLED, FALSE) ; hptr = WinQuerySysPointer (HWND_DESKTOP, SPTR_ARROW, FALSE) ; WinSetPointer (HWND_DESKTOP, hptr) ; return 0 ; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : ID_SORT routines. � ** � � ** � Description : Sort the shopping list by name or store. � ** � The C "qsort" function is called. If the � ** � cases were entered from the menu rather � ** � than from internal WinSendMsg calls the � ** � client window is redrawn. � ** � � ** � Called by : Internal cases or menu selections. � ** � � ** � Calls : Win... functions, qsort. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case ID_SORT_NAME : WinSetPointer (HWND_DESKTOP, hptr = WinQuerySysPointer (HWND_DESKTOP, SPTR_WAIT, FALSE)) ; qsort (pSlist, sListMax, sizeof (SLPMslist), SLPMNameSort) ; WinSetPointer (HWND_DESKTOP, hptr = WinQuerySysPointer (HWND_DESKTOP, SPTR_ARROW, FALSE)) ; if (SHORT1FROMMP (mp2) == CMDSRC_MENU) WinSendMsg (hwnd, WM_USER_REBUILD, 0, 0) ; return 0 ; case ID_SORT_STORE : WinSetPointer (HWND_DESKTOP, hptr = WinQuerySysPointer (HWND_DESKTOP, SPTR_WAIT, FALSE)) ; qsort (pSlist, sListMax, sizeof (SLPMslist), SLPMStoreSort) ; WinSetPointer (HWND_DESKTOP, hptr = WinQuerySysPointer (HWND_DESKTOP, SPTR_ARROW, FALSE)) ; if (SHORT1FROMMP (mp2) == CMDSRC_MENU) WinSendMsg (hwnd, WM_USER_REBUILD, 0, 0) ; return 0 ; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : ID_DELETE � ** � � ** � Description : Delete the current item. A message box is � ** � used to verify the delete. � ** � � ** � Called by : Accelerator (Ctrl+D) or menu selection. � ** � � ** � Calls : WM_USER_REBUILD � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case ID_DELETE : sCurrentItem = sVscrollPos + sCurrentLine ; sprintf (szWork, "Delete %s?", pSlist[sCurrentItem].szDescription); if (MBID_YES == WinMessageBox (HWND_DESKTOP, hwnd, szWork, "SLPM", 0, MB_YESNO | MB_HELP | MB_ICONQUESTION)) { for (sI = sCurrentItem; sI < sListMax; sI++) memcpy (&pSlist[sI].cStore, &pSlist[sI + 1].cStore, sizeof (SLPMslist)) ; sListMax -= 1 ; fFileHasChanged = TRUE ; WinSendMsg (hwnd, WM_USER_REBUILD, 0, 0) ; } return 0; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : ID_PRINT_ALL � ** � � ** � Description : Prints the entire shopping list. All items � ** � are marked as selected and a WM_COMMAND � ** � (ID_PRINT) is sent to the client window. � ** � The selections are then cleared and the � ** � client window is invalidated. � ** � � ** � Called by : Menu selection. � ** � � ** � Calls : Win... functions, ID_PRINT. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case ID_PRINT_ALL : for (sI = 0; sI < sListMax; sI++) pSlist[sI].cSelected = '\x01' ; WinSendMsg (hwnd, WM_COMMAND, MPFROMSHORT (ID_PRINT), MPFROM2SHORT (CMDSRC_OTHER, TRUE) ) ; for (sI = 0; sI < sListMax; sI++) pSlist[sI].cSelected = '\0' ; WinInvalidateRect (hwnd, NULL, FALSE) ; WinUpdateWindow (hwnd) ; return 0; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : ID_PRINT � ** � � ** � Description : Print the shopping list. � ** � � ** � Called by : Accelerator (Ctrl+P), menu selection or � ** � ID_PRINT_ALL. � ** � � ** � Calls : Win... functions, C routines, � ** � ID_SORT_NAME, ID_SORT_STORE. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case ID_PRINT : sLineCount = 0; /* clear line counter */ filePrint = fopen ("LPT1", "w"); fprintf (filePrint, "\x1bG"); /* set enhanced print */ WinSendMsg (hwnd, WM_COMMAND, MPFROMSHORT (ID_SORT_STORE), MPFROM2SHORT (CMDSRC_OTHER, TRUE) ) ; WinSetPointer (HWND_DESKTOP, hptr = WinQuerySysPointer (HWND_DESKTOP, SPTR_WAIT, FALSE)) ; for (sI = 0; sI < sListMax; sI++) { /* print the list */ if (pSlist[sI].cSelected & ~COUPON) { if (cPreviousStore != pSlist[sI].cStore) { strcpy (szWork, "_______________________"); for (sJ = 0; cWork = pStoreList[sJ].cStore; sJ++) if (cWork == pSlist[sI].cStore) { strcpy (szWork, pStoreList[sJ].szStoreName); break; } fprintf (filePrint, "\n\n\t\t\t\t\t\x0E%s\n\n", szWork); cPreviousStore = pSlist[sI].cStore; sLineCount += 5; } if (strcmp(szPreviousAisle, pSlist[sI].szAisle) != 0) { strcpy (szPreviousAisle, pSlist[sI].szAisle); fprintf (filePrint, "\n\t\t\t\t\t==== Aisle %s ====================\n", szPreviousAisle); sLineCount += 2; } if (sLineCount++ >= 59) {sLineCount = 0; fprintf (filePrint, "\f"); } /* eject page */ fprintf (filePrint, "\t\t\t\t\t%s_%c %s\n", pSlist[sI].cSelected & COUPON ? "(C)" : "___" , ('\x01' == (pSlist[sI].cSelected & ~COUPON)) ? '_' : (pSlist[sI].cSelected & ~ COUPON) | '0', pSlist[sI].szDescription); } } /* end of selected item */ fprintf (filePrint, "\n\t\t\t\t\t==== End of List =================\n") ; fclose (filePrint) ; WinSendMsg (hwnd, WM_COMMAND, MPFROMSHORT (ID_SORT_NAME), MPFROM2SHORT (CMDSRC_OTHER, TRUE) ) ; WinSetPointer (HWND_DESKTOP, hptr = WinQuerySysPointer (HWND_DESKTOP, SPTR_ARROW, FALSE)) ; if (SHORT1FROMMP (mp2) == CMDSRC_MENU) { WinInvalidateRect (hwnd, NULL, FALSE) ; WinUpdateWindow (hwnd) ; } return 0 ; /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Case : ID_ADD, ID_COPY � ** � � ** � Description : Uses AddCopyDlgProc to add an entry or to � ** � copy an existing entry. If ID_COPY, the � ** � current list entry is used as a template. � ** � Otherwise, null fields are used. The � ** � current item is tagged with a special � ** � PLACE_HOLDER bit and is restored after the � ** � list is sorted. � ** � � ** � Called by : Accelerator (Ctrl+A, Ctrl+C) or menu � ** � selection. � ** � � ** � Calls : Win... functions, RunAddCopyDlg. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ case ID_ADD : case ID_COPY : pSlist[sListMax].cSelected = NOT_SELECTED ; memset (&pSlist[sListMax].cStore, '\0', sizeof (pSlist -> cStore) + sizeof (pSlist -> szAisle)) ; memset (pSlist[sListMax].szDescription, '\0', sizeof (pSlist -> szDescription)) ; if (COMMANDMSG (&msg) -> cmd == ID_COPY) memcpy (&pSlist[sListMax].cStore, &pSlist[sCurrentItem].cStore, sizeof (SLPMslist)) ; if (RunAddCopyDlg (hwnd, &pSlist[sListMax].cStore, pSlist[sListMax].szDescription)) { strupr (&pSlist[sListMax].cStore) ; pSlist[sListMax].cSelected = PLACE_HOLDER ; sListMax += 1 ; WinSendMsg (hwnd, WM_COMMAND, MPFROMSHORT (ID_SORT_NAME), MPFROM2SHORT (CMDSRC_OTHER, TRUE) ) ; for (sCurrentItem = 0; sCurrentItem < sListMax; sCurrentItem++) if (pSlist[sCurrentItem].cSelected == PLACE_HOLDER) { pSlist[sCurrentItem].cSelected = '\0' ; sCurrentLine = (cyClient / cyChar) / 2 ; sVscrollPos = sCurrentItem - sCurrentLine ; break ; } fFileHasChanged = TRUE ; WinSendMsg (hwnd, WM_USER_REBUILD, 0, 0) ; } return 0 ; } } return WinDefWindowProc (hwnd, msg, mp1, mp2) ; } /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Function : AboutDlgProc � ** � � ** � Description : Dialog procedure for the About SLPM... � ** � menu item. Dismisses the diaglog box � ** � when either OK or CANCEL is selected. � ** � � ** � Called by : About Dialog Box. � ** � � ** � Calls : Win... functions. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ MRESULT EXPENTRY AboutDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2) { switch (msg) { case WM_COMMAND : switch (COMMANDMSG(&msg) -> cmd) { case DID_OK : case DID_CANCEL : WinDismissDlg (hwnd, TRUE) ; return 0 ; } break ; } return WinDefDlgProc (hwnd, msg, mp1, mp2) ; } /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Function : SetMenuAttr � ** � � ** � Description : Sets the attributes for "menuid" to � ** � ENABLED (if "state" is TRUE) or DISABLED. � ** � � ** � Called by : Client Window Procedure cases. � ** � � ** � Calls : Win... functions. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ void cdecl SetMenuAttr (HWND hwnd, USHORT menuid, USHORT attr, BOOL state) { WinSendMsg (WinWindowFromID(WinQueryWindow(hwnd,QW_PARENT,FALSE), FID_MENU), MM_SETITEMATTR, MPFROM2SHORT (menuid, TRUE), MPFROM2SHORT (attr, state ? attr : 0) ) ; } /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Function : SLPM...Sort � ** � � ** � Description : Sorts the shopping list by name or store � ** � position. The arguments are as passed � ** � from qsort. � ** � � ** � Called by : qsort library function. � ** � � ** � Calls : strcmp library function. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ int cdecl SLPMNameSort (PSLPMSLIST pArg1, PSLPMSLIST pArg2) { return strcmp (pArg1 -> szDescription, pArg2 -> szDescription ) ; } int cdecl SLPMStoreSort (PSLPMSLIST pArg1, PSLPMSLIST pArg2) { return strcmp (&pArg1 -> cStore, &pArg2 -> cStore ) ; } /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Function : RunAddCopyDlg � ** � � ** � Description : Creates the Add/Copy dialog box. Global � ** � pointers pchAddCopyLocation and � ** � pchAddCopyDesc are set based on the two � ** � parameters. � ** � � ** � Called by : ID_ADD/ID_COPY cases. � ** � � ** � Calls : WinDlgBox, AddCopyDlgProc. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ MRESULT EXPENTRY RunAddCopyDlg (HWND hwnd, CHAR *pchLocation, CHAR *pchDesc) { USHORT usRC ; pchAddCopyLocation = pchLocation ; pchAddCopyDesc = pchDesc ; usRC = WinDlgBox (HWND_DESKTOP, hwnd, AddCopyDlgProc, NULL, IDD_ADDCOPY, NULL) ; return (MRESULT) usRC ; } /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � Function : AddCopyDlgProc � ** � � ** � Description : Manages the Add/Copy dialog box. The � ** � entry fields in the dialog box are set � ** � using the global pointers pchAddCopyDesc � ** � and pchAddCopyLocation. � ** � If the user selects the OK button, the � ** � entry fields are queried and stored in � ** � the areas pointed to by the global � ** � pointers. � ** � � ** � Calls : Win... functions. � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */ MRESULT EXPENTRY AddCopyDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2) { switch (msg) { case WM_INITDLG : WinSetDlgItemText (hwnd, IDD_LOCATION, pchAddCopyLocation) ; WinSetDlgItemText (hwnd, IDD_ITEMNAME, pchAddCopyDesc) ; WinSendDlgItemMsg (hwnd, IDD_LOCATION, EM_SETTEXTLIMIT, MPFROM2SHORT(3,0), NULL) ; WinSendDlgItemMsg (hwnd, IDD_ITEMNAME, EM_SETTEXTLIMIT, MPFROM2SHORT(71,0), NULL) ; return 0 ; case WM_COMMAND : switch (COMMANDMSG (&msg) -> cmd) { case DID_OK : WinQueryDlgItemText (hwnd, IDD_LOCATION, 4, pchAddCopyLocation) ; WinQueryDlgItemText (hwnd, IDD_ITEMNAME, 72, pchAddCopyDesc) ; WinDismissDlg (hwnd, TRUE) ; return 0 ; case DID_CANCEL : WinDismissDlg (hwnd, FALSE) ; return 0 ; } } return WinDefDlgProc (hwnd, msg, mp1, mp2) ; } /* ** 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 ** � � ** � End of SLPM.C � ** � � ** 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 ** */