Quantcast
Channel: VBForums
Viewing all articles
Browse latest Browse all 16044

How to call IEnumVARIANT::Next() with DispCallFunc() - Without external TLBs

$
0
0
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.

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

Every time I try to do this however I get a crash... :confused: I'm clearly doing something wrong...


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

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?

Viewing all articles
Browse latest Browse all 16044

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>