7.5.9 Initializing Menus

Your application can, if necessary, initialize a menu before Windows displays the menu. Although you can specify a menu item's initial state (disabled, grayed, or checked) in the resource-definition file, this method does not work if the initialization differs from time to time. For example, to disable the Print command only if the user's system has no printer installed, you could disable the Print item when you initialize its menu. (Disabling the Print item in the .RC file would not work, since the application cannot determine whether a printer is available until the application is running.)

Just before Windows displays a menu, it sends a WM_INITMENU message to the window procedure for the window that owns that menu. This enables the window procedure to check the state of the menu items and, if necessary, modify them before Windows displays the menu. In the following example, the window function processes the WM_INITMENU message and sets the state of a menu item, based on the value of the wChecked variable:

WORD wChecked = IDM_LEFT;
    .
    .
    .

case WM_INITMENU:
    if (GetMenu(hWnd) != wParam)
        break;
    CheckMenuItem(wParam, IDM_LEFT,
        IDM_LEFT == wChecked ? MF_CHECKED : MF_UNCHECKED);
    CheckMenuItem(wParam, IDM_CENTER,
        IDM_CENTER == wChecked ? MF_CHECKED : MF_UNCHECKED);
    CheckMenuItem(wParam, IDM_RIGHT,
        IDM_RIGHT == wChecked ? MF_CHECKED : MF_UNCHECKED);
    break;

In this example, the WM_INITMENU message passes the given menu handle in the wParam message parameter.

To ensure that Windows is about to display the correct menu, the GetMenu function retrieves a handle of the current window's menu and compares that handle with the value of wParam. If these are not equal, the window's menu should not be initialized. Otherwise, the menu is correct and you can use the CheckMenuItem function to initialize the items in the menu.