在 Delphi 中替换组件类

cygmwpex  于 2023-02-19  发布在  其他
关注(0)|答案(2)|浏览(163)

我知道我在某个地方看到过这样一个例子:定义一个现有VCL组件的自定义版本,比如TButtonTEdit,使用相同的类名,并做一些事情来使其成为DFM流处理器将示例化您的版本而不是原始版本。我正处于这样一种情况,我需要能够做到这一点,但我找不到书面记录。有人知道在哪里可以找到如何完成这一点的信息吗?

xfb7svmp

xfb7svmp1#

在窗体中,可以重写ReadState方法,如下所示:

type
  TMyForm = class(TForm)
  protected
    procedure ReadState(Reader: TReader); override;
  end;

procedure TMyForm.ReadState(Reader: TReader);
begin
  Reader.OnFindComponentClass := FindComponentClass;
  inherited;
end;

procedure TMyForm.FindComponentClass(Reader: TReader; const ClassName: string;
  var ComponentClass: TComponentClass);
begin
  if ComponentClass=TButton then begin
    ComponentClass := TMySuperDuperButton;
  end else if ComponentClass=TEdit then begin
    ComponentClass := TMyTotallyAwesomeEdit;
  end;
end;

可能还有很多其他的方法可以做到这一点,但这就是我如何做到的!
编辑:检查TReader.GetFieldClass(Instance: TObject; const ClassName: string)会发现Mason回忆起的黑客攻击。第一行设置ClassType := Instance.ClassType。所以我怀疑通过将pas文件中的声明从Button1: TButton更改为Button1: MyUnit.TButton会导致创建您的按钮。或者,黑客攻击可能是将MyUnit添加到uses子句的最后,以便您的TButton版本在范围内。不过,这些听起来都不太实用。

kyks70gy

kyks70gy2#

我猜你要记住的是"interposer class":继承一个与祖先同名的类,通过前缀祖先的单元名。由于类名没有改变,dfm流机制没有被干扰。只会影响重新声明类的单元,除非它被放在一个单独的单元中,并且那个单元被包括在基类后面的uses节中。显然,你不能在一个插入类中发布属性。

type
  TButton = class(stdctrls.TButton)
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    [...]
  private

相关问题