If necessary, your application can initialize a menu before Windows displays that menu. Although you can specify a menu item's initial state (disabled, grayed, or checked) in the resource script file, this method doesn't work if the initialization differs from time to time. For example, to disable the Print menu item only if the user's system has no printer installed, you could disable the Print item when you initialize that menu. (Disabling the Print menu item in the .RC file wouldn't work, since you won't know whether or not there's a printer available until the application is running.)
Just before Windows displays a menu, it sends a WM_INITMENU message to the window function for the window that owns that menu. This lets the window function 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 command based on the value of the wChecked variable:
WORD wChecked = IDM_LEFT;
.
.
.
1 case WM_INITMENU:
2 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:
1 | The WM_INITMENU message passes the given menu handle in the wParam message parameter. |
2 | To make sure that Windows is about to display the correct menu, the GetMenu function retrieves a handle to 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 commands in the menu. |