有没有办法在Delphi中记录每个gui事件?

时间:2011-01-11 00:10:57

标签: delphi

Delphi调试器非常适合调试线性代码,其中一个函数以可预测的线性方式调用其他函数,我们可以逐行逐步执行该程序。

我发现调试器在处理事件驱动的gui代码时不那么有用,其中一行代码可以导致触发新事件,这可能反过来触发其他事件。 在这种情况下,“逐步执行代码”方法不会让我看到正在发生的一切。

我通常解决这个问题的方法是1)猜测哪些事件可能是问题的一部分,然后2)添加断点或记录每个事件。

问题在于这种方法是偶然且耗时的。

是否有一个开关我可以在调试器中轻弹以说'记录所有gui事件'?或者是否有一些我可以添加到陷阱事件的代码,例如

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

我正在寻找的最终结果是这样的(例如):

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

这将考虑到Delphi gui调试的所有猜测。

我正在使用Delphi 2010

[编辑] 一些答案提出了拦截或记录Windows消息的方法。其他人则指出并非所有Delphi事件都是Windows消息。我认为这是我要问的这类“非Windows消息”事件;由Delphi代码创建的事件。 [/编辑]

[EDIT2] 在阅读了这里的所有信息后,我有一个想法,即使用RTTI动态拦截TNotifyEvents并将它们记录到Debugging窗口中的Event Log。这包括OnEnter,OnExit,OnChange,OnClick,OnMouseEnter,OnMouseLeave事件。经过一段时间的黑客攻击后,我得到了相当好的工作,至少对我来说是这样(它不会记录Key事件,但可以添加)。 我发布了代码here

使用

  1. 下载EventInterceptor单元并将其添加到您的项目中
  2. 将EventInterceptor单元添加到Uses子句
  3. 在代码中的某个位置为要跟踪的每个表单添加此行。

    AddEventInterceptors(MyForm的);

  4. 打开调试器窗口,所有被调用的事件都将记录到事件日志

    [/ EDIT2]

7 个答案:

答案 0 :(得分:9)

使用我编写的download here“delphieventlogger”单元。它只是一个方法调用,非常容易使用。它将所有TNotifyEvents(例如OnChange,OnEnter,OnExit)记录到调试器窗口中的Delphi事件日志中。

答案 1 :(得分:3)

不,没有通用的方法可以做到这一点,因为Delphi没有任何可以以某种方式挂钩的“事件类型”。事件处理程序只是一个方法引用,它被调用如下:

if assigned(FEventHandler) then
  FEventHandler(self);

只是一个普通的方法引用调用。如果你想记录所有事件处理程序,你必须自己插入一些调用。

答案 2 :(得分:3)

我知道它有点贵,但你可以使用Automated QA(现在是SmartBear)TestRecorder作为TestComplete的扩展(如果你只想在你的系统上使用它,那么单独使用TestComplete)。这个软件将跟踪您的GUI操作并将其存储在类似语言的脚本中。甚至还有一个单元可以链接到您的exe中,以便直接在用户的系统上进行这些录制。当某些用户无法解释他们为产生错误所做的工作时,这尤其有用。

答案 3 :(得分:2)

使用WinSight实时查看消息流。

如果您确实希望程序生成日志,请覆盖WinProc和/或拦截Application中的消息。

答案 4 :(得分:2)

TApplication.OnMessage事件可用于捕获发布到主消息队列的消息。这主要是针对OS发出的消息,而不是内部VCL / RTL消息,这些消息通常直接分派给WndProc()方法。并非所有VCL事件都是以消息驱动的。没有任何一种解决方案可以满足您的需求。您必须在代码中使用TApplication.OnMessageTApplication.HookMainWindow()WndProc()覆盖,SetWindowsHook()和选择性断点/挂钩的组合。

Borland的WinSight工具不再发布了,但是有很多第三方工具可以与WinSight一样,例如微软的Spy ++,WinSpector等,用于实时跟踪日志窗口消息。

答案 5 :(得分:1)

作为替代方案,要调试触发事件,请使用调试器Step Into(F7)而不是Step Over(F8)命令。

调试器将在呼叫期间到达的任何可用代码行上停止。

答案 6 :(得分:-1)

您可以尝试其中一个AOP frameworks for Delphi。 MeAOP提供了一个可以使用的默认记录器。它不会告诉您事件处理程序内部发生了什么,但它会告诉您何时调用事件处理程序以及何时返回。