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:
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.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
The relevent snippit of code is here:
If I use CF_TEXT to get just the String value (having 'Copied' it into the ClipBoard explicitly) the code below works fineCode: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)
Has anyone an idea of what 'stupidity' I'm demonstrating ? (lstrlen and SysAllocStringByteLen are APIs by the way)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)
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.


Reply With Quote