Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to log every gui event in Delphi?

Tags:

delphi

The Delphi debugger is great for debugging linear code, where one function calls other functions in a predictable, linear manner, and we can step through the program line by line.

I find the debugger less useful when dealing with event driven gui code, where a single line of code can cause new events to be triggered, which may in turn trigger other events. In this situation, the 'step through the code' approach doesn't let me see everything that is going on.

The way I usually solve this is to 1) guess which events might be part of the problem, then 2) add breakpoints or logging to each of those events.

The problem is that this approach is haphazard and time consuming.

Is there a switch I can flick in the debugger to say 'log all gui events'? Or is there some code I can add to trap events, something like

procedure GuiEventCalled(ev:Event)
begin
    log(ev);
    ev.call();
end

The end result I'm looking for is something like this (for example):

FieldA.KeyDown 
FieldA.KeyPress 
FieldA.OnChange 
FieldA.OnExit 
FieldB.OnEnter

This would take all the guesswork out of Delphi gui debugging.

I am using Delphi 2010

[EDIT] A few answers suggested ways to intercept or log Windows messages. Others then pointed out that not all Delphi Events are Windows messages at all. I think it is these type of "Non Windows Message" Events that I was asking about; Events that are created by Delphi code. [/EDIT]

[EDIT2] After reading all the information here, I had an idea to use RTTI to dynamically intercept TNotifyEvents and log them to the Event Log in the Debugging window. This includes OnEnter, OnExit, OnChange, OnClick, OnMouseEnter, OnMouseLeave events. After a bit of hacking I got it to work pretty well, at least for my use (it doesn't log Key events, but that could be added). I've posted the code here

To use

  1. Download the EventInterceptor Unit and add it to your project
  2. Add the EventInterceptor Unit to the Uses clause
  3. Add this line somewhere in your code for each form you want to track.

    AddEventInterceptors(MyForm);

Open the debugger window and any events that are called will be logged to the Event Log

[/EDIT2]

like image 910
awmross Avatar asked Jan 11 '11 00:01

awmross


2 Answers

Use the "delphieventlogger" Unit I wrote download here. It's only one method call and is very easy to use. It logs all TNotifyEvents (e.g. OnChange, OnEnter, OnExit) to the Delphi Event Log in the debugger window.

like image 126
awmross Avatar answered Nov 09 '22 03:11

awmross


No, there's no generalized way to do this, because Delphi doesn't have any sort of "event type" that can be hooked in some way. An event handler is just a method reference, and it gets called like this:

if assigned(FEventHandler) then
  FEventHandler(self);

Just a normal method reference call. If you want to log all event handlers, you'll have to insert some call into each of them yourself.

like image 30
Mason Wheeler Avatar answered Nov 09 '22 02:11

Mason Wheeler