Copy picture to clipboard (Windows 7)

Hi all,

I’m trying to copy the picture of the backdrop of a canvas to the clipboard so I can paste it in Microsoft Word. This does not seem to work.
I tried two things:

c.Picture = me.Backdrop (c is a New Clipboard object)

And i tried:

c.AddRawData me.Backdrop.GetData(Picture.FormatJPEG,100),“JPG”

When I try to paste to Microsoft Word, nothing happens. Clipboard seems to be empty.

Any suggestions?

Best Regards,

Michael

I have made a test app which uses the clipboard.picture (from Xojo documentation). I can copy a picture from a canvas to the clipboard picture. When I try to paste this picture into Word, Wordpad or Outlook it does not work. When I try to paste this picture to “IrvanView”, the picture is horizontal and vertical mirrored. Only a paste into Gimp works correct.

[quote=118254:@Michael Beaucourt]Hi all,

I’m trying to copy the picture of the backdrop of a canvas to the clipboard so I can paste it in Microsoft Word. This does not seem to work.
I tried two things:

c.Picture = me.Backdrop (c is a New Clipboard object)

And i tried:

c.AddRawData me.Backdrop.GetData(Picture.FormatJPEG,100),“JPG”

When I try to paste to Microsoft Word, nothing happens. Clipboard seems to be empty.[/quote]

I just verified. It is a bit more complex.

The picture is indeed copied to the clipboard, but not all applications see it.

I can paste into Paint fine, but not in Microsoft Word. If text has been copied prior to Xojo attempt to place a picture in the clipboard, the text is pasted into Word and not the picture.

So it seems the clipboard structure retains different formats, and Word does not see the picture format that Paint recognizes fine.

After a picture coming from Xojo has been pasted into Paint, if copied, it is recognized fine by Word.

I am trying to use the API function SetClipboardData to place a picture on the clipboard. I found a declare in the NUG with it, but it is for text. So I tried to adapt it to pictures. But so far I have not been successful. Nothing gets to the clipboard. Here is what I have.
I will strongly appreciate any pointer.

[code]Sub Action()
dim pic as picture
pic = Studebaker

Const LR_LOADFROMFILE = &H10
Const IMAGE_BITMAP = 0
Const IMAGE_ICON = 1
Const IMAGE_CURSOR = 2
Const IMAGE_ENHMETAFILE = 3
Const CF_BITMAP = 2
const GMEM_DDESHARE = &H2000
const GMEM_MOVEABLE = &H02
const CF_TEXT = 1

declare function OpenClipboard lib “user32.dll” (i as integer) as boolean
declare sub SetClipboardData lib “user32.dll” (i as integer, hdl as Integer)
declare sub CloseClipboard lib “user32.dll” ()
declare function GlobalAlloc lib “kernel32.dll” (flags as Integer,numBytes as Integer) as Integer
declare function GlobalLock Lib “kernel32.dll” (hdl as Integer) as Ptr
declare sub GlobalUnlock Lib “kernel32.dll” (hdl as Integer)

dim hdl as Integer, mb as MemoryBlock
mb = pic.GetData(Picture.FormatBMP, -1)

if not OpenClipboard(0) then
break
else
hdl = GlobalAlloc (GMEM_MOVEABLE + GMEM_DDESHARE, mb.Size+4)
mb = GlobalLock(hdl)
mb = pic.GetData(Picture.FormatBMP, -1)
GlobalUnlock(hdl)
SetClipboardData(CF_BITMAP, hdl)
CloseClipboard
end if
End Sub
[/code]

I have tried to adapt the code to the best I could understand. In the original, hdl is set through GlobalAlloc with the len of a string+1, then the memory block mb.stringvalue is set to that string.

hdl = GlobalAlloc (GMEM_MOVEABLE + GMEM_DDESHARE, LenB(txt) + 1) mb = GlobalLock(hdl) mb.CString(0) = txt

What I did was to load mb with the picture with pic.GetData, and use mb.size+2 for hdl (4 bytes given the length of the picture). Then after locking the resource with GlobalLock, I again load it with the picture, like it was set with the string in the NUG code.
And I use as first parameter of SetClipboardData CF_BITMAP to indicate it is a picture.

The original code posted at http://www.monkeybreadsoftware.eu/listarchive-realbasic-nug/2009-07-02-7.shtml works perfectly to place text on the clipboard. So the declare for SetClipboardData is correct. Now the problem probably lies in the parameters passed to it.

I tried to follow the indications on the Microsoft Developer Network at
http://msdn.microsoft.com/en-us/library/windows/desktop/ms649051(v=vs.85).aspx
and what is not entirely clear is that Microsoft quotes the second argument (hdl) as being a handle to the data. So I would expect hdl to be a handle to a resource, but it is set in the original code that works for text as

hdl = GlobalAlloc (GMEM_MOVEABLE + GMEM_DDESHARE, LenB(txt) + 1) which shows no mention of the actual variable txt, but only of its length.

In the description of the declare for VB6 at http://www.ex-designz.net/apidetail.asp?api_id=610
the image is setting the integer variable hBitmap used as second parameter this way :

hBitmap = LoadImage(App.hInstance, "c:\\\\windows\\\\logow.sys", IMAGE_BITMAP, 320, 200, LR_LOADFROMFILE)

I notice the code I picked from the NUG does not use it.
Luckily, the declare for LoadImage is in the Windows Functionality Suite, so I should be able to copy from it…

Did you guys fill a feedback case?
this is really so an important feature, that it should be fixed.

Although we can work around, e.g. with WindowsClipboardMBS class.

[quote=118653:@Christian Schmitz]Did you guys fill a feedback case?
this is really so an important feature, that it should be fixed.

Although we can work around, e.g. with WindowsClipboardMBS class.[/quote]

I found mention of the issue as far back as 2009 :frowning: