VSOFT.Messaging เป็น libary ที่ให้บริการระบบส่งข้อความ/สมัครสมาชิกแบบซิงโครนัสภายใน/แบบอะซิงโครนัสสำหรับแอปพลิเคชัน Delphi
ห้องสมุดนี้ใช้โดย FinalBuilder และทำงานได้ดีมาหลายปีแล้ว
ไลบรารีนี้ใช้ประโยชน์จากวิธีการ TObject.Dispatch และแบบไดนามิกซึ่งได้รับการแนะนำกลับใน Delphi 1.0 วิธีการจัดส่งเป็นวิธีที่ข้อความ 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 นี่เป็นเพราะ defaulthandler ใน TControl , TWinControl และ TCustomForm ทำให้พารามิเตอร์ข้อความเป็น TMessage หากคุณใช้สิ่งนี้บนแพลตฟอร์มอื่น ๆ คุณสามารถใช้ Word สำหรับฟิลด์ msgid ได้เช่นเดียวกับที่ใช้โดย 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 อยู่ในช่องทางคุณสมบัติของ QUINEME คือการแก้ไขข้อ จำกัด ทั่วไปใน Delphi อย่างหมดจดซึ่งอินเทอร์เฟซที่ไม่ใช่ Generic ไม่สามารถมีวิธีการทั่วไป (บันทึกสามารถดังนั้นคิวจึงเป็นบันทึกจริง)
Queue.PostMessage ส่งข้อความแบบอะซิงโครนัสเช่นวิธีการส่งคืนก่อนที่จะได้รับข้อความ
Queue.SendMessage ส่งคืนหลังจาก dispatchers ทั้งหมดได้ส่งข้อความเสร็จแล้ว หมายเหตุไม่ควรใช้ SendMessage เพื่อส่งข้อความไปยัง dispatchers ที่ทำงานบนส่วนต่อประสานผู้ใช้ใช้ PostMessage แทน
สำหรับวัตถุที่จะได้รับข้อความจำเป็นต้องสร้าง dispatcher และเชื่อมต่อตัวแจกจ่ายให้กับตัวเองและช่อง
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 - สิ่งนี้ทำให้มั่นใจได้ว่าข้อความจะถูกส่งเฉพาะในเธรดหลัก (เรียก tthread.queue) ด้วยเหตุผลด้านประสิทธิภาพ createuidispatcher ไม่ควรใช้สำหรับรหัส UI ที่ไม่ใช่ UI และคุณควรหลีกเลี่ยงการใช้ UI Dispatchers มากเกินไปที่เชื่อมต่อกับช่องเดียวกัน
การจัดการข้อความก็เหมือนกับการจัดการข้อความ Windows ใน 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 ;