代码之家  ›  专栏  ›  技术社区  ›  Martin Prikryl

钩住脚踏车。OnFindComponentClass[重复]

  •  1
  • Martin Prikryl  · 技术社区  · 6 年前

    我知道我在某个地方见过一个黑客的例子,用相同的类名定义现有VCL组件的自定义版本,如TButton或TEdit,并做一些事情使其成为DFM streamer将实例化您的版本而不是原始版本。不幸的是,我现在的处境是,我需要能够做到这一点,但我找不到写作。有人知道在哪里可以找到关于如何实现这一点的信息吗?

    0 回复  |  直到 10 年前
        1
  •  23
  •   David Heffernan    14 年前

    在表单中,可以覆盖 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

        2
  •  12
  •   Sertac Akyuz    14 年前

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

    type
      TButton = class(stdctrls.TButton)
      protected
        procedure CreateParams(var Params: TCreateParams); override;
      end;
    
      TForm1 = class(TForm)
        Button1: TButton;
        [...]
      private