以"mdi frame 不显示菜单"等关键字搜索,可以找到很多文章,多是以重载特定方法如OnCreate() LoadFrame() PreCreateWindow()等方式实现,主要思路是截断虚函数的调用路径,防止MFC源码中的一些默认判断和逻辑弹出ASSERT错误。但遗憾的是我使用了几个文章中的方法,在VS2015中都不奏效,且感觉这些方式也并不优雅。于是阅读了MFC中的有关代码,并最终找到答案。
在基类CFrameWnd中有一个变量:m_dwMenuBarState。该变量可以控制对Menu的显示与隐藏!在MFC源码winfrm.cpp中:
BOOL CFrameWnd::SetMenuBarState(DWORD dwState)
{
ENSURE_ARG(dwState == AFX_MBS_VISIBLE ||
dwState == AFX_MBS_HIDDEN);
if (m_dwMenuBarState == dwState)
{
return FALSE;
}
if (dwState == AFX_MBS_VISIBLE)
{
OnShowMenuBar();
::SetMenu(m_hWnd, m_hMenu);
}
else
{
m_hMenu = ::GetMenu(m_hWnd);
OnHideMenuBar();
::SetMenu(m_hWnd, NULL);
}
m_dwMenuBarState = dwState;
return TRUE;
}
因此在MFC wizard生成的代码MainFrm.cpp中,添加对上述接口的调用即可隐藏菜单:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIFrameWndEx::OnCreate(lpCreateStruct) == -1)
return -1;
SetMenuBarState(AFX_MBS_HIDDEN);
......
}