Jump to content
dormky

Anonymous instance methods

Recommended Posts

Figured that anonymous methods on instance procedures such as OnClick was actually possible with this little tick :

 

type
  // Allows instance anonymous procs by giving it to the constructor here and giving OnSender to the OnClick event for example
  // You need to give the instance on which the OnSender will be attributed so the object gets garbage-collected.
  // MyButton.OnClick := TAnonProc.Create(MyButton, procedure (Sender: TObject) begin /* */ end).OnSender;
  TAnonProc = class(TComponent)
    proc: TProc<TObject>;
    constructor Create(AOwner: TComponent; AProc: TProc<TObject>); reintroduce;
    procedure OnSender(Sender: TObject);
  end;

constructor TAnonProc.Create(AOwner: TComponent; AProc: TProc<TObject>);
begin
  inherited Create(AOwner);
  proc := AProc;
end;

procedure TAnonProc.OnSender(Sender: TObject);
begin
  if Assigned(proc) then proc(Sender);
end;

image.thumb.jpeg.771c4bda12f8fe3b7e535f6919e1ba89.jpeg

Edited by dormky

Share this post


Link to post

Yes, thats nice and useful, you can also extend this a bit, to avoid dangling pointers.

See these rough ideas ...
 

destructor TAnonProc.Destroy;
begin

  if (Owner is TButton) and
     (TMethod(TButton(Owner).OnClick).Data = Self) then
  begin 
      TButton( Owner ).OnClick := nil;     // Ensure to remove dangling Pointer 
  end;

  inherited;
end;

or you could even separate the Owner from the Observer

type
  TAnonProc = class(TComponent)
  private
    FProc: TProc<TObject>;
    procedure Notification(AComponent: TComponent;
                           Operation: TOperation); override;
    procedure OnSender(Sender: TObject);
  public
    constructor Create(AOwner, AObserved: TComponent;
                       AProc: TProc<TObject>);
  end;

constructor TAnonProc.Create(AOwner, AObserved: TComponent;
  AProc: TProc<TObject>);
begin
  inherited Create(AOwner);   // Owner = Form
  FProc := AProc;
  AObserved.FreeNotification(Self);  // register observer
  if AObserved is TButton then
    TButton(AObserved).OnClick := OnSender;
end;

procedure TAnonProc.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  if (Operation = opRemove) and (AComponent is TButton) then
  begin 
    TButton(AComponent).OnClick := nil;   // Clear the Pointer
  end;
  
  inherited;
end;

procedure TAnonProc.OnSender(Sender: TObject);
begin
  if Assigned(FProc) then
    FProc(Sender);
end;


//..........................

TAnonProc.Create(Self, Button1,
  procedure(Sender: TObject)
  begin
    Caption := 'Click!';
  end);

 

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×