function getScreenDC: HDC;
{helper: returns the Handle for the Device Context (DC) of the Desktop-Window}
var h: HDC; {= THandle}
begin
h:=GetDC(0); {returns the handle of a Device Context (DC) for the client area of a window}
if h <> 0 then exit(h); {if OK}
writeln('Getting Handle for the DC of the Desktop-Window failed!');
halt; {this never occured}
end; {getScreenDC}
procedure saveScreenshotA(filespec: string);
{stores a screenshot of all monitors into a PNG-file}
const DEB: bool = True; {show Debug-Infos?}
var PNG: TPortableNetworkGraphic;
ScreenDC: HDC; {= THandle}
begin
ScreenDC:=getScreenDC; {get Handle for the Device Context of the Desktop-Window}
if DEB then writeln('Handle=', ScreenDC);
PNG:=TPortableNetworkGraphic.Create;
try
if DEB then writeln('AAA');
PNG.LoadFromDevice(ScreenDC); {takes the screenshot}
if DEB then writeln('BBB');
PNG.SaveToFile(filespec);
if DEB then writeln('CCC');
finally
PNG.Free;
ReleaseDC(0,ScreenDC);
if DEB then writeln('DDD');
end; {try}
end; {saveScreenshotA}
procedure saveScreenShotB(filespec: string);
{stores a screenshot of the primary monitor into a PNG-file. Notes for below code:
(1) fixes a bug in Lazarus 2.0.10 + 2.2.4, that command 'RD:=PNG.Canvas.ClipRect'
returns 2x 2000 because of a not initialized Handle of the Canvas.
(2) Linux only: without this fix the resulting PNG-file would be completely black}
procedure show_TRect(R: TRect; msg: string = '');
{displays the content of a 'TRect'}
begin
if msg <> '' then write(msg);
writeln('X1=', R.Left, ' Y1=', R.Top, ' X2=', R.Right, ' Y2=', R.Bottom,
' b=', R.Width, ' h=', R.Height);
end;
const DEB: bool = True; {show Debug-Infos?}
var PNG: TPortableNetworkGraphic;
M: TMonitor;
CVS: TCanvas; {canvas of the screen}
RS,RD: TRect;
w,h: integer;
begin
M:=Screen.PrimaryMonitor; {monitor to use}
CVS:=TCanvas.Create; {canvas of the screen}
try
CVS.Handle:=getScreenDC; {get Handle for the Device Context of the Desktop-Window}
if DEB then writeln('Handle=', CVS.Handle);
PNG:=TPortableNetworkGraphic.Create;
try
if DEB then writeln('PixelFormat=', PNG.PixelFormat);
PNG.PixelFormat:=pf24bit;
w:=M.Width; {get size of wanted monitor: }
h:=M.Height;
if DEB then writeln('w=', w, ' h=', h); {=> w=1280 h=1024}
if DEB then writeln('PixelsPerInch=', M.PixelsPerInch); {=> 96}
RS:=M.BoundsRect; {RS=Source-Rect}
if DEB then show_TRect(RS, 'RS: '); {=> X1=0 Y1=0 X2=1280 Y2=1024}
if DEB then writeln('AAA');
PNG.SetSize(w,h); {set size of PNG}
if DEB then writeln('BBB');
PNG.Canvas.CopyMode:=cmSrcCopy;
PNG.Canvas.Pixels[0,0]:=0; {fixes a bug, see above in (1)}
if DEB then writeln('CCC');
RD:=PNG.Canvas.ClipRect; {RD=Destination-Rect}
if DEB then show_TRect(RD, 'RD: ');
{$IFDEF LINUX}
inc(RD.Bottom); {fixes a bug only on Linux, see above in (2)}
if DEB then show_TRect(RD, 'RD: ');
{$ENDIF}
{copy a rectangular from 'RS' to 'RD': }
if DEB then writeln('DDD');
PNG.Canvas.CopyRect(RD,CVS,RS); {Destination,Source-Canvas,Source}
if DEB then writeln('EEE');
PNG.SaveToFile(filespec);
if DEB then writeln('FFF');
finally
PNG.Free;
ReleaseDC(0,CVS.Handle);
end; {try2}
finally
CVS.Free;
end; {try1}
end; {saveScreenShotB}