Sign in Join
Wiki copytemporary

Aero Glass: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11[![Windows logo - 2012.svg](https://upload.wikimedia.org/wikipedia/commons/thumb/5/5f/Windows_logo_-_2012.svg/50px-Windows_logo_-_2012.svg.png)](</File:Windows_logo_-_2012.svg>)
22
33This article applies to [Windows](</Category:Windows> "Category:Windows") only.
44
55See also: [[Multiplatform Programming Guide]]
66
77│ **[[Aero Glass/de|Deutsch (de)]]** │ **English (en)** │ **[[Aero Glass/es|español (es)]]** │ **[[Aero Glass/pl|polski (pl)]]** │
88****
99
1010## Contents
1111
1212 * 1 Aero Glass effect on Lazarus Form
1313 * 2 Windows 10
1414 * 3 Bugs
1515 * 4 About
1616
1717## Aero Glass effect on Lazarus Form
1818
1919[![aero glass lazarus.png](/wiki-images/8/83/aero_glass_lazarus.png)](</File:aero_glass_lazarus.png>)
2020
2121First save the above code to a text file "glass.pas":
2222```
2323unit glass;
2424
2525 {$mode delphi}
2626 //{$mode objfpc}{$H+}
2727
2828 interface
2929
3030 uses
3131 Windows, Forms, Graphics;
3232
3333 type
3434 _MARGINS = packed record
3535 cxLeftWidth : Integer;
3636 cxRightWidth : Integer;
3737 cyTopHeight : Integer;
3838 cyBottomHeight : Integer;
3939 end;
4040
4141 PMargins = ^_MARGINS;
4242 TMargins = _MARGINS;
4343
4444 DwmIsCompositionEnabledFunc = function(pfEnabled: PBoolean): HRESULT; stdcall;
4545 DwmExtendFrameIntoClientAreaFunc = function(destWnd: HWND; const pMarInset: PMargins): HRESULT; stdcall;
4646 SetLayeredWindowAttributesFunc = function(destWnd: HWND; cKey: TColor; bAlpha: Byte; dwFlags: DWord): BOOL; stdcall;
4747
4848 const
4949 WS_EX_LAYERED = $80000;
5050 LWA_COLORKEY = 1;
5151
5252 procedure GlassForm(frm: TForm; tmpMargins: TMargins; cBlurColorKey: TColor = clFuchsia);
5353 function WindowsAeroGlassCompatible: Boolean;
5454
5555 implementation
5656
5757 function WindowsAeroGlassCompatible: Boolean;
5858 var
5959 osVinfo: TOSVERSIONINFO;
6060 begin
6161 ZeroMemory(@osVinfo, SizeOf(osVinfo));
6262 OsVinfo.dwOSVersionInfoSize := SizeOf(TOSVERSIONINFO);
6363 if (
6464 (GetVersionEx(osVInfo) = True) and
6565 (osVinfo.dwPlatformId = VER_PLATFORM_WIN32_NT) and
6666 (osVinfo.dwMajorVersion >= 6)
6767 )
6868 then Result:=True
6969 else Result:=False;
7070 end;
7171
7272 procedure GlassForm(frm: TForm; tmpMargins: TMargins; cBlurColorKey: TColor = clFuchsia);
7373 var
7474 hDwmDLL: Cardinal;
7575 fDwmIsCompositionEnabled: DwmIsCompositionEnabledFunc;
7676 fDwmExtendFrameIntoClientArea: DwmExtendFrameIntoClientAreaFunc;
7777 fSetLayeredWindowAttributesFunc: SetLayeredWindowAttributesFunc;
7878 bCmpEnable: Boolean;
7979 mgn: TMargins;
8080 begin
8181 { Continue if Windows version is compatible }
8282 if WindowsAeroGlassCompatible then begin
8383 { Continue if 'dwmapi' library is loaded }
8484 hDwmDLL := LoadLibrary('dwmapi.dll');
8585 if hDwmDLL <> 0 then begin
8686 { Get values }
8787 @fDwmIsCompositionEnabled := GetProcAddress(hDwmDLL, 'DwmIsCompositionEnabled');
8888 @fDwmExtendFrameIntoClientArea := GetProcAddress(hDwmDLL, 'DwmExtendFrameIntoClientArea');
8989 @fSetLayeredWindowAttributesFunc := GetProcAddress(GetModulehandle(user32), 'SetLayeredWindowAttributes');
9090 { Continue if values are <> nil }
9191 if (
9292 (@fDwmIsCompositionEnabled <> nil) and
9393 (@fDwmExtendFrameIntoClientArea <> nil) and
9494 (@fSetLayeredWindowAttributesFunc <> nil)
9595 )
9696 then begin
9797 { Continue if composition is enabled }
9898 fDwmIsCompositionEnabled(@bCmpEnable);
9999 if bCmpEnable = True then begin
100100 { Set Form Color same as cBlurColorKey }
101101 frm.Color := cBlurColorKey;
102102 { ... }
103103 SetWindowLong(frm.Handle, GWL_EXSTYLE, GetWindowLong(frm.Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
104104 { ... }
105105 fSetLayeredWindowAttributesFunc(frm.Handle, cBlurColorKey, 0, LWA_COLORKEY);
106106 { Set margins }
107107 ZeroMemory(@mgn, SizeOf(mgn));
108108 mgn.cxLeftWidth := tmpMargins.cxLeftWidth;
109109 mgn.cxRightWidth := tmpMargins.cxRightWidth;
110110 mgn.cyTopHeight := tmpMargins.cyTopHeight;
111111 mgn.cyBottomHeight := tmpMargins.cyBottomHeight;
112112 { Extend Form }
113113 fDwmExtendFrameIntoClientArea(frm.Handle,@mgn);
114114 end;
115115 end;
116116 { Free loaded 'dwmapi' library }
117117 FreeLibrary(hDWMDLL);
118118 end;
119119 end;
120120 end;
121121
122122 end.
123123```
124124
125125Copy the "glass.pas" file to the main folder of your project:
126126```
127127MyProject\glass.pas
128128```
129129
130130In the "uses" section of your project you need to add "glass":
131131```
132132unit form1;
133133
134134 {$mode objfpc}{$H+}
135135
136136 interface
137137
138138 uses
139139 Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs
140140 glass; // This includes GlassForm procedure
141141```
142142
143143OnActivate event of each form call the procedure in this way:
144144```
145145procedure TForm1.FormActivate(Sender: TObject);
146146 var
147147 tmpMargins: TMargins;
148148 begin
149149 { If all margins are -1 the whole form will be aero glass}
150150 tmpMargins.cxLeftWidth := -1;
151151 tmpMargins.cxRightWidth := -1;
152152 tmpMargins.cyBottomHeight := -1;
153153 tmpMargins.cyTopHeight := -1;
154154 { FormName ; Margins ; TransparentColor }
155155 GlassForm(Self, tmpMargins, clFuchsia);
156156 end;
157157```
158158
159159Also you need to enable Themes to use this procedure, go to Options > Project Options > then select "Use Manifest to Enable Themes (Windows)".
160160
161161## Windows 10
162162
163163[![aeroglasswin10.png](/wiki-images/8/84/aeroglasswin10.png)](</File:aeroglasswin10.png>)
164164```
165165{
166166 author: vhanla
167167 http://vhanla.codigobit.info
168168 }
169169 unit Unit1;
170170
171171 interface
172172
173173 uses
174174 Windows, Messages, SysUtils, Variants, Classes, Graphics,
175175 Controls, Forms, Dialogs, DWMApi, png, IntfGraphics, FPImage, GraphType,
176176 StdCtrls, ExtCtrls, BCButtonFocus, BCLabel, Registry, LMessages, LCLType, LCLIntf;
177177
178178 type
179179
180180 { TForm1 }
181181
182182 TForm1 = class(TForm)
183183 BCButtonFocus1: TBCButtonFocus;
184184 BCLabel1: TBCLabel;
185185 Image1: TImage;
186186 Image2: TImage;
187187 Panel1: TPanel;
188188
189189 procedure BCButtonFocus1Click(Sender: TObject);
190190 procedure FormCreate(Sender: TObject);
191191 procedure Button1Click(Sender: TObject);
192192 procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton;
193193 Shift: TShiftState; X, Y: Integer);
194194 private
195195 { Private declarations }
196196 function TaskbarAccented:boolean;
197197 function TaskbarTranslucent:boolean;
198198 procedure EnableBlur;
199199 procedure AeroGlass;
200200 procedure UpdateColorization;
201201 function GetAccentColor:TColor;
202202 public
203203 { Public declarations }
204204 end;
205205
206206 AccentPolicy = packed record
207207 AccentState: Integer;
208208 AccentFlags: Integer;
209209 GradientColor: Integer;
210210 AnimationId: Integer;
211211 end;
212212
213213 TWinCompAttrData = packed record
214214 attribute: THandle;
215215 pData: Pointer;
216216 dataSize: ULONG;
217217 end;
218218
219219
220220 var
221221 Form1: TForm1;
222222
223223 var
224224 SetWindowCompositionAttribute: function (Wnd: HWND; const AttrData: TWinCompAttrData): BOOL; stdcall = Nil;
225225 implementation
226226
227227 {$R *.lfm}
228228
229229 procedure SetAlphaColorPicture(
230230 const Col: TColor;
231231 const Alpha: Integer;
232232 Picture: TPicture;
233233 const _width: Integer;
234234 const _height: Integer
235235 );
236236 var
237237 IM: TLazIntfImage;
238238 x,y: integer;
239239 sl: pByteArray;
240240 I, J, W, H: Integer;
241241 FC: TFPColor;
242242 begin
243243 IM := TLazIntfImage.Create(0, 0, [riqfRGB, riqfAlpha]);
244244 try
245245 IM.SetSize(_width, _height);
246246 for I := 0 to _width - 1 do
247247 begin
248248 for J := 0 to _height - 1 do
249249 begin
250250 FC.red := (128 + I) shl 8;
251251 FC.green := (128 + J) shl 8;
252252 FC.blue := 128 shl 8;
253253 FC.alpha := 128 shl 8; // now works fine
254254 IM.Colors[I, J] := FC;
255255 end;
256256 end;
257257 Picture.Assign(IM);
258258
259259
260260 finally
261261 IM.Free;
262262
263263 end;
264264 end;
265265
266266 procedure TForm1.Button1Click(Sender: TObject);
267267 begin
268268 Close;
269269 end;
270270
271271 procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
272272 Shift: TShiftState; X, Y: Integer);
273273 begin
274274 ReleaseCapture;
275275 SendMessage(Form1.Handle, LM_SYSCOMMAND, 61458, 0) ;
276276 end;
277277
278278 procedure TForm1.AeroGlass;
279279 var
280280 Aero: BOOL;
281281 Area: TRect;
282282 hDWM: THandle;
283283 begin
284284 hDWM:=LoadLibrary('dwmapi.dll');
285285 try
286286 @DwmIsCompositionEnabled:=GetProcAddress(hDWM,'DwmIsCompositionEnabled');
287287 if @DwmIsCompositionEnabled<>nil then
288288 DwmIsCompositionEnabled(Aero);
289289 if Aero then
290290 begin
291291 Area:=Rect(-1,-1,-1,-1);
292292 Color:=clBlack;
293293 @DwmExtendFrameIntoClientArea:=GetProcAddress(hDWM,'DwmExtendFrameIntoClientArea');
294294 if @DwmExtendFrameIntoClientArea<>nil then
295295 DwmExtendFrameIntoClientArea(Handle,@Area);
296296
297297 end
298298 else ShowMessage('Aero is Disabled');
299299 finally
300300 FreeLibrary(hDWM);
301301 end;
302302 end;
303303
304304 procedure TForm1.EnableBlur;
305305 const
306306 WCA_ACCENT_POLICY = 19;
307307 ACCENT_ENABLE_BLURBEHIND = 3;
308308 ACCENT_ENABLE_ACRYLICBLURBEHIND = 4;
309309 DrawLeftBorder = $20;
310310 DrawTopBorder = $40;
311311 DrawRightBorder = $80;
312312 DrawBottomBorder = $100;
313313 var
314314 dwm10: THandle;
315315 data : TWinCompAttrData;
316316 accent: AccentPolicy;
317317 begin
318318
319319 dwm10 := LoadLibrary('user32.dll');
320320 try
321321 @SetWindowCompositionAttribute := GetProcAddress(dwm10, 'SetWindowCompositionAttribute');
322322 if @SetWindowCompositionAttribute <> nil then
323323 begin
324324 accent.AccentState := ACCENT_ENABLE_BLURBEHIND ;
325325 //accent.AccentState := ACCENT_ENABLE_ACRYLICBLURBEHIND;
326326 accent.GradientColor := (100 SHL 24) or ($00E3E0DE);
327327 accent.AccentFlags := DrawLeftBorder or DrawTopBorder or DrawRightBorder or DrawBottomBorder;
328328
329329 data.Attribute := WCA_ACCENT_POLICY;
330330 data.dataSize := SizeOf(accent);
331331 data.pData := @accent;
332332 SetWindowCompositionAttribute(self.Handle, data);
333333 end
334334 else
335335 begin
336336 ShowMessage('Not found Windows 10 blur API');
337337 end;
338338 finally
339339 FreeLibrary(dwm10);
340340 end;
341341
342342 end;
343343
344344 procedure TForm1.FormCreate(Sender: TObject);
345345 begin
346346 DoubleBuffered := True;
347347 Color := clBlack;
348348 BorderStyle := bsnoNe;
349349 BorderIcons := [biSystemMenu, biMinimize, biMaximize];
350350 //AeroGlass;
351351 if TaskbarTranslucent then
352352 EnableBlur;
353353
354354 UpdateColorization;
355355 end;
356356
357357 procedure TForm1.BCButtonFocus1Click(Sender: TObject);
358358 begin
359359 close;
360360 end;
361361
362362 function TForm1.TaskbarAccented: boolean;
363363 var
364364 reg: TRegistry;
365365 begin
366366 Result := False;
367367 reg := TRegistry.Create;
368368 try
369369 reg.RootKey := HKEY_CURRENT_USER;
370370 reg.OpenKeyReadOnly('SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize');
371371 try
372372 if reg.ReadInteger('ColorPrevalence') = 1 then
373373 Result := True;
374374 except
375375 Result := False;
376376 end;
377377 reg.CloseKey;
378378
379379 finally
380380 reg.Free;
381381 end;
382382 end;
383383
384384 function TForm1.TaskbarTranslucent: boolean;
385385 var
386386 reg: TRegistry;
387387 begin
388388 Result := False;
389389 reg := TRegistry.Create;
390390 try
391391 reg.RootKey := HKEY_CURRENT_USER;
392392 reg.OpenKeyReadOnly('SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize');
393393 try
394394 if reg.ReadInteger('EnableTransparency') = 1 then
395395 Result := True;
396396 except
397397 Result := False;
398398 end;
399399 reg.CloseKey;
400400
401401 finally
402402 reg.Free;
403403 end;
404404 end;
405405
406406
407407
408408 procedure TForm1.UpdateColorization;
409409 begin
410410 if TaskbarTranslucent then
411411 begin
412412 SetAlphaColorPicture(clblack, 200, Image1.Picture, 10,10 );
413413 Image1.Align := alClient;
414414 Image1.Stretch := True;
415415 Image1.Visible := True;
416416 end
417417 else
418418 Image1.Visible := False;
419419
420420 if TaskbarAccented then
421421 begin
422422 SetAlphaColorPicture(9338482, 110, Image2.Picture, 10, 10);
423423 Image2.Visible := True;
424424 Image2.Align := alClient;
425425 Image2.Stretch := True;
426426 end
427427 else
428428 Image2.Visible := False;
429429 end;
430430
431431 function TForm1.GetAccentColor:TColor;
432432 var
433433 col: cardinal;
434434 opaque: longbool;
435435 newcolor: TColor;
436436 a,r,g,b: byte;
437437 begin
438438 DwmGetColorizationColor(col, opaque);
439439 a := Byte(col shr 24);
440440 r := Byte(col shr 16);
441441 g := Byte(col shr 8);
442442 b := Byte(col);
443443
444444
445445 newcolor := RGB(
446446 round(r*(a/255)+255-a),
447447 round(g*(a/255)+255-a),
448448 round(b*(a/255)+255-a)
449449 );
450450
451451 Result := newcolor;
452452
453453
454454 end;
455455
456456
457457 initialization
458458 SetWindowCompositionAttribute := GetProcAddress(GetModuleHandle(user32), 'SetWindowCompositionAttribute');
459459 end.
460460```
461461
462462## Bugs
463463
464464As you can see in the first image Labels aren't displayed fine in Aero Glass, there are links with components and code that show how to make "Glow Labels":
465465
466466 * [GlowLabel for Delphi](<http://development.mwcs.de/glowlabel.html>)
467467 * [Aero Glass - ein Text (Label) hintergrund "machen"](<http://www.delphipraxis.net/953968-post4.html>)
468468
469469Also if you clic the transparent part of the window the back window / desktop is selected (focus is lost in the form with aero glass).
470470
471471## About
472472
473473This was converted to Lazarus using "{$mode delphi}" from "Aero Glass Effekt für Delphi-Forms, Delphi-Unit von Daniel Mitte (2006)":
474474
475475 * [Aero Glass Effekt für Delphi-Forms](<http://www.delphipraxis.net/74538-aero-glass-effekt-fuer-delphi-forms.html>)
476476
477477There is a Delphi component here (to be ported in Lazarus):
478478
479479 * [D. Mitte in Torry's Delphi Page](<http://www.torry.net/authorsmore.php?id=6179>)
480480
481481---
482-*From the Free Pascal wiki, page "Aero Glass", as the Internet Archive kept it on 2024-01-21. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
482+*From the Free Pascal wiki, page "Aero Glass", as the Internet Archive kept it on 2024-01-21, last changed on 2020-06-25. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history