Click here to Skip to main content
12,457,226 members (56,345 online)
Click here to Skip to main content
Add your own
alternative version

Stats

32.5K views
22 bookmarked
Posted

How to Use the IMessageFilter

, 11 Jan 2006
Rate this:
Please Sign up or sign in to vote.
This article explains how to use the IMessageFilter.

Introduction

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.
    BEGIN_COM_MAP(CFoo)
        COM_INTERFACE_ENTRY(IFoo)
        COM_INTERFACE_ENTRY(IMessageFilter) ... 
    END_COM_MAP()
  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; 
        } 
        else 
        { 
            return SERVERCALL_REJECTED; 
        }
    }

The class

class ATL_NO_VTABLE CFoo : 

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

public: 

   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, 
                 threadIDCaller,dwTickCount,lpInterfaceInfo); 
   } 

   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() 
   { 
          return PENDINGMSG_WAITNOPROCESS; 
   }
};

License

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

Share

About the Author

Ohad Redlich
Israel Israel
worked for NICE systems (MFC C++ COM...)
worked for BMC software (Java, ...)
working for WatchDox (Java, Spring, Spring-Security...)

My Linkedin Profile

Visit my photography gallery

You may also be interested in...

Pro
Pro

Comments and Discussions

 
QuestionThanks Pin
Daniel Ramnath1-Sep-14 6:43
memberDaniel 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.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160826.1 | Last Updated 11 Jan 2006
Article Copyright 2006 by Ohad Redlich
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid