Author: Tomas Rutkauskas
I'm trying to produce a form that has transparent areas in it (no border or title
with odd shape edges/ holes). I've successfully done this; the problem I'm having
is the refreshing of the transparent areas. I have an idea form the conceptual
point of what to do, but was hoping some could let me know if this sounds like it
would work, and any technical information on how to do it.
I want to pass the WM_PAINT message that my form gets on to the window(s)
underneath my form, so that those windows refresh themselves. Then, only after the
window(s) beneath my form finish refreshing, I want to refresh my form (act on the
WM_PAINT message in a normal manner).
Answer:
While the method you are attempting to use could work, it's much easier to use
SetWindowRgn().
This API function will associate an HRGN with your window. This region will be used
to determine the area your window is allowed to paint in:
1 procedure CutOutClient(pForm: TForm);
2 var
3 rgnCenter: HRGN;
4 rcWindow: TRect;
5 rcClient: TRect;
6 begin
7 GetWindowRect(pForm.Handle, rcWindow);
8 Windows.GetClientRect(pForm.Handle, rcClient);
9 MapWindowPoints(pForm.Handle, HWND_DESKTOP, rcClient, 2);
10 OffsetRect(rcClient, -rcWindow.Left, -rcWindow.Top);
11 rgnCenter := CreateRectRgnIndirect(rcClient);
12 try
13 SetWindowRgn(pForm.Handle, rgnCenter, IsWindowVisible(pForm.Handle));
14 finally
15 DeleteObject(rgnCenter);
16 end;
17 end;
This procedure should clip the client area from your form. To extend this, you simply need to create a different region. See the CreateEllipticRgn, CreatePolygonRgn, CreateRectRgn, and CombineRgn (as well as a few others).
|