Hi All,
I've been trying for the past few hours to call IEnumVARIANT::Next() on a collection Enum. I would like this as I am building a wrapper for EnumVARIANTs giving them more possibilities.
Every time I try to do this however I get a crash... :confused: I'm clearly doing something wrong...
I've had numerous issues from compile errors to straight up crashes... I've also searched this forum and was surprised that I didn't actually find this being done before... I've seen 1 post by fafalone where oleexp3.IEnumVARIANT was used, but I want to avoid the need for external type libraries. I've also tried using passing in ObjPtr(e) as the first argument, however it appears ObjPtr doesn't support a parameter of type IEnumVARIANT (which I find a little odd given that IEnumVARIANT does implement IUnknown...)
Has anyone got any ideas of where I'm going wrong / have an example?
I've been trying for the past few hours to call IEnumVARIANT::Next() on a collection Enum. I would like this as I am building a wrapper for EnumVARIANTs giving them more possibilities.
Code:
'Example - Ideally i'd like to use more than just a Collection object
Dim col as Collection
set col = new Collection
Dim e as IEnumVARIANT
set e = col.[_NewEnum]
Do While true
Dim x as variant
CopyVariant x , vbEnumNext(e)
if isNull(x) then Exit Do
'...
Loop
Code:
Private Declare PtrSafe Function EnumCall Lib "oleaut32.dll" Alias "DispCallFunc" (ByRef pObject As IEnumVARIANT, ByVal offsetinVft As Long, ByVal CallConv As Long, ByVal retTYP As Integer, ByVal paCNT As Long, ByRef pTypes() As Long, ByRef pValues() As Long, ByRef retVar As Variant) As Long
Private Enum CALLRETURNTUYPE_ENUM
CR_None = vbEmpty
CR_LONG = vbLong
CR_BYTE = vbByte
CR_INTEGER = vbInteger
CR_SINGLE = vbSingle
CR_DOUBLE = vbDouble
CR_CURRENCY = vbCurrency
' if the value you need isn't in above list, you can pass the value manually to the
' CallFunction_DLL method below. For additional values, see:
' http://msdn.microsoft.com/en-us/library/cc237865.aspx
End Enum
Const CC_STDCALL As Long = 4&
Public Function vbEnumNext(ByRef e As IEnumVARIANT) as Variant
Dim paTypes() As Long
ReDim paTypes(1 To 3)
paTypes(1) = CR_INTEGER
paTypes(2) = CR_LONG
paTypes(3) = CR_LONG
Dim p1 As Long: p1 = 1
Dim p2 As Variant
Dim p3 As Long
Dim paValues(1 To 3) As Long
paValues(1) = VarPtr(p1)
paValues(2) = VarPtr(p2)
paValues(3) = VarPtr(p3)
Dim hResult As Long, retVar As Variant
hResult = EnumCall(e, 4, CC_STDCALL, CALLRETURNTUYPE_ENUM.CR_LONG, 3, paValues, paTypes, retVar)
Call CopyVariant(vbEnumNext, retVar)
End Function
Public Sub CopyVariant(ByRef dest As Variant, ByVal src As Variant)
If IsObject(src) Or VarType(src) = 13 Then
Set dest = src
Else
dest = src
End If
End Sub
Has anyone got any ideas of where I'm going wrong / have an example?