CAbstractUnknown.h
#include <objbase.h> #include <unknwn.h> #define DECLARE_IUNKNOWN_INTERFACE \ public: \ virtual HRESULT _stdcall QueryInterface(const IID& riid,void** ppvObject); \ virtual ULONG _stdcall AddRef (); \ virtual ULONG _stdcall Release(); class CAbstractUnknown:public IUnknown { public: CAbstractUnknown(); virtual HRESULT _stdcall QueryInterface(const IID& riid,void** ppvObject)=0; virtual ULONG _stdcall AddRef (); virtual ULONG _stdcall Release(); //virtual HRESULT _stdcall NonDelegatingQueryInterface(const IID& riid,void** ppvObject)=0; //virtual ULONG _stdcall NonDelegatingAddRef(); //virtual ULONG _stdcall NonDelegatingRelease(); protected: long m_ref; long g_components; }; const CLSID CLSID_CAbstractUnknown={0x38dd17, 0x6420, 0x47ca, { 0x8b, 0xca, 0xbf, 0x8b, 0x4d, 0x21, 0x32, 0x87 } }; template<class I,const GUID* pGUID>I* interface_cast(IUnknown* pIUnknown) { I* pi=NULL; HRESULT hr=pIUnknown->QueryInterface(*pGUID,(void**)&pi); assert(SUCCEEDED(hr)); return pi; }
CAbstractUnknown.cpp
#include "CAbstractUnknown.h" CAbstractUnknown::CAbstractUnknown() { m_ref=0; g_components=0; } /** HRESULT _stdcall CAbstractUnknown::QueryInterface(const IID& riid,void** ppvObject) { if(p_UnknownOuter!=NULL) { return p_UnknownOuter->QueryInterface(riid,ppvObject); } else { return NonDelegatingQueryInterface(riid,ppvObject); } }*/ ULONG _stdcall CAbstractUnknown::AddRef() { return InterlockedIncrement(&m_ref); } ULONG _stdcall CAbstractUnknown::Release() { if(InterlockedDecrement(&m_ref)==0) { InterlockedDecrement(&g_components); delete this; return 0; } return m_ref; } /** CAbstractUnknown::CAbstractUnknown(IUnknown* m_pUnknownouter) { m_ref=1; InterlockedIncrement(&g_components); p_UnknownOuter=m_pUnknownouter; } HRESULT _stdcall CAbstractUnknown::NonDelegatingQueryInterface(const IID& riid,void** ppvObject) { if(riid==IID_IUnknown) { *ppvObject=static_cast<INonDelegatingUnknown*>(this); ((IUnknown*)(*ppvObject))->AddRef(); } return S_OK; } ULONG _stdcall CAbstractUnknown::NonDelegatingAddRef() { return InterlockedIncrement(&m_ref); } ULONG _stdcall CAbstractUnknown::NonDelegatingRelease() { if(InterlockedDecrement(&m_ref)==0) { InterlockedDecrement(&g_components); delete this; return 0; } return m_ref; }*/