IEnumVARIANT and IEnumXXX
IEnumVARIANT is an enumerator interface used in COM/DCOM. Collection objects can be represented as IEnumVARIANT. The IEnumVARIANT interface has these methods.
- Clone - Creates a copy of the current state of enumeration.
- Next - Retrieves the specified items in the enumeration sequence.
- Reset - Resets the enumeration sequence to the beginning.
- Skip - Attempts to skip over the next celt elements in the enumeration sequence.
IEnumVARIANT example IDL
CWEEKDAYSENUMXXXLib is a COM server with coclass Weekdays and IWeekdays interface. GetEnumerator() function of IWeekdays returns IEnumVARIANT enumerator object which is a collection of BSTRs containing week days name.
import "oaidl.idl"; import "ocidl.idl"; [ object, uuid(37291CD6-6A49-4B1D-A110-FABD8402722A), dual, helpstring("IWeekdays Interface"), pointer_default(unique) ] interface IWeekdays : IDispatch { [id(0xfffffffc), helpstring("method GetEnumerator")] HRESULT GetEnumerator([out,retval] IEnumVARIANT **pDays); }; [ uuid(3AC6B05B-A8BC-4213-82E8-14AD17C9FE7D), version(1.0), helpstring("CWeekDaysEnumXXX 1.0 Type Library") ] library CWEEKDAYSENUMXXXLib { importlib("stdole32.tlb"); importlib("stdole2.tlb"); [ uuid(17975251-FF69-44B4-ABFA-58225428B4CE), helpstring("Weekdays Class") ] coclass Weekdays { [default] interface IWeekdays; }; };
IEnumVARIANT implementation C++
class CEnumWeekdays: public IEnumVARIANT { protected: int m_nCursor; VARIANT m_DayVars[5]; ULONG m_nRef; public: CEnumWeekdays() { unsigned short *days[5] = {L"Monday",L"Tuesday",L"Wednesday",L"Thursday",L"Friday"}; m_nCursor = 0; m_nRef = 0; for (int i = 0; i < 5; i++ ) { VariantInit(&m_DayVars[i]); m_DayVars[i].vt = VT_BSTR; m_DayVars[i].bstrVal = SysAllocString(days[i]); } } virtual long __stdcall QueryInterface(const struct _GUID & iid,void ** ppvObject) { if ( iid == IID_IUnknown) { *ppvObject = dynamic_cast( this ); } else if ( iid == IID_IEnumVARIANT) { *ppvObject = dynamic_cast ( this ); }else { *ppvObject = NULL; return E_NOINTERFACE; } this->AddRef(); return S_OK; } virtual unsigned long __stdcall AddRef(void) { return ++m_nRef; } virtual unsigned long __stdcall Release(void) { int ref = --m_nRef; if(ref == 0) { for (int i = 0; i < 5; i++ ) { SysFreeString( m_DayVars[i].bstrVal); } delete this; } return ref; } virtual HRESULT __stdcall Next( ULONG celt, VARIANT * rgVar, ULONG * pCeltFetched ) { UINT current = m_nCursor; if(rgVar == NULL) return E_POINTER; m_nCursor += celt; if(current > 4){ if(rgVar)rgVar = NULL; return S_FALSE; } int out; out = m_nCursor - current; memcpy(rgVar, &m_DayVars[current], (out)*sizeof(VARIANT)); if(pCeltFetched) *pCeltFetched = out; return S_OK; } virtual HRESULT __stdcall Skip( ULONG celt ) { m_nCursor += celt; if(m_nCursor > 4) { m_nCursor = 4; } return S_OK; } virtual HRESULT __stdcall Reset( ) { m_nCursor = 0; return S_OK; } virtual HRESULT __stdcall Clone( IEnumVARIANT ** ppEnum ) { if(ppEnum == NULL) return E_POINTER; *ppEnum = (IEnumVARIANT*)new CEnumWeekdays(); if(*ppEnum == NULL) return E_OUTOFMEMORY; (*ppEnum)->AddRef(); return S_OK; } };
CWeekdays class GetEnumerator()
class ATL_NO_VTABLE CWeekdays : public CComObjectRootEx, public CComCoClass , public IDispatchImpl { public: CWeekdays() { } DECLARE_REGISTRY_RESOURCEID(IDR_WEEKDAYS) DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP(CWeekdays) COM_INTERFACE_ENTRY(IWeekdays) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() // IWeekdays public: STDMETHOD(GetEnumerator)(/*[out,retval]*/ IEnumVARIANT **pDays); }; STDMETHODIMP CWeekdays::GetEnumerator(IEnumVARIANT **pDays) { CEnumWeekdays *pEnum = new CEnumWeekdays(); if(pEnum == NULL) return E_OUTOFMEMORY; pEnum->AddRef(); (*pDays) =dynamic_cast (pEnum); return S_OK; }
IEnumVARIANT VB client
Dim EnumerableObj As IEnumVARIANT Private Sub Form_Load() Set EnumerableClassObj = New CWEEKDAYSENUMXXXLib.Weekdays Dim day As Variant Dim str As String For Each day In EnumerableClassObj str = str & day & "," Next MsgBox str Set EnumerableClassObj = Nothing End Sub
IEnumVARIANT VB client output
About our authors: Team EQA
You have viewed 1 page out of 67. Your COM/DCOM learning is 0.00% complete. Login to check your learning progress.