### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: [Solved] Problem with Controls being Unselectable in Win 10 Transparent Forms !  (Read 873 times)

#### KodeZwerg

• Hero Member
• Posts: 1186
##### Re: [Solved] Problem with Controls being Unselectable in Win 10 Transparent Forms !
« Reply #15 on: December 21, 2022, 04:44:59 am »
Updated to be able to work better for different BorderStyle settings.
Make this method part of your form and call it in OnCreate and OnResize.
Code: Pascal  [Select][+][-]
1. procedure TForm1.MakeTransparent;
2. var
3.   AControl: TControl;
4.   A, Margin, X, Y, CtlX, CtlY: Integer;
5.   FullRgn, ClientRgn, CtlRgn: THandle;
6.   cXBorder, cYBorder, cWidth, cHeight: LongInt;
7. begin
8.   // calculate different border styles
9.   case Self.BorderStyle of
10.     bsDialog:
11.       begin
12.         cXBorder := 0;
13.         cYBorder := GetSystemMetrics(SM_CYCAPTION);
14.       end;
15.     bsNone:
16.       begin
17.         cXBorder := GetSystemMetrics(SM_CXBORDER);
18.         cYBorder := GetSystemMetrics(SM_CYBORDER);
19.       end;
20.     bsSingle:
21.       begin
22.         cXBorder := 0;
23.         cYBorder := GetSystemMetrics(SM_CYCAPTION);
24.       end;
25.     bsSizeable:
26.       begin
27.         cXBorder := GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CXEDGE) + GetSystemMetrics(SM_CXFOCUSBORDER);
28.         cYBorder := GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYEDGE) + GetSystemMetrics(SM_CYFOCUSBORDER) + GetSystemMetrics(SM_CYCAPTION);
29.       end;
30.     bsSizeToolWin:
31.       begin
32.         cXBorder := GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CXEDGE) + GetSystemMetrics(SM_CXFOCUSBORDER);
33.         cYBorder := GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYEDGE) + GetSystemMetrics(SM_CYFOCUSBORDER) + GetSystemMetrics(SM_CYCAPTION);
34.       end;
35.     bsToolWindow:
36.       begin
37.         cXBorder := 0;
38.         cYBorder := GetSystemMetrics(SM_CYCAPTION);
39.       end;
40.   end;
41.
42.   // set client dimension
43.   cWidth := Self.ClientRect.Width - cXBorder;
44.   cHeight:= Self.ClientRect.Height - cYBorder;
45.   Margin := (Self.Width - cWidth) div 2;
46.
47.   // get form and client area region
48.   X := Margin;
49.   case Self.BorderStyle of
50.     bsDialog:
51.       begin
52.         FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Self.Height + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
53.         Y := Self.Height - cHeight - Margin + GetSystemMetrics(SM_CYDLGFRAME);
54.         ClientRgn := CreateRectRgn(X, Y, X + cWidth + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Y + cHeight + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
55.       end;
56.     bsNone:
57.       begin
58.         FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder, Self.Height + cYBorder);
59.         Y := Self.Height - cHeight - Margin - GetSystemMetrics(SM_CYBORDER);
60.         ClientRgn := CreateRectRgn(X, Y, X + cWidth + GetSystemMetrics(SM_CXBORDER), Y + cHeight + GetSystemMetrics(SM_CYBORDER));
61.       end;
62.     bsSingle:
63.       begin
64.         FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Self.Height + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
65.         Y := Self.Height - cHeight - Margin + GetSystemMetrics(SM_CYDLGFRAME);
66.         ClientRgn := CreateRectRgn(X, Y, X + cWidth + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Y + cHeight + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
67.       end;
68.     bsSizeable:
69.       begin
70.         FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder, Self.Height + cYBorder);
71.         Y := Self.Height - cHeight - Margin - GetSystemMetrics(SM_CYBORDER);
72.         ClientRgn := CreateRectRgn( X, Y, X + cWidth + cXBorder, Y + cHeight + cYBorder);
73.       end;
74.     bsSizeToolWin:
75.       begin
76.         FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder, Self.Height + cYBorder);
77.         Y := Self.Height - cHeight - Margin - GetSystemMetrics(SM_CYBORDER);
78.         ClientRgn := CreateRectRgn( X, Y, X + cWidth + cXBorder, Y + cHeight + cYBorder);
79.       end;
80.     bsToolWindow:
81.       begin
82.         FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Self.Height + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
83.         Y := Self.Height - cHeight - Margin + GetSystemMetrics(SM_CYDLGFRAME);
84.         ClientRgn := CreateRectRgn(X, Y, X + cWidth + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Y + cHeight + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
85.       end;
86.   end;
87.
88.   // 'Mask' out all but non-client areas
89.   CombineRgn(FullRgn, FullRgn, ClientRgn, RGN_DIFF);
90.
91.   // Now, walk through all the controls on the form and 'OR' them into the existing Full region.
92.   for A := 0 to Pred(ControlCount) do
93.     begin
94.       AControl := Controls[A];
95.       if ((AControl is TWinControl) or (AControl is TGraphicControl) or (AControl is TControl)) then
96.         if AControl.Visible then
97.           begin
98.             CtlX := X + AControl.Left;
99.             CtlY := Y + AControl.Top;
100.             case Self.BorderStyle of
101.               bsDialog:
102.                 begin
103.                   CtlRgn := CreateRectRgn(CtlX + GetSystemMetrics(SM_CXDLGFRAME), CtlY, CtlX + AControl.Width + GetSystemMetrics(SM_CXDLGFRAME), CtlY + AControl.Height);
104.                 end;
105.               bsNone:
106.                 begin
107.                   CtlRgn := CreateRectRgn(CtlX, CtlY, CtlX + AControl.Width, CtlY + AControl.Height);
108.                 end;
109.               bsSingle:
110.                 begin
111.                   CtlRgn := CreateRectRgn(CtlX + GetSystemMetrics(SM_CXDLGFRAME), CtlY, CtlX + AControl.Width + GetSystemMetrics(SM_CXDLGFRAME), CtlY + AControl.Height);
112.                 end;
113.               bsSizeable:
114.                 begin
115.                   CtlRgn := CreateRectRgn(CtlX, CtlY, CtlX + AControl.Width + GetSystemMetrics(SM_CXEDGE), CtlY + AControl.Height + GetSystemMetrics(SM_CYEDGE));
116.                 end;
117.               bsSizeToolWin:
118.                 begin
119.                   CtlRgn := CreateRectRgn(CtlX, CtlY, CtlX + AControl.Width + GetSystemMetrics(SM_CXEDGE), CtlY + AControl.Height + GetSystemMetrics(SM_CYEDGE));
120.                 end;
121.               bsToolWindow:
122.                 begin
123.                   CtlRgn := CreateRectRgn(CtlX + GetSystemMetrics(SM_CXDLGFRAME), CtlY, CtlX + AControl.Width + GetSystemMetrics(SM_CXDLGFRAME), CtlY + AControl.Height);
124.                 end;
125.             end;
126.             CombineRgn(FullRgn, FullRgn, CtlRgn, RGN_OR);
127.           end;
128.     end;
129.
130.   // When the region is all ready, put it into effect:
131.   SetWindowRgn(Handle, FullRgn, TRUE);
132.
133.   // clean up the mess
134.   DeleteObject(ClientRgn);
135.   DeleteObject(FullRgn);
136.   DeleteObject(CtlRgn);
137. end;
Enjoy transparent forms for Windows
« Last Edit: Tomorrow at 31:76:97 by KodeZwerg »