Author: Tomas Rutkauskas
When I override the CreateParams method of the TForm class and put an "or" clause
to include a WS_EX_TRANSPARENT effect, all work fine. My Form appears with a
transparent effect (or better, it does not appear. Only controls appear). But if I
change the icons positions on the Desktop screen, my form does not get the changes
and redraws itself. Well, I call redraw manually, but the form cannot get the
desktop screen rectangle to correct the background of the form. How do I solve this
problem? Is there a way to get a selected rectangle of the desktop screen to be
copied to the canvas on the form?
Answer:
Here's a transparent form method that uses regions. It's so transparent, you can
click right through to the underlying windows:
unit Unit1;
{The transparent form effect is done with regions. First create a region that
encompasses the entire form. Then, find the client area of the form (Client vs.
non-Client) and combine with the full region with RGN_DIFF to make the borders and
title bar visible. Then create a region for each of the controls and combine them
with the original (FullRgn) region.}
1 interface
2
3 uses
4 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
5 ExtCtrls, StdCtrls;
6
7 type
8 TForm1 = class(TForm)
9 Button1: TButton;
10 Panel1: TPanel;
11 Button2: TButton;
12 procedure FormDestroy(Sender: TObject);
13 procedure FormCreate(Sender: TObject);
14 procedure Button1Click(Sender: TObject);
15 procedure Button2Click(Sender: TObject);
16 procedure FormResize(Sender: TObject);
17 private
18 { Private declarations }
19 procedure DoVisible;
20 procedure DoInvisible;
21 public
22 { Public declarations }
23 end;
24
25 var
26 Form1: TForm1;
27 FullRgn, ClientRgn, CtlRgn: THandle;
28
29 implementation
30
31 {$R *.DFM}
32
33 procedure TForm1.DoInvisible;
34 var
35 AControl: TControl;
36 A, Margin, X, Y, CtlX, CtlY: Integer;
37 begin
38 Margin := (Width - ClientWidth) div 2;
39 {First, get form region}
40 FullRgn := CreateRectRgn(0, 0, Width, Height);
41 {Find client area region}
42 X := Margin;
43 Y := Height - ClientHeight - Margin;
44 ClientRgn := CreateRectRgn(X, Y, X + ClientWidth, Y + ClientHeight);
45 {'Mask' out all but non-client areas}
46 CombineRgn(FullRgn, FullRgn, ClientRgn, RGN_DIFF);
47 {Now, walk through all the controls on the form and 'OR' them into the existing
48 Full region}
49 for A := 0 to ControlCount - 1 do
50 begin
51 AControl := Controls[A];
52 if (AControl is TWinControl) or (AControl is TGraphicControl) then
53 with AControl do
54 begin
55 if Visible then
56 begin
57 CtlX := X + Left;
58 CtlY := Y + Top;
59 CtlRgn := CreateRectRgn(CtlX, CtlY, CtlX + Width, CtlY + Height);
60 CombineRgn(FullRgn, FullRgn, CtlRgn, RGN_OR);
61 end;
62 end;
63 end;
64 {When the region is all ready, put it into effect:}
65 SetWindowRgn(Handle, FullRgn, TRUE);
66 end;
67
68 procedure TForm1.FormDestroy(Sender: TObject);
69 begin
70 {Clean up the regions we created}
71 DeleteObject(ClientRgn);
72 DeleteObject(FullRgn);
73 DeleteObject(CtlRgn);
74 end;
75
76 procedure TForm1.DoVisible;
77 begin
78 {To restore complete visibility:}
79 FullRgn := CreateRectRgn(0, 0, Width, Height);
80 CombineRgn(FullRgn, FullRgn, FullRgn, RGN_COPY);
81 SetWindowRgn(Handle, FullRgn, TRUE);
82 end;
83
84 procedure TForm1.FormCreate(Sender: TObject);
85 begin
86 {We start out as a transparent form ...}
87 DoInvisible;
88 end;
89
90 procedure TForm1.Button1Click(Sender: TObject);
91 begin
92 {This button just toggles between transparent and not transparent}
93 if Button1.Caption = 'Show Form' then
94 begin
95 DoVisible;
96 Button1.Caption := 'Hide Form';
97 end
98 else
99 begin
100 DoInvisible;
101 Button1.Caption := 'Show Form';
102 end;
103 end;
104
105 procedure TForm1.Button2Click(Sender: TObject);
106 begin
107 Application.Terminate;
108 end;
109
110 procedure TForm1.FormResize(Sender: TObject);
111 begin
112 {Need to address the transparency if the form gets resized. Also, note that Form1
113 scroll bars are set to VISIBLE/FALSE. I did that to save a little coding here....}
114 if Button1.Caption = 'Show Form' then
115 DoInvisible
116 else
117 DoVisible;
118 end;
119
120 end.
|