| Delphi Clinic | C++Builder Gate | Training & Consultancy | Delphi Notes Weblog | Dr.Bob's Webshop |
|
One of the question that I often hear is how I make these incredible screenshots in my articles. Actually, I just hit PrintScrn for the entire desktop or Alt+PrintScrn for the active Window. But you can write a little bit of Delphi code to do the same thing programmatically as well...
The first solution (Delphi 1.x only) is to emulate a print screen keypress from within your 16-bits Windows program using the undocumented KeyboardEvent API:
unit Shot;
interface
procedure ScreenShot;
implementation
uses
WinTypes;
procedure KeyboardEvent; far; external 'USER' index 289;
procedure ScreenShot; assembler;
asm
mov ax, VK_SNAPSHOT
sub bx, bx
call KeyboardEvent
end {ScreenShot};
end.
This works in Windows 3.x/Delphi 1.x (you get the bitmap in the Clipboard) but needs to be rewritten completely for Win32, since KeyboardEvent is now a documented API function with different parameters.
In fact, the Delphi-Way to do the same would be to get a handle to the entire DeskTopWindow using GetDeskTopWindow, and just BitBlt the contents of the corresponding DC to a TBitmap component. The result is copied to the Clipboard using Clipboard.Assign:
unit Shot;
interface
procedure ScreenShot;
implementation
uses
{$IFDEF WIN32}
Windows,
{$ELSE}
WinTypes, WinProcs,
{$ENDIF}
Forms, Graphics, Clipbrd;
procedure ScreenShot;
var
ScreenDC: HDC;
ScreenHandle: HWnd;
ScreenBitmap: TBitmap;
begin
ScreenHandle := GetDeskTopWindow;
ScreenDC := GetDC(ScreenHandle);
try
ScreenBitmap := TBitMap.Create;
try
ScreenBitmap.Width := Screen.Width;
ScreenBitmap.Height := Screen.Height;
BitBlt(ScreenBitmap.Canvas.Handle, 0, 0,
Screen.Width, Screen.Height, ScreenDC, 0, 0, SRCCOPY);
Clipboard.Assign(ScreenBitmap)
finally
ScreenBitmap.Free
end
finally
ReleaseDC(ScreenHandle, ScreenDC)
end
end {ScreenShot};
end.
The last method works fine in both versions of Delphi, of course.
Both methods result in a bitmap inside the Clipboard, which can be pasted in WinWord, PaintShop Pro or any other professional image processing application.
Of course, we can also use the bitmap image in the Clipboard to play a little further. For example by placing it inside a small image (102x77) that shows the entire screen in "stamp" format. All we need to do for this is to have a TImage on a Form, and execute Image1.Picture.Assign(Clipboard), as we can see in the following example program (a form with one button and one image only);
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Image1: TImage;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
Shot, Clipbrd;
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
ScreenShot;
Image1.Picture.Assign(Clipboard)
end;
end.
The following hood10.dpr is used as main program:
As you can see, the shooting program is also included in the screenshot above.program hood10; uses Forms, unit1 in 'unit1.pas' {Form1}; begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end.