# The Application Kit: BMessageFilter

Derived from: none

Declared in: be/app/MessageFilter.h

Library: libbe.so

## Overview

A BMessageFilter designates a function that's called whenever a BMessage arrives at a BLooper's door. The "filter" is run before the BLooper dispatches the BMessages to a BHandler. they're dispatched to their designated handlers. The filter can reject the message, reset the handler that the message will be sent to, or whatever else it wants to do--the implementation of the filter function isn't restricted.

You can provide the filter function either by...

- implementing the `Filter()` hook function in a BMessageFilter subclass, or...

- by supplying a `filter_hook` function to the BMessageFilter constructor.

If you do both, the `filter_hook` function wins.

You "attach" a BMessageFilter object to a message loop by assigning it either to a BHandler object or to a BLooper:

- If assigned to a BHandler object, the filter will apply only to messages targeted to that BHandler. See `SetFilterList()` and `AddFilter()` in the BHandler class.

- If assigned to a BLooper object as a common filter, it can apply to any message the BLooper dispatches regardless of the target handler. See `SetCommonFilterList()` and `AddCommonFilter()` in the BLooper class. (A BLooper can also be assigned specific filters in its role as a BHandler.)

All applicable filters in both categories are applied to a message before the message is dispatched to the target BHandler (before `DispatchMessage()` is called). Common filters apply before handler-specific filters.

The BMessageFilter belongs to the BHandler or BLooper to which it's assigned and should not be deleted in application code unless you first remove it from its owner. It will be deleted when the BHandler or BLooper is destroyed or when a set of replacement filters is assigned.

A BMessageFilter object should be assigned to only one BHandler or BLooper. To use the same filter in a variety of circumstances, simply copy the BMessageFilter object and assign a different instance to each BHandler or BLooper. It's a light object that can easily be duplicated without much overhead.

See also: `BHandler::SetFilterList()`, `BLooper::SetCommonFilterList()`

## Hook Functions

`Filter()
` Implemented by derived classes to respond to an incoming message before the message is dispatched to a target BHandler.

## Constructor and Destructor

### BMessageFilter()

          BMessageFilter(message_delivery delivery,
             message_source source,
             uint32 command,
             filter_hook filter = NULL)
          BMessageFilter(message_delivery delivery,
             message_source source,
             filter_hook filter = NULL)
          BMessageFilter(uint32 command,
             filter_hook filter = NULL)
          BMessageFilter(const BMessageFilter &object)
          BMessageFilter(const BMessageFilter *object)

Initializes the BMessageFilter object so that its `Filter()` function--or the filter hook function passed as an argument--will be called for every incoming message that meets the specified delivery, source, and command criteria.

The first argument, delivery, is a constant that specifies how the message must arrive:

- `B_DROPPED_DELIVERY`. Only messages that were dragged and dropped should be filtered.

- `B_PROGRAMMED_DELIVERY`. Only messages that were posted or sent in application code (by calling `PostMessage()` or a `Send`...`()` function) should be filtered.

- `B_ANY_DELIVERY`. All messages, no matter how they were delivered, should be filtered.

If a delivery method isn't specified, `B_ANY_DELIVERY` is assumed.

The second argument, source, specifies where the message must originate:

- `B_LOCAL_SOURCE`. Only messages that originate locally, from within the same team as the receiving thread, should be filtered.

- `B_REMOTE_SOURCE`. Only messages that are delivered from a remote source should be filtered.

- `B_ANY_SOURCE`. All messages, no matter what their source, should be filtered.

If a message source isn't specified, `B_ANY_SOURCE` is assumed.

The third argument, command, limits the filter to a particular type of message. Only messages that have `what` data members matching the specified command constant will be filtered. If a command isn't specified, the command constant won't be a criterion in selecting which messages to filter; any message that meets the other criteria will be filtered, no matter what its `what` data member may be.

The filtering criteria are conjunctive; for the filter function to be called, an arriving message must meet all the criteria specified.

