Visual c++ 当从应用程序主菜单栏中的弹出菜单工具栏按钮调用OnInitMenuOpup时,OnInitMenuOpup无法正确初始化

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

要缩短长历史记录,请设想我的主菜单是一个CMFCMenuBar,该菜单由以下内容定义:

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);
}