# IMessageFilter

The IMessageFilter interface provides OLE servers and applications with the ability to selectively handle incoming and outgoing OLE messages while waiting for responses from synchronous calls. Filtering messages helps to ensure that calls are handled in a manner that improves performance and avoids deadlocks. OLE messages can be synchronous, asynchronous, or input-synchronized; the majority of interface calls are synchronous.

Synchronous calls require the caller to wait for a reply before continuing. OLE enters a modal loop while waiting for the reply. During this time, the caller is still able to receive and dispatch incoming messages.

Asynchronous calls allow the caller to proceed without waiting for a response from the called object. Today, in OLE, the only asynchronous calls are to an object’s IAdviseSink interface. While the object is processing an asynchronous call, it is prohibited from making any synchronous calls back to the calling object.

Input-synchronized calls require the called object to complete the call before relinquishing control, ensuring that behaviors such as focus management and type-ahead function correctly.

##### When to Implement

You will probably want to implement your own message filter. The default implementation provided by COM offers only minimal message filtering capability. Although message filtering is no longer as significant as it was with 16-bit applications, since the size of the message queue is now virtually unlimited, you still should implement IMessageFilter as a way of resolving deadlocks.

COM will call your implementation of IMessageFilter to find out if an application is blocking, so that you can task-switch to that application and give the user an opportunity to deal with the situation. For example, if you have Microsoft Word talking to Microsoft Excel, with Excel running in the background in formula mode, in which formulas are being applied to data on the worksheet to compute different or “what if” results, Excel won’t check all calls, thereby blocking further action. IMessageFilter would put up a dialog box indicating which task was blocking and provide the user with an opportunity to deal with the deadlock.

Although it is probably obvious from the method descriptions, it may still be useful to point out that HandleIncomingCall is an object-based method and RetryRejectedCall and MessagePending are client-based methods. Clearly, the object must have some way of handling incoming calls from external clients. HandleIncomingCall provides that functionality by allowing the object to handle or defer some incoming calls and reject others. The client also needs to know how an object is going to handle its call. so that it can respond appropriately. The client needs to know if a call has been rejected, or just deferred temporarily, so that it can retry rejected calls after some specified time. The client also needs to be able to respond to Windows messages, while at the same time waiting for replies to pending messages.

You will use CoRegisterMessageFilter to register your message filter. Once registered, COM then calls your message filter instead of the default implementation.

##### When to Use

You don’t call this interface directly. It’s provided by the OLE server or application and called by the COM.

##### Application Shutdown with WM_QUERYENDSESSION and WM_ENDSESSION

When a user exits Windows, each open application receives a WM_QUERYENDSESSION message followed by a WM_ENDSESSION message, provided the exit is not canceled. These messages are invoked with SendMessage, which unfortunately restricts the initiation of all outgoing LRPC calls. This is a problem for container applications that have open embedded objects when they receive the shutdown request because LRPC is needed to close those objects.

Container and container/server applications with open documents typically display a message box on receipt of the WM_QUERYENDSESSION message that asks if the user wants to save changes before exiting. A positive response is usually the default. The recommendation for dealing with the situation described above is for the application to display an alternate message box asking if the user wants to discard changes; a negative response should be the default. If the user chooses to discard the changes, TRUE should be returned for WM_QUERYENDSESSION, which .signals to Windows that it can terminate. If the user does not want to discard the changes, FALSE should be returned. No attempt should be made to close or release running embeddings.

Server applications should return TRUE for WM_QUERYENDSESSION without prompting the user.On receipt of a WM_ENDSESSION message, all OLE applications should execute the normal close sequence for each application's documents and/or objects. At the same time, you should ignore any errors resulting from any cross-process calls or calls to IUnknown::Release. All storage pointers (IStorage and IStream interface pointers) must be released to properly flush any temporary files maintained by the compound file implementation of structured storage.

See Also

CoRegisterMessageFilter

Methods in Vtable Order

IUnknown Methods | Description
QueryInterface | Returns a pointer to a specified interface.
AddRef | Increments the reference count.
Release | Decrements the reference count.

IMessageFilter Methods | Description
HandleIncomingCall | Provides a single entry point for incoming calls.
RetryRejectedCall | Provides application with opportunity to display a dialog box offering retry or cancel or task switching options.
MessagePending | Indicates a Windows message has arrived while OLE is waiting to respond to a remote call.

See Also

OleUIBusy, OLEUIBUSY, In the WIN32 SDK: “Messages and Message Queues”