Forum > Graphics

How to copy bitmaps from/to the clipboard in Windows?

<< < (2/2)

mishob:

--- Quote from: "Phil" ---
Could you please log all of this as a bug report on Mantis? That way the results of your investigation won't be lost!
--- End quote ---


Done!
http://bugs.freepascal.org/view.php?id=12729

tReby:
What lib do i need to add in Uses???
can seem to run this code... :D



--- Quote from: mishob on November 27, 2008, 01:38:09 pm ---I have reached some kind of a working solution and I decided to post it here, for what it’s worth.

If one looks closely in win32winapi.inc, it turns out that the LCL’s clipboard format pcfDelphiBitmap is ‘short-circuited’ to CF_BITMAP when copying from the clipboard, so we can do this entirely via LCL:


--- Code: ---CF := Clipboard.FindPictureFormatID;
if CF = Windows.CF_BITMAP then // Handle CF_BITMAP separately
  Image.Picture.LoadFromClipboardFormat(PredefinedClipboardFormat(pcfDelphiBitmap))
else
  Image.Picture.LoadFromClipboardFormat(CF);

--- End code ---

Unfortunately, the same does not work for sending the bitmap back to the clipboard. TWin32WidgetSet.ClipboardRegisterFormat converts pcfBitmap to Windows.CF_BITMAP and Clipboard.Assign(Image.Picture.Bitmap) puts some data on the clipboard and marks them as CF_BITMAP but the format of the data itself is apparently incorrect (no application can retrieve them and even Windows does not recognize the data for its implicit conversions to CF_DIB and CF_DIBV5).

One way to circumvent the issue is to copy the bitmap into one created using Windows API:


--- Code: ---procedure TForm1.btnCopyResultClick(Sender: TObject);
var
  MemDC: HDC;
  MemBitmap, OldBitmap: HBITMAP;
  W, H: Integer;
begin
  W := Image3.Picture.Bitmap.Width;
  H := Image3.Picture.Bitmap.Height;

  MemDC := Windows.CreateCompatibleDC(Canvas.Handle);
  MemBitmap := Windows.CreateCompatibleBitmap(Canvas.Handle, W, H);
  OldBitmap := Windows.SelectObject(MemDC, MemBitmap);
  Windows.BitBlt(MemDC, 0, 0, W, H, Image3.Picture.Bitmap.Canvas.Handle, 0, 0, SRCCOPY);

  Windows.OpenClipboard(Handle);
  Windows.EmptyClipboard;
  Windows.SetClipboardData(CF_BITMAP, MemBitmap);
  Windows.CloseClipboard;

  Windows.SelectObject(MemDC, OldBitmap);
  Windows.DeleteDC(MemDC);
  Windows.DeleteObject(MemBitmap);
end;

--- End code ---

This is quite ugly but it works (that is, Photoshop, MS Paint and other applications are able to fetch the bitmap from the clipboard).

--- End quote ---

Navigation

[0] Message Index

[*] Previous page

Go to full version