Есть ли способ регистрировать каждое событие 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 предоставляет регистратор по умолчанию, который вы можете использовать. Он не скажет вам, что происходит внутри обработчика событий, но он скажет вам, когда вызывается обработчик событий и когда он возвращается.