gpt4 book ai didi

c++ - 如何找到激活时打开给定 HMENU 的菜单项(如果有)?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:32:25 24 4
gpt4 key购买 nike

我想用原型(prototype)实现一个功能

/* Locates the menu item of the application which caused the given menu 'mnu' to
* show up.
* @return true if the given menu 'mnu' was opened by another menu item, false
* if not.
*/
bool getParentMenuItem( HMENU mnu, HMENU *parentMenu, int *parentMenuIdx );

给定一个 HMENU 句柄,我希望能够找出应用程序中的哪个菜单项(如果有的话)打开了它。这基本上与 GetSubMenu 相反功能。

我目前的方法是查看应用程序顶层窗口的每个 HMENU,并检查是否可以找到激活时会打开给定子菜单的菜单项。我使用 GetMenuItemCount 递归地执行此操作/GetSubMenu .

虽然这是相当低效的,并且对于由上下文菜单项打开的菜单来说它会失败。因此,我想知道:

有没有人知道如何找到激活时打开给定 HMENU 的菜单项(如果有)?

更新:我刚刚想到的一个想法;应该可以(使用 SetWindowsHookEx 函数)安装一个 Hook ,它会收到菜单中发生的所有输入事件的通知。每当检测到菜单项激活时,记住菜单项(由 (HMENU,int) 对标识)和将由全局映射中的菜单项打开的 HMENU。然后上面的 getParentMenuItem 函数可以简单地执行对 map 的查找。

更新的更新: 上面更新中描述的 Hook 想法不会像现在这样工作,因为它当然只会识别菜单项 -> 已激活的项目的菜单关联一些点。

虽然这感觉有点难看,因为它需要我保持很多状态( map );有没有更简单的可能性?

最佳答案

您可以尝试将 MENUINFO.dwMenuData 设置为您在应用程序中创建的所有菜单的父菜单句柄:

MENUINFO mi;
mi.cbSize = sizeof(MENUINFO);
mi.dwMenuData = (ULONG_PTR)<parent HMENU if this is a sub menu>
mi.fMask = MIM_MENUDATA;

SetMenuInfo(hCreatedMenu, &mi);

那么你只需要在你的函数中查询这个dwMenuData字段:

bool getParentMenuItem(HMENU mnu, HMENU *parentMenu, int *parentMenuIdx)
{
MENUINFO mi;
mi.cbSize = sizeof(MENUINFO);
mi.fMask = MIM_MENUDATA;

if (!GetMenuInfo(mnu,&mi) || mi.dwMenuData == 0)
return false;

*parentMenu = (HMENU)mi.dwMenuData;

// not sure how or why you need the parentMenuIdx, but you should be able
// to derive that from the parent HMENU

return true;
}

编辑:如果您无法控制所有菜单的创建方式,您可以使用 WH_CALLWNDPROC Hook 来捕获首次创建菜单的时间。 A good article (带有源代码)描述了如何做到这一点 - 然后您可以尝试使用上述方法将父 HMENU 注入(inject)到创建的菜单中。

关于c++ - 如何找到激活时打开给定 HMENU 的菜单项(如果有)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1320899/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com