O VSOFT.Messaging é um Libary que fornece um sistema de mensagens síncronas/assíncronas internas para aplicativos Delphi.
Esta biblioteca é usada pela FinalBuilder e trabalha bem há muitos anos.
Esta biblioteca tira proveito dos métodos TObject.Dispatch e dinâmico que foram introduzidos em Delphi 1.0. O método de despacho é como as mensagens do Windows são despachadas para os métodos de manipulador de mensagens nos descendentes do TOBJECT.
Enquanto TObject.Dispatch foi originalmente adicionado com o objetivo de despachar as mensagens do Windows, ele não está realmente ligado ao Windows. Isso significa que essa biblioteca deve funcionar em qualquer plataforma que a Delphi suporta. Dito isto, eu só testei isso no Win32/Win64 (VCL e FMX).
As mensagens são definidas como registros, com um campo de 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 é definido como TMessageID = Cardinal;
O campo de preenchimento é necessário apenas se você estiver lidando com mensagens nos aplicativos VCL ou FMX (no Windows) e somente se você estiver lidando com eles em formulários, molduras ou Wincontrols, ou seja, qualquer coisa com um WindProc. Isso ocorre porque o Defeito em TControl , TWinControl e TCustomForm lança o parâmetro da mensagem para TMessage . Se você estiver usando isso em outras plataformas, poderá usar o Word para o campo MSGID, pois é tudo o que é usado pelo TObject.Dispatch
As mensagens são enviadas através de um objeto de canal. Para criar um canal, use o método TMessageChannelFactory.CreateChannel
var
channel : IMessageChannel;
begin
channel := TMessageChannelFactory.CreateChannel;
...Exemplo :
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 ; Observe que o motivo pelo qual a PostMessage e SendMessage estão no canal. A propriedade é puramente para contornar as limitações genéricas em Delphi, onde interfaces não genéricas não podem ter métodos genéricos (os registros podem, portanto, a fila é realmente um registro).
Queue.PostMessage envia a mensagem de forma assíncrona, ou seja, o método retorna antes que a mensagem seja recebida.
Queue.SendMessage Retorna depois que todos os despachantes terminam de despachar a mensagem. Nota SendMessage não deve ser usado para enviar mensagens para despachantes que operam na interface do usuário, use PostMessage .
Para um objeto receber as mensagens, ele precisa criar um despachante e conectar o despachante a si mesmo e ao canal
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 ;
NOTA: Se você estiver lidando com mensagens em formulários/quadros/controles onde você fará atualizações da interface do usuário, você deve usar TMessageDispatcherFactory.CreateUIDispatcher - isso garante que as mensagens sejam despachadas apenas no encadeamento principal (chamadas de tthread.queue). Por razões de desempenho, o CreateUidispatcher não deve ser usado para o código não da interface do usuário e você deve evitar o uso de muitos despachantes da interface do usuário presos ao mesmo canal.
Lidar com mensagens é como lidar com mensagens do Windows em 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 ;