ATL-CComCreator(CComCoClass的使用)
2011-06-15 20:35 Clingingboy 阅读(2301) 评论(0) 编辑 收藏 举报
接上篇http://www.cnblogs.com/Clingingboy/archive/2011/06/14/2081019.html
一.封装生命周期步骤
由于以上过程容易出错,所以在CComCreator 对其生命周期调用进行了封装
template <class T1>
class CComCreator
{
public:
_Success_(return == S_OK) static HRESULT WINAPI CreateInstance(
_In_opt_ void* pv,
_In_ REFIID riid,
_Deref_out_ LPVOID* ppv)
{
ATLASSERT(ppv != NULL);
if (ppv == NULL)
return E_POINTER;
*ppv = NULL;
HRESULT hRes = E_OUTOFMEMORY;
T1* p = NULL;
ATLPREFAST_SUPPRESS(6014)
/* prefast noise VSW 489981 */
ATLTRY(p = new T1(pv))
ATLPREFAST_UNSUPPRESS()
if (p != NULL)
{
p->SetVoid(pv);
p->InternalFinalConstructAddRef();
hRes = p->_AtlInitialConstruct();
if (SUCCEEDED(hRes))
hRes = p->FinalConstruct();
if (SUCCEEDED(hRes))
hRes = p->_AtlFinalConstruct();
p->InternalFinalConstructRelease();
if (hRes == S_OK)
hRes = p->QueryInterface(riid, ppv);
if (hRes != S_OK)
delete p;
}
return hRes;
}
};
现在创建对象又简化了一些
class CPenguin : ... {
public:
...
typedef CComCreator<
CComPolyObject<CPenguin> > _CreatorClass;
};
STDMETHODIMP CAviary::CreatePenguin(IBird** ppbird) {
return CPenguin::_CreatorClass::CreateInstance(0,
IID_IBird,
(void**)ppbird);
}
二.使用CComCoClass 进一步简化
由于CreateInstance方法很常用,进一步简化就是继承一个既有封装好的类,就是CComCoClass,其实现方式是一样的
template <class T, const CLSID* pclsid = &CLSID_NULL>
class CComCoClass {
public:
...
template <class Q>
static HRESULT CreateInstance(IUnknown* punkOuter, Q** pp) {
return T::_CreatorClass::CreateInstance(punkOuter,
__uuidof(Q), (void**) pp);
}
template <class Q>
static HRESULT CreateInstance(Q** pp) {
return T::_CreatorClass::CreateInstance(NULL,
__uuidof(Q), (void**) pp);
}
};
三.用宏简化CComCreator的创建
#define DECLARE_POLY_AGGREGATABLE(x) public:\
typedef ATL::CComCreator< \
ATL::CComPolyObject< x > > _CreatorClass;
现在简化成这样(或者将DECLARE_AGGREGATABLE放在CComCoClass内部)
class CPenguin : public CComCoClass<CPenguin, &CLSID_CPenguin> {
public:
...
DECLARE_AGGREGATABLE(CPenguin)
};
四.是否支持聚合(CComFailCreator)