代码改变世界

ATL-CComCreator(CComCoClass的使用)

  Clingingboy  阅读(2309)  评论(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)

编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
历史上的今天:
2008-06-15 wpf-装饰器
2007-06-15 脚本与后端数据传递小技巧
点击右上角即可分享
微信分享提示