Sending and Receiving Messages Using the RTL

From RAD Studio
Jump to: navigation, search

Go Up to Using the RTL Cross-Platform Messaging Solution


The RTL provides a cross-platform messaging solution, implemented in the System.Messaging unit.

To use this messaging solution:

  1. Obtain an instance of the message manager.
  2. Subscribe methods to specific message types.
  3. Send messages to the message manager.

The RTL only defines one type of message, TMessage. It is actually a template that you can use to create messages for specific types of values; for example: TMessage<int> or TMessage<UnicodeString>. You can also subclass TMessage to define your own message types or, if you are using FireMonkey, you can reuse the message types defined by the framework.

Note: For C++ projects use TMessageBase instead of TMessage.

Obtaining an Instance of the Message Manager

The TMessageManager class defines an object that acts as an application-wide notification center.

You can create many instances of TMessageManager, but this class can also work as a singleton. You can call TMessageManager.DefaultManager to access an instance of TMessageManager instead of instantiating your own instances and keeping tracking of them:

Delphi:

// var MessageManager: TMessageManager;
MessageManager := TMessageManager.DefaultManager;

C++:

TMessageManager* MessageManager = TMessageManager::DefaultManager();

FireMonkey, for example, relays system notifications using the default message manager.

Subscribing or Unsubscribing from Message Types

Once you have an instance of TMessageManager, you can subscribe message-handling methods to specific types of messages. Message-handling methods may be methods of an object or anonymous methods. The following code shows how to subscribe an anonymous method:

Delphi:

// var SubscriptionId: Integer;
SubscriptionId := MessageManager.SubscribeToMessage(TMessage<UnicodeString>, procedure(const Sender: TObject; const M: TMessage)
begin
  ShowMessage((M as TMessage<UnicodeString>).Value);
end);

C++:

1. Define a method in your class with the following signature:
void __fastcall TForm1::ShowReceivedMessage(System::TObject* const Sender, System::Messaging::TMessageBase* const M)
{
  TMessage__1<UnicodeString>* Message = dynamic_cast<TMessage__1<UnicodeString>*>(M);
  if (Message)
    ShowMessage(Message->Value);
}
2. Then subscribe this method as follows:
TMessageManager* MessageManager = TMessageManager::DefaultManager;
TMetaClass* MessageClass = __classid(TMessage__1<UnicodeString>);
TMessageListenerMethod ShowReceivedMessagePointer = &(this->ShowReceivedMessage);
int SubscriptionId = MessageManager->SubscribeToMessage(MessageClass, ShowReceivedMessagePointer);

After you subscribe a method to a type of message (TMessage<UnicodeString> in the example above), every time there is a broadcast of a message of this type, the subscribed method is called.

To unsubscribe a previously-subscribed method from a message type, call TMessageManager.Unsubscribe.

Broadcasting Messages

To broadcast a message to all those methods subscribed to the type of your message in a message manager, create an instance of TMessageBase or a subclass, and call TMessageManager.SendMessage:

Delphi:

MessageManager := TMessageManager.DefaultManager;
Message := TMessage<UnicodeString>.Create('This is a string message.');
MessageManager.SendMessage(Sender, Message, True);

C++:

TMessageManager* MessageManager = TMessageManager::DefaultManager;
TMessage__1<UnicodeString>* Message = new TMessage__1<UnicodeString>("This is a string message.");
MessageManager->SendMessage(Sender, Message, true);

See Also