When a user chooses a menu item in a Windows program, the system sends a WM_COMMAND message to the frame window that contains the menu bar. The arguments that are sent with the WM_COMMAND message contain a menu-item ID number. The ID number is the same as defined in the resource definition file (.RC). In the Microsoft Foundation Class Library, you typically define one messagehandler function for each menu item that your window supports. You associate these message-handler functions with specific menu-item ID numbers by defining a message map, as explained below.
·To handle menu-command messages:
1.Define one message-handler function for each menu item. For example, if your menu includes two items, Open and Save, with the ID numbers IDM_OPEN and IDM_SAVE, you would declare your window class as follows:
class CMyWnd : public CFrameWnd
{
// constructor not shown...
public:
afx_msg void OnOpen();
afx_msg void OnSave();
DECLARE_MESSAGE_MAP()
};
Note:
The declaration of all message-handler functions should use the afx_msg prefix to show that they will be called through the message-map mechanism, although the prefix is not required.
Notice that message-handler functions for menu commands have no arguments and return no value. Since they are member functions of the window class, they have access to the other member functions and member variables of the window object to get the information they need to perform their task.
Notice also the DECLARE_MESSAGE_MAP macro in the class declaration. This macro is required to enable the message-map mechanism for the class.
2.Once the message-handler functions are defined and the message map enabled by the DECLARE_MESSAGE_MAP macro, define the message map itself to indicate which message-handler functions are to be associated with which messages, as follows:
BEGIN_MESSAGE_MAP( CMyWnd, CFrameWnd )
ON_COMMAND( IDM_OPEN, OnOpen )
ON_COMMAND( IDM_SAVE, OnSave )
END_MESSAGE_MAP()
The BEGIN_MESSAGE_MAP macro has two arguments: the name of the derived class and the name of the base class. The ON_COMMAND message- map entry macro takes the ID number of the menu item and a pointer to the member function (the function pointer is produced by simply using the name of the function). Finally, the END_MESSAGE_MAP macro has no arguments.
The above message map directs the window procedure for the base window class to call the derived window class member function OnOpen (which you must define) when the window receives a WM_COMMAND menu message where wParam is equal to IDM_OPEN. Likewise, the IDM_SAVE menu command is associated with the OnSave function. Other menu item commands can be associated with other message-handler member functions in a similar manner. The message map shown above is equivalent to the following switch statement in a traditional window procedure:
switch( msg )
{
case WM_COMMAND:
{
if( LOWORD( lParam ) == 0 )
{
switch( wParam )
{
case IDM_OPEN:
DoOpen();
break;
case IDM_SAVE:
DoSave();
break;
default:
return FALSE;
}
}
break;
}
default:
return FALSE;
}
The message-map definition macros (eg. BEGIN_MESSAGE_MAP) for a particular class should be evaluated only one time during a compilation; thus they typically appear in the implementation file (.CPP) for your window class rather than in the interface file (.H).
The next section shows how to use the message-map mechanism to respond to notification messages from child windows.