系统菜单消失时,我最大的一个子窗口

问题描述 投票:0回答:2

有没有人遇到过这个问题?

我使用的MDI应用MFC。我使用的SetMenu()切换菜单,但有系统菜单的副作用(最大化,最小化,关闭按钮)消失时,我最大限度的子窗口。

CMenu* pMenu = GetMenu();
if (pMenu == NULL) return;
pMenu->Detach();

// Reset application menu
CMenu newMenu;
newMenu.LoadMenu(menuID);
SetMenu(&newMenu);

如果我不叫的SetMenu(),这个问题不会发生。

c++ mfc mdi cview
2个回答
2
投票
CMenu newMenu;
newMenu.LoadMenu(menuID);
SetMenu(&newMenu);

newMenu是临时对象。将尽快函数退出销毁。其结果是不确定的行为。

CMenu* pMenu = GetMenu();
if (pMenu == NULL) return;
pMenu->Detach();

我不知道这是什么代码将完成。需要注意的是CWnd::SetMenu将取代旧的菜单。它不会破坏旧菜单句柄,但MFC将负责清理在年底(Detach不会破坏把手,如果这是目标)


Try this code instead:

声明菜单对象作为类成员:

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
投票

我会推荐不同的东西:只需使用菜单管理功能最初是由MFC打算。对于典型的MDI MFC应用程序,你真的不需要做任何事情的菜单(我的意思是这些调用SetMenu())。只定义他们,MFC将完成剩下的为您服务。

更具体地,向导生成MDI应用程序包含以下菜单:

  • IDR_MAINFRAME,当不存在MDI子窗口(打开的文档),它会显示出来。通常包含的文件,查看和帮助子菜单。
  • IDR_DocType,一个已定义的每个文档类型。当显示这种类型的文档的MDI子窗口是活动一个时显示。通常包含文件,编辑,查看,窗口和帮助子菜单。

请注意:

  • 你只需要定义/编辑这些菜单,比如添加更多命令,甚至更多的子菜单。你并不需要切换菜单,框架会为你做这个。
  • 该框架将不会合并子菜单或菜单项,这反而只要选择IDR_MAINFRAMEIDR_DocType者之一,这取决于MDI子窗口目前活跃。
  • 因此,一些子菜单或项目可能是重复的(虽然不一定精确副本),有些则没有。例如,对于IDR_MAINFRAME视图子菜单通常包含两个菜单项,工具栏(或工具栏)和状态栏(切换工具栏和状态栏中的显示),而特定的文档类型酮典型地含有上述以外,再加上一些附加的,确定如何显示该文件;例如,如果该文件是一个图像,则通常会增加一些显示选择像1:1,适合宽度,适合高度和最佳拟合(在无线电按钮设置),上述工具栏和状态栏那些所示,用分离分隔符菜单项。

我已经开发了很多这样的应用,并且从未使用过SetMenu()。我建议你先恢复IDR_MAINFRAMEIDR_DocType菜单到其原始状态,然后把任何额外/自定义的。如果你已经破坏或改变显著最初由向导生成的菜单,你可以创建一个具有相同的设置你的一个新的MFC项目/解决方案,并在资源文件复制粘贴菜单。

© www.soinside.com 2019 - 2024. All rights reserved.