home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winui / menu / menu.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  29KB  |  712 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright (C) 1993 - 1997 Microsoft Corp.
  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.     HINSTANCE hInstance,
  69.     HINSTANCE 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.     HMENU hMenu;
  548.     RECT rc;
  549.     POINT pt;
  550.  
  551.  
  552.     switch (message){
  553.         case WM_SYSCOMMAND:
  554.             /* Show the About ... dialog */
  555.             if (wParam == ID_ABOUT){
  556.                 DialogBox (hInst,
  557.                            "AboutBox",
  558.                            hWnd,
  559.                            About);
  560.  
  561.                 break;
  562.             }
  563.             else
  564.               return DefWindowProc (hWnd, message, wParam, lParam);
  565.  
  566.         case WM_COMMAND:
  567.             // LOWORD added for portability
  568.             switch (LOWORD(wParam)){
  569.                  case IDM_EXIT:
  570.                    DestroyWindow (hWnd);
  571.                    break;
  572.  
  573.                  case IDM_ABOUT:
  574.                    /* Bring up the About.. dialog box */
  575.                    DialogBox (hInst,
  576.                               "AboutBox",
  577.                               hWnd,
  578.                               About);
  579.  
  580.                    break;
  581.  
  582.                  case IDM_COLOROWNERDR:
  583.                      /* Change colors in color menu depending on state of this
  584.                         menu item. */
  585.                      HandleChangeColors (hWnd);
  586.                      break;
  587.  
  588.                  case IDM_STATE1:
  589.                  case IDM_STATE2:
  590.                  case IDM_STATE3:
  591.                  case IDM_STATE4:
  592.                       /* Get a handle to the states menu... */
  593.                       hMenu = GetSubMenu (GetMenu (hWnd), IDSTATES_POS);
  594.  
  595.                       /* Uncheck all the items. */
  596.                       CheckMenuItem (hMenu, IDM_STATE1,
  597.                                      MF_BYCOMMAND | MF_UNCHECKED);
  598.                       CheckMenuItem (hMenu, IDM_STATE2,
  599.                                      MF_BYCOMMAND | MF_UNCHECKED);
  600.                       CheckMenuItem (hMenu, IDM_STATE3,
  601.                                      MF_BYCOMMAND | MF_UNCHECKED);
  602.                       CheckMenuItem (hMenu, IDM_STATE4,
  603.                                      MF_BYCOMMAND | MF_UNCHECKED);
  604.  
  605.                       /* ...and just check the selected one.*/
  606.                       CheckMenuItem (hMenu, (WORD)wParam,
  607.                                      MF_BYCOMMAND | MF_CHECKED);
  608.                      break;
  609.  
  610.                  case IDM_BLACK:
  611.                  case IDM_RED:
  612.                  case IDM_BLUE:
  613.                  case IDM_GREEN:
  614.                       /* Get a handle to the Colors menu. */
  615.                       hMenu = GetSubMenu (GetMenu (hWnd),IDCOLORS_POS);
  616.  
  617.                       /* Uncheck all the items. */
  618.                       CheckMenuItem (hMenu, IDM_BLACK,
  619.                                      MF_BYCOMMAND | MF_UNCHECKED);
  620.                       CheckMenuItem (hMenu, IDM_RED,
  621.                                      MF_BYCOMMAND | MF_UNCHECKED);
  622.                       CheckMenuItem (hMenu, IDM_BLUE,
  623.                                      MF_BYCOMMAND | MF_UNCHECKED);
  624.                       CheckMenuItem (hMenu, IDM_GREEN,
  625.                                      MF_BYCOMMAND | MF_UNCHECKED);
  626.  
  627.                       /* ...and just check the selected one.*/
  628.                       CheckMenuItem (hMenu, (WORD)wParam,
  629.                                      MF_BYCOMMAND | MF_CHECKED);
  630.                       break;
  631.  
  632.                  case IDM_FONT:
  633.                       /* Messages sent to us from TrackPopupMenu when
  634.                        * items are selected from the "floating" popups
  635.                        */
  636.                       MessageBox (hWnd,
  637.                                   "A font was selected",
  638.                                   "Popup Menu Alert",
  639.                                   MB_APPLMODAL|MB_OK);
  640.                       break;
  641.  
  642.                  case IDM_SIZE:
  643.                       MessageBox (hWnd,
  644.                                   "A size was selected",
  645.                                   "Popup Menu Alert",
  646.                                   MB_APPLMODAL|MB_OK);
  647.                       break;
  648.  
  649.                  case IDM_STYLE:
  650.                       MessageBox (hWnd,
  651.                                   "A style was selected",
  652.                                   "Popup Menu Alert",
  653.                                   MB_APPLMODAL|MB_OK);
  654.                       break;
  655.             }
  656.             break;
  657.  
  658.         case WM_SIZE:
  659.             if (lParam){
  660.                 /* If window is being sized to a non zero value...
  661.                  * invalidate it's client area.
  662.                  */
  663.                 InvalidateRect (hWnd, NULL, TRUE);
  664.             }
  665.             break;
  666.  
  667.         case WM_PAINT:
  668.             HandlePaint (hWnd);
  669.             break;
  670.  
  671.         case WM_MEASUREITEM:
  672.             /* Use the same width for all items. We could examine the item id
  673.                and use different widths/heights for each item. */
  674.             ((LPMEASUREITEMSTRUCT)lParam)->itemWidth  = MEASUREITEMWIDTH;
  675.             ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = MEASUREITEMHEIGHT;
  676.             return TRUE;
  677.  
  678.         case WM_DRAWITEM:
  679.             /* Redraw the "colors" menu in normal/ownerdrawmode */
  680.             HandleDrawItem (hWnd,(LPDRAWITEMSTRUCT)lParam);
  681.             return TRUE;
  682.             break;
  683.  
  684.         case WM_CREATE:
  685.             /* Create the menu */
  686.             HandleCreate (hWnd);
  687.             break;
  688.  
  689.         case WM_DESTROY:
  690.             /* Delete the on/off bitmaps so that they don't waste memory. */
  691.             DeleteObject (hbmCheckOn);
  692.             DeleteObject (hbmCheckOff);
  693.  
  694.             PostQuitMessage (0);
  695.             break;
  696.  
  697.         case WM_LBUTTONDOWN:
  698.             /* Draw the "floating" popup in the app's client area */
  699.             GetClientRect (hWnd, (LPRECT)&rc);
  700.  
  701.             // Temporary porting macro
  702.             LONG2POINT(lParam, pt);
  703.             if (PtInRect ((LPRECT)&rc, pt))
  704.                 HandlePopupMenu (hWnd, pt);
  705.             break;
  706.  
  707.         default:
  708.             return DefWindowProc(hWnd, message, wParam, lParam);
  709.     }
  710.     return(0);
  711. }
  712.