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.