Alex Rivera | Logout

How do I copy a form as an image to the clipboard

Asked 2010-07-06T22:50:03.477
14

I need to copy a form (Delphi 2007) to the clipboard as an image to paste what the user can see into a word document. The clipboard part is not really a problem. The questions is how to get a bitmap for the form.

Searching has turned up multiple options.

All of these options seem to have different problems. Most of the information I am finding seems to be outdated. I can't seem any good source that compares the different options with enough detail for me to make a choice. Any advice on which option to go with.

I have tried these on my form and they all seem to work OK, I just trying to avoid problems down the road. Any advice on what solution to go with?

Update: What Potential Problems with GetFormImage?
Andreas asked what the problem is with GetFormImage. Hopefully nothing anymore, that is part of what I am trying to get an answer to. What has me concerned is so many of my search results seem to be suggesting creative alternatives to using GetFormImage. I was hoping the answers would clear up the waters a little bit.

I would be rea

Edit
Report

1 Answer

13

I do not know what the problem is with GetFormImage, but an option that you have not tried (at least not explicitly) is

procedure TForm1.FormClick(Sender: TObject);
var
  bm: TBitmap;
begin

  bm := TBitmap.Create;
  try
    bm.SetSize(ClientWidth, ClientHeight);
    BitBlt(bm.Canvas.Handle, 0, 0, ClientWidth, ClientHeight, Canvas.Handle, 0, 0, SRCCOPY);
    Clipboard.Assign(bm);
  finally
    bm.Free;
  end;

end;

In almost all cases I would expect this to produce the same result as

bm := GetFormImage;
try
  Clipboard.Assign(bm);
finally
  bm.Free;
end;

though. (Also, the Canvas.CopyRect procedure employes StretchBlt which I would expect to produce the same result as BitBlt when no stretching is applied.)

Method 2

You can always use Print Screen:

procedure TForm1.FormClick(Sender: TObject);
begin
  keybd_event(VK_SNAPSHOT, 1, 0, 0);
end;

This will also capture the border and the title bar. If you only wish to obtain the client area, you can crop the image:

procedure TForm1.FormClick(Sender: TObject);
var
  bm, bm2: TBitmap;
  DX, DY: integer;
begin
  Clipboard.Clear;
  keybd_event(VK_SNAPSHOT, 1, 0, 0);
  repeat
    Application.ProcessMessages;
  until Clipboard.HasFormat(CF_BITMAP);
  bm := TBitmap.Create;
  try
    bm.Assign(Clipboard);
    bm2 := TBitmap.Create;
    try
      bm2.SetSize(ClientWidth, ClientHeight);
      DX := (Width - ClientWidth) div 2;
      DY := GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYSIZEFRAME );
      BitBlt(bm2.Canvas.Handle, 0, 0, ClientWidth, ClientHeight, bm.Canvas.Handle, DX, DY, SRCCOPY);
      Clipboard.Assign(bm2);
    finally
      bm2.Free;
    end;
  finally
    bm.Free;
  end;
end;
answered 2010-07-06T23:11:05.220

Your Answer