如何找到的菜单项(如果有),它在激活时将打开一给定HMENU? [英] How to find the menu item (if any) which opens a given HMENU when activated?
问题描述
我想实现与原型的函数
/* 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 / < A HREF =http://msdn.microsoft.com/en-us/library/ms647984%28VS.85%29.aspx相对=nofollow> GetSubMenu 。
My current approach is to look into each HMENU of the top level windows of the application and check for whether I can find a menu item which would open the given sub menu when activated. I do this recursively, using GetMenuItemCount/GetSubMenu.
这是相当低效虽然,发生故障,这是由上下文菜单项打开菜单。因此,我想知道:
This is rather inefficient though, and it fails for menus which are opened by context menu items. Hence, I'm wondering:
没有任何人有一个不错的主意如何找到菜单项(如有的话)打开时激活一个给定的HMENU?
Does anybody have a nice idea how to find the menu item (if any) which opens a given HMENU when activated?
更新:刚刚来到我的头脑的思想;它应该是可能的(使用调用SetWindowsHookEx 的功能)要安装的得到通知,这发生在一个菜单中的所有输入事件的钩子。每当检测到菜单项的激活,熟记菜单项(由(HMENU,INT)对来标识),并且将通过该菜单项中的全局地图获取打开HMENU。接着上面的 getParentMenuItem
功能可以简单地执行查找到地图。
UPDATE: An idea which just came to my mind; it should be possible (using the SetWindowsHookEx function) to install a hook which gets notified of all input events which happened in a menu. Whenever a menu item activation is detected, memorize the menu item (identified by a (HMENU,int) pair) and the HMENU which will get opened by the menu item in a global map. The getParentMenuItem
function above could then simply perform a lookup into the map.
更新的更新:的在更新中描述的挂钩上面的想法是行不通的,因为它是因为它会当然只认菜单 - >菜单协会对于已经在被激活的项目某些时候。
UPDATE to the update: The hooking idea described in the update above won't work as it is since it will of course only recognize menu item -> menu associations for items which have been activated at some point.
这感觉有点难看,虽然因为它reqiures我保持了很多状态(图);是否有任何容易的可能性?
This feels a bit ugly though since it reqiures me to keep a lot of state (the map); are there any easier possibilities?
推荐答案
您可以尝试设置 MENUINFO.dwMenuData code>父菜单句柄为你的应用程序创建的所有菜单
You could try setting MENUINFO.dwMenuData
to the parent menu handle for all menus you create in your application:
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 code>字段:
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
勾陷阱当菜单第一次创建。 一篇好文章(附源$ C $ C)讲述如何可以做到的 - 你可以再看看试图到母体HMENU注入使用上述方法所创建的菜单
If you don't have control over how all menus are created, you could use a WH_CALLWNDPROC
hook to trap when a menu is first created. A good article (with source code) describes how this can be done - you could then look at trying to inject the parent HMENU into the created menu using the method described above.
这篇关于如何找到的菜单项(如果有),它在激活时将打开一给定HMENU?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!