User interface Delphi:记录用户触发的UI事件

User interface Delphi:记录用户触发的UI事件,user-interface,delphi,logging,delphi-xe2,activity-tracing,User Interface,Delphi,Logging,Delphi Xe2,Activity Tracing,我被要求在我们的程序中加入一些东西,以便在某个地方记录表单上发生的事情 记录这样的东西…单击这个或那个按钮、上下文菜单、组件上触发的事件等等 这主要是因为我们处理的是遗留代码,没有很好的结构化。不幸的是,我们正在尽可能地调整/审查(Delphi XE10),我们希望从用户的角度跟踪正在发生的一切(或大部分),以便 -当一些神秘的事情发生时,能够引导用户做什么 -当我们不知道事情是如何发生的时候,能够在必要的时候检查代码 -最终速度问题 我不是说异常或数据记录……这些都得到了正确的处理 这只是关于

我被要求在我们的程序中加入一些东西,以便在某个地方记录表单上发生的事情

记录这样的东西…单击这个或那个按钮、上下文菜单、组件上触发的事件等等

这主要是因为我们处理的是遗留代码,没有很好的结构化。不幸的是,我们正在尽可能地调整/审查(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
    中修改
    t按钮
    。。。在pas和dfm文件中(我希望 您正在使用文本dfm,如果不是,最好将它们转换为文本)
  • 您必须将新设备添加到所有设备的接口部分 包含您感兴趣的控件的窗体
  • 你应该 在自定义库中注册新类以使它们 在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;