A filter function passed as an argument must be of the type `filter_hook`. This type is defined as follows

          filter_result (*filter_hook)(BMessage *message,
             BHandler **target,
             BMessageFilter *messageFilter)

The return type of the function and its first two arguments are the same as for the member `Filter()` function. The third argument gives the `filter_hook` access to the same information as `Filter()`. For example, the member function can discover which BLooper is dispatching the message by calling another member function, `Looper()`:

       filter_result MyFilter::Filter(BMessage *message, BHandler **target)
       {
           . . .
           BLooper *theLooper = Looper();
           . . .
       }

The `filter_hook` can call the same function through its messageFilter pointer:

       filter_result filter(BMessage *message, BHandler **target
                               BMessageFilter *messageFilter)
       {
           . . .
           BLooper *theLooper = messageFilter->Looper();
           . . .
       }

For more information, refer to the description of the member `Filter()` function.

See also: `Filter()`

### ~BMessageFilter()

          virtual ~BMessageFilter()

Does nothing.

## Member Functions

### Command(), FiltersAnyCommand()

          uint32 Command(void) const

          bool FiltersAnyCommand(void) const

`Command()` returns the command constant (the `what` data member) that an arriving message must match for the filter to apply. `FiltersAnyCommand()` returns `true` if the filter applies to messages regardless of their `what` data members, and `false` if it's limited to a certain type of message.

Because all command constants are valid, including negative numbers and 0, `Command()` returns a reliable result only if `FiltersAnyCommand()` returns `false`.

See also: the BMessageFilter constructor, the BMessage class

### Filter()

          virtual filter_result Filter(BMessage *message, BHandler **target)

Implemented by derived classes to examine an arriving message just before it's dispatched. The message is passed as the first argument; the second argument indirectly points to the target BHandler object that's slated to respond to the message.

You can implement this function to do anything you please with the message, including replace the designated target with another BHandler object. For example:

       filter_result MyFilter::Filter(BMessage *message, BHandler **target)
       {
           . . .
           if ( *target->IsIndisposed() )
               *target = *target->FindReplacement();
           . . .
           return B_DISPATCH_MESSAGE;
       }

The replacement target must be associated with the same BLooper as the original target. If the new target has filters that apply to the message, those filtering functions will be called before the message is dispatched.

This function returns a constant that instructs the BLooper whether or not to dispatch the message as planned:

- `B_DISPATCH_MESSAGE`. Go ahead and dispatch the message.

- `B_SKIP_MESSAGE`. Stop. Don't dispatch the message and don't filter it any further; this function took care of handling it.

The default version of this function does nothing but return `B_DISPATCH_MESSAGE`.

If a `filter_hook` function was assigned to the BMessageFilter object when it was constructed, it will be called instead of `Filter()`.

See also: the BMessageFilter constructor

### FiltersAnyCommand() see Command()

### Looper()

          BLooper *Looper(void) const

Returns the BLooper object that dispatches the messages that the BMessageFilter filters, or `NULL` if the BMessageFilter hasn't yet been assigned to a BHandler or BLooper.

### MessageDelivery(), MessageSource()

          message_delivery MessageDelivery(void) const

          message_source MessageSource(void) const

These functions return constants, set when the BMessageFilter object was constructed, that describe the categories of messages that can be filtered. `MessageDelivery()` returns a constant that specifies how the message must be delivered (`B_DROPPED_DELIVERY`, `B_PROGRAMMED_DELIVERY`, or `B_ANY_DELIVERY`). `MessageSource()` returns how the source of the message is constrained (`B_LOCAL_SOURCE`, `B_REMOTE_SOURCE`, or `B_ANY_SOURCE`).

See also: the BMessageFilter constructor

## Operators

### = (assignment)

          BMessageFilter &operator=(const BMessageFilter&)

Assigns one BMessageFilter object to another so that both objects are independent copies of each other. After the assignment, both objects share the same filtering function and record the same calling criteria.

The Be Book, in lovely HTML, for BeOS Release 3.

Copyright © 1998 Be, Inc. All rights reserved.

Last modified March 26, 1998.