详细解读COM中集合和枚举器笔记(2)枚举器内部实现

简介: 详细解读COM中集合和枚举器笔记(2)枚举器内部实现

一.ATL枚举器接口

CComIEnum通用枚举器接口

template[span style="color: rgba(0, 0, 255, 1)">class T>

class ATL_NO_VTABLE CComIEnum :

public IUnknown

{

public:

STDMETHOD(Next)(

In ULONG celt,

Out T rgelt,

_Outopt ULONG pceltFetched) = 0;

STDMETHOD(Skip)(In ULONG celt) = 0;

STDMETHOD(Reset)(void) = 0;

STDMETHOD(Clone)(_Derefout CComIEnum ppEnum) = 0;

};

二.CComEnumImpl定义

template [span style="color: rgba(0, 0, 255, 1)">class Base, const IID piid, class T, class Copy>

class ATL_NO_VTABLE CComEnumImpl :

public Base

{

public:

CComEnumImpl()

{

m_begin = m_end = m_iter = NULL;

m_dwFlags = 0;

}

virtual ~CComEnumImpl();

STDMETHOD(Next)(

//代码效果参考:http://www.zidongmutanji.com/zsjx/367637.html

In ULONG celt,

Out T rgelt,

_Outopt ULONG* pceltFetched);

STDMETHOD(Skip)(In ULONG celt);

STDMETHOD(Reset)(void)

{

m_iter = m_begin;

return S_OK;

}

STDMETHOD(Clone)(_Derefout Base ppEnum);

HRESULT Init(

In T begin,

In T end,

_Inopt IUnknown pUnk,

In CComEnumFlags flags = AtlFlagNoCopy);

CComPtr m_spUnk;

T m_begin;

T m_end;

T m_iter;

DWORD m_dwFlags;

protected:

enum FlagBits

{

BitCopy=1,

BitOwn=2

};

};

m_begin,m_end,m_iter表示元素位置

三.Next实现

template [span style="color: rgba(0, 0, 255, 1)">class Base, const IID piid, class T, class Copy>

STDMETHODIMP CComEnumImpl::Next(

In ULONG celt,

Out T rgelt,

_Outopt ULONG pceltFetched)

{

if (pceltFetched != NULL)

pceltFetched = 0;

if (rgelt == NULL || (celt > 1 && pceltFetched == NULL))

return E_POINTER;

if (m_begin == NULL || m_end == NULL || m_iter == NULL)

return E_FAIL;

ULONG nRem = (ULONG)(m_end - m_iter);

HRESULT hRes = S_OK;

if (nRem < celt)

hRes = S_FALSE;

ULONG nMin = celt < nRem ? celt : nRem ;

if (pceltFetched != NULL)

pceltFetched = nMin;

T pelt = rgelt;

while(nMin--)

{

HRESULT hr = Copy::copy(pelt, m_iter);

if (FAILED(hr))

{

while (rgelt < pelt)

Copy::destroy(rgelt++);

if (pceltFetched != NULL)

pceltFetched = 0;

return hr;

}

pelt++;

m_iter++;

}

return hRes;

}

关键部分在于Copy::copy和Copy::destroy方法,所以拷贝策略在于外部的Copy类的的静态方法copy

四.拷贝策略类

template [span style="color: rgba(0, 0, 255, 1)">class T>

class _Copy

{

public:

static HRESULT copy(Out T p1, In const T p2)

{

Checked::memcpy_s(p1, sizeof(T), p2, sizeof(T));

return S_OK;

}

static void init(_Inoutopt T)

{

}

static void destroy(_Inoutopt T)

{

}

};

除此之外,还提供了一些常用的特化类

五.CComEnum类

template [span style="color: rgba(0, 0, 255, 1)">class Base, const IID piid, class T, class Copy, class ThreadModel = CComObjectThreadModel>

class ATL_NO_VTABLE CComEnum :

public CComEnumImpl,

public CComObjectRootEx

{

public:

typedef CComEnum _CComEnum;

typedef CComEnumImpl _CComEnumBase;

//代码效果参考:http://www.zidongmutanji.com/bxxx/52900.html

BEGIN_COM_MAP(_CComEnum)

COM_INTERFACE_ENTRY_IID(*piid, _CComEnumBase)

END_COM_MAP()

};

如上,所以要所以CComEnum 的话,需如下定义

typedef CComEnum< IEnumVARIANT, &IID_IEnumVARIANT, VARIANT,

_Copy > CComEnumVariant;

相关文章
|
6月前
|
C语言
|
6月前
|
安全 算法 编译器
【C++基础语法 枚举】C/C++ 中enum枚举量的介绍:介绍enum枚举量在C/C中的作用和使用方法
【C++基础语法 枚举】C/C++ 中enum枚举量的介绍:介绍enum枚举量在C/C中的作用和使用方法
77 2
|
5月前
|
设计模式 存储 Java
JavaSE——面向对象高级三(3/5)-枚举(认识枚举、拓展:抽象枚举、用枚举实现单例模式、枚举的应用场景)
JavaSE——面向对象高级三(3/5)-枚举(认识枚举、拓展:抽象枚举、用枚举实现单例模式、枚举的应用场景)
34 0
|
存储 安全 Java
枚举的 7 种使用方法
枚举的 7 种使用方法
|
安全 Java 编译器
枚举使用、转数组、实现接口、枚举单例
枚举使用、转数组、实现接口、枚举单例
124 0
|
Swift
Swift实用小册07:枚举的创建、使用、遍历、关联值、原始值
Swift实用小册07:枚举的创建、使用、遍历、关联值、原始值
420 0
Swift实用小册07:枚举的创建、使用、遍历、关联值、原始值
|
安全 Java API
枚举很好用啊!为啥阿里不建议返回值用枚举??
小伙伴说在一次接口定义时,使用了枚举,结果被其它人深深嫌弃,说不好拓展。 为什么会被嫌弃呢?我们先来看看阿里开发手册关于枚举使用的建议
枚举很好用啊!为啥阿里不建议返回值用枚举??
|
开发者
枚举(枚举中定义其它结构)|学习笔记
快速学习 枚举(枚举中定义其它结构)
119 0