如何找到的菜单项(如果有),它在激活时将打开一给定HMENU? [英] How to find the menu item (if any) which opens a given HMENU when activated?

查看:120
本文介绍了如何找到的菜单项(如果有),它在激活时将打开一给定HMENU?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现与原型的函数

/* 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 =htt​​p://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 父菜单句柄为你的应用程序创建的所有菜单

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 字段:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