CComObject

来源:互联网 发布:尘埃3mac汉化补丁 编辑:程序博客网 时间:2024/05/22 09:04


//Base is the user's class that derives from CComObjectRoot and whatever
//interfaces the user wants to support on the object
template <class Base>
class CComObject : public Base
{
public:
typedef Base _BaseClass;
CComObject(void* = NULL) throw()
{
_pAtlModule->Lock();
}
// Set refcount to -(LONG_MAX/2) to protect destruction and 
// also catch mismatched Release in debug builds
virtual ~CComObject() throw()
{
m_dwRef = -(LONG_MAX/2);
FinalRelease();
#ifdef _ATL_DEBUG_INTERFACES
_AtlDebugInterfacesModule.DeleteNonAddRefThunk(_GetRawUnknown());
#endif
_pAtlModule->Unlock();
}
//If InternalAddRef or InternalRelease is undefined then your class
//doesn't derive from CComObjectRoot
STDMETHOD_(ULONG, AddRef)() {return InternalAddRef();}
STDMETHOD_(ULONG, Release)()
{
ULONG l = InternalRelease();
if (l == 0)
delete this;
return l;
}
//if _InternalQueryInterface is undefined then you forgot BEGIN_COM_MAP
STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject) throw()
{return _InternalQueryInterface(iid, ppvObject);}
template <class Q>
HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp) throw()
{
return QueryInterface(__uuidof(Q), (void**)pp);
}


static HRESULT WINAPI CreateInstance(CComObject<Base>** pp) throw();
};


template <class Base>
HRESULT WINAPI CComObject<Base>::CreateInstance(CComObject<Base>** pp) throw()
{
ATLASSERT(pp != NULL);
if (pp == NULL)
return E_POINTER;
*pp = NULL;


HRESULT hRes = E_OUTOFMEMORY;
CComObject<Base>* p = NULL;
ATLTRY(p = new CComObject<Base>())
if (p != NULL)
{
p->SetVoid(NULL);
p->InternalFinalConstructAddRef();
hRes = p->_AtlInitialConstruct();
if (SUCCEEDED(hRes))
hRes = p->FinalConstruct();
if (SUCCEEDED(hRes))
hRes = p->_AtlFinalConstruct();
p->InternalFinalConstructRelease();
if (hRes != S_OK)
{
delete p;
p = NULL;
}
}
*pp = p;
return hRes;
}


//Base is the user's class that derives from CComObjectRoot and whatever
//interfaces the user wants to support on the object
// CComObjectCached is used primarily for class factories in DLL's
// but it is useful anytime you want to cache an object
template <class Base>
class CComObjectCached : public Base
{
public:
typedef Base _BaseClass;
CComObjectCached(void* = NULL){}
// Set refcount to -(LONG_MAX/2) to protect destruction and 
// also catch mismatched Release in debug builds
virtual ~CComObjectCached()
{
m_dwRef = -(LONG_MAX/2);
FinalRelease();
#ifdef _ATL_DEBUG_INTERFACES
_AtlDebugInterfacesModule.DeleteNonAddRefThunk(_GetRawUnknown());
#endif
}
//If InternalAddRef or InternalRelease is undefined then your class
//doesn't derive from CComObjectRoot
STDMETHOD_(ULONG, AddRef)() throw()
{
ULONG l = InternalAddRef();
if (l == 2)
_pAtlModule->Lock();
return l;
}
STDMETHOD_(ULONG, Release)() throw()
{
ULONG l = InternalRelease();
if (l == 0)
delete this;
else if (l == 1)
_pAtlModule->Unlock();
return l;
}
//if _InternalQueryInterface is undefined then you forgot BEGIN_COM_MAP
STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject) throw()
{return _InternalQueryInterface(iid, ppvObject);}
static HRESULT WINAPI CreateInstance(CComObjectCached<Base>** pp) throw();
};


template <class Base>
HRESULT WINAPI CComObjectCached<Base>::CreateInstance(CComObjectCached<Base>** pp) throw()
{
ATLASSERT(pp != NULL);
if (pp == NULL)
return E_POINTER;
*pp = NULL;


HRESULT hRes = E_OUTOFMEMORY;
CComObjectCached<Base>* p = NULL;
ATLTRY(p = new CComObjectCached<Base>())
if (p != NULL)
{
p->SetVoid(NULL);
p->InternalFinalConstructAddRef();
hRes = p->_AtlInitialConstruct();
if (SUCCEEDED(hRes))
hRes = p->FinalConstruct();
if (SUCCEEDED(hRes))
hRes = p->_AtlFinalConstruct();
p->InternalFinalConstructRelease();
if (hRes != S_OK)
{
delete p;
p = NULL;
}
}
*pp = p;
return hRes;
}




