Vsoft.Messaging ist eine Libary, die ein internes synchrones/asynchrones Veröffentlichung/Abonnement -Messaging -System für Delphi -Anwendungen bietet.
Diese Bibliothek wird von Finalbuilder verwendet und arbeitet seit vielen Jahren gut.
Diese Bibliothek nutzt TObject.Dispatch und dynamische Methoden, die in Delphi 1.0 zurückgestellt wurden. Die Versandmethode ist, wie Windows -Nachrichten auf Message -Handler -Methoden auf Tobject -Nachkommen versandt werden.
Während TObject.Dispatch ursprünglich zum Zweck des Versendens von Windows -Nachrichten hinzugefügt wurde, ist es nicht wirklich an Windows gebunden. Das bedeutet, dass diese Bibliothek auf jeder Plattform funktionieren sollte, die Delphi unterstützt. Trotzdem habe ich dies nur auf Win32/Win64 (VCL und FMX) getestet.
Nachrichten werden als Datensätze mit einem MSGID -Feld definiert.
// create a unique message id.
// on windows this needs to be higher than WM_USER
const PROJECT_OPENED_MSG = WM_USER + $ 1000 ;
type
TProjectOpenedMessage = record
MsgID : TMessageID;
Filler : TMessageFiller;
// payload starts here.
ProjectName : string;
public
constructor Create( const theProjectName : string);
end ;
implementation
constructor TProjectOpenedMessage.Create( const theProjectName : string);
begin
MsgID := PROJECT_OPENED_MSG; // assign our message id
ProjectName := theProjectName; // store the payload.
end ;
TMessageID ist definiert als TMessageID = Cardinal;
Das Füllstofffeld wird nur benötigt, wenn Sie Nachrichten in VCL- oder FMX -Anwendungen (unter Windows) bearbeiten, und dann nur, wenn Sie sie für Formulare, Frames oder Wincontrols bearbeiten, dh irgendetwas mit einem Windproc. Dies liegt daran, dass der Defaulthandler in TControl , TWinControl und TCustomForm den Meldungsparameter auf TMessage übertragen. Wenn Sie dies auf anderen Plattformen verwenden, können Sie Word für das MSGID -Feld verwenden, da dies alles ist, was von TObject.Dispatch verwendet wird
Nachrichten werden über ein Kanalobjekt gesendet. Verwenden Sie zum Erstellen eines Kanals die Methode TMessageChannelFactory.CreateChannel
var
channel : IMessageChannel;
begin
channel := TMessageChannelFactory.CreateChannel;
...Beispiel :
procedure SendProjectOpenedMessage ( const projectName : string)
var
msg : TProjectOpenedMessage;
begin
msg := TProjectOpened.Create(projectName);
FChannel.Queue.PostMessage(msg); // async
// or
FChannel.Queue.SendMessage(msg); // sync
end ; Beachten Sie, dass der Grund, warum PostMessage und SendMessage auf dem Kanal liegen. Die Eigenschaft in der Queue ist nur darin, die Generika-Einschränkungen in Delphi zu bearbeiten, wobei nicht generische Schnittstellen keine generischen Methoden haben können (Datensätze können also eine Warteschlange sind tatsächlich ein Datensatz).
Queue.PostMessage sendet die Nachricht asynchron, dh die Methode kehrt zurück, bevor die Nachricht empfangen wurde.
Queue.SendMessage kehrt zurück, nachdem alle Disponenten die Nachricht abgeschlossen haben. HINWEIS SendMessage sollte nicht verwendet werden, um Nachrichten an Disponenten zu senden, die auf der Benutzeroberfläche arbeiten, und verwenden Sie stattdessen PostMessage .
Damit ein Objekt die Nachrichten empfängt, muss es einen Dispatcher erstellen und den Dispatcher an sich selbst und den Kanal anschließen
type
TReceiver = class
private
FDispatcher : IMessageDispatcher;
public
constructor Create( const channel : IMessageChannel);
end ;
implementation
constructor TReceiver.Create( const channel : IMessageChannel);
begin
FDispatcher := TMessageDispatcherFactory.CreateDispatcher;
// tell the dispatcher where to dispatch the messages to.
FDispatcher.Target := Self;
// hook up the dispatcher to the channel.
FDispatcher.Channel := channel;
end ;
Hinweis: Wenn Sie Nachrichten zu Formularen/Frames/Steuerelementen abwickeln, in denen Sie UI -Updates erstellen, sollten Sie TMessageDispatcherFactory.CreateUIDispatcher verwenden, sodass Sie sicherstellen, dass Nachrichten nur auf dem Haupt -Thread versandt werden (thead.queue). Aus Leistungsgründen sollte CreateUidispatcher nicht für Non -UI -Code verwendet werden, und Sie sollten vermeiden, dass zu viele UI -Disponenten an demselben Kanal angewendet werden.
Die Handhabung von Nachrichten ist genau wie die Handhabung von Windows -Nachrichten in Delphi
type
TReceiver = class
private
...
procedure ProjectOpened ( var msg : TProjectOpenedMessage); message PROJECT_OPENED_MSG;
...
end ;
implementation
procedure TReceiver.ProjectOpened ( var msg : TProjectOpenedMessage);
begin
// use msg.ProjectName payload here.
end ;