Click here to Skip to main content
15,920,704 members
Articles / Programming Languages / C++

How to Use the IMessageFilter

Rate me:
Please Sign up or sign in to vote.
3.92/5 (9 votes)
11 Jan 2006 44.2K   24   1
This article explains how to use the IMessageFilter.


In my system, I found out that I needed to use the IMessageFilter – and don’t ask me how and why – so I looked in books on COM, newsgroups, and even here – but could not find a good example of how to use this interface.

Maybe, this is something trivial for others, but anyway – after I found a good example (of a guy named Darma Sukla, from the MS team), the first thing that came through my mind was sharing it. So I hope that the next desperate guy, who will need to use this interface, and comes here – he will have a nice example available…

So, the IMessageFilter is used to solve the re-entrance problem in STA objects. This solution that I’ve found is not very generic, but it is a good example.

The idea is that I inherit the interface, using the class IMessageFilterImpl. Then, the problematic COM object implements this interface.

Using the code

  1. Add the IMessageFilterImpl<> to your STA object's base class list.
    class ATL_NO_VTABLE CFoo : 
        public CComObjectRootEx<CComSingleThreadModel>,
        public IMessageFilterImpl<CFoo>, ...
  2. Add COM_INTERFACE_ENTRY(IMessageFilter) to your COM_MAP.
        COM_INTERFACE_ENTRY(IMessageFilter) ... 
  3. Call RegisterFilter() in the FinalConstruct().
  4. Implement the following helper as a class method:
    DWORD ProcessInComingCall(DWORD dwCallType, 
          HTASK threadIDCaller,DWORD dwTickCount,
          LPINTERFACEINFO lpInterfaceInfo)
        //Do the right thing ! 
        if(dwCallType == CALLTYPE_TOPLEVEL) 
            return SERVERCALL_ISHANDLED; 
            return SERVERCALL_REJECTED; 

The class

class ATL_NO_VTABLE CFoo : 

template <class T, DWORD dwTimeOut = 5000> 
class ATL_NO_VTABLE IMessageFilterImpl : public IMessageFilter 
   IMessageFilterImpl()     {} 
   ~IMessageFilterImpl()    { RevokeFilter(); } 


   HRESULT RegisterFilter() 
     { return ::CoRegisterMessageFilter(
        static_cast<IMessageFilter*>(this), NULL);} 
   HRESULT RevokeFilter()
     { return /*::CoRegisterMessageFilter(NULL, NULL)*/ S_OK; } 

public: //IMessageFilter 

   STDMETHODIMP_(DWORD) HandleInComingCall( 
          DWORD dwCallType, 
          HTASK threadIDCaller, 
          DWORD dwTickCount, 
          LPINTERFACEINFO lpInterfaceInfo) 
          //we CANNOT reject these calls 
          if(dwCallType == CALLTYPE_ASYNC_CALLPENDING 
                  || dwCallType == CALLTYPE_ASYNC) 
                 return SERVERCALL_ISHANDLED; 

          T* pT = static_cast<T*>(this); 
          return pT->ProcessInComingCall(dwCallType, 

   STDMETHODIMP_(DWORD) RetryRejectedCall( 
          HTASK threadIDCallee, 
          DWORD dwTickCount, 
          DWORD dwRejectType)
          //the ret val from HandleInComingCall() 
          if(dwRejectType == SERVERCALL_REJECTED) 
          { return -1; }
          //indicates that the call should be canceled 

          //we must've got SERVERCALL_RETRYLATER 
          return dwTimeOut; 

   STDMETHODIMP_(DWORD) MessagePending( 
          HTASK threadIDCallee, 
          DWORD dwTickCount, 
          DWORD dwPendingType)
          //the ret val from RetryRejectedCall() 


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Written By
Israel Israel
working for Intel

My Linkedin Profile

Visit my photography gallery

Comments and Discussions

QuestionThanks Pin
Daniel Ramnath1-Sep-14 6:43
Daniel Ramnath1-Sep-14 6:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.