Vsoft.messaging es una liberación que proporciona un sistema de mensajería de publicación/suscripción de publicación/publicación asíncrona interna para aplicaciones Delphi.
Esta biblioteca es utilizada por FinalBuilder y ha estado funcionando bien durante muchos años.
Esta biblioteca aprovecha los métodos de disco y dinámicos de TObject.Dispatch . Que se introducieron en Delphi 1.0. El método de despacho es cómo se envían los mensajes de Windows a los métodos del controlador de mensajes en los descendientes de Tobject.
Mientras que TObject.Dispatch se agregó originalmente con el fin de enviar mensajes de Windows, en realidad no está vinculado a Windows. Eso significa que esta biblioteca debería funcionar en cualquier plataforma que Delphi admita. Dicho esto, solo he probado esto en Win32/Win64 (VCL y FMX).
Los mensajes se definen como registros, con un campo 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 se define como TMessageID = Cardinal;
El campo de relleno solo es necesario si está manejando mensajes en aplicaciones VCL o FMX (en Windows), y luego solo si los está manejando en formularios, marcos o wincontrols, es decir, cualquier cosa con un windproc. Esto se debe a que el defaulthandler en TControl , TWinControl y TCustomForm lanza el parámetro del mensaje a TMessage . Si está utilizando esto en otras plataformas, puede usar Word para el campo MSGID, ya que es todo lo que usa TObject.Dispatch
Los mensajes se envían a través de un objeto de canal. Para crear un canal, use el método TMessageChannelFactory.CreateChannel
var
channel : IMessageChannel;
begin
channel := TMessageChannelFactory.CreateChannel;
...Ejemplo :
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 ; Tenga en cuenta que la razón por la cual el PostMessage y SendMessage están en el canal. La propiedad de la cortesía es exclusivamente para trabajar alrededor de las limitaciones genéricas en Delphi, donde las interfaces no genéricas no pueden tener métodos genéricos (los registros pueden, por lo que la cola es en realidad un registro).
Queue.PostMessage envía el mensaje de forma asincrónica, es decir, el método regresa antes de que se haya recibido el mensaje.
Queue.SendMessage Devuelve después de que todos los despachadores hayan terminado de enviar el mensaje. Nota SendMessage no debe usarse para enviar mensajes a los despachadores que operan en la interfaz de usuario, use PostMessage en su lugar.
Para que un objeto reciba los mensajes, necesita crear un despachador y enganchar al despachador y el 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: Si está manejando mensajes en formularios/marcos/controles donde realizará actualizaciones de la interfaz de usuario, entonces debe usar TMessageDispatcherFactory.CreateUIDispatcher : esto asegura que los mensajes solo se envíen en el hilo principal (llame a thread.queue). Por razones de rendimiento, CreateUidispatcher no debe usarse para el código no UI, y debe evitar usar demasiados despachadores de interfaz de usuario conectados al mismo canal.
Manejar mensajes es como manejar los mensajes de Windows en 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 ;