在delphi中替换组件类

时间:2011-01-13 22:06:17

标签: delphi controls

我知道我已经看到一个黑客的例子来定义现有VCL组件的自定义版本,比如TButton或TEdit,具有相同的类名并做一些事情来使DFM流媒体实例化你的版本而不是原始版本。不幸的是,我处于一种我需要能够做到这一点的情况,我找不到写作。有谁知道在哪里可以找到有关如何实现这一目标的信息?

2 个答案:

答案 0 :(得分:19)

在表单中,您可以覆盖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)表明了梅森回忆起的黑客行为。第一行设置ClassType := Instance.ClassType。所以我怀疑通过将pas文件中的声明从Button1: TButton更改为Button1: MyUnit.TButton将导致您的按钮被创建。或者也许黑客是将MyUnit添加到最后的uses子句中,以便您的TButton版本是范围内的那个。但是,这听起来都不是很实用。

答案 1 :(得分:11)

我猜你要记住的是"interposer class":继承一个与祖先同名的类,通过在祖先的单位名称前加上前缀。由于类名未更改,因此dfm流机制不会受到干扰。只会影响该类重新声明的单位,除非它被放在一个单独的单元中,并且该单元包含在基类之后的使用部分中。显然,您不能在插入的类中发布属性。

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

  TForm1 = class(TForm)
    Button1: TButton;
    [...]
  private
相关问题