//Base is the user's class that derives from CComObjectRoot and whatever
//interfaces the user wants to support on the object
template <class Base>
class CComObjectNoLock : public Base
{
public:
typedef Base _BaseClass;
CComObjectNoLock(void* = NULL){}
// Set refcount to -(LONG_MAX/2) to protect destruction and 
// also catch mismatched Release in debug builds


virtual ~CComObjectNoLock()
{
m_dwRef = -(LONG_MAX/2);
FinalRelease();
#ifdef _ATL_DEBUG_INTERFACES
_AtlDebugInterfacesModule.DeleteNonAddRefThunk(_GetRawUnknown());
#endif
}


//If InternalAddRef or InternalRelease is undefined then your class
//doesn't derive from CComObjectRoot
STDMETHOD_(ULONG, AddRef)() throw() {return InternalAddRef();}
STDMETHOD_(ULONG, Release)() throw()
{
ULONG l = InternalRelease();
if (l == 0)
delete this;
return l;
}
//if _InternalQueryInterface is undefined then you forgot BEGIN_COM_MAP
STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject) throw()
{return _InternalQueryInterface(iid, ppvObject);}
};




// It is possible for Base not to derive from CComObjectRoot
// However, you will need to provide _InternalQueryInterface
template <class Base>
class CComObjectGlobal : public Base
{
public:
typedef Base _BaseClass;
CComObjectGlobal(void* = NULL)
{
m_hResFinalConstruct = S_OK;
__if_exists(FinalConstruct)
{
__if_exists(InternalFinalConstructAddRef)
{
InternalFinalConstructAddRef();
}
m_hResFinalConstruct = _AtlInitialConstruct();
if (SUCCEEDED(m_hResFinalConstruct))
m_hResFinalConstruct = FinalConstruct();
__if_exists(InternalFinalConstructRelease)
{
InternalFinalConstructRelease();
}
}
}
virtual ~CComObjectGlobal()
{
__if_exists(FinalRelease)
{
FinalRelease();
}
#ifdef _ATL_DEBUG_INTERFACES
_AtlDebugInterfacesModule.DeleteNonAddRefThunk(_GetRawUnknown());
#endif
}


STDMETHOD_(ULONG, AddRef)() throw()
{
return _pAtlModule->Lock();
}
STDMETHOD_(ULONG, Release)() throw()
{
return _pAtlModule->Unlock();
}
STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject) throw()
{
return _InternalQueryInterface(iid, ppvObject);
}
HRESULT m_hResFinalConstruct;
};


// It is possible for Base not to derive from CComObjectRoot
// However, you will need to provide FinalConstruct and InternalQueryInterface
template <class Base>
class CComObjectStack : public Base
{
public:
typedef Base _BaseClass;
CComObjectStack(void* = NULL)
{
m_hResFinalConstruct = _AtlInitialConstruct();
if (SUCCEEDED(m_hResFinalConstruct))
m_hResFinalConstruct = FinalConstruct();
}
virtual ~CComObjectStack()
{
FinalRelease();
#ifdef _ATL_DEBUG_INTERFACES
_AtlDebugInterfacesModule.DeleteNonAddRefThunk(_GetRawUnknown());
#endif
}




STDMETHOD_(ULONG, AddRef)() throw() {ATLASSERT(FALSE);return 0;}
STDMETHOD_(ULONG, Release)() throw() {ATLASSERT(FALSE);return 0;}
STDMETHOD(QueryInterface)(REFIID, void**) throw()
{ATLASSERT(FALSE);return E_NOINTERFACE;}
HRESULT m_hResFinalConstruct;
};


// Base must be derived from CComObjectRoot
template <class Base>
class CComObjectStackEx : public Base
{
public:
typedef Base _BaseClass;


CComObjectStackEx(void* = NULL) 

#ifdef _DEBUG
m_dwRef = 0;
#endif
m_hResFinalConstruct = _AtlInitialConstruct();
if (SUCCEEDED(m_hResFinalConstruct))
m_hResFinalConstruct = FinalConstruct(); 
}


