CNonDelegatingUnknown.h
#ifndef __unknwn_h__ #include <unknwn.h> #include <objbase.h> #include <atlbase.h> #endif class INonDelegatingUnknown { public: virtual HRESULT _stdcall NonDelegatingQueryInterface(const IID& riid,void** ppvObject)=0; virtual ULONG _stdcall NonDelegatingAddRef()=0; virtual ULONG _stdcall NonDelegatingRelease()=0; }; class CNonDelegatingUnknown:public INonDelegatingUnknown { public: CNonDelegatingUnknown(){} ~CNonDelegatingUnknown(){} CNonDelegatingUnknown(IUnknown* pi) { pIUnknownOuter=pi; } virtual HRESULT _stdcall NonDelegatingQueryInterface(const IID& riid,void** ppvObject)=0; virtual ULONG _stdcall NonDelegatingAddRef(){return InterlockedIncrement(&m_cNon);} virtual ULONG _stdcall NonDelegatingRelease() { if(InterlockedDecrement(&m_cNon)==0) { delete this; return 0; } return m_cNon; } virtual long _stdcall getRleaseCount() { return m_cNon; } virtual IUnknown* _stdcall getUnknownOuter() { return pIUnknownOuter; } protected: long m_cNon; CComPtr<IUnknown> pIUnknownOuter; }; #define DECLARE_UNKNOWN \ virtual HRESULT _stdcall QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject) \ { \ CComPtr<IUnknown> pt=getUnknownOuter(); \ if(pt!=NULL) \ { \ return pt->QueryInterface(riid,ppvObject); \ } \ return NonDelegatingQueryInterface(riid,ppvObject); \ } \ virtual ULONG _stdcall AddRef() \ { \ CComPtr<IUnknown> pt=getUnknownOuter(); \ if(pt!=NULL) \ { \ return pt->AddRef(); \ } \ return NonDelegatingAddRef(); \ } \ virtual ULONG _stdcall Release() \ { \ CComPtr<IUnknown> pt=getUnknownOuter(); \ if(pt!=NULL) \ { \ return pt->Release(); \ } \ return NonDelegatingRelease(); \ } \ // {D07A3146-CEE6-40c6-A5F5-63687189205E} const IID IID_INONDELEGATINGUNKNOWN = { 0xd07a3146, 0xcee6, 0x40c6, { 0xa5, 0xf5, 0x63, 0x68, 0x71, 0x89, 0x20, 0x5e } };
CNonDelegatingUnknown.cpp
#include "INonDelegatingUnknown.h" HRESULT _stdcall CNonDelegatingUnknown::NonDelegatingQueryInterface(const IID& riid,void** ppvObject) { if(riid==IID_IUnknown) { *ppvObject=(INonDelegatingUnknown*)(this); ((IUnknown*)(*ppvObject))->AddRef(); } else { *ppvObject=NULL; return E_NOINTERFACE; } return S_OK; }