Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2010-05

Copying form client area to clipboard and to file

5 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Mark Morgan Lloyd

Please excuse a dumb question, but I've done very little graphics programming and so far haven't found an answer in the docs or via Google.

I want to be able to save a bitmap representation of a form's client area, i.e. including status line at the bottom but excluding main menu and frame, to the clipboard in a format that can be read by e.g. Gimp, and also to bitmap files (.png etc. but not JPEG).

Can I do this directly from the form, do I have to group the controls into a panel to give me a single canvas, or do I have to work via a TImage?

Any suggestions would be very much appreciated, I'm developing on x86 Linux but if possible would like a generic solution.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Felipe Monteiro de Carvalho
to Mark Morgan Lloyd

I don't think you will find a solution using only LCL code, because the canvas doesn't include child windowed controls. You could even try to rebuild the image using the canvases, but that won't guarantee that it is the exact image on the screen.

I did a short googling and there is a Qt routine to do what you want in Windows:

http://stackoverflow.com/questions/1774222/taking-screenshot-of-a-specific-window-c-qt

You could see the Qt source code to check what this does for the Windows part of the solution.

They also recommend checking out the code of KSnapShot to see how to do this using X11.

I would try that stuff.

If you find the solution it would be great it you document it in the wiki =)

Like I did for screenshot taking:

http://wiki.lazarus.freepascal.org/Developing_with_Graphics#Taking_a_screenshot_of_the_screen

Felipe Monteiro de Carvalho

Reply by email

Graeme Geldenhuys
to Felipe Monteiro de Carvalho
Felipe Monteiro de Carvalho wrote
http://stackoverflow.com/questions/1774222/taking-screenshot-of-a-specific-window-c-qt You could see the Qt source code to check what this does for the Windows part of the solution.

Here is another way of doing it under Windows - as coded in tiOPF. I've never used this myself, so don't really know the code at all, just know it is there.

---------------------------------------------------------
procedure TtiBruteForceNoFlicker.ScreenShot(ABitmap: TBitmap; ALeft,
ATop, AWidth, AHeight: Integer; AWindow: HWND);
var
  WinDC: HDC;
  Pal: TMaxLogPalette;
begin
  ABitmap.Width := AWidth;
  ABitmap.Height := AHeight;
  // Get the HDC of the window...
  WinDC := GetDC(AWindow);
  try
    if WinDC = 0 then
      raise Exception.Create('No DeviceContext For Window');
    // Palette-device?
    if (GetDeviceCaps(WinDC, RASTERCAPS) and RC_PALETTE) = RC_PALETTE then
    begin
      FillChar(Pal, SizeOf(TMaxLogPalette), #0);  // fill the
structure with zeros
      Pal.palVersion := $300;                     // fill in the palette version
      // grab the system palette entries...
      Pal.palNumEntries := GetSystemPaletteEntries(WinDC, 0, 256,
Pal.palPalEntry);
      if Pal.PalNumEntries  0 then
        {$IFDEF FPC}
        ABitmap.Palette := CreatePalette(LPLOGPALETTE(@Pal)^);
        {$else}
        ABitmap.Palette := CreatePalette(PLogPalette(@Pal)^);
        {$endif}
    end;
    // copy from the screen to our bitmap...
    BitBlt(ABitmap.Canvas.Handle, 0, 0, AWidth, AHeight, WinDC, ALeft,
ATop, SRCCOPY);
  finally
    ReleaseDC(AWindow, WinDC);        // finally, relase the DC of the window
  end;
end;

---------------------------------------------------------

I had some code for X11, but couldn't find it now - it might be on my work PC. If I find it, I'll post it here.

Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/

Reply by email

Mark Morgan Lloyd
to Felipe Monteiro de Carvalho: I don't think you will find a solution using only LCL code, because the canvas doesn't…
Felipe Monteiro de Carvalho wrote 22 lines
I don't think you will find a solution using only LCL code, because the canvas doesn't include child windowed controls. You could even try to rebuild the image using the canvases, but that won't guarantee that it is the exact image on the screen. I did a short googling and there is a Qt routine to do what you want in Windows: http://stackoverflow.com/questions/1774222/taking-screenshot-of-a-specific-window-c-qt You could see the Qt source code to check what this does for the Windows part of the solution. They also recommend checking out the code of KSnapShot to see how to do this using X11. I would try that stuff. If you find the solution it would be great it you document it in the wiki =) Like I did for screenshot taking: http://wiki.lazarus.freepascal.org/Developing_with_Graphics#Taking_a_screenshot_of_the_screen

And there was I thinking it was bound to be easy and I was asking a FAQ :-)

OK, so if I composite the small group of visible controls into something- a TImage on a non-visible form?- what do I do next to transfer that to the clipboard or a file? I'm still having difficulty seeing how the various classes etc. hang together.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Mark Morgan Lloyd
to Graeme Geldenhuys: Here is another way of doing it under Windows - as coded in tiOPF. I've never used this…
Graeme Geldenhuys wrote 12 lines
On 29 May 2010 23:20, Felipe Monteiro de Carvalho wrote: > http://stackoverflow.com/questions/1774222/taking-screenshot-of-a-specific-window-c-qt > > You could see the Qt source code to check what this does for the > Windows part of the solution. Here is another way of doing it under Windows - as coded in tiOPF. I've never used this myself, so don't really know the code at all, just know it is there. I had some code for X11, but couldn't find it now - it might be on my work PC. If I find it, I'll post it here.

Thanks for that. Presumably some of the portability issues are due to the difficulty of manipulating bitmaps, hence TLazIntfImage etc.

Looking back through something I wrote in Delphi I see I used TCustomForm.GetFormImage. Bug 11292 implies this is in 0.9.26 for Win32 and GTK2, position with other widget sets uncertain.

I might take a look at this later but since it turns out to be non-trivial it would probably be wise if I concentrated on core functionality first.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email