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