Using Owner-Draw Menus

Your application can take complete control over the appearance of menu items by using owner-draw menu items. An owner-draw menu item is a menu for which the application has total responsibility for drawing the item in its normal, selected (highlighted), checked, and unchecked states.

For example, suppose your application provides a menu that allows the user to select a font. Your application could draw each menu item using the font that the menu item represents: the item for roman would be drawn with a roman font, the item for italic would be drawn in italic, and so on.

You cannot define an owner-draw menu item in your application's resource-script (.RC) file. Instead, you must create a new menu item or modify an existing menu item with the MF_OWNERDRAW menu flag. You can use any of the following functions to specify an owner-draw menu item:

AppendMenu

InsertMenu

ModifyMenu

When you call any of these functions, you can pass a 32-bit value as the lpNewItem parameter. This 32-bit value can represent any information that is meaningful to your application, and will be available to your application when the menu item is to be displayed. For example, the 32-bit value could contain a pointer to a data structure; the data structure, in turn, might contain a string and the handle of a logical font that your application will use to draw the string.

Before Windows displays an owner-draw menu item for the first time, it sends the WM_MEASUREITEM message to the window that owns the menu. This message's lParam parameter points to a MEASUREITEMSTRUCT data structure that identifies the menu item and contains the optional 32-bit value for the item. When your application receives the WM_MEASUREITEM message, it must fill in the itemWidth and itemHeight fields of the data structure before returning from processing the message. Windows uses the information in these fields when creating the bounding rectangle in which your application draws the menu item; it also uses the information to detect the user's interaction with the item.

When the item needs to be drawn (for example, when it is first displayed, or when the user chooses it), Windows sends the WM_DRAWITEM message to the window that owns the menu. The lParam parameter of the WM_DRAWITEM message points to a DRAWITEMSTRUCT data structure. Like MEASUREITEMSTRUCT, the DRAWITEMSTRUCT data structure contains identifying information about the menu item and its optional 32-bit data. In addition, DRAWITEMSTRUCT contains flags that indicate the state of the item (such as grayed or checked) as well as a bounding rectangle and device context with which your application will draw the item.

In response to the WM_DRAWITEM message, your application must perform the following actions before returning from processing the message:

1.Determine the type of drawing that is needed. To do so, check the itemAction field of the DRAWITEMSTRUCT data structure.

2.Draw the menu item appropriately, using the rectangle and device context obtained from the DRAWITEMSTRUCT data structure. Your application must draw only within the bounding rectangle. For performance reasons, Windows does not clip portions of the image that are drawn outside the rectangle.

3.Restore all GDI objects selected for the menu item's device context.

For example, if the menu item is selected, Windows sets the itemAction field of the DRAWITEMSTRUCT data structure to ODA_SELECT, and sets the ODS_SELECTED bit in the itemState field. This is your application's cue to redraw the menu item so that the item indicates that it has been selected.