在C++中根据鼠标位置查找菜单项

Find menu item based on mouse position in C++

本文关键字:位置 查找 菜单项 鼠标 C++      更新时间:2023-10-16

我正在尝试从另一个应用程序获取菜单项。

我可以通过手动获取主菜单的句柄并在其子菜单中循环来实现这一点。但是很难找出给定菜单有多少级别的子菜单。例如,如果我们在outlook视图菜单中看到这样的东西,view(视图)->Arrangeby(排列方式)->Current view(当前视图)->Messages(消息)。

所以我决定根据鼠标的位置来获取菜单项。但是我找不到办法。

请提出一些这样做的想法。

我怀疑,由于windows中的菜单系统的设计方式,您试图实现的目标或多或少是不可能的。

请注意,可能有一些非传统的方法来解决这一问题,但我怀疑您是否会找到这样一种解决方案,它比您当前遍历菜单层次结构的策略所需的工作量更少。

问题是,菜单和子菜单的层次结构实际上是一棵常规菜单树。在MFC中,您有一个CMenu对象树,而在win32 C api中,它是一个HMENU句柄树。

每个菜单,无论是子菜单还是主菜单,都有许多项目,它们本身不是对象。即,没有名为CMenuItem的MFC类,也没有名为HMENUITEM的win32 API句柄类型。如果你看看任何处理菜单的函数,它总是关于传递菜单项的ID。例如,查看CMenu::EnableMenuItem或CMenu::GetDefaultItem。

现在,真正的问题由两个事实组成-菜单项是它们所在菜单的本地项。如果你查看C API中的任何函数,你总是需要同时指定菜单句柄和菜单项ID,因为除非框架知道你谈论的是哪个菜单对象,否则无法解决菜单项ID。因此ID不是全局的。在MFC中,通常不需要指定菜单句柄,但这当然是因为CMenu对象本身包装了HMENU句柄。

问题的第二部分是,没有从位置检索菜单(CMenu或HMENU)的自然方法。您可以通过MenuItemFromPoint从位置获取菜单项,但正如您所看到的,您还需要菜单句柄,并且返回的ID仅与您指定的菜单句柄组合有效。由于除了遍历子菜单层次结构之外,您无法以任何其他方式获得该菜单句柄,因此您又回到了原点。

最后一点要注意的是,Visual C++菜单(CMenu)的功能始终局限于Win32 C API菜单函数的功能,因此在那里找不到的任何功能或多或少都是遥不可及的。