Get the visible rectangle area of a windowed control (Views: 102)


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.


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:

const {Region identifiers for GetRandomRgn}
  CLIPRGN = 1;
  METARGN = 2;
  APIRGN = 3;
  SYSRGN = 4;

function GetRandomRgn(DC: HDC; Rgn: HRGN; iNum: Integer): Integer; stdcall; external

According to MSDN only SYSRGN can be used with GetRandomRgn. I found the other IDs too, however I don't know what they are for and they do not return anything. A typical scenario to get that region is:

{ ... }
  {Retrieve the visible region of the window. This is important to avoid overpainting parts of other windows which overlap this one.}
VisibleTreeRegion := CreateRectRgn(0, 0, 1, 1);
GetRandomRgn(DC, VisibleTreeRegion, SYSRGN);
ReleaseDC(Handle, DC);
{In Win9x the returned visible region is given in client coordinates. We need it in screen coordinates, though.}
if not IsWinNT then
  with ClientToScreen(Point(0, 0)) do
    OffsetRgn(VisibleTreeRegion, X, Y);
{ ... }

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.

<< Back to main page