CComObject

来源:互联网 发布:尘埃3mac汉化补丁 编辑:程序博客网 时间:2024/05/22 09:01
//Base is the user's class that derives from CComObjectRoot and whatever//interfaces the user wants to support on the objecttemplate <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 buildsvirtual ~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 CComObjectRootSTDMETHOD_(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_MAPSTDMETHOD(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 objecttemplate <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 buildsvirtual ~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 CComObjectRootSTDMETHOD_(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_MAPSTDMETHOD(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 objecttemplate <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 buildsvirtual ~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 CComObjectRootSTDMETHOD_(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_MAPSTDMETHOD(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 _InternalQueryInterfacetemplate <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 InternalQueryInterfacetemplate <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 CComObjectRoottemplate <class Base>class CComObjectStackEx : public Base{public:typedef Base _BaseClass;CComObjectStackEx(void* = NULL) { #ifdef _DEBUGm_dwRef = 0;#endifm_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 _DEBUGreturn InternalAddRef();#elsereturn 0;#endif}STDMETHOD_(ULONG, Release)() throw(){#ifdef _DEBUGreturn InternalRelease();#elsereturn 0;#endif}STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject) throw(){return _InternalQueryInterface(iid, ppvObject);}HRESULT m_hResFinalConstruct;};template <class Base> //Base must be derived from CComObjectRootclass CComContainedObject : public Base{public:typedef Base _BaseClass;CComContainedObject(void* pv) {m_pOuterUnknown = (IUnknown*)pv;}#ifdef _ATL_DEBUG_INTERFACESvirtual ~CComContainedObject(){_AtlDebugInterfacesModule.DeleteNonAddRefThunk(_GetRawUnknown());_AtlDebugInterfacesModule.DeleteNonAddRefThunk(m_pOuterUnknown);}#endifSTDMETHOD_(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_INTERFACESIUnknown* p;_AtlDebugInterfacesModule.AddNonAddRefThunk(m_pOuterUnknown, _T("CComContainedObject"), &p);return p;#elsereturn m_pOuterUnknown;#endif}};//contained is the user's class that derives from CComObjectRoot and whatever//interfaces the user wants to support on the objecttemplate <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 thisHRESULT 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 buildsvirtual ~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}elsehRes = 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 aggregatedtemplate <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 thisHRESULT 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 buildsvirtual ~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_TESTSATLASSERT(ppvObject != NULL);#endifif (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}elsehRes = 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 buildsvirtual ~CComTearOffObject(){m_dwRef = -(LONG_MAX/2);FinalRelease();#ifdef _ATL_DEBUG_INTERFACES_AtlDebugInterfacesModule.DeleteNonAddRefThunk(_GetRawUnknown());#endifm_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 thisHRESULT 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 buildsvirtual ~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}elsehRes = m_contained._InternalQueryInterface(iid, ppvObject);return hRes;}CComContainedObject<contained> m_contained;};