C++ 中根据鼠标位置查找菜单项
我正在尝试从另一个应用程序获取菜单项。
我可以通过手动获取主菜单的句柄并循环遍历其子菜单来完成此操作。但要找出给定菜单有多少级子菜单是非常困难的。例如,如果我们查看 Outlook 视图菜单,如下所示:View ->排列方式->当前视图 ->消息。
所以我决定根据鼠标位置获取菜单项。但我找不到办法做到这一点。
请提出一些想法来做到这一点。
I am trying to get the menu item from another application.
I can do this by manually getting the handle to the main menu and loop through its sub menu. But it is very difficult to find out how many levels of sub menus are there for a given menu. For example if we look at outlook view menu some thing like this, View -> Arrange by -> Current View -> Messages.
So i decided to get the menu item based on mouse position. But i cant find a way to do that.
Please suggest some idea to do this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我怀疑 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< 获取菜单项/a>,但正如您所看到的,您还需要菜单句柄,并且返回的 ID 仅与您指定的菜单句柄结合使用才有效。由于除了遍历子菜单层次结构之外,您无法以任何其他方式获取该菜单句柄 - 您又回到了第一步。
最后一点 - Visual C++ 菜单 (CMenu) 的功能始终仅限于 Win32 C API 菜单功能,因此任何未找到的功能或多或少都无法实现。
I suspect that what you're trying to achieve is more or less made impossible by how the menu system in windows is designed.
Note that there might be some non-conventional ways around this, however I doubt you'll find such a solution to carry less amount of work than your current strategy of traversing the menu hierarchy.
The thing is, a hierarchy of menus and submenus is actually a tree of regular menus. In MFC you have a tree of CMenu objects and in the win32 C api it's a tree of HMENU handles.
Each menu, regardless if it's a submenu or main menu, have a number of items which by themselves are not objects. I.e. there's no MFC class called CMenuItem and no win32 API handle type called HMENUITEM. If you look at any function dealing with menus, it's always about passing an ID of a menu item. For instance look at CMenu::EnableMenuItem or CMenu::GetDefaultItem.
Now, the real problem is comprised of two facts - Menu items are local to the menu they're located in. If you look at any function in the C API, you always need to specify both menu handle and menu item ID, due to the fact that item IDs can't be resolved unless the framework knows which menu object you're talking about. Hence IDs are not global. In MFC you usually don't need to specify the menu handle, but that's ofcourse because the CMenu object itself wraps the HMENU handle.
The second part of the problem is that there's no natural way of retrieving a menu (CMenu or HMENU) from position. You can get a menu item from position through MenuItemFromPoint, but as you can see you also need the menu handle and the returned ID is only valid in combination with the menu handle you specify. Since you can't get that menu handle any other way than traversing the submenu hierarchy - you're back to square one.
As a final note - the capabilities of Visual C++ menus (CMenu) are always limited to the capabilities of the Win32 C API menu functions, so any functionality not found there is more or less out of reach.