Author: Tomas Rutkauskas
How do I get the visible rectangle area of a windowed control (including TForm)?
Sometimes parts of the control's client area are not visible or not even on screen.
Answer:
This is one of the secrets which is seldomly asked or answered. Each window has
serveral clipping regions, which determine where it is allowed to draw. One is the
well not clipping region, which you can set with SetClipRgn. But this is only an
application defined part. Another one is the socalled meta region, which includes
all of the window plus the application defined clipping region. And yet another one
is the socalled system region, which includes all other plus anything clipped out
which is currently overlapped by other windows (including those from other
applications) and the screen area. This one must be made available first so you can
use it. The definition is:
1
2 const {Region identifiers for GetRandomRgn}
3 CLIPRGN = 1;
4 METARGN = 2;
5 APIRGN = 3;
6 SYSRGN = 4;
7
8 function GetRandomRgn(DC: HDC; Rgn: HRGN; iNum: Integer): Integer; stdcall; external
9 'GDI32.DLL';
10
11 {According to MSDN only SYSRGN can be used with GetRandomRgn. I found the other IDs
12 too, however I don't know what they are for and they do not return anything. A
13 typical scenario to get that region is:}
14
15 { ... }
16 {Retrieve the visible region of the window. This is important to avoid
17 overpainting parts of other windows which overlap this one.}
18 VisibleTreeRegion := CreateRectRgn(0, 0, 1, 1);
19 DC := GetDCEx(Handle, 0, DCX_CACHE or DCX_WINDOW or DCX_CLIPSIBLINGS
20 or DCX_CLIPCHILDREN);
21 GetRandomRgn(DC, VisibleTreeRegion, SYSRGN);
22 ReleaseDC(Handle, DC);
23 {In Win9x the returned visible region is given in client coordinates. We need it in
24 screen coordinates, though.}
25 if not IsWinNT then
26 with ClientToScreen(Point(0, 0)) do
27 OffsetRgn(VisibleTreeRegion, X, Y);
28 { ... }
You can see you have to create (and later destroy, don't forget that) a region first, which is then filled with the system region data.
|