代码改变世界

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)