Annotation of q_a/samples/menu/menu.c, revision 1.1

1.1     ! root        1: 
        !             2: /******************************************************************************\
        !             3: *       This is a part of the Microsoft Source Code Samples. 
        !             4: *       Copyright (C) 1993 Microsoft Corporation.
        !             5: *       All rights reserved. 
        !             6: *       This source code is only intended as a supplement to 
        !             7: *       Microsoft Development Tools and/or WinHelp documentation.
        !             8: *       See these sources for detailed information regarding the 
        !             9: *       Microsoft samples programs.
        !            10: \******************************************************************************/
        !            11: 
        !            12: /***************************************************************************
        !            13:  *                                                                         *
        !            14:  *  PROGRAM     : Menu.c                                                   *
        !            15:  *                                                                         *
        !            16:  *  PURPOSE     : To give a demonstration of the use of popup menus, user  *
        !            17:  *                defined menus and menu functions.                        *
        !            18:  *                                                                         *
        !            19:  *  FUNCTIONS   : WinMain()           - Calls the initialization function  *
        !            20:  *                                      and enters the message loop.       *
        !            21:  *                                                                         *
        !            22:  *                MenuInit()          - Registers the app. window class.   *
        !            23:  *                                                                         *
        !            24:  *                About()             - Dialog function for the About..    *
        !            25:  *                                      dialog.                            *
        !            26:  *                                                                         *
        !            27:  *                ShrinkBitmap()      - Shrinks a 64x64 bitmap to a size   *
        !            28:  *                                      useable for a user-defined menu    *
        !            29:  *                                      checkmark.                         *
        !            30:  *                                                                         *
        !            31:  *                HandleCreate()      - Creates a new menu and appends it  *
        !            32:  *                                      to the main menu                   *
        !            33:  *                                                                         *
        !            34:  *                HandlePaint()       - Handles repainting the app's client*
        !            35:  *                                      area                               *
        !            36:  *                                                                         *
        !            37:  *                HandleChangeColors()- Changes the state of the "colors"  *
        !            38:  *                                      menu item.                         *
        !            39:  *                                                                         *
        !            40:  *                HandleDrawItem()    - Redraws the menu items in the      *
        !            41:  *                                      "colors" menu                      *
        !            42:  *                                                                         *
        !            43:  *                HandlePopupMenu()   - handles display of the "floating"  *
        !            44:  *                                      popup.                             *
        !            45:  *                                                                         *
        !            46:  *                MenuWndProc()       - Window function for the app.       *
        !            47:  *                                                                         *
        !            48:  *                                                                         *
        !            49:  ***************************************************************************/
        !            50: #include "windows.h"
        !            51: #include "menu.h"
        !            52: 
        !            53: 
        !            54: HANDLE   hInst;
        !            55: HMENU    hBigMenu;
        !            56: HBITMAP  hbmCheckOn;
        !            57: HBITMAP  hbmCheckOff;
        !            58: 
        !            59: /****************************************************************************
        !            60:  *                                                                          *
        !            61:  *  FUNCTION   : WinMain(HANDLE, HANDLE, LPSTR, int)                        *
        !            62:  *                                                                          *
        !            63:  *  PURPOSE    : Creates the main app. window, calls an initialization      *
        !            64:  *               function and enters the message loop.                      *
        !            65:  *                                                                          *
        !            66:  ****************************************************************************/
        !            67: int APIENTRY WinMain(
        !            68:     HANDLE hInstance,
        !            69:     HANDLE hPrevInstance,
        !            70:     LPSTR lpCmdLine,
        !            71:     int nCmdShow
        !            72:     )
        !            73: {
        !            74: 
        !            75:     HWND  hWnd;
        !            76:     MSG msg;                                 /* message                      */
        !            77: 
        !            78:     UNREFERENCED_PARAMETER( lpCmdLine );
        !            79: 
        !            80:     /* Register main window class if this is the first instance of the app. */
        !            81:     if (!hPrevInstance)
        !            82:         if (!MenuInit (hInstance))
        !            83:             return 0;
        !            84: 
        !            85:     hInst = hInstance;
        !            86: 
        !            87:     /* Create the app. window */
        !            88:     hWnd = CreateWindow ("menu",
        !            89:                          "Menu Example",
        !            90:                          WS_OVERLAPPEDWINDOW,
        !            91:                          CW_USEDEFAULT,
        !            92:                          CW_USEDEFAULT,
        !            93:                          CW_USEDEFAULT,
        !            94:                          CW_USEDEFAULT,
        !            95:                          (HWND) NULL,
        !            96:                          NULL,
        !            97:                          hInstance,
        !            98:                          (LPSTR) NULL);
        !            99: 
        !           100:     if (!hWnd)
        !           101:         return 0;
        !           102: 
        !           103:     ShowWindow (hWnd, nCmdShow);
        !           104:     UpdateWindow (hWnd);
        !           105: 
        !           106:     while (GetMessage (&msg, NULL, 0, 0)){
        !           107:         /* Since we have no accelerators, no need to call
        !           108:          * TranslateAccelerator here.
        !           109:          */
        !           110:         TranslateMessage (&msg);
        !           111:         DispatchMessage (&msg);
        !           112:     }
        !           113:     return(msg.wParam);
        !           114: }
        !           115: 
        !           116: 
        !           117: /****************************************************************************
        !           118:  *                                                                          *
        !           119:  *  FUNCTION   : MenuInit (hInstance)                                       *
        !           120:  *                                                                          *
        !           121:  *  PURPOSE    : Registers the main window class.                           *
        !           122:  *                                                                          *
        !           123:  *  RETURNS    : TRUE   -  if RegisterClass() went off ok                   *
        !           124:  *               FALSE  -  otherwise.                                       *
        !           125:  *                                                                          *
        !           126:  ****************************************************************************/
        !           127: BOOL NEAR PASCAL MenuInit (HANDLE hInstance)
        !           128: {
        !           129:     HANDLE    hMemory;
        !           130:     PWNDCLASS pWndClass;
        !           131:     BOOL      bSuccess;
        !           132: 
        !           133:     /* Initialize the menu window class */
        !           134:     hMemory   = LocalAlloc(LPTR, sizeof(WNDCLASS));
        !           135:     if(!hMemory){
        !           136:         MessageBox(NULL, "<MenuInit> Not enough memory.", NULL, MB_OK | MB_ICONHAND);
        !           137:         return(FALSE);
        !           138:     }
        !           139: 
        !           140:     pWndClass = (PWNDCLASS) LocalLock(hMemory);
        !           141: 
        !           142:     pWndClass->style         = 0;
        !           143:     pWndClass->lpfnWndProc   = (WNDPROC) MenuWndProc;
        !           144:     pWndClass->hInstance     = hInstance;
        !           145:     pWndClass->hIcon         = LoadIcon (hInstance, "menu");
        !           146:     pWndClass->hCursor       = LoadCursor (NULL, IDC_ARROW);
        !           147:     pWndClass->hbrBackground = GetStockObject (WHITE_BRUSH);
        !           148:     pWndClass->lpszMenuName  = (LPSTR) "MenuMenu",
        !           149:     pWndClass->lpszClassName = (LPSTR) "menu";
        !           150: 
        !           151:     bSuccess = RegisterClass (pWndClass);
        !           152:     LocalUnlock (hMemory);
        !           153:     LocalFree (hMemory);
        !           154: 
        !           155:     return bSuccess;
        !           156: }
        !           157: 
        !           158: 
        !           159: /****************************************************************************
        !           160:  *                                                                          *
        !           161:  *  FUNCTION   : About (hDlg, message, wParam, lParam)                      *
        !           162:  *                                                                          *
        !           163:  *  PURPOSE    : Dialog function for the About menu... dialog.              *
        !           164:  *                                                                          *
        !           165:  ****************************************************************************/
        !           166: BOOL APIENTRY About(
        !           167:         HWND hDlg,
        !           168:         UINT message,
        !           169:         UINT wParam,
        !           170:         LONG lParam)
        !           171: 
        !           172: {
        !           173:     switch (message){
        !           174:         case WM_INITDIALOG:
        !           175:             return(TRUE);
        !           176: 
        !           177:         case WM_COMMAND:
        !           178:             // LOWORD added for portability
        !           179:             if (LOWORD(wParam) == IDOK){
        !           180:                 EndDialog(hDlg,0);
        !           181:                 return(TRUE);
        !           182:             }
        !           183:             break;
        !           184:     }
        !           185:     return(FALSE);
        !           186:         UNREFERENCED_PARAMETER(lParam);
        !           187: }
        !           188: 
        !           189: 
        !           190: /****************************************************************************
        !           191:  *                                                                          *
        !           192:  *  FUNCTION   : ShrinkBitmap(hwnd, hbm)                                    *
        !           193:  *                                                                          *
        !           194:  *  PURPOSE    : This function shrinks a 64x64 bitmap into a bitmap useable *
        !           195:  *               for the user-defined checkmark for menu items. This can be *
        !           196:  *               easily generalized to shrink bitmaps of any size.          *
        !           197:  *                                                                          *
        !           198:  *  RETURNS    : HBITMAP - A handle to the new bitmap.                      *
        !           199:  *                                                                          *
        !           200:  ****************************************************************************/
        !           201: HBITMAP APIENTRY ShrinkBitmap (
        !           202:         HWND hwnd,
        !           203:         HBITMAP hbm)
        !           204: {
        !           205:     HDC     hdc;
        !           206:     HDC     hmemorydcNew;
        !           207:     HDC     hmemorydcOld;
        !           208:     LONG    checkMarkSize;
        !           209:     HBITMAP hCheckBitmap;
        !           210:     HBITMAP hOldBitmapSave;
        !           211:     HBITMAP hNewBitmapSave;
        !           212: 
        !           213:     hdc = GetDC (hwnd);
        !           214: 
        !           215:     /* Create DCs for the source (old) and target (new) bitmaps */
        !           216:     hmemorydcNew = CreateCompatibleDC (hdc);
        !           217:     hmemorydcOld = CreateCompatibleDC (hdc);
        !           218: 
        !           219:     /* Determine the dimensions of the default menu checkmark and
        !           220:      * create a target bitmap of the same dimensions
        !           221:      */
        !           222:     checkMarkSize = GetMenuCheckMarkDimensions ();
        !           223:     hCheckBitmap  = CreateCompatibleBitmap (hdc,
        !           224:                                             LOWORD (checkMarkSize),
        !           225:                                             HIWORD (checkMarkSize));
        !           226: 
        !           227:     /* Select the source bitmap and the target bitmap into their
        !           228:      * respective DCs.
        !           229:      */
        !           230:     hOldBitmapSave = SelectObject (hmemorydcNew, hCheckBitmap);
        !           231:     hNewBitmapSave = SelectObject (hmemorydcOld, hbm);
        !           232: 
        !           233:     /* Shrink the source bitmap into the target DC */
        !           234:     StretchBlt (hmemorydcNew,
        !           235:                 0,
        !           236:                 0,
        !           237:                 LOWORD(checkMarkSize),
        !           238:                 HIWORD(checkMarkSize),
        !           239:                 hmemorydcOld,
        !           240:                 0,
        !           241:                 0,
        !           242:                 64,
        !           243:                 64,
        !           244:                 SRCCOPY);
        !           245: 
        !           246:     /* De-select the bitmaps and clean up .. */
        !           247:     SelectObject (hmemorydcNew, hOldBitmapSave);
        !           248:     SelectObject (hmemorydcOld, hNewBitmapSave);
        !           249:     DeleteDC (hmemorydcNew);
        !           250:     DeleteDC (hmemorydcOld);
        !           251:     ReleaseDC (hwnd, hdc);
        !           252: 
        !           253:     /* .. and return a handle to the target bitmap */
        !           254:     return hCheckBitmap;
        !           255: }
        !           256: 
        !           257: 
        !           258: /****************************************************************************
        !           259:  *                                                                          *
        !           260:  *  FUNCTION   : HandleCreate ( hwnd )                                      *
        !           261:  *                                                                          *
        !           262:  *  PURPOSE    : Creates a new (empty) menu and appends to it the "State"   *
        !           263:  *               menu items. It sets up the user-defined checkmarks for the *
        !           264:  *               menu. It then inserts this menu into the main menu bar.    *
        !           265:  *                                                                          *
        !           266:  ****************************************************************************/
        !           267: VOID APIENTRY HandleCreate (HWND hwnd)
        !           268: {
        !           269:     HMENU   hMenu;
        !           270:     HMENU   hWndMenu;
        !           271: 
        !           272:     /* Create a new menu into the menubar on the fly */
        !           273:     hMenu = CreateMenu ();
        !           274:     if (!hMenu)
        !           275:         return;
        !           276: 
        !           277:     /* Append the state menu items to it */
        !           278:     AppendMenu (hMenu, MF_STRING, IDM_STATE1, "South Dakota");
        !           279:     AppendMenu (hMenu, MF_STRING, IDM_STATE2, "Washington");
        !           280:     AppendMenu (hMenu, MF_STRING, IDM_STATE3, "California");
        !           281:     if (!AppendMenu (hMenu, MF_STRING, IDM_STATE4, "Oregon")){
        !           282:         /* It is unlikely the other appends will fail and this will succeed.
        !           283:          * So just check this one. And if it fails, Destroy the menu for
        !           284:          * good measure and return.
        !           285:          */
        !           286:         DestroyMenu(hMenu);
        !           287:         return;
        !           288:     }
        !           289:     hbmCheckOn  = ShrinkBitmap (hwnd, LoadBitmap (hInst, "checkon"));
        !           290:     hbmCheckOff = ShrinkBitmap (hwnd, LoadBitmap (hInst, "checkoff"));
        !           291: 
        !           292:     /* Set up the user-defined check marks */
        !           293:     SetMenuItemBitmaps (hMenu, 0, MF_BYPOSITION, hbmCheckOff, hbmCheckOn);
        !           294:     SetMenuItemBitmaps (hMenu, 1, MF_BYPOSITION, hbmCheckOff, hbmCheckOn);
        !           295:     SetMenuItemBitmaps (hMenu, 2, MF_BYPOSITION, hbmCheckOff, hbmCheckOn);
        !           296:     SetMenuItemBitmaps (hMenu, 3, MF_BYPOSITION, hbmCheckOff, hbmCheckOn);
        !           297: 
        !           298:     /* Now insert the menu into the main menu bar. */
        !           299:     hWndMenu = GetMenu (hwnd);
        !           300:     InsertMenu (hWndMenu, 2, MF_POPUP|MF_BYPOSITION, (DWORD)hMenu, "States");
        !           301: 
        !           302:     return;
        !           303: }
        !           304: 
        !           305: /****************************************************************************
        !           306:  *                                                                          *
        !           307:  *  FUNCTION   : HandlePaint ( hwnd )                                       *
        !           308:  *                                                                          *
        !           309:  *  PURPOSE    : Handles the repainting of the main app's client area.      *
        !           310:  *                                                                          *
        !           311:  ****************************************************************************/
        !           312: VOID APIENTRY HandlePaint (HWND hwnd)
        !           313: {
        !           314:     HDC         hdc;
        !           315:     PAINTSTRUCT ps;
        !           316:     RECT        rc;
        !           317: 
        !           318:     hdc = BeginPaint (hwnd, (LPPAINTSTRUCT)&ps);
        !           319: 
        !           320:     /* Center the text in the client area */
        !           321:     GetClientRect (hwnd, (LPRECT)&rc);
        !           322:     DrawText (hdc,
        !           323:               "Down click in the window for a popup menu",
        !           324:                41,
        !           325:                (LPRECT)&rc,
        !           326:                DT_CENTER | DT_WORDBREAK);
        !           327:     EndPaint(hwnd, (LPPAINTSTRUCT)&ps);
        !           328: }
        !           329: 
        !           330: 
        !           331: /****************************************************************************
        !           332:  *                                                                          *
        !           333:  *  FUNCTION   : HandleChangeColors (hwnd)                                  *
        !           334:  *                                                                          *
        !           335:  *  PURPOSE    : Toggles the state of the Owner Draw item in the Colors     *
        !           336:  *               menu. If it is on, the "Black", "Blue", "Red", and "Green" *
        !           337:  *               individual menu text items are modified so that they will  *
        !           338:  *               contain bands of color. Otherwise, the colors are replaced *
        !           339:  *               by the text.                                               *
        !           340:  *                                                                          *
        !           341:  ****************************************************************************/
        !           342: VOID APIENTRY HandleChangeColors(HWND hwnd)
        !           343: {
        !           344:     HMENU hMenu;
        !           345:     BOOL  fOwnerDraw;
        !           346: 
        !           347:     /* Get a handle to the Colors menu. This is at position 1. */
        !           348:     hMenu = GetSubMenu (GetMenu (hwnd), IDCOLORS_POS);
        !           349: 
        !           350:     /* Get the current state of the item */
        !           351:     fOwnerDraw = GetMenuState ( hMenu,
        !           352:                                 IDM_COLOROWNERDR, MF_BYCOMMAND) & MF_CHECKED;
        !           353: 
        !           354:     /* Toggle the state of the item. */
        !           355:     CheckMenuItem ( hMenu,
        !           356:                     IDM_COLOROWNERDR,
        !           357:                     MF_BYCOMMAND | (fOwnerDraw ? MF_UNCHECKED : MF_CHECKED));
        !           358: 
        !           359:     if (!fOwnerDraw){
        !           360:         /* Change the items to owner-draw items. Pass the RGB value for the
        !           361:          * color as the application-supplied data. This makes it easier for
        !           362:          * us to draw the items.
        !           363:          */
        !           364:         ModifyMenu(hMenu,
        !           365:                    IDM_BLACK,
        !           366:                    MF_OWNERDRAW | MF_BYCOMMAND,
        !           367:                    IDM_BLACK,
        !           368:                    (LPSTR)RGB (0,0,0));
        !           369: 
        !           370:         ModifyMenu(hMenu,
        !           371:                    IDM_BLUE,
        !           372:                    MF_OWNERDRAW | MF_BYCOMMAND,
        !           373:                    IDM_BLUE,
        !           374:                    (LPSTR)RGB (0,0,255));
        !           375: 
        !           376:         ModifyMenu(hMenu,
        !           377:                    IDM_RED,
        !           378:                    MF_OWNERDRAW | MF_BYCOMMAND,
        !           379:                    IDM_RED,
        !           380:                    (LPSTR)RGB (255,0,0));
        !           381: 
        !           382:         ModifyMenu(hMenu,
        !           383:                    IDM_GREEN,
        !           384:                    MF_OWNERDRAW | MF_BYCOMMAND,
        !           385:                    IDM_GREEN,
        !           386:                    (LPSTR)RGB (0,255,0));
        !           387:     }
        !           388:     else {
        !           389:         /* Change the items to normal text items. */
        !           390:         ModifyMenu(hMenu, IDM_BLACK, MF_BYCOMMAND, IDM_BLACK, "Black");
        !           391: 
        !           392:         ModifyMenu(hMenu, IDM_BLUE, MF_BYCOMMAND, IDM_BLUE, "Blue");
        !           393: 
        !           394:         ModifyMenu(hMenu, IDM_RED, MF_BYCOMMAND, IDM_RED, "Red");
        !           395: 
        !           396:         ModifyMenu(hMenu, IDM_GREEN, MF_BYCOMMAND, IDM_GREEN, "Green");
        !           397:     }
        !           398: }
        !           399: 
        !           400: 
        !           401: /****************************************************************************
        !           402:  *                                                                          *
        !           403:  *  FUNCTION   : HandleDrawItem ( hwnd, lpdis)                              *
        !           404:  *                                                                          *
        !           405:  *  PURPOSE    : Called in response to a WM_DRAWITEM message, i.e. when the *
        !           406:  *               colors menu is being modified to an owner-draw menu, or    *
        !           407:  *               one of the items is selected. It sizes the checkmark bitmap*
        !           408:  *               to fit next to a color band and draws the color bands and  *
        !           409:  *               the checkmark on the popup menu.                           *
        !           410:  *                                                                          *
        !           411:  ****************************************************************************/
        !           412: VOID APIENTRY HandleDrawItem(
        !           413:         HWND             hwnd,
        !           414:         LPDRAWITEMSTRUCT lpdis)
        !           415: 
        !           416: {
        !           417:     HDC     hdcBitmap;
        !           418:     HBITMAP hbmSave;
        !           419:     HBRUSH  hbr;
        !           420:     RECT    rc;
        !           421:     LONG    checkMarkSize;
        !           422:     DWORD   textColorSave;
        !           423:     DWORD   bkColorSave;
        !           424: 
        !           425:     /* Get the size of the checkmark so we can leave room for it since we
        !           426:      * want to be able to check the selected color.
        !           427:      */
        !           428:     checkMarkSize = GetMenuCheckMarkDimensions ();
        !           429: 
        !           430:     if (lpdis->itemAction == ODA_SELECT ||
        !           431:         lpdis->itemAction == ODA_DRAWENTIRE){
        !           432: 
        !           433:         CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem);
        !           434:         InflateRect ((LPRECT)&rc, (-2 - LOWORD(checkMarkSize)), -2);
        !           435: 
        !           436:         if (lpdis->itemState & ODS_SELECTED)
        !           437:         {
        !           438:             /* Item has been selected -- hilite with a gray frame */
        !           439:             hbr = GetStockObject (GRAY_BRUSH);
        !           440:             FrameRect (lpdis->hDC, (LPRECT)&rc, hbr);
        !           441:         }
        !           442:         else if (lpdis->itemAction == ODA_SELECT)
        !           443:         {
        !           444:             /* Item has been de-selected -- remove gray frame */
        !           445:             hbr = CreateSolidBrush (GetSysColor (COLOR_MENU));
        !           446:             FrameRect (lpdis->hDC, (LPRECT)&rc, hbr);
        !           447:             DeleteObject (hbr);
        !           448:         }
        !           449:     }
        !           450: 
        !           451:     if (lpdis->itemAction == ODA_DRAWENTIRE){
        !           452: 
        !           453:         /* Paint the color item in the color requested. */
        !           454:         hbr = CreateSolidBrush (lpdis->itemData);
        !           455:         CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem);
        !           456:         InflateRect ((LPRECT)&rc, -10-LOWORD(checkMarkSize), -10);
        !           457:         FillRect (lpdis->hDC, (LPRECT)&rc, hbr);
        !           458:         DeleteObject (hbr);
        !           459: 
        !           460:         if (lpdis->itemState & ODS_CHECKED){
        !           461:             /* Draw the check mark if the item is checked. */
        !           462:             hdcBitmap = CreateCompatibleDC (lpdis->hDC);
        !           463:             hbmSave = SelectObject (hdcBitmap, hbmCheckOn);
        !           464: 
        !           465:             textColorSave = SetTextColor (lpdis->hDC, 0x00000000L);
        !           466:             bkColorSave   = SetBkColor (lpdis->hDC, 0x00FFFFFFL);
        !           467: 
        !           468:             /* Use Magic bitblt op so that monochrome bitmaps preserve
        !           469:                background and foreground colors. */
        !           470:             BitBlt (lpdis->hDC,
        !           471:                     lpdis->rcItem.left,
        !           472:                     lpdis->rcItem.top+
        !           473:                            (MEASUREITEMHEIGHT - HIWORD (checkMarkSize)) / 2,
        !           474:                     LOWORD (checkMarkSize),
        !           475:                     HIWORD (checkMarkSize),
        !           476:                     hdcBitmap,
        !           477:                     0,
        !           478:                     0,
        !           479:                     ROP_PSDPxax);
        !           480: 
        !           481:             /* Restore colors and bitmap and clean up */
        !           482:             SetTextColor (lpdis->hDC, textColorSave);
        !           483:             SetBkColor (lpdis->hDC, bkColorSave);
        !           484:             SelectObject (hdcBitmap, hbmSave);
        !           485:             DeleteDC (hdcBitmap);
        !           486: 
        !           487:         }
        !           488:     }
        !           489:         UNREFERENCED_PARAMETER(hwnd);
        !           490: }
        !           491: 
        !           492: /****************************************************************************
        !           493:  *                                                                          *
        !           494:  *  FUNCTION   : HandlePopupMenu (hwnd, point)                              *
        !           495:  *                                                                          *
        !           496:  *  PURPOSE    : Handles the display of the "floating" popup that appears   *                                                           *
        !           497:  *               on a mouse click in the app's client area.                 *
        !           498:  *                                                                          *
        !           499:  ****************************************************************************/
        !           500: VOID APIENTRY HandlePopupMenu (
        !           501:         HWND   hwnd,
        !           502:         POINT point)
        !           503: 
        !           504: {
        !           505:     HMENU hMenu;
        !           506:     HMENU hMenuTrackPopup;
        !           507: 
        !           508:     /* Get the menu for the popup from the resource file. */
        !           509:     hMenu = LoadMenu (hInst, "PopupMenu");
        !           510:     if (!hMenu)
        !           511:         return;
        !           512: 
        !           513:     /* Get the first menu in it which we will use for the call to
        !           514:      * TrackPopup(). This could also have been created on the fly using
        !           515:      * CreatePopupMenu and then we could have used InsertMenu() or
        !           516:      * AppendMenu.
        !           517:      */
        !           518:     hMenuTrackPopup = GetSubMenu (hMenu, 0);
        !           519: 
        !           520:     /* Convert the mouse point to screen coordinates since that is what
        !           521:      * TrackPopup expects.
        !           522:      */
        !           523:     ClientToScreen (hwnd, (LPPOINT)&point);
        !           524: 
        !           525:     /* Draw and track the "floating" popup */
        !           526:     TrackPopupMenu (hMenuTrackPopup, 0, point.x, point.y, 0, hwnd, NULL);
        !           527: 
        !           528:     /* Destroy the menu since were are done with it. */
        !           529:     DestroyMenu (hMenu);
        !           530: }
        !           531: 
        !           532: /****************************************************************************
        !           533:  *                                                                          *
        !           534:  *  FUNCTION   : MenuWndProc (hWnd, message, wParam, lParam)                *
        !           535:  *                                                                          *
        !           536:  *  PURPOSE    : Window function for the main app. window. Processes all the*
        !           537:  *               menu selections and oter messages.                         *
        !           538:  *                                                                          *
        !           539:  ****************************************************************************/
        !           540: LONG APIENTRY MenuWndProc (
        !           541:         HWND hWnd,
        !           542:         UINT message,
        !           543:         UINT wParam,
        !           544:         LONG lParam)
        !           545: 
        !           546: {
        !           547:     FARPROC lpProc;
        !           548:     HMENU hMenu;
        !           549:     RECT rc;
        !           550:     POINT pt;
        !           551: 
        !           552: 
        !           553:     switch (message){
        !           554:         case WM_SYSCOMMAND:
        !           555:             /* Show the About ... dialog */
        !           556:             if (wParam == ID_ABOUT){
        !           557:                 lpProc = MakeProcInstance ((FARPROC)About, hInst);
        !           558:                 DialogBox (hInst,
        !           559:                            "AboutBox",
        !           560:                            hWnd,
        !           561:                            lpProc);
        !           562: 
        !           563:                 FreeProcInstance (lpProc);
        !           564:                 break;
        !           565:             }
        !           566:             else
        !           567:               return DefWindowProc (hWnd, message, wParam, lParam);
        !           568: 
        !           569:         case WM_COMMAND:
        !           570:             // LOWORD added for portability
        !           571:             switch (LOWORD(wParam)){
        !           572:                  case IDM_EXIT:
        !           573:                    DestroyWindow (hWnd);
        !           574:                    break;
        !           575: 
        !           576:                  case IDM_ABOUT:
        !           577:                    /* Bring up the About.. dialog box */
        !           578:                    lpProc = MakeProcInstance ((FARPROC)About, hInst);
        !           579:                    DialogBox (hInst,
        !           580:                               "AboutBox",
        !           581:                               hWnd,
        !           582:                               lpProc);
        !           583: 
        !           584:                    FreeProcInstance (lpProc);
        !           585:                    break;
        !           586: 
        !           587:                  case IDM_COLOROWNERDR:
        !           588:                      /* Change colors in color menu depending on state of this
        !           589:                         menu item. */
        !           590:                      HandleChangeColors (hWnd);
        !           591:                      break;
        !           592: 
        !           593:                  case IDM_STATE1:
        !           594:                  case IDM_STATE2:
        !           595:                  case IDM_STATE3:
        !           596:                  case IDM_STATE4:
        !           597:                       /* Get a handle to the states menu... */
        !           598:                       hMenu = GetSubMenu (GetMenu (hWnd), IDSTATES_POS);
        !           599: 
        !           600:                       /* Uncheck all the items. */
        !           601:                       CheckMenuItem (hMenu, IDM_STATE1,
        !           602:                                      MF_BYCOMMAND | MF_UNCHECKED);
        !           603:                       CheckMenuItem (hMenu, IDM_STATE2,
        !           604:                                      MF_BYCOMMAND | MF_UNCHECKED);
        !           605:                       CheckMenuItem (hMenu, IDM_STATE3,
        !           606:                                      MF_BYCOMMAND | MF_UNCHECKED);
        !           607:                       CheckMenuItem (hMenu, IDM_STATE4,
        !           608:                                      MF_BYCOMMAND | MF_UNCHECKED);
        !           609: 
        !           610:                       /* ...and just check the selected one.*/
        !           611:                       CheckMenuItem (hMenu, (WORD)wParam,
        !           612:                                      MF_BYCOMMAND | MF_CHECKED);
        !           613:                      break;
        !           614: 
        !           615:                  case IDM_BLACK:
        !           616:                  case IDM_RED:
        !           617:                  case IDM_BLUE:
        !           618:                  case IDM_GREEN:
        !           619:                       /* Get a handle to the Colors menu. */
        !           620:                       hMenu = GetSubMenu (GetMenu (hWnd),IDCOLORS_POS);
        !           621: 
        !           622:                       /* Uncheck all the items. */
        !           623:                       CheckMenuItem (hMenu, IDM_BLACK,
        !           624:                                      MF_BYCOMMAND | MF_UNCHECKED);
        !           625:                       CheckMenuItem (hMenu, IDM_RED,
        !           626:                                      MF_BYCOMMAND | MF_UNCHECKED);
        !           627:                       CheckMenuItem (hMenu, IDM_BLUE,
        !           628:                                      MF_BYCOMMAND | MF_UNCHECKED);
        !           629:                       CheckMenuItem (hMenu, IDM_GREEN,
        !           630:                                      MF_BYCOMMAND | MF_UNCHECKED);
        !           631: 
        !           632:                       /* ...and just check the selected one.*/
        !           633:                       CheckMenuItem (hMenu, (WORD)wParam,
        !           634:                                      MF_BYCOMMAND | MF_CHECKED);
        !           635:                       break;
        !           636: 
        !           637:                  case IDM_FONT:
        !           638:                       /* Messages sent to us from TrackPopupMenu when
        !           639:                        * items are selected from the "floating" popups
        !           640:                        */
        !           641:                       MessageBox (hWnd,
        !           642:                                   "A font was selected",
        !           643:                                   "Popup Menu Alert",
        !           644:                                   MB_APPLMODAL|MB_OK);
        !           645:                       break;
        !           646: 
        !           647:                  case IDM_SIZE:
        !           648:                       MessageBox (hWnd,
        !           649:                                   "A size was selected",
        !           650:                                   "Popup Menu Alert",
        !           651:                                   MB_APPLMODAL|MB_OK);
        !           652:                       break;
        !           653: 
        !           654:                  case IDM_STYLE:
        !           655:                       MessageBox (hWnd,
        !           656:                                   "A style was selected",
        !           657:                                   "Popup Menu Alert",
        !           658:                                   MB_APPLMODAL|MB_OK);
        !           659:                       break;
        !           660:             }
        !           661:             break;
        !           662: 
        !           663:         case WM_SIZE:
        !           664:             if (lParam){
        !           665:                 /* If window is being sized to a non zero value...
        !           666:                  * invalidate it's client area.
        !           667:                  */
        !           668:                 InvalidateRect (hWnd, NULL, TRUE);
        !           669:             }
        !           670:             break;
        !           671: 
        !           672:         case WM_PAINT:
        !           673:             HandlePaint (hWnd);
        !           674:             break;
        !           675: 
        !           676:         case WM_MEASUREITEM:
        !           677:             /* Use the same width for all items. We could examine the item id
        !           678:                and use different widths/heights for each item. */
        !           679:             ((LPMEASUREITEMSTRUCT)lParam)->itemWidth  = MEASUREITEMWIDTH;
        !           680:             ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = MEASUREITEMHEIGHT;
        !           681:             return TRUE;
        !           682: 
        !           683:         case WM_DRAWITEM:
        !           684:             /* Redraw the "colors" menu in normal/ownerdrawmode */
        !           685:             HandleDrawItem (hWnd,(LPDRAWITEMSTRUCT)lParam);
        !           686:             return TRUE;
        !           687:             break;
        !           688: 
        !           689:         case WM_CREATE:
        !           690:             /* Create the menu */
        !           691:             HandleCreate (hWnd);
        !           692:             break;
        !           693: 
        !           694:         case WM_DESTROY:
        !           695:             /* Delete the on/off bitmaps so that they don't waste memory. */
        !           696:             DeleteObject (hbmCheckOn);
        !           697:             DeleteObject (hbmCheckOff);
        !           698: 
        !           699:             PostQuitMessage (0);
        !           700:             break;
        !           701: 
        !           702:         case WM_LBUTTONDOWN:
        !           703:             /* Draw the "floating" popup in the app's client area */
        !           704:             GetClientRect (hWnd, (LPRECT)&rc);
        !           705: 
        !           706:             // Temporary porting macro
        !           707:             LONG2POINT(lParam, pt);
        !           708:             if (PtInRect ((LPRECT)&rc, pt))
        !           709:                 HandlePopupMenu (hWnd, pt);
        !           710:             break;
        !           711: 
        !           712:         default:
        !           713:             return DefWindowProc(hWnd, message, wParam, lParam);
        !           714:     }
        !           715:     return(0);
        !           716: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.