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.