Method pointer and regular procedure

This is the difference between a "procedure" and a "procedure of object"

The OnClick is defined as a TNotifyEvent:

type TNotifyEvent = procedure(Sender: TObject) of object;

You cannot assign a procedure to the OnClick as it is the wrong type. It needs to be a procedure of object.

You can wrap your procedures into a class. This class might look like this in a separate unit:

unit CommonUnit;

interface

uses
  Dialogs;

type
  TMenuActions = class // dummy class to hold event handlers
  public
    class procedure BrowseCategoriesClick(Sender: TObject);
  end;

implementation

{ TMenuActions }

class procedure TMenuActions.BrowseCategoriesClick(Sender: TObject);
begin
  ShowMessage('BrowseCategoriesClick');
end;

end

And to assign the action to a menu item in a different unit is enough to use this:

uses
  CommonUnit;

procedure TForm1.FormCreate(Sender: TObject);
begin
  PopupMenuItem1.OnClick := TMenuActions.BrowseCategoriesClick;
end;

Update:

Updated to use class procedures (instead of object methods) by David's suggestion.
For those who want to use the object methods with the need of object instance, follow this version of the post.

unit CommonUnit;

interface

uses
  Dialogs;

type
  TMenuActions = class
  public
    procedure BrowseCategoriesClick(Sender: TObject);
  end;

var
  MenuActions: TMenuActions;

implementation

{ TMenuActions }

procedure TMenuActions.BrowseCategoriesClick(Sender: TObject);
begin
  ShowMessage('BrowseCategoriesClick');
end;

initialization
  MenuActions := TMenuActions.Create;
finalization
  MenuActions.Free;

end.

Use a procedure as a fake method

procedure MyClick(Self, Sender: TObject);
begin
  //...
end;

var
  M: TMethod;
begin
  M.Data := nil;
  M.Code := @MyClick;
  MyMenuItem.OnClick := TNotifyEvent(M);
end;

use record methods ( global variable )

type
  TMyEventHandler = record
    procedure OnConnectionError(Sender: TObject; E: EDAError; var Fail: Boolean);
    procedure OnConnectionLost(Sender: TObject; Component: TComponent; ConnLostCause: TConnLostCause; var RetryMode: TRetryMode);
  end;

procedure TMyEventHandler.OnConnectionError(Sender: TObject; E: EDAError; var Fail: Boolean);
begin
  ....
end;

procedure TMyEventHandler.OnConnectionLost(Sender: TObject; Component: TComponent; ConnLostCause: TConnLostCause; var RetryMode: TRetryMode);
begin
  ....
end;

var
  EventHandler: TEventHandler;

......

mydb.OnError := EventHandler.OnConnectionError;
mydb.OnConnectionLost := EventHandler.OnConnectionLost;

原文地址:https://www.cnblogs.com/shangdawei/p/3051802.html