SAFEARRAY Data

VBZeroPlus
VBZeroPlus used Ask the Experts™
on
I am having trouble usinf a VB6 program to read the actual data contained within a SAFEARRAY.  I can get the dimensions, element size etc, but have been unable to read the actual data.  Using watch, I can see the character numbers, but cannot get program to give me the alpha string.  Here is the code I am using, with the problem area between the  '########' lines.  

I am weak in this area, so need help!!

Function GetArrayInfo(TheArray As Variant, ArrayInfo As SafeArray) As Boolean
    Dim lp As Long         ' work pointer variable
    Dim VType As Integer   ' the VARTYPE member of the VARIANT structure
    Dim Count As Integer
    Dim TempString As String
    Dim Dest() As Byte

    ' Exit if no array supplied
    If Not IsArray(TheArray) Then Exit Function

    With ArrayInfo
        ' Get the VARTYPE value from the first 2 bytes of the VARIANT structure
        CopyMemory VType, TheArray, 2

        ' Get the pointer to the array descriptor (SAFEARRAY structure)
        ' NOTE: A Variant's descriptor, padding & union take up 8 bytes.
        CopyMemory lp, ByVal VarPtr(TheArray) + 8, 4

        ' Test if lp is a pointer or a pointer to a pointer.
        If (VType And VT_BYREF) <> 0 Then
            ' Get real pointer to the array descriptor (SAFEARRAY structure)
            CopyMemory lp, ByVal lp, 4
        End If

        ' Fill the SAFEARRAY structure with the array info
        ' NOTE: The fixed part of the SAFEARRAY structure is 16 bytes.
        CopyMemory ArrayInfo.cDims, ByVal lp, 16

        ' Ensure the array has been dimensioned before getting SAFEARRAYBOUND
        ' Information
        If ArrayInfo.cDims > 0 Then
            ' Fill the SAFEARRAYBOUND structures with the array info
            CopyMemory .rgsabound(1), ByVal lp + 16, _
                ArrayInfo.cDims * Len(.rgsabound(1))

            ' So caller knows there is information available for the array in
            ' output SAFEARRAY
            GetArrayInfo = ArrayInfo.cDims
           
      '##################################################
        'This is declared elsewhere ( VarPtrArray )
       ' Public Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (Ptr() As Any) As Long
       
            ReDim Dest(.rgsabound(1).cElements)
            For Count = 1 To .rgsabound(1).cElements
                CopyMemory ByVal VarPtrArray(Dest), VarPtr(lp), 4
                Debug.Print Dest
            Next Count
           
     '##################################################

           
        End If
    End With

End Function
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
"...but cannot get program to give me the alpha string."

Is this a string array?  Then you need to use the VarPtrStringArray and/or the StrPtr functions.  Without knowing the exact data structure you are working with, I can't guess what is needed right now.  See:

http://support.microsoft.com/default.aspx?scid=KB;en-us;q199824

for more info.

Author

Commented:
I am actually trying to capture the PostData information in the WebBrowser BeforeNavigate event.  I think this will be a single dimension alpha-numeric string.

Author

Commented:
I am actually trying to capture the PostData information in the WebBrowser BeforeNavigate event.  I think this will be a single dimension alpha-numeric string.
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Author

Commented:
I am still lost I think.  I have tried several iterations, and am now crashing VB with the CopyMemory statement.  The code as it currently stands is:

     '##################################################
            Dim AddressofString As Long
            Dim MyString() As String
            ReDim MyString(.rgsabound(1).cElements)
            AddressofString = StrPtr(MyString(0))
            'For Count = 1 To .rgsabound(1).cElements
                'CopyMemory ByVal AddressofString, VarPtr(lp), 4
                CopyMemory ByVal AddressofString, StrPtr(lp), 4
               ' Debug.Print Dest
            'Next Count
           
     '##################################################

I searched for the VarPtrStringArray, and did not find an API type definition like I expected.  Do I need to use that function rather that StrPtr as suggested above?  If so, do I need to use the .odl file and MIDL compiler as mentioned in the reference?  I created that file, but not sure how to proceed from that point.

HELP!!!
I discovered how to read the PostData information without all of the SAFEARRAY and memory headaches.  If anyone is interested, here is the gist of my solution:

Private Sub WebBrowser_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean)
    Dim TestString As String
    Dim MyString As String
   
       
        If Len(PostData) <> 0 Then
            Dim MyVar As Variant
       
            MyVar = PostData
            If VarType(MyVar) = (vbArray Or vbByte) Then
                Dim Bytes() As Byte
                Bytes = MyVar
                TestString = ""
                For Test = 0 To 500
                  If Bytes(Test) = 0 Then Exit For
                  TestString = TestString + Chr(Bytes(Test))
                Next Test
                 
             End If
        End If
    debug.print TestString
End Sub
Author of the Year 2009

Commented:
Hi VBZeroPlus,
It appears that you have forgotten this question. I will ask Community Support to close it unless you finalize it within 7 days. I will ask a Community Support Moderator to:

    Refund points and save as a 0-pt PAQ.

VBZeroPlus, Please DO NOT accept THIS comment as an answer.
EXPERTS: Post a comment if you are certain that an expert deserves credit.  Explain why.
==========
DanRollins -- EE database cleanup volunteer

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial