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;
}*/