尝试填充动态菜单时断言 IsMenu 异常

Assert IsMenu exception when attempting to populate a dynamic menu

我正在尝试从 this answer 中所示的字符串数组中填充对话框中的“子菜单”。

我的尝试如下所示:

#define ID_APP0 14000
#define ID_APP1 14001
#define ID_APP2 14002
#define ID_APP3 14003
#define ID_APP4 14004
#define ID_APP5 14005
#define ID_APP6 14006
#define ID_APP7 14007

void SoftwareDlg::DynamicAppMenu()
{
    CMenu MyMainMenu;
    VERIFY(MyMainMenu.LoadMenu(IDR_MENU1));
    
    CMenu* SomeMenu = MyMainMenu.GetSubMenu(0);
    if (SomeMenu)
    {
        for (auto i = 0; i < 1; i++)
        {
            SomeMenu->AppendMenu(MF_STRING, 14000+i, Client::m_vszAppArr[i]);
        }
    }
}

...但是我在 AppendMenu() 函数之后(期间?)立即从下面的断言中得到一个异常。

_AFXWIN_INLINE BOOL CMenu::AppendMenu(UINT nFlags, UINT_PTR nIDNewItem, LPCTSTR lpszNewItem)
    { ASSERT(::IsMenu(m_hMenu)); return ::AppendMenu(m_hMenu, nFlags, nIDNewItem, lpszNewItem); }

我不知道如何继续调试这个问题,因为 LoadMenu() 函数似乎可以正常工作,并且 none 的变量被填充到发生异常的地方。

我可能只是在错误的地方调用它吗?它正在(有条件地)发生在对话框的计划成员函数内......它是否需要发生在 OnDraw()OnPaint() 或其他地方?

Edit1:设置菜单的值->m_hMenu

编辑 2:IDR_MENU1 资源定义:

IDR_MENU1 MENU
BEGIN
    POPUP "Tools"
    BEGIN
        MENUITEM "New Test                  F11", ID_TOOLS_NEWTEST
        MENUITEM "Export Data",                 ID_TOOLS_EXPORTDATA
        MENUITEM "Upload Data",                 ID_TOOLS_UPLOADDATA
        MENUITEM "Test Control",                ID_TOOLS_TESTCONTROL
    END
    POPUP "Settings"
    BEGIN
        POPUP "USB_PORT"
        BEGIN
            MENUITEM "Serial Ports",                ID_PORT_SERIALPORTS, INACTIVE
            MENUITEM "COM1",                        ID_PORT_COM1
            MENUITEM "COM2",                        ID_PORT_COM2
            MENUITEM "COM3",                        ID_PORT_COM3
            MENUITEM "COM4",                        ID_PORT_COM4
            MENUITEM "COM5",                        ID_PORT_COM5
            MENUITEM "COM6",                        ID_PORT_COM6
            MENUITEM "COM7",                        ID_PORT_COM7
            MENUITEM "COM8",                        ID_PORT_COM8
        END
        MENUITEM "Debug Mode",                  ID_SETTINGS_DEBUGMODE
        MENUITEM "Display in OSD",       ID_SETTINGS_DISPLAYINOSD
        MENUITEM "Test Upload Mode",            ID_SETTINGS_TESTUPLOADMODE
        MENUITEM "Preferences",                 ID_SETTINGS_PREFERENCES
        POPUP "Target Window"
        BEGIN
            MENUITEM "Placeholder",                 ID_TARGETWINDOW_PLACEHOLDER
        END
    END
END

正如@Vlad Feinstein 的评论所暗示的那样,CMenu MyMainMenu; 不应在函数内部声明...该修复使我能够通过断言,但新菜单项仍未出现。我开始从创建和删除函数中捕获并记录 return 值,这让我意识到因为我已经有了一个现有菜单,所以我需要使用指向该菜单的指针(而不是创建我自己的菜单然后闲置)。

我的最终函数看起来像这样:

void SoftwareDlg::DynamicAppMenu(){
    CMenu* MainMenu = GetMenu();
    CMenu* SettingsMenu = MainMenu->GetSubMenu(1);
    CMenu* TargetAppMenu = SettingsMenu->GetSubMenu(5);
    
    if (TargetAppMenu)
    {
        BOOL appended = false;
        BOOL deleted = false;

        for (auto i = 0; i < Client::m_vszAppArr.size(); i++)
        {
            appended = TargetAppMenu->AppendMenu(MF_STRING, 14000+i, Client::m_vszAppArr[i].c_str());
        }
        deleted = TargetAppMenu->DeleteMenu(ID_TARGETWINDOW_PLACEHOLDER, MF_BYCOMMAND);
        
        OutputDebugString(("String appended: " + std::to_string(appended)).c_str());
        OutputDebugString(("Placeholder deleted: " + std::to_string(deleted)).c_str());
    }
    
}