VSOFT.Messaging adalah lebary yang menyediakan sistem pesan publikasi/asinkron/asinkron internal untuk aplikasi Delphi.
Perpustakaan ini digunakan oleh FinalBuilder dan telah bekerja dengan baik selama bertahun -tahun.
Perpustakaan ini mengambil keuntungan dari TObject.Dispatch dan metode dinamis yang diperkenalkan kembali di Delphi 1.0. Metode pengiriman adalah bagaimana pesan Windows dikirim ke metode penangan pesan pada keturunan Tobject.
Sementara TObject.Dispatch awalnya ditambahkan untuk tujuan mengirim pesan Windows, itu sebenarnya tidak terikat pada windows. Itu berarti perpustakaan ini harus bekerja pada platform apa pun yang didukung Delphi. Yang mengatakan, saya hanya menguji ini di Win32/Win64 (VCL dan FMX).
Pesan didefinisikan sebagai catatan, dengan bidang 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 didefinisikan sebagai TMessageID = Cardinal;
Bidang pengisi hanya diperlukan jika Anda menangani pesan di aplikasi VCL atau FMX (pada Windows), dan kemudian hanya jika Anda menanganinya pada formulir, bingkai atau wincontrrol, yaitu apa pun dengan windproc. Ini karena defaulthandler dalam TControl , TWinControl dan TCustomForm melemparkan parameter pesan ke TMessage . Jika Anda menggunakan ini di platform lain, Anda dapat menggunakan Word untuk bidang MSGID, karena hanya itu yang digunakan oleh TObject.Dispatch
Pesan dikirim melalui objek saluran. Untuk membuat saluran, gunakan metode TMessageChannelFactory.CreateChannel
var
channel : IMessageChannel;
begin
channel := TMessageChannelFactory.CreateChannel;
...Contoh :
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 ; Perhatikan bahwa alasan PostMessage dan SendMessage ada di saluran. Properti Queue murni untuk mengatasi batasan generik di Delphi, di mana antarmuka non-generik tidak dapat memiliki metode generik (catatan dapat, jadi antrian sebenarnya adalah catatan).
Queue.PostMessage mengirimkan pesan secara tidak sinkron, yaitu metode pengembalian sebelum pesan telah diterima.
Queue.SendMessage Catatan SendMessage tidak boleh digunakan untuk mengirim pesan ke operator yang beroperasi di antarmuka pengguna, menggunakan PostMessage sebagai gantinya.
Agar suatu objek menerima pesan, ia perlu membuat operator, dan menghubungkan operator ke dirinya sendiri dan saluran
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 ;
Catatan: Jika Anda menangani pesan pada formulir/bingkai/kontrol di mana Anda akan membuat pembaruan UI, maka Anda harus menggunakan TMessageDispatcherFactory.CreateUIDispatcher - ini memastikan bahwa pesan hanya dikirim di utas utama (panggilan tThread.queue). Untuk alasan kinerja createUidispatcher tidak boleh digunakan untuk kode non UI, dan Anda harus menghindari menggunakan terlalu banyak operator UI yang terhubung ke saluran yang sama.
Menangani pesan sama seperti menangani pesan Windows di 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 ;