virtual ~CComObjectStackEx()
{
// This assert indicates mismatched ref counts.
//
// The ref count has no control over the
// lifetime of this object, so you must ensure
// by some other means that the object remains 
// alive while clients have references to its interfaces.
ATLASSUME(m_dwRef == 0);
FinalRelease();
#ifdef _ATL_DEBUG_INTERFACES
_AtlDebugInterfacesModule.DeleteNonAddRefThunk(_GetRawUnknown());
#endif
}


STDMETHOD_(ULONG, AddRef)() throw()
{
#ifdef _DEBUG
return InternalAddRef();
#else
return 0;
#endif
}


STDMETHOD_(ULONG, Release)() throw()
{
#ifdef _DEBUG
return InternalRelease();
#else
return 0;
#endif
}


STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject) throw()
{
return _InternalQueryInterface(iid, ppvObject);
}


HRESULT m_hResFinalConstruct;
};


template <class Base> //Base must be derived from CComObjectRoot
class CComContainedObject : public Base
{
public:
typedef Base _BaseClass;
CComContainedObject(void* pv) {m_pOuterUnknown = (IUnknown*)pv;}
#ifdef _ATL_DEBUG_INTERFACES
virtual ~CComContainedObject()
{
_AtlDebugInterfacesModule.DeleteNonAddRefThunk(_GetRawUnknown());
_AtlDebugInterfacesModule.DeleteNonAddRefThunk(m_pOuterUnknown);
}
#endif


STDMETHOD_(ULONG, AddRef)() throw() {return OuterAddRef();}
STDMETHOD_(ULONG, Release)() throw() {return OuterRelease();}
STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject) throw()
{
return OuterQueryInterface(iid, ppvObject);
}
template <class Q>
HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp)
{
return QueryInterface(__uuidof(Q), (void**)pp);
}
//GetControllingUnknown may be virtual if the Base class has declared
//DECLARE_GET_CONTROLLING_UNKNOWN()
IUnknown* GetControllingUnknown() throw()
{
#ifdef _ATL_DEBUG_INTERFACES
IUnknown* p;
_AtlDebugInterfacesModule.AddNonAddRefThunk(m_pOuterUnknown, _T("CComContainedObject"), &p);
return p;
#else
return m_pOuterUnknown;
#endif
}
};


//contained is the user's class that derives from CComObjectRoot and whatever
//interfaces the user wants to support on the object
template <class contained>
class CComAggObject :
public IUnknown,
public CComObjectRootEx< typename contained::_ThreadModel::ThreadModelNoCS >
{
public:
typedef contained _BaseClass;
CComAggObject(void* pv) : m_contained(pv)
{
_pAtlModule->Lock();
}
HRESULT _AtlInitialConstruct()
{
HRESULT hr = m_contained._AtlInitialConstruct();
if (SUCCEEDED(hr))
{
hr = CComObjectRootEx< typename contained::_ThreadModel::ThreadModelNoCS >::_AtlInitialConstruct();
}
return hr;
}
//If you get a message that this call is ambiguous then you need to
// override it in your class and call each base class' version of this
HRESULT FinalConstruct()
{
CComObjectRootEx<contained::_ThreadModel::ThreadModelNoCS>::FinalConstruct();
return m_contained.FinalConstruct();
}
void FinalRelease()
{
CComObjectRootEx<contained::_ThreadModel::ThreadModelNoCS>::FinalRelease();
m_contained.FinalRelease();
}
// Set refcount to -(LONG_MAX/2) to protect destruction and 
// also catch mismatched Release in debug builds
virtual ~CComAggObject()
{
m_dwRef = -(LONG_MAX/2);
FinalRelease();
#ifdef _ATL_DEBUG_INTERFACES
_AtlDebugInterfacesModule.DeleteNonAddRefThunk(this);
#endif
_pAtlModule->Unlock();
}


STDMETHOD_(ULONG, AddRef)() {return InternalAddRef();}
STDMETHOD_(ULONG, Release)()
{
ULONG l = InternalRelease();
if (l == 0)
delete this;
return l;
}
STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)
{
ATLASSERT(ppvObject != NULL);
if (ppvObject == NULL)
return E_POINTER;
*ppvObject = NULL;


HRESULT hRes = S_OK;
if (InlineIsEqualUnknown(iid))
{
*ppvObject = (void*)(IUnknown*)this;
AddRef();
#ifdef _ATL_DEBUG_INTERFACES
_AtlDebugInterfacesModule.AddThunk((IUnknown**)ppvObject, (LPCTSTR)contained::_GetEntries()[-1].dw, iid);
#endif // _ATL_DEBUG_INTERFACES
}
else
hRes = m_contained._InternalQueryInterface(iid, ppvObject);
return hRes;
}
template <class Q>
HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp)
{
return QueryInterface(__uuidof(Q), (void**)pp);
}
static HRESULT WINAPI CreateInstance(LPUNKNOWN pUnkOuter, CComAggObject<contained>** pp)
{
ATLASSERT(pp != NULL);
if (pp == NULL)
return E_POINTER;
*pp = NULL;


HRESULT hRes = E_OUTOFMEMORY;
CComAggObject<contained>* p = NULL;
ATLTRY(p = new CComAggObject<contained>(pUnkOuter))
if (p != NULL)
{
p->SetVoid(NULL);
p->InternalFinalConstructAddRef();
hRes = p->_AtlInitialConstruct();
if (SUCCEEDED(hRes))
hRes = p->FinalConstruct();
if (SUCCEEDED(hRes))
hRes = p->_AtlFinalConstruct();
p->InternalFinalConstructRelease();
if (hRes != S_OK)
{
delete p;
p = NULL;
}
}
*pp = p;
return hRes;
}


