一.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;