Visual c++ 当从应用程序主菜单栏中的弹出菜单工具栏按钮调用OnInitMenuOpup时,OnInitMenuOpup无法正确初始化
要缩短长历史记录,请设想我的主菜单是一个CMFCMenuBar,该菜单由以下内容定义:Visual c++ 当从应用程序主菜单栏中的弹出菜单工具栏按钮调用OnInitMenuOpup时,OnInitMenuOpup无法正确初始化,visual-c++,mfc,toolbar,popupmenu,mfc-feature-pack,Visual C++,Mfc,Toolbar,Popupmenu,Mfc Feature Pack,要缩短长历史记录,请设想我的主菜单是一个CMFCMenuBar,该菜单由以下内容定义: IDR_MAINFRAME MENU BEGIN POPUP "&File" BEGIN MENUITEM "New", ID_FILE_NEW MENUITEM "Open", ID_FILE_OPEN MENUITEM "Save", ID_FILE_SA
IDR_MAINFRAME MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "New", ID_FILE_NEW
MENUITEM "Open", ID_FILE_OPEN
MENUITEM "Save", ID_FILE_SAVE
POPUP "Save As"
BEGIN
MENUITEM "Format XXX", ID_FILE_SAVEAS_XXX
MENUITEM SEPARATOR
MENUITEM "Format YYY", ID_FILE_SAVEAS_YYY
MENUITEM SEPARATOR
MENUITEM "Format ZZZ", ID_FILE_SAVEAS_ZZZ
MENUITEM "Format WWW", ID_FILE_SAVEAS_WWW
END
MENUITEM "Close", ID_FILE_CLOSE
END
POPUP "&Object"
BEGIN
POPUP "Create object"
BEGIN
MENUITEM "Create object...", ID_CREATE_OBJECT
MENUITEM "Create object as...", ID_CREATE_OBJECTAS
END
POPUP "Save object"
BEGIN
MENUITEM "Save object...", ID_SAVE_AS_XXX
MENUITEM "Save object copy", ID_SAVE_OBJECT_COPY
END
END
MENUITEM "Delete", ID_DELETE_OBJECT
END
END
由于弹出菜单没有ID(所有菜单的值都是-1),为了知道我在哪个菜单上进行初始化,我采用了on方法并实现了如下功能
bool CMainFrame::IsFileMenu(CMenu* pPopupMenu) const
{
if(!pPopupMenu);
return false;
return (pPopupMenu->GetMenuItemCount() > 0) && (pPopupMenu->GetMenuItemID(0) == ID_FILE_NEW);
}
bool CMainFrame::IsObjectMenu(CMenu* pPopupMenu) const
{
if(!pPopupMenu);
return false;
return (pPopupMenu->GetMenuItemCount() > 0) && (pPopupMenu->GetMenuItemID(2) == ID_DELETE_OBJECT);
}
菜单初始化如下所示:
void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
if(!license.supports("SaveAsFile"))
{
if(IsFileMenu())
{
//code to find ID_FILE_SAVEAS_XXX parent menu ("Save As"), then recursively delete all its descendants and itself
}
if(IsObjectMenu())
{
for(int i = 0; i < pPopupMenu->GetMenuItemCount();i++)
{
MENUITEMINFO MenuItemInfo;
memset(&MenuItemInfo, 0, sizeof(MENUITEMINFO));
MenuItemInfo.cbSize = sizeof (MENUITEMINFO); // must fill up this field
MenuItemInfo.fMask = MIIM_SUBMENU;
if (!pPopupMenu->GetMenuItemInfo(i, &MenuItemInfo, TRUE))
continue;
CMenu* SubMenu = pPopupMenu->GetSubMenu(i);
if (SubMenu != NULL)
{
memset(&MenuItemInfo, 0, sizeof(MENUITEMINFO));
MenuItemInfo.cbSize = sizeof (MENUITEMINFO);
MenuItemInfo.fMask = MIIM_ID | MIIM_TYPE;
for(int j=0; j<SubMenu->GetMenuItemCount() ;j++ )
{
SubMenu->GetMenuItemInfo(j, &MenuItemInfo, TRUE);
if (MenuItemInfo.wID == ID_CREATE_OBJECTAS)
{
for (int i=0; i<m_custom_objects.GetSize(); i++)
pPopup->AppendMenu(MF_STRING | MF_ENABLED, WM_MENU_CUSTOM_OBJECTS_BEGIN + i, (LPCTSTR) m_custom_objects[i].GetName() );
found= true;
break;
}
}
if(found)
break;
}
}
}
}
__super::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
}
void CMainFrame::OnInitMenuPopup(CMenu*ppopumenu、UINT nIndex、BOOL bSysMenu)
{
如果(!license.supports(“SaveAsFile”))
{
如果(IsFileMenu())
{
//查找ID_FILE_SAVEAS_XXX父菜单(“另存为”)的代码,然后递归删除其所有子体及其自身
}
如果(IsObjectMenu())
{
对于(int i=0;iGetMenuItemCount();i++)
{
MENUITEMINFO MENUITEMINFO;
memset(&MenuItemInfo,0,sizeof(MenuItemInfo));
MenuItemInfo.cbSize=sizeof(MenuItemInfo);//必须填写此字段
MenuItemInfo.fMask=MIIM_子菜单;
如果(!ppopumenu->GetMenuItemInfo(i,&MenuItemInfo,TRUE))
继续;
CMenu*子菜单=PPOPUPMENUS->Get子菜单(i);
如果(子菜单!=NULL)
{
memset(&MenuItemInfo,0,sizeof(MenuItemInfo));
MenuItemInfo.cbSize=sizeof(MenuItemInfo);
MenuItemInfo.fMask=MIIM_ID | MIIM_TYPE;
对于(int j=0;jGetMenuItemCount();j++)
{
子菜单->GetMenuItemInfo(j和MenuItemInfo,TRUE);
if(MenuItemInfo.wID==ID\u创建\u对象)
{
对于(inti=0;iAppendMenu(MF|STRING | MF|u ENABLED,WM|u MENU CUSTOM_OBJECTS_BEGIN+i,(LPCTSTR)m_CUSTOM_OBJECTS[i].GetName());
发现=真;
打破
}
}
如果(找到)
打破
}
}
}
}
__super::OnInitMenuPopup(ppopmenus、nIndex、bsysmenus);
}
请注意,ID\u FILE\u SAVEAS\u XXX
MENUITEM identifer重复出现!因为我不想在缺少支持“SaveAsFile”的许可证时删除“Save Object”弹出窗口,所以绝对需要确定现在正在处理的菜单
现在,用户已经使用MFC自定义对话框创建了一个工具栏,然后他将“创建对象”弹出窗口拖到新工具栏上。当他单击工具栏的这个新按钮时,他会看到“创建对象”和“创建对象为”选项,但不会看到自定义对象没有被附加到IsObjectMenu()
条件不满足。当他从主菜单过来时,行为完全不同;追加操作已经完成
如何使代码在用户单击工具栏按钮时添加自定义对象?我对自己的代码并不自豪,但我通过将“对象”代码与“创建对象”菜单分离来解决它
bool CMainFrame::IsCreateObjectMenu(CMenu*pPopupMenu)常量
{
如果(!ppopumenu);
返回false;
返回(ppopumenu->GetMenuItemCount()>0)和&(ppopumenu->GetMenuItemID(0)==ID\u创建\u对象);
}
无效CMInframe::OnInitMenuPopup(CMenu*ppOppMenu、UINT nIndex、BOOL bSysMenu)
{
如果(!license.supports(“SaveAsFile”))
{
如果(IsFileMenu())
{
//查找ID_FILE_SAVEAS_XXX父菜单(“另存为”)的代码,然后递归删除其所有子体及其自身
}
如果(IsObjectMenu())
{
//做事
}
如果(IsCreateObjectMenu())
{
对于(inti=0;iAppendMenu(MF|STRING | MF|u ENABLED,WM|u MENU CUSTOM_OBJECTS_BEGIN+i,(LPCTSTR)m_CUSTOM_OBJECTS[i].GetName());
}
}
__super::OnInitMenuPopup(ppopmenus、nIndex、bsysmenus);
}
我对自己的代码并不感到自豪,但我通过将“对象”的代码与“创建对象”菜单分离来解决它
bool CMainFrame::IsCreateObjectMenu(CMenu*pPopupMenu)常量
{
如果(!ppopumenu);
返回false;
返回(ppopumenu->GetMenuItemCount()>0)和&(ppopumenu->GetMenuItemID(0)==ID\u创建\u对象);
}
无效CMInframe::OnInitMenuPopup(CMenu*ppOppMenu、UINT nIndex、BOOL bSysMenu)
{
如果(!license.supports(“SaveAsFile”))
{
如果(IsFileMenu())
{
//查找ID_FILE_SAVEAS_XXX父菜单(“另存为”)的代码,然后递归删除其所有子体及其自身
}
如果(IsObjectMenu())
{
//做事
}
如果(IsCreateObjectMenu())
{
对于(inti=0;iAppendMenu(MF|STRING | MF|u ENABLED,WM|u MENU CUSTOM_OBJECTS_BEGIN+i,(LPCTSTR)m_CUSTOM_OBJECTS[i].GetName());
}
}
__super::OnInitMenuPopup(ppopmenus、nIndex、bsysmenus);
}
a的要点是要有一个最小的代码示例,它展示了错误情况。@IInspectable:我的帖子满足了这一要求。你菜单资源的代码当然不是最小的。什么?它没有足够的项目吗?我没有要求更多。我特别要求更少。你明白什么意思吗?a的要点是要有一个显示错误条件的最小代码示例。@IInspectable:我的帖子满足了这一要求。菜单资源的代码当然不是最小的。什么?它没有足够的项目吗?我没有要求更多。我特别要求更少。你明白什么意思吗?
bool CMainFrame::IsCreateObjectMenu(CMenu* pPopupMenu) const
{
if(!pPopupMenu);
return false;
return (pPopupMenu->GetMenuItemCount() > 0) && (pPopupMenu->GetMenuItemID(0) == ID_CREATE_OBJECT);
}
void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
if(!license.supports("SaveAsFile"))
{
if(IsFileMenu())
{
//code to find ID_FILE_SAVEAS_XXX parent menu ("Save As"), then recursively delete all its descendants and itself
}
if(IsObjectMenu())
{
// Do things
}
if(IsCreateObjectMenu())
{
for (int i=0; i<m_custom_objects.GetSize(); i++)
pPopupMenu->AppendMenu(MF_STRING | MF_ENABLED, WM_MENU_CUSTOM_OBJECTS_BEGIN + i, (LPCTSTR) m_custom_objects[i].GetName());
}
}
__super::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
}