How to Use Multiple Menus in MFC App That Uses GetDefaultMenu This article was written about products for which Microsoft no longer offers support. Therefore, this article is offered "as is" and will no longer be updated.
This article was previously published under Q145857 SUMMARY
In an MFC application, you may occasionally find it useful to switch
between menus within the same frame window, such as when using static
splitter windows or objects in a view requiring a whole new menu. Because
the framework provides automatic support for only one menu per document
template (hence per frame), additional code must be added to switch
automatically between multiple menu resources. MFC provides the
undocumented virtual function CDocument::GetDefaultMenu() to allow the
document to determine which menu to display.
MORE INFORMATION
When AppWizard generates an SDI or MDI application, it creates a menu
resource by using IDR_MAINFRAME as its resource ID. This menu is displayed
at all times for an SDI application and only when there are no active
documents in an MDI application. For an MDI application, AppWizard also
generates a menu resource for the one multidoc template it creates using
IDR_xxxxTYPE as its resource ID. Additional menu resources can be used by
creating them using the resource editor and associating them with another
multidoc template (see CMultiDocTemplate). The framework will display the
menu resource associated with each multidoc template automatically. This
method limits you one menu per document template. To bypass this
limitation, you can override CDocument::GetDefaultMenu() and perform some
calls to display the menu. MFC uses CMDIChildWnd::m_hMenuShared and CFrameWnd::m_hMenuDefault data members to determine which menu to display. In an MDI application, the menu resource associated with each document template is loaded during the construction of the document templates and copied into CMDIChildWnd::m_hMenuShared. This menu is then used in CMDIChildWnd::OnUpdateFrameMenu() to set the menu of the MDI Frame window when there is an active MDI child window. CMDIChildWnd::OnUpdateFrameMenu() uses CFrameWnd::m_hMenuDefault, which is loaded during CFrameWnd construction using IDR_MAINFRAME when there are no active child windows. An SDI program calls CFrameWnd::OnUpdateFrameMenu(), which uses CFrameWnd::m_hMenuDefault for its menu. In both an SDI and MDI application, the menu you need to display is obtained from two other sources before using the m_hMenuShared or m_hMenuDefault menus. The framework first checks CFrameWnd::m_hMenuAlt. This is used in OLE supported programs with in-place activated objects that provide its own menus. The second source it checks is CDocument::GetDefaultMenu(), which is also virtual. The default implementation of it is to return NULL. This function can be overridden to allow the program to select the menu to display. Changing the menus manually is done by calling OnUpdateFrameMenu() and DrawMenuBar(). You must call CFrameWnd::OnUpdateFrameMenu(NULL) or CMDIFrameWnd::OnUpdateFrameMenu(NULL) in order to set the new menu into the window. Call DrawMenuBar() to redraw the menu. Use the following code to implement for both MDI and SDI:
Menus can also be switched simply by changing the value of CMDIChildWnd::m_hMenuShared (MDI) or CFrameWnd::m_hMenuDefault (SDI). However, using GetDefaultMenu() allows a safer method of changing the menus. For more information about how to share menus between MDI child windows, please see the following article in the Microsoft Knowledge Base: 118435 (http://support.microsoft.com/kb/118435/EN-US/) Sharing Menus Between MDI Child Windows. REFERENCES
MFC Source Code.
APPLIES TO
| Article Translations
| ||||||||||||||||||||||||||||||||||||||||||||


Back to the top
