2011-01-11 74 views
14

Delphi调试器非常适合调试线性代码,其中一个函数以可预测的线性方式调用其他函数,并且我们可以逐行执行程序。有没有办法在Delphi中记录每一个gui事件?

我发现调试器在处理事件驱动的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调试。

我使用德尔福2010

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

[EDIT2] 在阅读了这里的所有信息后,我有一个想法是使用RTTI动态截取TNotifyEvents并将它们记录到调试窗口中的事件日志中。这包括OnEnter,OnExit,OnChange,OnClick,OnMouseEnter,OnMouseLeave事件。经过一番黑客攻击之后,我得到了很好的工作,至少对于我的使用来说(它不会记录关键事件,但可以添加)。 我已经发布的代码here

要使用

  1. 下载EventInterceptor单位,并将其添加到您的项目
  2. 添加EventInterceptor股uses子句
  3. 在某处添加此行您想要跟踪的每种表单的代码。

    AddEventInterceptors(MyForm);

打开调试窗口以及调用的任何事件将被记录到事件日志

[/ EDIT2]

回答

8

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

2

使用WinSight看到实时消息流。

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

+0

是否所有的Delphi事件都是Windows消息?我刚刚尝试使用TApplicationEvents.OnMessage记录事件,而我似乎只能看到鼠标移动和键盘事件。我没有看到OnChange,或OnExit或OnEnter事件(据我所知)。我想我希望得到比Windows消息更高级别的东西。 – awmross 2011-01-11 02:50:11

+0

btw WinSight没有与德尔福2010年 – awmross 2011-01-11 02:50:42

+2

@awmross:德尔福事件不是Windows消息。 Windows消息被派发到Delphi控件上的消息处理例程,其中一些调用事件处理程序(如果附加了一个)。 – 2011-01-11 04:42:54

3

不,没有通用的方法来做到这一点,因为德尔福没有任何可以以某种方式挂钩的“事件类型”。一个事件处理程序只是一个方法引用,它会像这样调用:

if assigned(FEventHandler) then 
    FEventHandler(self); 

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

3

我知道这有点贵,但是您可以使用自动化QA(现在称为SmartBear)TestRecorder作为TestComplete的扩展(如果您只想在您的系统上使用TestComplete,那么只有TestComplete会这样做)。这部分软件会跟踪您的GUI操作,并将其存储在像语言这样的脚本中。甚至有一个单元可以链接到您的exe文件中,直接在用户的系统上进行录制。当一些用户无法解释他们已经做了什么来产生错误时,这是​​特别有用的。

-1

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

1

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

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

2

TApplication.OnMessage事件可用于捕获发布到主消息队列的消息。这主要是针对OS发布的消息,而不是内部的VCL/RTL消息,通常直接发送到WndProc()方法。并非所有的VCL事件都是以消息驱动开始的。没有单一的解决方案,你在找什么。您将不得不使用代码中的TApplication.OnMessage,TApplication.HookMainWindow(),WndProc()替代组合,SetWindowsHook()和选择性断点/钩子的组合。

Borland的WinSight工具不再发布,但有许多第三方工具可以像WinSight一样随时提供功能,例如Microsoft Spy ++,WinSpector等,用于实时跟踪日志窗口消息。

相关问题