WINAPI,从菜单中删除弹出菜单

WINAPI, remove popup menu from menu

我想在我的应用程序中有动态菜单。这个动态菜单应该包含将被动态添加和删除的弹出菜单。对于第一种方法,我制作了使用单个菜单项创建的动态菜单。

AppendMenu(menu, MF_STRING, item_id, "TEST");

我创建了生成 item_id 并将它们存储在数组中的算法,因此我可以通过

删除它们
DeleteMenu(menu, id_to_be_deleted, MF_BYCOMMAND);

我没有发现此实现有任何缺陷,对此我很满意。但随后坚持最终实施。我希望我的菜单是弹出式菜单。

new_popup_menu = CreatePopupMenu();
AppendMenu(new_popup_menu, MF_STRING, 1, "TEST1");
AppendMenu(new_popup_menu, MF_STRING, 2, "TEST2");
AppendMenu(new_popup_menu, MF_STRING, 3, "TEST3");
AppendMenu(menu, MF_STRING|MF_POPUP, 
          (UINT_PTR)new_popup_menu, "dynamic menu");

此代码按预期工作,但我不知道如何从 "menu" 中删除 "new_popup_menu",因为 AppendMenu 的 "UINT_PTR uIDNewItem" 参数现在用作子菜单的句柄,而不是 ID并且不能与 DeleteMenu+MF_BYCOMMAND 一起使用。 除了 DeleteMenu+MF_BYPOSITION 之外,还有什么方法可以删除这个子菜单项吗? 有没有办法通过 CreatePopupMenu()) 返回的句柄获取菜单项位置? 我觉得跟踪哪个菜单在哪个位置的实现算法很麻烦。由于 Windows 有 API 在其他特定菜单之后插入菜单,重新创建整个菜单树是在浪费 CPU 时间。

如果您想创建一个打开子菜单并具有 ID 的菜单项,请使用 InsertMenuItem(...) 而不是 AppendMenu(...) 创建它。 InsertMenuItem(...) 允许您填写一个结构,该结构指定要在您正在创建的菜单项上设置的所有属性,包括 ID 和子菜单。许多 Win32 都是这样工作的:AppendMenu(...) 就像 shorthand 版本一样,是同一功能的更详细版本。当您 运行 遇到无法对某个 Win32 调用执行合理操作的情况时,请查找采用 *INFO 结构的同义调用。

代码如下:

...
HMENU menu_bar = GetMenu(hWnd);
HMENU new_menu = CreateMenu();
AppendMenu(menu_bar, MF_POPUP, (UINT_PTR)new_menu, "foobar");
AppendMenu(new_menu, MF_ENABLED | MF_STRING, 1002, "item1");
AppendMenu(new_menu, MF_ENABLED | MF_STRING, 1003, "item2");

HMENU dynamic_popup = CreatePopupMenu();
AppendMenu(dynamic_popup, MF_ENABLED | MF_STRING, 1004, "mumble");
AppendMenu(dynamic_popup, MF_ENABLED | MF_STRING, 1005, "quux");

// Below will add an item named "dynamic menu" to the end of new_menu
// that has an ID of 1006.

MENUITEMINFO mii = { 0 };
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_SUBMENU | MIIM_STRING | MIIM_ID;
mii.dwTypeData = (LPSTR)"dynamic menu";
mii.hSubMenu = dynamic_popup;
mii.wID = 1006;
InsertMenuItem(new_menu, 0, FALSE, &mii);

//DeleteMenu(new_menu, 1006, MF_BYCOMMAND);
...