简体   繁体   English

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

[英]WINAPI, remove popup menu from menu

I would like to have dynamic menu in my application.我想在我的应用程序中有动态菜单。 This dynamic menu should contain popupmenus which will be added and removed on the fly.此动态菜单应包含将即时添加和删除的弹出菜单。 For the first approach I made dynamic menu created with single menu items.对于第一种方法,我使用单个菜单项创建了动态菜单。

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

I have created algorithm which generate item_id and store them in array, so I could remove them by我创建了生成 item_id 并将它们存储在数组中的算法,所以我可以通过

DeleteMenu(menu, id_to_be_deleted, MF_BYCOMMAND);

I do not see any pitfalls of this implementation and I am happy with it.我没有看到这个实现的任何缺陷,我对此很满意。 But then stuck with final implementation.但随后坚持最终实施。 I would like my menus would be popup menus.我希望我的菜单是弹出菜单。

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

This code works as expected, but I have no idea how to remove "new_popup_menu" from "menu" since the "UINT_PTR uIDNewItem" parameter of AppendMenu now is used as handle to submenu, not ID and cannot be used with DeleteMenu+MF_BYCOMMAND.此代码按预期工作,但我不知道如何从“menu”中删除“new_popup_menu”,因为 AppendMenu 的“UINT_PTR uIDNewItem”参数现在用作子菜单的句柄,而不是 ID,并且不能与 DeleteMenu+MF_BYCOMMAND 一起使用。 Is there any way to remove this submenu item other then DeleteMenu+MF_BYPOSITION?除了 DeleteMenu+MF_BYPOSITION 之外,还有什么方法可以删除这个子菜单项? Is there a way to get menu item position by handle which is returned by CreatePopupMenu())?有没有办法通过 CreatePopupMenu()) 返回的句柄获取菜单项 position? I feel implementation algorithm of tracking which menu is on which position is pain in the ass.我觉得跟踪哪个菜单在哪个 position 上的实现算法很痛苦。 Since Windows has API to insert the menu after other specific menu, recreating whole menu tree is a waste of CPU time.由于 Windows 有 API 在其他特定菜单之后插入菜单,因此重新创建整个菜单树是浪费 CPU 时间。

If you want to create a menu item that opens a submenu and has an ID then create it with InsertMenuItem(...) rather than AppendMenu(...) .如果您想创建一个打开子菜单并具有 ID 的菜单项,则使用InsertMenuItem(...)而不是AppendMenu(...)创建它。 InsertMenuItem(...) lets you fill in a struct that specifies all of the properties you want to be set on the menu item you are creating, including ID and submenu. InsertMenuItem(...)允许您填写一个结构,该结构指定要在您正在创建的菜单项上设置的所有属性,包括 ID 和子菜单。 A lot of Win32 works this way: AppendMenu(...) is like a shorthand version for the more verbose version of the same function.许多 Win32 以这种方式工作: AppendMenu(...)就像是相同 function 的更详细版本的简写版本。 When you run into situations in which you can't do something reasonable with a certain Win32 call, look for a synonymous call that takes a *INFO structure.当您遇到无法对某个 Win32 调用执行合理操作的情况时,请查找采用 *INFO 结构的同义调用。

Code below:下面的代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM