BMessageFilter
BMessageFilter is a class in Haiku OS that allows you to filter messages before they are dispatched to the target BHandler. It provides a way to intercept messages before they are processed by the target handler, allowing you to modify or discard messages based on certain criteria.
This class is defined at location:
- header file:
headers/os/app/MessageFilter.h
- src file:
src/kits/app/MessageFilter.cpp
Key Features of BMessageFilter:
- Message Filtering: Allows you to filter messages based on specific criteria.
- Interception: Intercept messages before they are processed by the target handler.
- Modification: Modify message content before it reaches the target handler.
- Discarding: Discard messages that do not meet the filtering criteria.
How BMessageFilter Works
- Creation: You create a subclass of BMessageFilter and override the Filter() function to define your filtering criteria.
- Installation: You install the message filter on a BHandler or a BLooper to intercept messages sent to that object.
- Message Processing: When a message is sent to the target object, it first goes through the message filter. If the message passes the filtering criteria, it is dispatched to the target handler. Otherwise, it is discarded or modified based on the filter's implementation.
+-----------------+
| Application |
+-----------------+
|
| Posts Message
v
+-----------------+
| BMessageQueue |
+-----------------+
|
| Message Sent
v
+-----------------+
| BMessageFilter|
+-----------------+
|
+----------+----------+
| |
v v
Discard Message Dispatch Message
| |
v v
+-----------------+ +-----------------+
| Discarded | | Target Handler |
| Message | | Message |
+-----------------+ +-----------------+
Explanation:
- Application: The application posts a message to the message queue.
- BMessageQueue: The message is sent to the message filter from the message queue.
- BMessageFilter: The message is intercepted by the message filter.
- If the message meets the filtering criteria, it is dispatched to the target handler.
- If the message does not meet the filtering criteria, it is discarded.
- Discarded Message: If the message is discarded, it is not sent to the target handler.
- Target Handler Message: If the message is dispatched, it is sent to the target handler for processing.
Example Usage:
Let's say you want to filter out all messages with the 'QUIT'
command before they reach the target handler. You can achieve this using BMessageFilter:
#include <Looper.h>
#include <Handler.h>
#include <Message.h>
#include <stdio.h>
class MyFilter : public BMessageFilter {
public:
MyFilter() : BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE) {}
filter_result Filter(BMessage* message, BHandler** target) {
if (message->what == B_QUIT_REQUESTED) {
// Discard the 'QUIT' message
return B_SKIP_MESSAGE;
}
return B_DISPATCH_MESSAGE;
}
};
class MyHandler : public BHandler {
public:
MyHandler() {}
void MessageReceived(BMessage* message) {
printf("Message received: %ld\n", message->what);
}
};
int main() {
MyHandler* handler = new MyHandler();
MyFilter* filter = new MyFilter();
handler->AddFilter(filter);
handler->Looper()->AddHandler(handler);
BMessage message('TEST');
handler->Looper()->PostMessage(&message);
BMessage quitMessage(B_QUIT_REQUESTED);
handler->Looper()->PostMessage(&quitMessage);
handler->Looper()->Run();
delete handler;
delete filter;
return 0;
}
Explanation:
1 Creating a Filter:
class MyFilter : public BMessageFilter {
public:
MyFilter() : BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE) {}
filter_result Filter(BMessage* message, BHandler** target) {
if (message->what == B_QUIT_REQUESTED) {
// Discard the 'QUIT' message
return B_SKIP_MESSAGE;
}
return B_DISPATCH_MESSAGE;
}
};
- We create a MyFilter subclass of BMessageFilter and override the Filter() function.
- In the Filter() function, we check if the message has the 'QUIT' command. If it does, we discard the message by returning B_SKIP_MESSAGE. Otherwise, we dispatch the message by returning B_DISPATCH_MESSAGE.
2 Adding Filter to Handler:
MyHandler* handler = new MyHandler();
MyFilter* filter = new MyFilter();
handler->AddFilter(filter);
- We create a MyHandler object and a MyFilter object.
- We add the filter to the handler using AddFilter().
3 Posting Messages:
BMessage message('TEST');
handler->Looper()->PostMessage(&message);
BMessage quitMessage(B_QUIT_REQUESTED);
handler->Looper()->PostMessage(&quitMessage);
- We post two messages to the handler's looper: one with the 'TEST' command and another with the 'QUIT' command.
4 Running the Looper:
handler->Looper()->Run();
- We start the looper to process the posted messages.
Advantages of Using BMessageFilter
- Message Filtering: Allows you to filter messages based on specific criteria.
- Interception: Intercept messages before they are processed by the target handler.
- Modification: Modify message content before it reaches the target handler.
- Discarding: Discard messages that do not meet the filtering criteria.