vsoft.messagingは、Delphiアプリケーション向けに内部同期/非同期パブリッシュ/サブスクライブメッセージングシステムを提供するLibaryです。
このライブラリはFinalBuilderが使用しており、長年にわたってうまく機能しています。
このライブラリは、delphi 1.0で導入されたTObject.Dispatchと動的な方法を利用しています。ディスパッチ方法は、WindowsメッセージがTobjectの子孫に関するメッセージハンドラーメソッドにディスパッチされる方法です。
TObject.DispatchもともとWindowsメッセージを派遣する目的で追加されましたが、実際にはWindowsに結び付けられていません。つまり、このライブラリは、Delphiがサポートする任意のプラットフォームで動作する必要があります。とはいえ、Win32/Win64(VCLおよびFMX)でのみこれをテストしました。
メッセージは、MSGIDフィールドを備えたレコードとして定義されます。
// 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 TMessageID = Cardinal;
フィラーフィールドは、VCLまたはFMX(Windows)アプリケーションでメッセージを処理する場合にのみ必要です。その後、フォーム、フレーム、またはWinControlsでそれらを処理する場合にのみ、WindProcのあるものは何でも。これは、 TControl 、 TWinControlおよびTCustomFormの債務不履行者がメッセージパラメーターをTMessageにキャストするためです。他のプラットフォームでこれを使用している場合は、MSGIDフィールドにWordを使用できますTObject.Dispatchで使用されているのはそれだけです。
メッセージはチャネルオブジェクトを介して送信されます。チャネルを作成するには、 TMessageChannelFactory.CreateChannelメソッドを使用します
var
channel : IMessageChannel;
begin
channel := TMessageChannelFactory.CreateChannel;
...例 :
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 ; PostMessageとSendMessageがチャンネルにある理由に注意してください。Queueプロパティは純粋にデルファイのジェネリック制限を回避するためです。非遺伝子インターフェイスはジェネリックメソッドを持つことができません(レコードは実際にはレコードです)。
Queue.PostMessageメッセージを非同期に送信します。つまり、メッセージが受信される前にメソッドが返されます。
Queue.SendMessage 、すべてのディスパッチャーがメッセージの派遣を終了した後に戻ります。メモSendMessage使用して、ユーザーインターフェイスで動作するディスパッチャーにメッセージを送信しないでください。代わりにPostMessageを使用してください。
オブジェクトがメッセージを受信するには、ディスパッチャーを作成し、ディスパッチャーを自分自身とチャンネルにフックする必要があります
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 ;
注:uiの更新を行うフォーム/フレーム/コントロールでメッセージを処理する場合は、 TMessageDispatcherFactory.CreateUIDispatcherを使用する必要があります。パフォーマンスの理由から、CreateUidisPatcherをUI以外のコードに使用しないでください。同じチャネルにフックしたUIディスパッチャーが多すぎることを避ける必要があります。
メッセージを処理することは、DelphiでWindowsメッセージを処理するようなものです
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 ;