Using MFC Menu Update Handlers

Your application needs to enable and disable menu items at appropriate times to let the user know which commands are available in any given context. In C-language applications for Windows, it's fairly typical to update the state of all menu items in a single message handler. For example, in response to the WM_INITMENU message, SHOWDIB executes eighteen lines like the following line for the Edit Copy menu item:


... EnableMenuItem(wParam, IDM_COPY, bLegitDraw ? MF_ENABLED : MF_GRAYED); ...

You saw this code in Handling Messages Not Sent to the View. Except for a difference in command IDs, this code can be replaced by an MFC update handler like the following:


void CScribDoc::OnUpdateEditCopy(CCmdUI* pCmdUI) { pCmdUI->Enable(bLegitDraw ? MF_ENABLED : MF_GRAYED); }

The code uses the same Boolean condition as the C version, but it makes the Boolean test in a call to the Enable member function of a CCmdUI object that MFC has attached to the ID_EDIT_COPY command. The bLegitDraw variable must be visible.

Tip In MFC version 3.0, you can update multiple command IDs with a single handler by specifying a range of contiguous IDs. For more information, see the article "Message Maps: Ranges of Messages" in Part 2 of Programming with the Microsoft Foundation Class Library (Visual C++ 2.0).

The MFC approach lets the framework manage the timing and complexity of keeping menus up to date. Although you now won't be able to find all such code in one place, you can easily get to the appropriate update handler for a command through ClassWizard's Edit Code button. The greatest advantage is that the same update handler that updates the menu item also updates the corresponding toolbar button if you have one. This works because both the menu item and the toolbar button have the same command ID.

Þ To add an update handler

1. Open ClassWizard, select the class you want to create a handler in, and specify the command ID that the handler is to update.

ClassWizard creates a prototype for the handler function in the class declaration. It also creates the shell of the handler function, complete with the correct parameter signature.

2. Move your code for that menu command into the handler.

In most cases, you can use the same Boolean expression you used when calling EnableMenuItem.

For SHOWDIB, you would move the code now found in CMainFrame::WindowProc into update handlers, then delete the WindowProc function in CMainFrame.

Note When you begin to update menus this way, remove the line of code that disables the MFC update mechanism in CFrameWnd::CFrameWnd (MAINFRM.CPP):

CMainFrame::CMainFrame()
{
// m_bAutoMenuEnable = FALSE; // bypass MFC menu enabling mechanism
}