Results 1 to 5 of 5

Thread: [UPDATE] API - Is my logic flawed?

  1. #1

    Thread Starter
    Member
    Join Date
    Feb 2002
    Posts
    38

    [UPDATE] API - Is my logic flawed?

    the original thread started here but i guess it's better suited for this forum.

    i'm trying to read mail from a Microsoft Exchange server. the HTML portion is stored in a field in a compressed format. MS provides a function to uncompress the RTF here but it's in C++ which i'm pretty much clueless about. MerrionComputin gave me this API call which i've added:
    Code:
    Public Declare Function WrapCompressedRTFStream Lib "mapi32.dll" (ByVal lpCompressedRTFStream As Long , _ 
                              ByVal uFlags As Long , _ 
                              lpUncompressedStream As Long ) As Long
    i though i could pretty much do something like this:
    Code:
    CONST S_OK = &H0
    myRTF = myMessage.Fields(CdoPR_RTF_COMPRESSED) ' get the compressed portion - this works fine
    myRTF_U = Space(50000)
    If WrapCompressedRTFStream(StrPtr(myRTF), 0, StrPtr(myRTF_U)) <> S_OK Then
    MsgBox("Error")
    End If
    the function returns S_OK but the value of RTF_U is just 50000 spaces. is my logic flawed here?

    thanks!
    Last edited by ChrisHaas; May 20th, 2002 at 12:20 PM.
    Chris Haas
    Web Developer
    Ovation Advertising & Marketing
    p. (608) 785-2460
    e. [email protected]

  2. #2

    Thread Starter
    Member
    Join Date
    Feb 2002
    Posts
    38
    okay, i've been talking with someone and they've suggested that i need to use an LPSTREAM instead of just a string. now i have no idea how i would create one of these in VB, can someone help me with that?

    thanks
    Chris Haas
    Web Developer
    Ovation Advertising & Marketing
    p. (608) 785-2460
    e. [email protected]

  3. #3
    Frenzied Member MerrionComputin's Avatar
    Join Date
    Apr 2001
    Location
    Dublin, Ireland
    Posts
    1,616
    There isn't really such a thing as an LPSTREAM in VB, but that's not too much of a problem as that is just a pointer so you can use VB LOng.

    CONST S_OK = &H0
    myRTF = myMessage.Fields(CdoPR_RTF_COMPRESSED) ' get the compressed portion - this works fine
    myRTF_U = Space(50000)
    If WrapCompressedRTFStream(StrPtr(myRTF), 0, StrPtr(myRTF_U)) <> S_OK Then
    MsgBox("Error")
    End If
    OK - here you need to declare a variable to accept the pointer...because the last parameter of WrapCompressedRTFStream is defined as [ o u t ] which means the call itself will allocate the memory and tell you where it is.

    So instead try:
    VB Code:
    1. Dim lpTarget As Long
    2. CONST S_OK = &H0
    3. myRTF = myMessage.Fields(CdoPR_RTF_COMPRESSED) ' get the compressed portion - this works fine
    4. myRTF_U = Space(50000)
    5. If WrapCompressedRTFStream(StrPtr(myRTF), 0, lpTarget) <> S_OK Then
    6.    MsgBox("Error")
    7. Else
    8.   If lpTarget > 0 Then
    9.      '\\ This is a pointer to the uncompressed stream...you could try StringFromPointer?
    10.      Debug.Print StringFromPointer(lpTarget, 2048)
    11.   End If
    12. End If

    Where StringFromPointer is coded thus:
    VB Code:
    1. '\\ API declarations
    2. '\ Declarations for StringFromPointer
    3. Private Declare Function IsBadStringPtrByLong Lib "kernel32" Alias "IsBadStringPtrA" (ByVal lpsz As Long, ByVal ucchMax As Long) As Long
    4.  
    5. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
    6.                        (Destination As Any, _
    7.                        Source As Any, _
    8.                        ByVal Length As Long)
    9.  
    10. Private Function StringFromPointer(lpString As Long, lMaxlength As Long) As String
    11.  
    12. Dim sRet As String
    13. Dim lRet As Long
    14.  
    15. If lpString = 0 Then
    16.     StringFromPointer = ""
    17.     Exit Function
    18. End If
    19.  
    20. If Not IsBadStringPtrByLong(lpString, lMaxlength) Then
    21.     '\ Set aside space to copy string to
    22.     sRet = String$(lMaxlength, 0)
    23.     CopyMemory ByVal sRet, ByVal lpString, ByVal Len(sRet)
    24.     If InStr(sRet, Chr$(0)) > 0 Then
    25.         sRet = Left$(sRet, InStr(sRet, Chr$(0)) - 1)
    26.     End If
    27. End If
    28.  
    29. StringFromPointer = sRet
    30.  
    31. End Function

    Hope this helps,
    Duncan
    ----8<---------------------------------------
    NEW - The .NET printer queue monitor component
    ----8<---------------------------------------
    Now with Examples of use

  4. #4

    Thread Starter
    Member
    Join Date
    Feb 2002
    Posts
    38
    thanks a lot duncan. unfortunately i'm running into an issue now where the WrapCompressedRTFStream function returns a value of -2147024809 which according to MS error lookup util is a "Parameter is incorrect" message. unfortunately it doesn't tell me which parameter is incorrect. i highly doubt it's the constants in the second parameter (i've tried them all.) i also took a closer look at the MSDN site and they kinda make it sound like i'm supposed to pass a pointer to the property field itself instead of just a string variable holding the value. i tried using ObjPtr and VarPtr on that but still got the same error message. i can't really seem to tell what else i'm doing wrong. i pass it a pointer to the stream, a constant, and a variable that it can modify ByRef to drop the decoded string. please, any help that you or anyone else can give me i would be forever grateful. this project has become a crusade for me and i really want to solve this!

    thanks!

    [edit]
    is there any chance this has something to do with the encoding of the stream, like in ANSI or UNICODE or anything?

    thanks again!
    Last edited by ChrisHaas; May 20th, 2002 at 11:53 PM.
    Chris Haas
    Web Developer
    Ovation Advertising & Marketing
    p. (608) 785-2460
    e. [email protected]

  5. #5

    Thread Starter
    Member
    Join Date
    Feb 2002
    Posts
    38
    okay Duncan, i think i have a little bit more of my mystery solved. the function is looking for a pointer to an LPSTREAM, and i think an ADODB.Stream object is the closest VB equivalent. so i've created the stream, set it's mode to text, loaded the compressed RTF stream, set the position of the pointer back to 0, and used ObjPtr to point my pointer variable to the stream. however, when i pass this into the function and run it, VB completely shuts down, so i don't think that's too good. but i think this might be the right track to go down. any help that you or anyone can provide would be really great!

    thanks
    Chris Haas
    Web Developer
    Ovation Advertising & Marketing
    p. (608) 785-2460
    e. [email protected]

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width