TProc<TObject> to TNotifyEvent

anonymous, delphi, delphi-xe

Solution

This will do the job readily enough:

type
  TNotifyEventWrapper = class(TComponent)
  private
    FProc: TProc<TObject>;
  public
    constructor Create(Owner: TComponent; Proc: TProc<TObject>);
  published
    procedure Event(Sender: TObject);
  end;

constructor TNotifyEventWrapper.Create(Owner: TComponent; Proc: TProc<TObject>);
begin
  inherited Create(Owner);
  FProc := Proc;
end;

procedure TNotifyEventWrapper.Event(Sender: TObject);
begin
  FProc(Sender);
end;

function AnonProc2NotifyEvent(Owner: TComponent; Proc: TProc<TObject>): TNotifyEvent;
begin
  Result := TNotifyEventWrapper.Create(Owner, Proc).Event;
end;

The `Owner` parameter in `AnonProc2NotifyEvent` is so that the lifetime of the wrapper object can be managed. Without something like that you would leak instances of `TNotifyEventWrapper`.

Pass as `Owner`, the component to which you are connecting the event. For example:

Button1.OnClick := AnonProc2NotifyEvent(
  Button1,
  procedure(Sender: TObject)
  begin
    (Sender as TButton).Caption := 'Clicked';
  end
);

So, when the button is destroyed, the `TNotifyEventWrapper` will also be destroyed. The wrapper object must live at least as long as the object to whose events it is associated. And so the choice of `Button1` as the owner is the natural and obvious one.

Problem

Further to this post whose accepted answer remains very cryptic: ``` @Button1.OnClick := pPointer(Cardinal(pPointer( procedure (sender: tObject) begin ((sender as TButton).Owner as TForm).Caption := 'Freedom to anonymous methods!' end )^ ) + $0C)^; ``` I wonder wether it is possible to devise a simplest and elegant way akin to: ``` Button.OnClick := AnonProc2NotifyEvent ( procedure (Sender: TObject) begin ((Sender as TButton).Owner as TForm).Caption := 'Freedom to anonymous methods!' end ); ``` so as to attain the same purpose and where AnonProc2NotifyEvent is a method of the owner of Button with the following signature: ``` TOwnerOfButton = class(TForm) Button: TButton; ... private ... protected function AnonProc2NotifyEvent(aProc: TProc<TObject>): TNotifyEvent; public ... end; ``` Is that feasible and if so how to implement it ?

Original source

Related problems