User interface Delphi:记录用户触发的UI事件
我被要求在我们的程序中加入一些东西,以便在某个地方记录表单上发生的事情 记录这样的东西…单击这个或那个按钮、上下文菜单、组件上触发的事件等等 这主要是因为我们处理的是遗留代码,没有很好的结构化。不幸的是,我们正在尽可能地调整/审查(Delphi XE10),我们希望从用户的角度跟踪正在发生的一切(或大部分),以便 -当一些神秘的事情发生时,能够引导用户做什么 -当我们不知道事情是如何发生的时候,能够在必要的时候检查代码 -最终速度问题 我不是说异常或数据记录……这些都得到了正确的处理 这只是关于用户界面 你知道有没有类似的图书馆? 如果没有,您将如何尝试实现这一目标 代码示例被愉快地接受(即使是简单的,比如一个/多个表单,带有几个按钮等)User interface Delphi:记录用户触发的UI事件,user-interface,delphi,logging,delphi-xe2,activity-tracing,User Interface,Delphi,Logging,Delphi Xe2,Activity Tracing,我被要求在我们的程序中加入一些东西,以便在某个地方记录表单上发生的事情 记录这样的东西…单击这个或那个按钮、上下文菜单、组件上触发的事件等等 这主要是因为我们处理的是遗留代码,没有很好的结构化。不幸的是,我们正在尽可能地调整/审查(Delphi XE10),我们希望从用户的角度跟踪正在发生的一切(或大部分),以便 -当一些神秘的事情发生时,能够引导用户做什么 -当我们不知道事情是如何发生的时候,能够在必要的时候检查代码 -最终速度问题 我不是说异常或数据记录……这些都得到了正确的处理 这只是关于
谢谢大家 作为您可以使用的轻量级解决方案,或
如果您想使用特殊的查看器、线程安全等进行奇特的日志记录,您可以包括一些特殊的日志记录框架。在这种情况下,最好在线搜索并自己比较功能,而不是在这里征求意见。您可以开发一个非可视组件,并将其放到每个表单上,但这必须是一个非常复杂的组件,它要么使用RTTI,要么偷看windows消息,试图监听表单中其他可视组件的情况 我发现有两种更简单的方法至少可以部分满足你的要求 1) 拦截对EventHandler的调用 开发一个组件(比我上面暗示的要简单一些),该组件连接到您感兴趣的控件类的事件,记录调用,然后将它们转发到原始eventhandler过程(如果有) 假设您感兴趣的是
TWinControl.oneter
和OnExit
,TButton.OnClick
和TEdit.OnChange
TEventLogger = Class(TComponent)
Private
Procedure Hookup(Const EventName: String; Const Component: TComponent; Const LoggingHandler: TNotifyEvent; Var Handler: TNotifyEvent);
Public
Procedure Setup(Const Container: TComponent);
Procedure HandleChange(Sender: TObject);
Procedure HandleClick(Sender: TObject);
Procedure HandleEnter(Sender: TObject);
Procedure HandleExit(Sender: TObject);
End;
Procedure TEventLoggerHookup(Const EventName: String; Const Component: TComponent; Const LoggingHandler: TNotifyEvent; Var Handler: TNotifyEvent);
Begin
if Assigned(Handler) Then
Handlers.AddObject(Component.Name + ';' + EventName, Handler);
Handler := LoggingHandler;
End;
Procedure TEventLogger.Setup(Const Container: TComponent);
Var
i: Integer;
c: TComponent;
Begin
For i:=0 to Container.ComponentCount - 1 Do Begin
c := Container.Components[i];
if c Is TWinControl Then Begin
Hookup('Enter',HandleEnter,TWinControl(c).OnEnter;
Hookup('Exit',HandleExit,TWinControl(c).OnExit;
End;
If c Is TButton Then
Hookup('Click',HandleClick,TButton(c).OnClick;
If c Is TEdit Then
Hookup('Change',HandleChange,TEdit(c).OnChange;
End;
End;
Procedure TEventLogger.Procedure HandleChange(Sender: TObject);
Var
s: String;
i: Integer;
e: TNotifyEvent;
Begin
With Sender As TComponent Do Begin
s := Name + ';Change';
Log(s);
i:= Handlers.IndexOf(s);
If i <> -1 Then Begin
e := Handlers.Objects[i];
e(Sender);
End;
End;
End;
然后可以实现Log方法,添加所需的所有信息(表单和组件类、名称或其他信息)。如果您想做一些复杂的事情,那么最好将日志操作委托给一个专门的类
这也没有经过测试。要记住的事情:
- 要设置它,您只需使用大量搜索和替换。。。到
在
中修改TLogButton
。。。在pas和dfm文件中(我希望 您正在使用文本dfm,如果不是,最好将它们转换为文本)李>t按钮
- 您必须将新设备添加到所有设备的接口部分 包含您感兴趣的控件的窗体
- 你应该 在自定义库中注册新类以使它们 在IDE中可用,否则您将无法打开表单 在设计时
- 你每上一节课都要这样做 对……感兴趣。。。如果应用程序使用多个 不同但相似的控件类别
- 你必须知道 要记录的类的内部。。。并非所有的方法都适用 可重写的。。。许多第三方库没有提供源代码。。。 可能是地狱
总的来说。。。我可能会选择后一种解决方案。它基本上更容易在单个控件类上实现,而且您可能已经可以通过一组类获得一些非常有用的用户活动跟踪。前一种解决方案有点复杂,可能会扩展到涵盖某些情况。。。但是,如果您不太了解自己的代码库,则更难进行全面测试,而且风险太大 当你在这个网站上问“你知道图书馆吗”时要小心,因为这是违反规定的。当人们审查/结束一定数量的问题时,他们会获得额外的特权。哦,谢谢你……我不认为这可能是个问题;)嗯,谢谢……但我知道如何记录一些东西……问题更多的是如何构造东西,以便构建一些可以“注入”到实际代码上的东西,而无需逐个事件,并在其中放入一些代码。。。。让我们说一些更有“活力”的话……;)谢谢你的意见。是的,我的意图是使用RTTI构建一个非可视组件来遍历表单上的每个控件等等。。。也可能使用观察者。我现在不能花一些时间来尝试和测试,因为我正在SQL server端构建一个日志工具来记录表上的更改等等。。。。。我会尽快处理好的,希望。。。我最终会让你知道事情的进展;)
TLogButton = class(TButton)
private
procedure Log(Const Event: String);
protected
procedure Click; override;
end;
TLogButton.Click;
begin
Log('Click');
Inherited;
end;