MFC菜单打开标签页动态菜单
MFC menus Open tabs dynamic menu
我正在使用 MFC 应用程序,想删除显示在“排列图标”下的动态条目。
我不确定这是如何添加到应用程序中的,或者我该如何关闭它?
打开 windows 的列表由 MFC 框架添加到“Window”菜单,在 WM_INITMENUPOPUP
命令的应用程序主 window 处理程序中。 (实际上,框架将项目添加到所有已经包含 ID 介于 AFX_IDM_WINDOW_FIRST
和 AFX_IDM_WINDOW_LAST
之间的命令的菜单 - 其中包括“Cascasde”、“Tile...”和“Arrange Icons”默认值。)
您可以通过将 ON_WM_INITMENUPOPUP()
处理程序添加到框架 window 的消息映射并覆盖该框架的 OnInitMenuPopup()
member function.
来删除这些项目
假设您的主框架派生自 CMDIFrameWnd
class,此覆盖将如下所示:
void MyFrameWnd::OnInitMenuPopup(CMenu *pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
CMDIFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);// Call base class FIRST
// <Insert any other code for your override>
UINT commID = AFX_IDM_FIRST_MDICHILD; // MFC gives the first item this ID
BOOL hadID;
do {
hadID = pPopupMenu->RemoveMenu(commID, MF_BYCOMMAND);
++commID;
} while (hadID);
return;
}
你的 class 中函数的 声明 应该正确地具有 afx_msg
属性,如下所示,虽然这通常被定义为 'nothing' 在最近的 MFC 版本中:
class MyFrameWnd : public CMDIFrameWnd
{
//...
protected:
afx_msg void OnInitMenuPopup(CMenu *pPopupMenu, UINT nIndex, BOOL bSysMenu);
//...
如果您更喜欢这样的压缩代码,您还可以将删除 'loop' 代码减少到以下单行:
for (UINT commID = AFX_IDM_FIRST_MDICHILD; Menu->RemoveMenu(commID, MF_BYCOMMAND); ++commID) ; // Empty loop
请注意,此删除过程会在您应用程序的“Window”菜单底部留下一个 'separator';删除它也会涉及更多的工作,因为该分隔符没有命令 ID – 因此您需要确定它在菜单中的位置(索引)并使用该索引调用 RemoveMenu()
函数,并且MF_BYPOSITION
标记为第二个参数。
使用第一个代码段中的代码,并假设分隔符位于菜单的最后,这可以通过在删除循环之后添加以下代码来实现:
if (commID > AFX_IDM_FIRST_MDICHILD + 1) { // We removed at least one item, so ...
int nItems = Menu->GetMenuItemCount(); // ... remove the separator,
pPopupMenu->RemoveMenu(nItems - 1, MF_BYPOSITION); // assuming it's the last item!
}
我正在使用 MFC 应用程序,想删除显示在“排列图标”下的动态条目。
我不确定这是如何添加到应用程序中的,或者我该如何关闭它?
打开 windows 的列表由 MFC 框架添加到“Window”菜单,在 WM_INITMENUPOPUP
命令的应用程序主 window 处理程序中。 (实际上,框架将项目添加到所有已经包含 ID 介于 AFX_IDM_WINDOW_FIRST
和 AFX_IDM_WINDOW_LAST
之间的命令的菜单 - 其中包括“Cascasde”、“Tile...”和“Arrange Icons”默认值。)
您可以通过将 ON_WM_INITMENUPOPUP()
处理程序添加到框架 window 的消息映射并覆盖该框架的 OnInitMenuPopup()
member function.
假设您的主框架派生自 CMDIFrameWnd
class,此覆盖将如下所示:
void MyFrameWnd::OnInitMenuPopup(CMenu *pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
CMDIFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);// Call base class FIRST
// <Insert any other code for your override>
UINT commID = AFX_IDM_FIRST_MDICHILD; // MFC gives the first item this ID
BOOL hadID;
do {
hadID = pPopupMenu->RemoveMenu(commID, MF_BYCOMMAND);
++commID;
} while (hadID);
return;
}
你的 class 中函数的 声明 应该正确地具有 afx_msg
属性,如下所示,虽然这通常被定义为 'nothing' 在最近的 MFC 版本中:
class MyFrameWnd : public CMDIFrameWnd
{
//...
protected:
afx_msg void OnInitMenuPopup(CMenu *pPopupMenu, UINT nIndex, BOOL bSysMenu);
//...
如果您更喜欢这样的压缩代码,您还可以将删除 'loop' 代码减少到以下单行:
for (UINT commID = AFX_IDM_FIRST_MDICHILD; Menu->RemoveMenu(commID, MF_BYCOMMAND); ++commID) ; // Empty loop
请注意,此删除过程会在您应用程序的“Window”菜单底部留下一个 'separator';删除它也会涉及更多的工作,因为该分隔符没有命令 ID – 因此您需要确定它在菜单中的位置(索引)并使用该索引调用 RemoveMenu()
函数,并且MF_BYPOSITION
标记为第二个参数。
使用第一个代码段中的代码,并假设分隔符位于菜单的最后,这可以通过在删除循环之后添加以下代码来实现:
if (commID > AFX_IDM_FIRST_MDICHILD + 1) { // We removed at least one item, so ...
int nItems = Menu->GetMenuItemCount(); // ... remove the separator,
pPopupMenu->RemoveMenu(nItems - 1, MF_BYPOSITION); // assuming it's the last item!
}