📄 atlcom.h
字号:
};
#ifdef _ATL_DEBUG
#define DEBUG_QI_ENTRY(x) \
{NULL, \
(DWORD_PTR)_T(#x), \
(_ATL_CREATORARGFUNC*)0},
#else
#define DEBUG_QI_ENTRY(x)
#endif //_ATL_DEBUG
#ifdef _ATL_DEBUG_INTERFACES
#define _ATL_DECLARE_GET_UNKNOWN(x)\
IUnknown* GetUnknown() \
{ \
IUnknown* p; \
_Module.AddNonAddRefThunk(_GetRawUnknown(), _T(#x), &p); \
return p; \
}
#else
#define _ATL_DECLARE_GET_UNKNOWN(x) IUnknown* GetUnknown() {return _GetRawUnknown();}
#endif
//If you get a message that FinalConstruct is ambiguous then you need to
// override it in your class and call each base class' version of this
#define BEGIN_COM_MAP(x) public: \
typedef x _ComMapClass; \
static HRESULT WINAPI _Cache(void* pv, REFIID iid, void** ppvObject, DWORD_PTR dw)\
{\
_ComMapClass* p = (_ComMapClass*)pv;\
p->Lock();\
HRESULT hRes = CComObjectRootBase::_Cache(pv, iid, ppvObject, dw);\
p->Unlock();\
return hRes;\
}\
IUnknown* _GetRawUnknown() \
{ ATLASSERT(_GetEntries()[0].pFunc == _ATL_SIMPLEMAPENTRY); return (IUnknown*)((DWORD_PTR)this+_GetEntries()->dw); } \
_ATL_DECLARE_GET_UNKNOWN(x)\
HRESULT _InternalQueryInterface(REFIID iid, void** ppvObject) \
{ return InternalQueryInterface(this, _GetEntries(), iid, ppvObject); } \
const static _ATL_INTMAP_ENTRY* WINAPI _GetEntries() { \
static const _ATL_INTMAP_ENTRY _entries[] = { DEBUG_QI_ENTRY(x)
#define DECLARE_GET_CONTROLLING_UNKNOWN() public:\
virtual IUnknown* GetControllingUnknown() {return GetUnknown();}
#if !defined(_ATL_NO_UUIDOF)
#define _ATL_IIDOF(x) __uuidof(x)
#else
#define _ATL_IIDOF(x) IID_##x
#endif
#define COM_INTERFACE_ENTRY_BREAK(x)\
{&_ATL_IIDOF(x), \
NULL, \
_Break},
#define COM_INTERFACE_ENTRY_NOINTERFACE(x)\
{&_ATL_IIDOF(x), \
NULL, \
_NoInterface},
#define COM_INTERFACE_ENTRY(x)\
{&_ATL_IIDOF(x), \
offsetofclass(x, _ComMapClass), \
_ATL_SIMPLEMAPENTRY},
#define COM_INTERFACE_ENTRY_IID(iid, x)\
{&iid,\
offsetofclass(x, _ComMapClass),\
_ATL_SIMPLEMAPENTRY},
// The impl macros are now obsolete
#define COM_INTERFACE_ENTRY_IMPL(x)\
COM_INTERFACE_ENTRY_IID(_ATL_IIDOF(x), x##Impl<_ComMapClass>)
#define COM_INTERFACE_ENTRY_IMPL_IID(iid, x)\
COM_INTERFACE_ENTRY_IID(iid, x##Impl<_ComMapClass>)
//
#define COM_INTERFACE_ENTRY2(x, x2)\
{&_ATL_IIDOF(x),\
(DWORD_PTR)((x*)(x2*)((_ComMapClass*)8))-8,\
_ATL_SIMPLEMAPENTRY},
#define COM_INTERFACE_ENTRY2_IID(iid, x, x2)\
{&iid,\
(DWORD_PTR)((x*)(x2*)((_ComMapClass*)8))-8,\
_ATL_SIMPLEMAPENTRY},
#define COM_INTERFACE_ENTRY_FUNC(iid, dw, func)\
{&iid, \
dw, \
func},
#define COM_INTERFACE_ENTRY_FUNC_BLIND(dw, func)\
{NULL, \
dw, \
func},
#define COM_INTERFACE_ENTRY_TEAR_OFF(iid, x)\
{&iid,\
(DWORD_PTR)&_CComCreatorData<\
CComInternalCreator< CComTearOffObject< x > >\
>::data,\
_Creator},
#define COM_INTERFACE_ENTRY_CACHED_TEAR_OFF(iid, x, punk)\
{&iid,\
(DWORD_PTR)&_CComCacheData<\
CComCreator< CComCachedTearOffObject< x > >,\
offsetof(_ComMapClass, punk)\
>::data,\
_Cache},
#define COM_INTERFACE_ENTRY_AGGREGATE(iid, punk)\
{&iid,\
offsetof(_ComMapClass, punk),\
_Delegate},
#define COM_INTERFACE_ENTRY_AGGREGATE_BLIND(punk)\
{NULL,\
offsetof(_ComMapClass, punk),\
_Delegate},
#define COM_INTERFACE_ENTRY_AUTOAGGREGATE(iid, punk, clsid)\
{&iid,\
(DWORD_PTR)&_CComCacheData<\
CComAggregateCreator<_ComMapClass, &clsid>,\
offsetof(_ComMapClass, punk)\
>::data,\
_Cache},
#define COM_INTERFACE_ENTRY_AUTOAGGREGATE_BLIND(punk, clsid)\
{NULL,\
(DWORD_PTR)&_CComCacheData<\
CComAggregateCreator<_ComMapClass, &clsid>,\
offsetof(_ComMapClass, punk)\
>::data,\
_Cache},
#define COM_INTERFACE_ENTRY_CHAIN(classname)\
{NULL,\
(DWORD_PTR)&_CComChainData<classname, _ComMapClass>::data,\
_Chain},
#ifdef _ATL_DEBUG
#define END_COM_MAP() {NULL, 0, 0}}; return &_entries[1];} \
virtual ULONG STDMETHODCALLTYPE AddRef( void) = 0; \
virtual ULONG STDMETHODCALLTYPE Release( void) = 0; \
STDMETHOD(QueryInterface)(REFIID, void**) = 0;
#else
#define END_COM_MAP() {NULL, 0, 0}}; return _entries;} \
virtual ULONG STDMETHODCALLTYPE AddRef( void) = 0; \
virtual ULONG STDMETHODCALLTYPE Release( void) = 0; \
STDMETHOD(QueryInterface)(REFIID, void**) = 0;
#endif // _ATL_DEBUG
#define BEGIN_CATEGORY_MAP(x)\
static const struct _ATL_CATMAP_ENTRY* GetCategoryMap() {\
static const struct _ATL_CATMAP_ENTRY pMap[] = {
#define IMPLEMENTED_CATEGORY( catid ) { _ATL_CATMAP_ENTRY_IMPLEMENTED, &catid },
#define REQUIRED_CATEGORY( catid ) { _ATL_CATMAP_ENTRY_REQUIRED, &catid },
#define END_CATEGORY_MAP()\
{ _ATL_CATMAP_ENTRY_END, NULL } };\
return( pMap ); }
#define BEGIN_OBJECT_MAP(x) static _ATL_OBJMAP_ENTRY x[] = {
#define END_OBJECT_MAP() {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}};
#define OBJECT_ENTRY(clsid, class) {&clsid, class::UpdateRegistry, class::_ClassFactoryCreatorClass::CreateInstance, class::_CreatorClass::CreateInstance, NULL, 0, class::GetObjectDescription, class::GetCategoryMap, class::ObjectMain },
#define OBJECT_ENTRY_NON_CREATEABLE(class) {&CLSID_NULL, class::UpdateRegistry, NULL, NULL, NULL, 0, NULL, class::GetCategoryMap, class::ObjectMain },
#ifdef _ATL_DEBUG
extern HRESULT WINAPI AtlDumpIID(REFIID iid, LPCTSTR pszClassName, HRESULT hr);
#endif // _ATL_DEBUG
// the functions in this class don't need to be virtual because
// they are called from CComObject
class CComObjectRootBase
{
public:
CComObjectRootBase()
{
m_dwRef = 0L;
}
HRESULT FinalConstruct()
{
return S_OK;
}
// For library initialization only
HRESULT _AtlFinalConstruct()
{
return S_OK;
}
void FinalRelease() {}
void _AtlFinalRelease() {}
//ObjectMain is called during Module::Init and Module::Term
static void WINAPI ObjectMain(bool /* bStarting */) {}
static HRESULT WINAPI InternalQueryInterface(void* pThis,
const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject)
{
ATLASSERT(pThis != NULL);
// First entry in the com map should be a simple map entry
ATLASSERT(pEntries->pFunc == _ATL_SIMPLEMAPENTRY);
#if defined(_ATL_DEBUG_INTERFACES) || defined(_ATL_DEBUG_QI)
LPCTSTR pszClassName = (LPCTSTR) pEntries[-1].dw;
#endif // _ATL_DEBUG_INTERFACES
HRESULT hRes = AtlInternalQueryInterface(pThis, pEntries, iid, ppvObject);
#ifdef _ATL_DEBUG_INTERFACES
_Module.AddThunk((IUnknown**)ppvObject, pszClassName, iid);
#endif // _ATL_DEBUG_INTERFACES
return _ATLDUMPIID(iid, pszClassName, hRes);
}
//Outer funcs
ULONG OuterAddRef()
{
return m_pOuterUnknown->AddRef();
}
ULONG OuterRelease()
{
return m_pOuterUnknown->Release();
}
HRESULT OuterQueryInterface(REFIID iid, void ** ppvObject)
{
return m_pOuterUnknown->QueryInterface(iid, ppvObject);
}
void SetVoid(void*) {}
void InternalFinalConstructAddRef() {}
void InternalFinalConstructRelease()
{
ATLASSERT(m_dwRef == 0);
}
// If this assert occurs, your object has probably been deleted
// Try using DECLARE_PROTECT_FINAL_CONSTRUCT()
static HRESULT WINAPI _Break(void* /* pv */, REFIID iid, void** /* ppvObject */, DWORD_PTR /* dw */)
{
iid;
_ATLDUMPIID(iid, _T("Break due to QI for interface "), S_OK);
DebugBreak();
return S_FALSE;
}
static HRESULT WINAPI _NoInterface(void* /* pv */, REFIID /* iid */, void** /* ppvObject */, DWORD_PTR /* dw */)
{
return E_NOINTERFACE;
}
static HRESULT WINAPI _Creator(void* pv, REFIID iid, void** ppvObject, DWORD_PTR dw)
{
_ATL_CREATORDATA* pcd = (_ATL_CREATORDATA*)dw;
return pcd->pFunc(pv, iid, ppvObject);
}
static HRESULT WINAPI _Delegate(void* pv, REFIID iid, void** ppvObject, DWORD_PTR dw)
{
HRESULT hRes = E_NOINTERFACE;
IUnknown* p = *(IUnknown**)((DWORD_PTR)pv + dw);
if (p != NULL)
hRes = p->QueryInterface(iid, ppvObject);
return hRes;
}
static HRESULT WINAPI _Chain(void* pv, REFIID iid, void** ppvObject, DWORD_PTR dw)
{
_ATL_CHAINDATA* pcd = (_ATL_CHAINDATA*)dw;
void* p = (void*)((DWORD_PTR)pv + pcd->dwOffset);
return InternalQueryInterface(p, pcd->pFunc(), iid, ppvObject);
}
static HRESULT WINAPI _Cache(void* pv, REFIID iid, void** ppvObject, DWORD_PTR dw)
{
HRESULT hRes = E_NOINTERFACE;
_ATL_CACHEDATA* pcd = (_ATL_CACHEDATA*)dw;
IUnknown** pp = (IUnknown**)((DWORD_PTR)pv + pcd->dwOffsetVar);
if (*pp == NULL)
hRes = pcd->pFunc(pv, IID_IUnknown, (void**)pp);
if (*pp != NULL)
hRes = (*pp)->QueryInterface(iid, ppvObject);
return hRes;
}
union
{
long m_dwRef;
IUnknown* m_pOuterUnknown;
};
};
//foward declaration
template <class ThreadModel>
class CComObjectRootEx;
template <class ThreadModel>
class CComObjectLockT
{
public:
CComObjectLockT(CComObjectRootEx<ThreadModel>* p)
{
if (p)
p->Lock();
m_p = p;
}
~CComObjectLockT()
{
if (m_p)
m_p->Unlock();
}
CComObjectRootEx<ThreadModel>* m_p;
};
template <> class CComObjectLockT<CComSingleThreadModel>;
template <class ThreadModel>
class CComObjectRootEx : public CComObjectRootBase
{
public:
typedef ThreadModel _ThreadModel;
typedef _ThreadModel::AutoCriticalSection _CritSec;
typedef CComObjectLockT<_ThreadModel> ObjectLock;
ULONG InternalAddRef()
{
ATLASSERT(m_dwRef != -1L);
return _ThreadModel::Increment(&m_dwRef);
}
ULONG InternalRelease()
{
ATLASSERT(m_dwRef > 0);
return _ThreadModel::Decrement(&m_dwRef);
}
void Lock() {m_critsec.Lock();}
void Unlock() {m_critsec.Unlock();}
private:
_CritSec m_critsec;
};
template <>
class CComObjectRootEx<CComSingleThreadModel> : public CComObjectRootBase
{
public:
typedef CComSingleThreadModel _ThreadModel;
typedef _ThreadModel::AutoCriticalSection _CritSec;
typedef CComObjectLockT<_ThreadModel> ObjectLock;
ULONG InternalAddRef()
{
ATLASSERT(m_dwRef != -1L);
return _ThreadModel::Increment(&m_dwRef);
}
ULONG InternalRelease()
{
return _ThreadModel::Decrement(&m_dwRef);
}
void Lock() {}
void Unlock() {}
};
template <>
class CComObjectLockT<CComSingleThreadModel>
{
public:
CComObjectLockT(CComObjectRootEx<CComSingleThreadModel>*) {}
~CComObjectLockT() {}
};
typedef CComObjectRootEx<CComObjectThreadModel> CComObjectRoot;
#if defined(_WINDLL) | defined(_USRDLL)
#define DECLARE_CLASSFACTORY_EX(cf) typedef CComCreator< CComObjectCached< cf > > _ClassFactoryCreatorClass;
#else
// don't let class factory refcount influence lock count
#define DECLARE_CLASSFACTORY_EX(cf) typedef CComCreator< CComObjectNoLock< cf > > _ClassFactoryCreatorClass;
#endif
#define DECLARE_CLASSFACTORY() DECLARE_CLASSFACTORY_EX(CComClassFactory)
#define DECLARE_CLASSFACTORY2(lic) DECLARE_CLASSFACTORY_EX(CComClassFactory2<lic>)
#define DECLARE_CLASSFACTORY_AUTO_THREAD() DECLARE_CLASSFACTORY_EX(CComClassFactoryAutoThread)
#define DECLARE_CLASSFACTORY_SINGLETON(obj) DECLARE_CLASSFACTORY_EX(CComClassFactorySingleton<obj>)
#define DECLARE_OBJECT_DESCRIPTION(x)\
static LPCTSTR WINAPI GetObjectDescription()\
{\
return _T(x);\
}
#define DECLARE_NO_REGISTRY()\
static HRESULT WINAPI UpdateRegistry(BOOL /*bRegister*/)\
{return S_OK;}
#define DECLARE_REGISTRY(class, pid, vpid, nid, flags)\
static HRESULT WINAPI UpdateRegistry(BOOL bRegister)\
{\
return _Module.UpdateRegistryClass(GetObjectCLSID(), pid, vpid, nid,\
flags, bRegister);\
}
#define DECLARE_REGISTRY_RESOURCE(x)\
static HRESULT WINAPI UpdateRegistry(BOOL bRegister)\
{\
return _Module.UpdateRegistryFromResource(_T(#x), bRegister);\
}
#define DECLARE_REGISTRY_RESOURCEID(x)\
static HRESULT WINAPI UpdateRegistry(BOOL bRegister)\
{\
return _Module.UpdateRegistryFromResource(x, bRegister);\
}
//DECLARE_STATIC_* provided for backward compatibility
#ifdef _ATL_STATIC_REGISTRY
#define DECLARE_STATIC_REGISTRY_RESOURCE(x) DECLARE_REGISTRY_RESOURCE(x)
#define DECLARE_STATIC_REGISTRY_RESOURCEID(x) DECLARE_REGISTRY_RESOURCEID(x)
#endif //_ATL_STATIC_REGISTRY
template<class Base> class CComObject; // fwd decl
template <class Owner, class ThreadModel = CComObjectThreadModel>
class CComTearOffObjectBase : public CComObjectRootEx<ThreadModel>
{
public:
typedef Owner _OwnerClass;
CComObject<Owner>* m_pOwner;
CComTearOffObjectBase() {m_pOwner = NULL;}
};
//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)
{
_Module.Lock();
}
// Set refcount to 1 to protect destruction
~CComObject()
{
m_dwRef = 1L;
FinalRelease();
#ifdef _ATL_DEBUG_INTERFACES
_Module.DeleteNonAddRefThunk(_GetRawUnknown());
#endif
_Module.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)
{return _InternalQueryInterface(iid, ppvObject);}
template <class Q>
HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp)
{
return QueryInterface(__uuidof(Q), (void**)pp);
}
static HRESULT WINAPI CreateInstance(CComObject<Base>** pp);
};
template <class Base>
HRESULT WINAPI CComObject<Base>::CreateInstance(CComObject<Base>** pp)
{
ATLASSERT(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->FinalConstruct();
p->InternalFinalConstructRelease();
if (hRes != S_OK)
{
delete p;
p = NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -