vsoft.messaging은 델파이 애플리케이션을위한 내부 동기/비동기 출판/구독 메시징 시스템을 제공하는 리바리입니다.
이 라이브러리는 FinalBuilder가 사용하며 수년간 잘 작동해 왔습니다.
이 라이브러리는 TObject.Dispatch 및 Delphi 1.0에 다시 소개 된 동적 방법을 활용합니다. 디스패치 방법은 Windows 메시지가 Tobject Descendant의 메시지 처리 방법으로 발송되는 방법입니다.
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에서 처리하는 경우에만 필요합니다. TControl , TWinControl 및 TCustomForm 의 defaulthandler가 메시지 매개 변수를 TMessage 에 캐스팅하기 때문입니다. 다른 플랫폼에서 이것을 사용하는 TObject.Dispatch Msgid 필드에 단어를 사용할 수 있습니다.
메시지는 채널 객체를 통해 전송됩니다. 채널을 만들려면 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 사용해야합니다. 이렇게하면 메시지가 기본 스레드에서만 발송되도록합니다 (tthread.queue 호출). 성능의 이유로 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 ;