IMessageFilterImpl
Chase your STA reentrancy blues away. Use IMessageFilter (with its known limitations, of course). I wrote this helper class to save some of your time :-). Its not very generic and you may need to tweak it here and there.
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); }
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) MessagePending(HTASK threadIDCallee,DWORD
dwTickCount,DWORD
dwPendingType)
{ return PENDINGMSG_WAITNOPROCESS; }
STDMETHODIMP_(DWORD) RetryRejectedCall(HTASK threadIDCallee,DWORD
dwTickCount,DWORD
dwRejectType)
{
if(dwRejectType == SERVERCALL_REJECTED) {
return -1; }
//we must've got SERVERCALL_RETRYLATER
return dwTimeOut;
}
};
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 the COM_INTERFACE_ENTRY(IMessageFilter) to your COM_MAP
BEGIN_COM_MAP(CFoo)
COM_INTERFACE_ENTRY(IFoo)
COM_INTERFACE_ENTRY(IDispatch)
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 !
return -1; //return suitable Values !
}
This page and the source contained in(or
referred to) by this page are Copyright (c) 1998, Dharma Shukla.
All rights reserved. No warrenties extended. Use at your own risk.
Do send Comments/Bugs to me :-)