CComContainedObject<contained> m_contained;
};


///////////////////////////////////////////////////////////////////////////////
// CComPolyObject can be either aggregated or not aggregated


template <class contained>
class CComPolyObject :
public IUnknown,
public CComObjectRootEx< typename contained::_ThreadModel::ThreadModelNoCS >
{
public:
typedef contained _BaseClass;
CComPolyObject(void* pv) : m_contained(pv ? pv : this)
{
_pAtlModule->Lock();
}
HRESULT _AtlInitialConstruct()
{
HRESULT hr = m_contained._AtlInitialConstruct();
if (SUCCEEDED(hr))
{
hr = CComObjectRootEx< typename contained::_ThreadModel::ThreadModelNoCS >::_AtlInitialConstruct();
}
return hr;
}
//If you get a message that this call is ambiguous then you need to
// override it in your class and call each base class' version of this
HRESULT FinalConstruct()
{
InternalAddRef();
CComObjectRootEx<contained::_ThreadModel::ThreadModelNoCS>::FinalConstruct();
HRESULT hr = m_contained.FinalConstruct();
InternalRelease();
return hr;
}
void FinalRelease()
{
CComObjectRootEx<contained::_ThreadModel::ThreadModelNoCS>::FinalRelease();
m_contained.FinalRelease();
}
// Set refcount to -(LONG_MAX/2) to protect destruction and 
// also catch mismatched Release in debug builds
virtual ~CComPolyObject()
{
m_dwRef = -(LONG_MAX/2);
FinalRelease();
#ifdef _ATL_DEBUG_INTERFACES
_AtlDebugInterfacesModule.DeleteNonAddRefThunk(this);
#endif
_pAtlModule->Unlock();
}


STDMETHOD_(ULONG, AddRef)() {return InternalAddRef();}
STDMETHOD_(ULONG, Release)()
{
ULONG l = InternalRelease();
if (l == 0)
delete this;
return l;
}
STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)
{
#ifndef _ATL_OLEDB_CONFORMANCE_TESTS
ATLASSERT(ppvObject != NULL);
#endif
if (ppvObject == NULL)
return E_POINTER;
*ppvObject = NULL;


HRESULT hRes = S_OK;
if (InlineIsEqualUnknown(iid))
{
*ppvObject = (void*)(IUnknown*)this;
AddRef();
#ifdef _ATL_DEBUG_INTERFACES
_AtlDebugInterfacesModule.AddThunk((IUnknown**)ppvObject, (LPCTSTR)contained::_GetEntries()[-1].dw, iid);
#endif // _ATL_DEBUG_INTERFACES
}
else
hRes = m_contained._InternalQueryInterface(iid, ppvObject);
return hRes;
}
template <class Q>
HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp)
{
return QueryInterface(__uuidof(Q), (void**)pp);
}
static HRESULT WINAPI CreateInstance(LPUNKNOWN pUnkOuter, CComPolyObject<contained>** pp)
{
ATLASSERT(pp != NULL);
if (pp == NULL)
return E_POINTER;
*pp = NULL;




HRESULT hRes = E_OUTOFMEMORY;
CComPolyObject<contained>* p = NULL;
ATLTRY(p = new CComPolyObject<contained>(pUnkOuter))
if (p != NULL)
{
p->SetVoid(NULL);
p->InternalFinalConstructAddRef();
hRes = p->_AtlInitialConstruct();
if (SUCCEEDED(hRes))
hRes = p->FinalConstruct();
if (SUCCEEDED(hRes))
hRes = p->_AtlFinalConstruct();
p->InternalFinalConstructRelease();
if (hRes != S_OK)
{
delete p;
p = NULL;
}
}
*pp = p;
return hRes;
}


