1.2.19 Menus

A menu is a list of commands from which the user can select using the mouse or the keyboard. When the user selects an item, Windows sends a corresponding message to the window function to indicate which command was selected. Windows provides two types of menus: menu bars (sometimes called static menus) and pop-up menus.

A menu bar is a horizontal menu that appears at the top of a window and below the title bar, if one exists. Any window except a child window can have a menu bar. If an application does not specify a menu when it creates a window, the window receives the default menu bar (if any) defined by the window class.

Pop-up menus contain a vertical list of items and are often displayed when a user selects a menu-bar item. In turn, a pop-up menu item can display another pop-up menu. Also, a pop-up menu can be “floating.” A floating pop-up menu can appear anywhere on the screen designated by the application. An application creates an empty pop-up menu by calling the CreatePopupMenu function, and then fills in the menu using the AppendMenu and InsertMenu functions. It displays the pop-up menu by calling TrackPopupMenu.

Individual menu items can be created or modified with the MF_OWNERDRAW style, indicating that the item is an owner-draw item. In this case, the owner of the menu is responsible for drawing all visual aspects of the menu item, including checked, grayed, and highlighted states. When the menu is displayed for the first time, the window that owns the menu receives a WM_MEASUREITEM message. The lParam parameter of this message points to a MEASUREITEMSTRUCT data structure. The owner then fills in this data structure with the dimensions of the item and returns. Windows uses the information in the data structure to determine the size of the item so that Windows can appropriately detect the user's interaction with the item.

Windows sends the WM_DRAWITEM message whenever the owner of the menu must update the visual appearance of the item. Unlike other owner-draw controls, however, the owner of the menu item does not receive the WM_DELETEITEM message when the menu item is removed from the menu. A top-level menu item cannot be an owner-draw item.

When the application calls AppendMenu, InsertMenu, or ModifyMenu to add an owner-draw menu item to a menu or to change an existing menu item to be an owner-draw menu item, the application can supply a 32-bit value as the lpNewItem parameter to the function. The application can use this value to maintain additional data associated with the item. This value is available to the application as the itemData field of the structures pointed to by the lParam parameter of the WM_MEASUREITEM and WM_DRAWITEM messages. For example, if an application were to draw the text in a menu item using a specific color, the 32-bit value could contain a pointer to a string. The application could then set the text color before drawing the item when it received the WM_DRAWITEM message.