Есть ли способ регистрировать каждое событие gui в Delphi?
Отладчик Delphi отлично подходит для отладки линейного кода, где одна функция вызывает другие функции в предсказуемом, линейном режиме, и мы можем проделывать программу по строкам.
Я считаю, что отладчик менее полезен при работе с управляемым событиями gui-кодом, где одна строка кода может вызывать запуск новых событий, что может в свою очередь инициировать другие события.
В этой ситуации подход "шаг за шагом" не позволяет мне видеть все, что происходит.
Как я обычно решаю это: 1) угадать, какие события могут быть частью проблемы, затем 2) добавить контрольные точки или вести журнал для каждого из этих событий.
Проблема заключается в том, что этот подход является случайным и требует много времени.
Есть ли переключатель, который я могу щелкнуть в отладчике, чтобы сказать "log all gui events"? Или есть какой-то код, который я могу добавить в события ловушки, что-то вроде
procedure GuiEventCalled(ev:Event)
begin
log(ev);
ev.call();
end
Конечный результат, который я ищу, это что-то вроде этого (например):
FieldA.KeyDown
FieldA.KeyPress
FieldA.OnChange
FieldA.OnExit
FieldB.OnEnter
Это приведет к догадкам из отладки Delphi gui.
Я использую Delphi 2010
[EDIT]
Несколько ответов предложили способы перехвата или регистрации сообщений Windows. Другие затем отметили, что не все события Delphi - это сообщения Windows вообще. Я думаю, что это те типы событий "Non Windows Message", о которых я спрашивал; События, созданные кодом Delphi. [/EDIT]
[EDIT2]
Прочитав всю информацию здесь, у меня возникла идея использовать RTTI для динамического перехвата TNotifyEvents и регистрации их в журнале событий в окне "Отладка". Сюда входят события OnEnter, OnExit, OnChange, OnClick, OnMouseEnter, OnMouseLeave. После небольшого взлома я получил его для работы очень хорошо, по крайней мере для моего использования (он не регистрирует ключевые события, но может быть добавлен).
Я разместил код здесь
Чтобы использовать
- Загрузите блок EventInterceptor и добавьте его в свой проект
- Добавить блок EventInterceptor в предложение Uses
-
Добавьте эту строку где-нибудь в свой код для каждой формы, которую вы хотите отслеживать.
AddEventInterceptors (MyForm);
Откройте окно отладки, и все события, которые вызывают, будут зарегистрированы в журнале событий
[/EDIT2]
Ответы
Ответ 1
Используйте блок delphieventlogger, который я написал скачать здесь. Это только один метод вызова и очень прост в использовании. Он регистрирует все TNotifyEvents (например, OnChange, OnEnter, OnExit) в журнале событий Delphi в окне отладчика.
Ответ 2
Нет, нет общего способа сделать это, потому что у Delphi нет никакого типа событий, который может быть каким-то образом подключен. Обработчик событий - это просто ссылка на метод, и он вызван так:
if assigned(FEventHandler) then
FEventHandler(self);
Просто обычный вызов справочной системы. Если вы хотите регистрировать все обработчики событий, вам придется вставить некоторый вызов в каждый из них самостоятельно.
Ответ 3
Я знаю, что это немного дорого, но вы можете использовать Automated QA (теперь SmartBear) TestRecorder как расширение для TestComplete ( если вы хотите это только в своей системе, TestComplete самостоятельно сделает). Эта часть программного обеспечения будет отслеживать действия вашего GUI и хранить их на языке script. Существует даже блок, который можно связать с вашим exe, чтобы сделать эти записи непосредственно в пользовательской системе. Это особенно полезно, когда некоторые пользователи не могут объяснить, что они сделали, чтобы создать ошибку.
Ответ 4
Используйте WinSight для просмотра потока сообщений в режиме реального времени.
Если вы действительно хотите, чтобы программа создала журнал, переопределите WinProc
и/или перехватите сообщения в Application
.
Ответ 5
Событие TApplication.OnMessage
может использоваться для улавливания сообщений, которые отправляются в очередь основных сообщений. Это прежде всего для сообщений, выпущенных OS, а не внутренних сообщений VCL/RTL, которые обычно отправляются непосредственно в методы WndProc()
. Не все события VCL предназначены для начала сообщений. Нет единого решения того, что вы ищете. Вам нужно будет использовать комбинацию переопределений TApplication.OnMessage
, TApplication.HookMainWindow()
, WndProc()
, SetWindowsHook()
и выборочных контрольных точек/крючков в коде.
Инструмент Borland WinSight больше не распространяется, но есть много доступных сторонних инструментов, которые делают то же самое, что и WinSight, например Microsoft Spy ++, WinSpector и т.д. для отслеживания сообщений окна журнала в режиме реального времени.
Ответ 6
В качестве альтернативы для отладки запущенных событий используйте отладчик Step Into (F7) вместо команд Step Over (F8).
Отладчик остановится на любой доступной кодовой строке, достигнутой во время вызова.
Ответ 7
Вы можете попробовать один из AOP-фреймворков для Delphi. MeAOP предоставляет регистратор по умолчанию, который вы можете использовать. Он не скажет вам, что происходит внутри обработчика событий, но он скажет вам, когда вызывается обработчик событий и когда он возвращается.