有人遇到过这个问题吗?
我在MDI应用程序上使用MFC。我使用SetMenu()在菜单之间切换,但是当我最大化子窗口时,系统菜单(最大化,最小化,关闭按钮)的副作用消失了。
CMenu* pMenu = GetMenu();
if (pMenu == NULL) return;
pMenu->Detach();
// Reset application menu
CMenu newMenu;
newMenu.LoadMenu(menuID);
SetMenu(&newMenu);
如果我不调用SetMenu(),则不会发生此问题。
答案 0 :(得分:2)
CMenu newMenu; newMenu.LoadMenu(menuID); SetMenu(&newMenu);
newMenu
是一个临时对象。该函数退出后将立即销毁它。结果是未定义的行为。
CMenu* pMenu = GetMenu(); if (pMenu == NULL) return; pMenu->Detach();
我不确定这段代码将完成什么。请注意,CWnd::SetMenu
将替换旧菜单。它不会破坏旧的菜单句柄,但是MFC会在最后进行清理(Detach
不会破坏该句柄)
将菜单对象声明为类成员:
class CMainFrame : public CMDIFrameWnd
{
CMenu m_menu1, m_menu2;
...
};
一次加载菜单:
CMainFrame::CMainFrame()
{
m_menu1.LoadMenu(IDR_MENU1);
m_menu2.LoadMenu(IDR_MENU2);
...
}
更改菜单:
void CMainFrame::OnChangeMenu()
{
if(want_menu1)
{
SetMenu(&m_menu1);
}
else if (want_menu2)
{
SetMenu(&m_menu2);
}
}
答案 1 :(得分:1)
我建议采取其他措施:只需使用MFC最初打算的菜单管理功能即可。对于典型的MDI MFC应用程序,您实际上不需要对菜单做任何事情(我的意思是这些对SetMenu()
的调用)。仅定义它们,MFC就会为您完成其余的工作。
更具体地说,向导生成的MDI应用程序包含以下菜单:
IDR_MAINFRAME
,当不存在MDI子窗口(打开的文档)时将显示。通常包含 File , View 和 Help 子菜单。IDR_DocType
,用于您定义的每种文档类型。当显示此类文档的MDI子窗口为活动窗口时,将显示该窗口。通常包含文件,编辑,视图,窗口和 Help 子菜单。请注意:
IDR_MAINFRAME
或IDR_DocType
中的一个,具体取决于当前活动的MDI子窗口。IDR_MAINFRAME
的 View 子菜单通常包含两个菜单项,即 Toolbar (或 Toolbars )和状态栏(切换工具栏和状态栏的显示),而特定于doctype的文档通常包含以上内容,另外还包含一些其他内容,以确定如何显示文档;例如,如果文档是图像,则通常会添加一些显示选项,例如 1:1 ,适合宽度,适合高度和< em>最适合(在单选按钮设置中),显示在工具栏和状态栏上方,并用分隔符菜单项分隔。
我已经开发了许多这样的应用程序,而不必使用SetMenu()
。我建议您首先将IDR_MAINFRAME
和IDR_DocType
菜单恢复到其原始状态,然后再放入其他/自定义菜单。如果您破坏或更改了向导最初生成的菜单,则可以使用与您的设置相同的设置创建一个新的MFC项目/解决方案,然后将菜单复制粘贴到资源文件中。