Author: Tomas Rutkauskas
I have a TScrollBox. In it are between 10 to 300 other components (TCustomControls
and TGraphic descendants) which are moveable and resizeable. For a better overview
of the large scrollbox workspace I would like to write a small zoombox component
showing an overview of the whole workspace in a small 50x50 pixel (or whatever
size) area. Is there any easy Windows function for doing this fast? Or do I have to
write an own routine?
Answer:
You have to write your own. Following is a little example that shows a 50% reduced
preview of the full scrollbox. The controls edit1, edit2, shape1, shape2, image1,
memo1 are all on the scrollbox, image2 is used for the preview, button1 triggers
the painting of the preview. The main problem here is the way I use to paint a
TWinControl owned by the scrollbox. The WM_PRINT message used is supported by all
standard and common Windows controls, but not by pure VCL controls like TPanel or
the grid classes. For those you may have to use WM_PAINT instead, or the PaintTo
method.
1 unit Unit1;
2
3 interface
4
5 uses
6 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
7 ComCtrls, StdCtrls, ExtCtrls;
8
9 type
10 TForm1 = class(TForm)
11 Button1: TButton;
12 ScrollBox1: TScrollBox;
13 Edit1: TEdit;
14 Edit2: TEdit;
15 Image1: TImage;
16 Shape1: TShape;
17 Shape2: TShape;
18 Memo1: TMemo;
19 Image2: TImage;
20 procedure Button1Click(Sender: TObject);
21 private
22 { Private declarations }
23 public
24 { Public declarations }
25 end;
26
27 var
28 Form1: TForm1;
29
30 implementation
31
32 {$R *.DFM}
33
34 procedure PaintControl(aControl: TWinControl; aCanvas: TCanvas; offsetx, offsety:
35 Integer);
36 begin
37 SaveDC(aCanvas.handle);
38 try
39 SetWindowOrgEx(aCanvas.handle, -(acontrol.left + offsetx), -(acontrol.top +
40 offsety), nil);
41 acontrol.perform(WM_PRINT, acanvas.handle, PRF_CHILDREN or PRF_CLIENT or
42 PRF_NONCLIENT or PRF_ERASEBKGND);
43 finally
44 RestoreDC(aCanvas.handle, -1);
45 end;
46 end;
47
48 procedure TForm1.Button1Click(Sender: TObject);
49 var
50 bmp: TBitmap;
51 i: integer;
52 begin
53 bmp := TBitmap.Create;
54 try
55 bmp.width := scrollbox1.HorzScrollBar.Range div 2;
56 bmp.height := scrollbox1.VertScrollBar.Range div 2;
57 bmp.canvas.lock;
58 SetMapMode(bmp.canvas.handle, MM_ISOTROPIC);
59 SetWindowExtEx(bmp.canvas.handle, 200, 200, nil);
60 SetViewportExtEx(bmp.canvas.handle, 100, 100, nil);
61 try
62 SetWindowOrgEx(bmp.canvas.handle, -scrollbox1.HorzScrollBar.Position,
63 -scrollbox1.VertScrollBar.POsition, nil);
64 scrollbox1.perform(WM_PAINT, bmp.canvas.handle, 1);
65 SetWindowOrgEx(bmp.canvas.handle, 0, 0, nil);
66 for i := 0 to scrollbox1.controlcount - 1 do
67 if scrollbox1.controls[i] is TWincontrol then
68 Paintcontrol(TWincontrol(scrollbox1.Controls[i]), bmp.canvas,
69 scrollbox1.horzscrollBar.Position, scrollbox1.vertScrollBar.Position);
70 finally
71 bmp.canvas.unlock;
72 end;
73 image2.picture.bitmap := bmp;
74 finally
75 bmp.free;
76 end;
77 end;
78
79 end.
|