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.