Sending and Receiving Messages Using the RTL
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:
- Obtain an instance of the message manager.
- Subscribe methods to specific message types.
- 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.
Contents
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
- System.Messaging (Delphi) code example
- System.Messaging (C++) code example