Replacing a component class in delphi

前端 未结 2 1810
时光说笑
时光说笑 2020-11-29 02:15

I know I\'ve seen an example somewhere of a hack to define a custom version of an existing VCL component, like TButton or TEdit, with the same class name and do something to

相关标签:
2条回答
  • 2020-11-29 02:37

    I guess what you're trying to remember is an "interposer class": inheriting a class giving the same name as the ancestor, by prefixing the ancestor's unit name. Since the class name is not changed, the dfm streaming mechanism is not disturbed. Would only affect the unit the class is re-declared in, unless it is put in a separate unit and that unit is included in the uses section after the base class'es. Obviously, you cannot have published properties in an interposed class.

    type
      TButton = class(stdctrls.TButton)
      protected
        procedure CreateParams(var Params: TCreateParams); override;
      end;
    
      TForm1 = class(TForm)
        Button1: TButton;
        [...]
      private
    
    0 讨论(0)
  • 2020-11-29 02:56

    In your form you can override the ReadState method like so:

    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;
    

    There are likely numerous other ways to do this, but this is how I do it!

    EDIT: Inspecting TReader.GetFieldClass(Instance: TObject; const ClassName: string) suggests the hack that Mason recalls. The first line sets ClassType := Instance.ClassType. So I suspect that by changing the declaration in the pas file from Button1: TButton to Button1: MyUnit.TButton will result in your button being created. Or perhaps the hack was to add MyUnit to the uses clause right at the end so that your version of TButton is the one that is in scope. However, none of this sounds very practical.

    0 讨论(0)
提交回复
热议问题