Получение статуса выпадающего меню проблематично, код, который делает всплывающее меню довольно запутанным, использует некоторые перехватчики сообщений.Как правило, это не тот код, к которому вы бы хотели прикоснуться.К счастью, сама панель инструментов отслеживает состояние выпадающего меню, используя переменную FMenuDropped
.К сожалению, эта переменная private , вы не можете получить к ней доступ извне, «взломанный» трюк не работает.Будучи закрытым, он также не предлагает RTTI!
Существует два возможных решения:
Изменить VCL и добавить свойство, которое делает FMenuDropped доступным извне
Перейти к ComCtrls.pas, найдите объявление TToolBar = class(TToolWindow)
, перейдите в публичный раздел и добавьте следующее:
property MenuDropped:Boolean read FMenuDropped;
Из своего кода вы сможете проверить панель инструментов, есть ли у нее выпадающее меню или нет,К сожалению, это требует внесения изменений в VCL.Никогда не хорошая идея, трудно синхронизировать между несколькими программистами.
Используйте хак для прямого доступа к полю FMenuDropped без изменения VCL
. Для этого вам нужно получить смещение FMenuDropped
поле.Как только вы это получите, вы можете написать что-то вроде этого:
if PBoolean(Integer(Toolbar1) + 865)^ then
DoStuffIfMenuIsDropped
else
OtherStuffIfMenuIsNotDropped;
865
на самом деле правильная константа для Delphi 2010!Вот очень быстрый способ получения константы.
- Перейдите в настройки компилятора, установите флажок "compile using debug DCU's" *
- Откройте ComCtrls.pas, перейдите к
procedure TToolButton.Paint
, поместите туда точку торможения. - Запустите приложение, возьмите лист бумаги и ручку.Когда программа остановится в точке торможения, откройте Debug Inspector.Для этого просто наведите курсор на название поля, любого поля и нажмите Alt + F5 .В окне «Инспектор отладки» нажмите Ctrl + N , чтобы открыть общий редактор
Inspect
, который позволяет вам что-либо проверять.Введите Integer(FToolbar)
.Запишите результат на листе бумаги. - Снова нажмите Ctrl + N , на этот раз введите
Integer(@FToolBar.FMenuDropped)
.Запомните это второе число. - Вам нужна постоянная разница между вторым и первым. Вот и все!
Есть, конечно, некоторые возможные проблемы.Прежде всего, это зависит от используемой версии точной Delphi.Если код должен быть скомпилирован на разных версиях компилятора Delphi, необходимо использовать умный $IFDEF
.Тем не менее, это выполнимо.
(Правка) : Вы можете использовать эту же технику для доступа к любому приватному полю любого класса.Но вам нужно будет подумать много раз, прежде чем делать это, потому что частные поля по какой-то причине становятся личными.