For most Windows-based applications, a menu bar is a part
of the user interface. The menu bar provides a functionality summary for the
person using the program. However, it is not required that every Windows-based
application must contain a menu bar. This article describes how to create an
MFC application that does not have a menu bar.
For Windows-based
applications generated by AppWizard, the IDR_MAINFRAME menu resource is the
standard menu resource for both SDI and MDI applications. It is the only menu
resource for an SDI application. MDI applications contain additional menus for
each type of MDI child window they support. Those menu resources are usually
named IDR_xxxTYPE, where xxx is related to the name of the corresponding
document type. Thus, creating an application with no menus is not as easy for
an MDI application as for an SDI application. You basically have to modify all
functions related to loading and switching menus.
Steps to Create SDI Application that Has No Menu Bar
- Generate an SDI application with AppWizard. Do not delete
the IDR_MAINFRAME menu resource. If you have an application that was not
generated with AppWizard, do not delete the corresponding main menu resource.
Leaving the menu resource is required to avoid assertion failures in the MFC
code.
- To prevent the main application window from having a menu
bar, delete the already loaded menu, and set the hMenu field of the
CREATESTRUCT structure to NULL in the CFrameWnd::PreCreateWindow() function:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if(cs.hMenu!=NULL)
{
::DestroyMenu(cs.hMenu); // delete menu if loaded
cs.hMenu = NULL; // no menu for this window
}
return CFrameWnd::PreCreateWindow(cs);
}
Steps to Create MDI Application that Has No Menu Bar
- Generate an MDI application with AppWizard. Do not delete
the IDR_MAINFRAME menu resource. If you have an application that was not
generated with AppWizard, do not delete the corresponding main menu resource.
Leaving the menu resource is required to avoid assertion failures in the MFC
code.
- Delete menu resources associated with MDI child windows
(IDR_xxxTYPE). They are not used. By deleting them, you avoid a resource
(memory) leak.
- Override the PreCreateWindow() function for the CMainFrame
class:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if(cs.hMenu!=NULL)
{
::DestroyMenu(cs.hMenu); // delete menu if loaded
cs.hMenu = NULL; // no menu for this window
}
return CMDIFrameWnd::PreCreateWindow(cs);
}
- Modify the code responsible for switching menus by
overriding the LoadFrame() and OnCreateClient() methods of CMainFrame. This is
necessary because MFC has already loaded and switched menus automatically. The
following shows what must be done:
// Overridden method declarations for CMainFrame
BOOL LoadFrame( UINT nIDResource,
DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,
CWnd* pParentWnd = NULL, CCreateContext* pContext = NULL );
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs,
CCreateContext* /*pContext*/);
// Overridden method declarations for CMainFrame
BOOL CMainFrame::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle,
CWnd* pParentWnd, CCreateContext* pContext)
{
return CFrameWnd::LoadFrame(nIDResource,dwDefaultStyle,
pParentWnd,pContext);
}
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs,
CCreateContext* /*pContext*/)
{
return CreateClient(lpcs,NULL);
}
NOTE: Instead of calling the base class (CMDIFrameWnd) in the override
of LoadFrame, you call its base class, CFrameWnd, instead. That way you can
avoid the code that deals with MDI menus.