Wesley Bobato
Wesley Bobato

Reputation: 105

Replace Call from one class to another?

I wonder if it is possible to replace the call from one class to another?

Example

TmyButton = class (TButton)
  procedure Click; override;
end;

initialization
  UnRegisterClass (TButton);
  RegisterClass (TButton);

But this code does not work properly, does anyone have any tips?

thank you

Please see the full example below, I'm calling at startup but unfortunately it has not worked correctly.

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls;

type
 TmyButton = class( TButton )
  procedure Click; override;

 end;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
begin
 inherited;
 ShowMessage( 'Hello' );
end;

{ TmyButton }

procedure TmyButton.Click;
begin

 ShowMessage( 'myClass' );
 inherited;

end;

initialization
 UnRegisterClass( TButton );
 RegisterClass( TMyButton );

end.

Upvotes: 1

Views: 191

Answers (2)

Ken Bourassa
Ken Bourassa

Reputation: 6467

I am not experienced with FMX, but I'd be really surprised if the following doesn't apply...

The reason your code isn't called is relatively simple, you don't create an object of that type.

Declaring a class TMyButton = class(TButton) doesn't replace code for the TButton class, it merely allow you to create instances of a class TMyButton that inherits from TButton.

Since Button1: TButton; is a TButton, clicking on it calls code from TButton, not code from TMyButton.

Upvotes: 4

Remy Lebeau
Remy Lebeau

Reputation: 596352

You are going about this the wrong way. What you need is an interposer class instead. Meaning your custom class has the same name as the class you are trying to replace. The DFM system doesn't use full qualified class names, so at runtime, the streaming system will create instances of the last class that has been defined with a given class name.

So, change this:

type
 TmyButton = class( TButton )
  procedure Click; override;
 end;

To this:

type
 TButton = class( FMX.StdCtrls.TButton )
  procedure Click; override;
 end;

And this:

{ TmyButton }

procedure TmyButton.Click;
begin

 ShowMessage( 'myClass' );
 inherited;

end;

To this:

{ TButton }

procedure TButton.Click;
begin

 ShowMessage( 'myClass' );
 inherited;

end;

And get rid of your initialization section completely.

Here is the full code:

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls;

type
 TButton = class( FMX.StdCtrls.TButton )
  procedure Click; override;

 end;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
begin
 inherited;
 ShowMessage( 'Hello' );
end;

{ TButton }

procedure TButton.Click;
begin

 ShowMessage( 'myClass' );
 inherited;

end;

end.

Upvotes: 7

Related Questions