是否可以操作我的CMDIFrameWndEx的CMFCMenuBar菜单?

时间:2010-10-11 17:44:41

标签: c++ mfc dynamic menu mfc-feature-pack

我的主框架有一个CMFCMenuBar成员,它包含当前文档类型的菜单。 我想动态添加/删除子菜单。 例如,如果用户选择显示地图窗格,我想在“文件”菜单旁边添加地图子菜单。

反之亦然,如果地图窗格关闭,我还想删除地图菜单项。

有一件事可行,但我不喜欢的是简单地禁用ON_UPDATE_COMMAND_UI处理程序中的菜单项。
Frame有一个名为GetMenuBar()的方法,但是那个给我一个const CMFCMenuBar *,所以我不能从外面修改它。我添加了一个getter,所以我得到了一个非const引用菜单栏,但这也没有用:

CMenu menu;
VERIFY(menu.LoadMenu(IDR_MAP));
CMFCMenuBar & menuBar = pFrm->GetNonConstMenuBar(); // Custom getter
menuBar.InsertButton(CMFCToolBarMenuButton(0, menu, -1));
menuBar.AdjustLayout();
menuBar.AdjustSizeImmediate();

以上代码是void CMyMenuBar::AddSubMenu ()样本中DynamicMenu的修改。 我感觉这个样本已被破坏,因为我无法确定是否或何时执行该特定代码。在示例中,代码仅在菜单栏被重置时执行或者尚未将任何州保存到注册表中。

这是不可能还是我做错了什么?

添加/删除子菜单会有不错的选择吗?

1 个答案:

答案 0 :(得分:4)

执行此操作的一种方法是处理WM_INITMENUPOPUP消息。在显示菜单之前,将使用指向菜单的指针调用OnInitMenuPopup

请注意,每次弹出菜单时都会调用此方法,并且您在调用之间所做的任何更改都会丢失(每次调用OnInitMenuPopup时都必须添加菜单项。)

使用它的技巧是弄清楚如何识别已调用的菜单。一种方法是比较已知项目的菜单项ID。例如,如果菜单上的第一项是ID_FILE_OPEN,则可以查找该项。如果找到,您会认为您的“文件”菜单是正在打开的菜单,您可以添加自定义子菜单。

可能您也可以使用dwMenuData结构的MENUINFO成员,但由于CMFCMenuBar构建菜单的方式,我似乎记得有问题。