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
使用
在代码中的某个位置为要跟踪的每个表单添加此行。
AddEventInterceptors(MyForm的);
打开调试器窗口,所有被调用的事件都将记录到事件日志
[/ EDIT2]
答案 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.OnMessage
,TApplication.HookMainWindow()
,WndProc()
覆盖,SetWindowsHook()
和选择性断点/挂钩的组合。
Borland的WinSight工具不再发布了,但是有很多第三方工具可以与WinSight一样,例如微软的Spy ++,WinSpector等,用于实时跟踪日志窗口消息。
答案 5 :(得分:1)
作为替代方案,要调试触发事件,请使用调试器Step Into(F7)而不是Step Over(F8)命令。
调试器将在呼叫期间到达的任何可用代码行上停止。
答案 6 :(得分:-1)
您可以尝试其中一个AOP frameworks for Delphi。 MeAOP提供了一个可以使用的默认记录器。它不会告诉您事件处理程序内部发生了什么,但它会告诉您何时调用事件处理程序以及何时返回。