I'm trying to use the Spring4d framework for Delphi and I want to use the Multicast Events. While using the "normal" TNotifyEvent, it works and the handler will get called twice.
uses
...
Spring,
Spring.Events,
Spring.Events.Base;
procedure TfrmMain.EventHandler1(Sender: TObject);
begin
Log('called handler1');
end;
procedure TfrmMain.btnNotifyEventClick(Sender: TObject);
var
MulticastEvent: TEvent<TNotifyEvent>;
begin
MulticastEvent := TEvent<TNotifyEvent>.Create;
try
MulticastEvent.Add(EventHandler1);
MulticastEvent.Add(EventHandler1);
MulticastEvent.Add(EventHandler1);
MulticastEvent.Remove(EventHandler1);
MulticastEvent.Invoke;
finally
MulticastEvent.Free;
end;
end;
But I can't figure out how to use these Multicast events with my own Event TSyncEvent
. The EventHandler2 expects a string. So I want to call the Invoke-method with the text.
type
TSyncEvent = procedure(Sender: TObject; const iMsg: string) of object;
procedure TfrmMain.EventHandler2(Sender: TObject; const iMsg: string);
begin
Log('called handler2: '+iMsg);
end;
procedure TfrmMain.btnSyncEventClick(Sender: TObject);
var
MulticastEvent: TEvent<TSyncEvent>;
begin
MulticastEvent := TEvent<TSyncEvent>.Create;
try
MulticastEvent.Add(EventHandler2);
MulticastEvent.Add(EventHandler2);
MulticastEvent.Invoke('text for handler2');
finally
MulticastEvent.Free;
end;
end;
This code does not compile with the error message "too many params for method Invoke". Unfortunately there is no example using the Multicast events in the framework or on the project page. I'm using Delphi 10.3.3 Community Edition.
Thank you.
You are not supposed to use the TEvent<T>
class from Spring.Events.pas
because it's an implementation detail and in fact, in 2.0 it will not even exist anymore because it was refactored.
Instead, use the record type Event<T>
from Spring.pas
. It does not need to be created nor destroyed because it does that automatically.
Once you change that in your code you will see that you are missing the Sender
argument.
Press Ctrl+Shift+Space to see the parameters of Invoke
- it has exactly the same signature of the type of T
you are providing.
Fixed code:
procedure TfrmMain.btnSyncEventClick(Sender: TObject);
var
MulticastEvent: Event<TSyncEvent>;
begin
MulticastEvent.Add(EventHandler2);
MulticastEvent.Add(EventHandler2);
MulticastEvent.Invoke(Sender, 'text for handler2');
end;