Search code examples
delphieventscompiler-errorsdelphi-2007

How to compare an event and its corresponding procedure avoiding E2035 and E2036?


I'm trying to check if an event (TNotifyEvent) has been already assigned with a particular procedure(Sender: TObject) of object.

Here is my example code:

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

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  if(Button1.OnClick = Button1Click) then
  begin
    //...
  end;
end;

In this case, I get the following error message:

[DCC Error] Unit1.pas(28): E2035 Not enough actual parameters

So, I've tried as follows:

procedure TForm1.Button1Click(Sender: TObject);
begin
  if(@Button1.OnClick = @Button1Click) then
  begin
    //...
  end;
end;

On compiling, the error is changed to:

[DCC Error] Unit1.pas(28): E2036 Variable required

How can I check if Button1.OnClick points to the Button1Click?


Solution

  • ... of object procedures/functions are implemented as closures, which contains 2 pointers - a pointer for the implicit Self parameter, and a pointer to the procedure/function itself. You can use the TMethod record to access those pointers to compare them directly:

    procedure TForm1.Button1Click(Sender: TObject);
    var
      oc1, oc2: TNotifyEvent;
    begin
      oc1 := Button1.OnClick;
      oc2 := Button1Click;
      if (TMethod(oc1).Data = TMethod(oc2).Data) and
         (TMethod(oc1).Code = TMethod(oc2).Code) then
      begin
        //...
      end;
    end;