Events and Method Pointers
20.1 Method Pointers (of object)
A method pointer = code pointer + object pointer (TMethod). VCL/FMX events are single-cast (one handler per event).
type
TNotifyEvent = procedure(Sender: TObject) of object; // already declared in System.Classes
TProgressEvent = procedure(Sender: TObject; Percent: Integer; var Cancel: Boolean) of object;
TDownloader = class
private
FOnProgress: TProgressEvent;
FOnComplete: TNotifyEvent;
public
procedure Run;
property OnProgress: TProgressEvent read FOnProgress write FOnProgress;
property OnComplete: TNotifyEvent read FOnComplete write FOnComplete;
end;
procedure TDownloader.Run;
var
Cancel: Boolean;
begin
Cancel := False;
for var I := 1 to 100 do
begin
if Assigned(FOnProgress) then FOnProgress(Self, I, Cancel); // fire only if assigned
if Cancel then Exit;
end;
if Assigned(FOnComplete) then FOnComplete(Self);
end;
// Subscriber (a form method)
procedure TMainForm.HandleProgress(Sender: TObject; Percent: Integer; var Cancel: Boolean);
begin
ProgressBar1.Position := Percent;
end;
Downloader.OnProgress := HandleProgress; // assign the handler20.2 Multicast Events
Implement a list of handlers (TList<TNotifyEvent>), or use the Spring4D Event<T> / IEvent<T> multicast events, or System.Messaging.TMessageManager (publish/subscribe).
uses System.Messaging;
type TOrderPlacedMessage = class(TMessage<Integer>);
var SubId := TMessageManager.DefaultManager.SubscribeToMessage(TOrderPlacedMessage,
procedure(const Sender: TObject; const M: TMessage)
begin
Writeln('Order placed: ', TOrderPlacedMessage(M).Value);
end);
TMessageManager.DefaultManager.SendMessage(nil, TOrderPlacedMessage.Create(42));
TMessageManager.DefaultManager.Unsubscribe(TOrderPlacedMessage, SubId);