windows - WINAPI,从菜单中删除弹出菜单
问题描述
我想在我的应用程序中有动态菜单。此动态菜单应包含将即时添加和删除的弹出菜单。对于第一种方法,我使用单个菜单项创建了动态菜单。
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(...)
就像是同一函数的更详细版本的简写版本。当您遇到无法对某个 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);
...
推荐阅读
- arangodb - ArangoDB 集群低遍历查询性能
- sql - 在表中具有大量数据的 Sql Server 查询的简单选择中需要帮助
- c# - 在自定义 ActionFilter 上实现 OnActionExecuted
- java - java中.txt文件的路径
- reactjs - 如何将 ReactJS 与 Craft CMS 一起使用(主要只是想在客户端使用)
- performance - 如何加快 Common Lisp `IF` 语句的编译速度?
- domain-driven-design - How to process Read Model in CQRS
- supercsv - super CSV 是否支持解析文件头?
- php - 以编程方式生成的查询中的语法错误
- java - Hystrix 作为带有 ElasticSearch 的断路器 - 可取还是使用 ES 断路器?