尝试填充动态菜单时断言 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());
}
}
我正在尝试从 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());
}
}