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.
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::TMessage* 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 TMessage 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