Delphi 如何实现基类事件?

Delphi how to implement baseclass event?

我有一个抽象的 Delphi XE 表单,作为我的应用程序中使用的一系列表单的基础 class。我正在尝试找出创建帮助功能(在 F1 按键上)的最佳方法,该功能可以为活动表单打开 wiki 页面。

我非常希望这个函数在 base-class 级别实现并在用户按下 F1 时调用,但我需要一些关于如何以巧妙的方式执行此操作的建议。目前我只是在基本窗体上放置一个 KeyDown 事件,但是如果子窗体接收到它自己的 KeyDown,这将被覆盖,此时我必须手动调用 baseKeyDown。显然,这不是最优的。有没有办法确保我在 baseclass 级别捕获 F1 按键,随机重载不受影响?

我是 运行 Delphi XE Windows 7

您应该在基本表单 class 中覆盖 KeyDown 方法。

type
  TBaseForm = class(TForm)
  protected
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  end;

procedure TBaseForm.KeyDown(var Key: Word; Shift: TShiftState);
begin
  // do your processing here
  // ...
  inherited; // call inherited method that will call OnKeyDown if assigned
end;

这是调用 OnKeyDown 事件的 KewDown 方法的默认实现

procedure TWinControl.KeyDown(var Key: Word; Shift: TShiftState);
begin
  if Assigned(FOnKeyDown) then FOnKeyDown(Self, Key, Shift);
end;

您问题的直接答案是库编写者不应分配给事件处理程序。这是因为这样做会使图书馆消费者很难同时消费这些事件。当你写一个 base class 时,你就扮演了图书馆作者的角色。

因此,不要在 OnKeyDown 事件中实现处理程序,而是覆盖 KeyDown 方法。

type
  TBaseForm = class(TForm)
  protected
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  end;
....
procedure TBaseForm.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited; // this will fire the OnKeyDown event
  // your processing for F1 goes here
end;

不过,我想知道使用内置的帮助系统是否会更好。就我个人而言,我会为 Application 对象添加一个 OnHelp 事件,并将集中式逻辑放在那里。