Results 1 to 1 of 1

Thread: 'Unscrambling' a UDT

  1. #1
    PowerPoster
    Join Date
    Jul 06
    Location
    Maldon, Essex. UK
    Posts
    5,136

    'Unscrambling' a UDT

    I was producing some example code to help with this post http://www.vbforums.com/showthread.p...ipboard-in-VB6

    It's basically attempting to pass a UDT to the ClipBoard and then read it back. The UDT looks like:
    Code:
    Private Type Doogle
        Size As Long
        aByteArray(4) As Byte
        aSingleByte As Byte
        anInteger As Integer
        aLong As Long
        aSingle As Single
        aDouble As Double
        aCurrency As Currency
        aDate As Date
        aBoolean As Boolean
        aString As String
    End Type
    Everything goes well with the 'Copy' operation (as far as I can tell) but the 'Paste' is not so straightforward when it comes to getting the String value back. The GetClipBoardData API returns a Handle to the data and I can use CopyMemory to populate the non-string items in the UDT. As far as the String is concerned, I would expect a 4 byte pointer which I could pick up ByVal and use to find the actual data. I'd expect that pointer to be the last 4 bytes of the data pointed to by the Handle. This doesn't seem to be the case; when I try that I either get; a zero length returned by lstrlen, an incorrect String Value, or VB6 explodes.

    The relevent snippit of code is here:
    Code:
    lngHData = GetClipboardData(lngRet)
    If lngHData <> 0 Then
        lngHandle = GlobalLock(lngHData)
        CopyMemory myPastedUDT, ByVal lngHandle, LenB(myPastedUDT) - 4 
        lngString = lngHandle + (LenB(myPastedUDT) - 4)     
        lngLen = lstrlen(byVal lngString)                    
        myPastedUDT.aString = SysAllocStringByteLen(ByVal lngString, lngLen) 
        GlobalUnlock (lngHData)
    If I use CF_TEXT to get just the String value (having 'Copied' it into the ClipBoard explicitly) the code below works fine
    Code:
        lngHData = GetClipboardData(CF_TEXT)
        If lngHData <> 0 Then
            lngHandle = GlobalLock(lngHData)
            lngLen = lstrlen(ByVal lngHandle)
            '
            ' Following line is as per Merri
            ' (http://www.vbforums.com/showthread.php?644597-How-to-get-String-from-Pointer-in-VB)
            '
            myPastedUDT.aString = SysAllocStringByteLen(ByVal lngHandle, lngLen)
            GlobalUnlock (lngHData)
    Has anyone an idea of what 'stupidity' I'm demonstrating ? (lstrlen and SysAllocStringByteLen are APIs by the way)

    I'm aware that 'normally' Handles are not Pointers, but in this case it's certainly acting like one as far as the majority of the data is concerned. I can't seem to find any documentation regarding the layout of the ClipBoard data but I would expect it to be in the same order that I 'Copied' it - perhaps it's not - or I can't see the Wood for the Trees !

    EDIT: I just had a thought, perhaps the String Pointer in the UDT that was 'Copied' to the ClipBoard is 'out of scope' by the time I pick it up - after all as far as the ClipBoard is concerned it just sees a 4 byte value, and it's in my Address Space - it has no idea it's a pointer to a String pointer. If that is the case would it be safe to conclude that the only way to pass a String Type into the Clipboard is via CF_TEXT (or equivalents)? It seems reasonable to expect CF_TEXT to copy the actual data to the ClipBoard and point to it, rather than just a Pointer.
    Last edited by Doogle; Sep 24th, 2012 at 01:58 AM.

Posting Permissions

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