CComContainedObject<contained> m_contained;
};


template <class Base>
class CComTearOffObject : public Base
{
public:
CComTearOffObject(void* pv)
{
ATLASSUME(m_pOwner == NULL);
m_pOwner = reinterpret_cast<Base::_OwnerClass*>(pv);
m_pOwner->AddRef();
}
// Set refcount to -(LONG_MAX/2) to protect destruction and 
// also catch mismatched Release in debug builds
virtual ~CComTearOffObject()
{
m_dwRef = -(LONG_MAX/2);
FinalRelease();
#ifdef _ATL_DEBUG_INTERFACES
_AtlDebugInterfacesModule.DeleteNonAddRefThunk(_GetRawUnknown());
#endif
m_pOwner->Release();
}


STDMETHOD_(ULONG, AddRef)() throw() {return InternalAddRef();}
STDMETHOD_(ULONG, Release)() throw()
{
ULONG l = InternalRelease();
if (l == 0)
delete this;
return l;
}
STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject) throw()
{
return m_pOwner->QueryInterface(iid, ppvObject);
}
};


template <class contained>
class CComCachedTearOffObject :
public IUnknown,
public CComObjectRootEx<typename contained::_ThreadModel::ThreadModelNoCS>
{
public:
typedef contained _BaseClass;
CComCachedTearOffObject(void* pv) :
m_contained(((contained::_OwnerClass*)pv)->GetControllingUnknown())
{
ATLASSUME(m_contained.m_pOwner == NULL);
m_contained.m_pOwner = reinterpret_cast<contained::_OwnerClass*>(pv);
}
HRESULT _AtlInitialConstruct()
{
HRESULT hr = m_contained._AtlInitialConstruct();
if (SUCCEEDED(hr))
{
hr = CComObjectRootEx< typename contained::_ThreadModel::ThreadModelNoCS >::_AtlInitialConstruct();
}
return hr;
}
//If you get a message that this call is ambiguous then you need to
// override it in your class and call each base class' version of this
HRESULT FinalConstruct()
{
CComObjectRootEx<contained::_ThreadModel::ThreadModelNoCS>::FinalConstruct();
return m_contained.FinalConstruct();
}
void FinalRelease()
{
CComObjectRootEx<contained::_ThreadModel::ThreadModelNoCS>::FinalRelease();
m_contained.FinalRelease();
}
// Set refcount to -(LONG_MAX/2) to protect destruction and 
// also catch mismatched Release in debug builds
virtual ~CComCachedTearOffObject()
{
m_dwRef = -(LONG_MAX/2);
FinalRelease();
#ifdef _ATL_DEBUG_INTERFACES
_AtlDebugInterfacesModule.DeleteNonAddRefThunk(this);
#endif
}




STDMETHOD_(ULONG, AddRef)() {return InternalAddRef();}
STDMETHOD_(ULONG, Release)()
{
ULONG l = InternalRelease();
if (l == 0)
delete this;
return l;
}
STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)
{
ATLASSERT(ppvObject != NULL);
if (ppvObject == NULL)
return E_POINTER;
*ppvObject = NULL;


HRESULT hRes = S_OK;
if (InlineIsEqualUnknown(iid))
{
*ppvObject = (void*)(IUnknown*)this;
AddRef();
#ifdef _ATL_DEBUG_INTERFACES
_AtlDebugInterfacesModule.AddThunk((IUnknown**)ppvObject, (LPCTSTR)contained::_GetEntries()[-1].dw, iid);
#endif // _ATL_DEBUG_INTERFACES
}
else
hRes = m_contained._InternalQueryInterface(iid, ppvObject);
return hRes;
}
CComContainedObject<contained> m_contained;
};
原创粉丝点击