Owner-drawn context menu in WTL
In this article, I’ll show you how to implement an owner-drawn context menu and how to add cool-looking menus to your application real easy using my class CCoolContextMenu.
In order to make an item an owner-drawn item, you must create a new menu item, or modify an existing one by setting the MFT_OWNERDRAW menu flag.
You can use the InsertMenuItem or SetMenuItemInfo functions to set or change information about a menu item. When calling these two functions, you must specify a pointer to a MENUITEMINFO structure, which specifies the properties of the menu item.
You need to specify the MFT_OWNERDRAW value for the fType member for an item to become an owner-drawn item. You can also associate an application-defined value, which is called item data, with each menu item. The CCoolContextMenu class defines the MenuItemData structure that contains information used to draw a menu item. The application uses the dwItemData member to store a pointer to this structure.
The MenuItemData structure is sent to the menu's owner window with the WM_MEASUREITEM and WM_DRAWITEM messages. The GetMenuItemInfo function is used to retrieve the item data for a menu at any time.
How to use it
To use the CCoolContextMenu class, all you have to do is to derive your class from CCoolContextMenu and follow the next few steps:
class CCoolEdit : public CWindowImpl<CCoolEdit, CRichEditCtrl>,
public CRichEditCommands<CCoolEdit>,
public CCoolContextMenu<CCoolEdit>
In the message map use CHAIN_MSG_MAP to redirect messages to CCoolContextMenu's message map:
BEGIN_MSG_MAP(CCoolEdit)
...
CHAIN_MSG_MAP(CCoolContextMenu<CCoolEdit>)
END_MSG_MAP()
In the OnInitDialog() function of your dialog class, or in the OnCreate() function of the window class, call the GetSystemSettings() method of CCoolContextMenu:
LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL&)
{
...
GetSystemSettings();
...
}
But what about images? Just create the image list and implement the AssociateImage(CMenuItemInfo& mii, MenuItemData * pMI) function in your CCoolContextMenu derived class:
void AssociateImage(CMenuItemInfo& mii, MenuItemData * pMI)
{
switch (mii.wID)
{
case ID_EDIT_UNDO:
pMI->iImage = 17;
break;
case ID_EDIT_CUT:
pMI->iImage = 3;
break;
case ID_EDIT_COPY:
pMI->iImage = 4;
break;
case ID_EDIT_PASTE:
pMI->iImage = 5;
break;
case ID_EDIT_CLEAR:
pMI->iImage = 20;
break;
default:
pMI->iImage = -1;
break;
}
}