Найти пункт меню в зависимости от положения мыши в C ++ - PullRequest
1 голос
/ 07 июня 2011

Я пытаюсь получить пункт меню из другого приложения.

Я могу сделать это вручную, переместив ручку в главное меню и перебрав его подменю.Но очень трудно определить, сколько уровней подменю существует для данного меню.Например, если мы посмотрим на меню внешнего вида что-то вроде этого, View -> Arrange by -> Current View -> Messages.

Поэтому я решил получить пункт меню, основанный на положении мыши.Но я не могу найти способ сделать это.

Пожалуйста, предложите какую-нибудь идею сделать это.

1 Ответ

2 голосов
/ 07 июня 2011

Я подозреваю, что то, чего вы пытаетесь достичь, более или менее невозможно из-за того, как устроена система меню в Windows.

Обратите внимание, что могут быть некоторые нетрадиционные способы решения этой проблемы, однако я сомневаюсь, что вы найдете такое решение для выполнения меньшего объема работы, чем ваша текущая стратегия обхода иерархии меню.

Дело в том, что иерархия меню и подменю на самом деле является деревом регулярных меню. В MFC у вас есть дерево объектов CMenu, а в Win32 C API это дерево дескрипторов HMENU.

В каждом меню, независимо от того, является ли оно подменю или главным меню, есть несколько пунктов, которые сами по себе не являются объектами. То есть нет класса MFC с именем CMenuItem и нет типа дескриптора win32 API с именем HMENUITEM. Если вы посмотрите на любую функцию, имеющую дело с меню, это всегда про передачу идентификатора пункта меню. Например, посмотрите на CMenu :: EnableMenuItem или CMenu :: GetDefaultItem .

Теперь настоящая проблема состоит из двух фактов: пункты меню являются локальными по отношению к меню, в котором они находятся. Если вы посмотрите на любую функцию в C API, вам всегда нужно указывать как дескриптор меню, так и идентификатор пункта меню. из-за того, что идентификаторы элементов не могут быть разрешены, если инфраструктура не знает, о каком объекте меню вы говорите. Следовательно, идентификаторы не являются глобальными. В MFC вам обычно не нужно указывать дескриптор меню, но это естественно, потому что сам объект CMenu оборачивает дескриптор HMENU.

Вторая часть проблемы заключается в том, что нет естественного способа восстановить меню (CMenu или HMENU) из позиции. Вы можете получить пункт меню из позиции через MenuItemFromPoint , но, как вы можете видеть, вам также нужен дескриптор меню, и возвращенный идентификатор действителен только в сочетании с указанным дескриптором меню. Поскольку вы не можете получить управление этим меню каким-либо иным способом, кроме обхода иерархии подменю - вы вернулись к исходной точке.

В качестве заключительного замечания - возможности меню Visual C ++ (CMenu) всегда ограничены возможностями функций меню Win32 C API , поэтому любая функциональность, которая там не найдена, более или менее недоступна ,

...