Sign in Join
Wiki copytemporary

Aero Glass: what changed

Revision 3 to 4. 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)]]** │
8-****
9-
10-## Contents
11-
12- * 1 Aero Glass effect on Lazarus Form
13- * 2 Windows 10
14- * 3 Bugs
15- * 4 About
168
179## Aero Glass effect on Lazarus Form
1810
1911[![aero glass lazarus.png](/wiki-images/8/83/aero_glass_lazarus.png)](</File:aero_glass_lazarus.png>)
2012
2113First save the above code to a text file "glass.pas":
2214```
2315unit glass;
2416
2517 {$mode delphi}
2618 //{$mode objfpc}{$H+}
2719
2820 interface
2921
3022 uses
3123 Windows, Forms, Graphics;
3224
3325 type
3426 _MARGINS = packed record
3527 cxLeftWidth : Integer;
3628 cxRightWidth : Integer;
3729 cyTopHeight : Integer;
3830 cyBottomHeight : Integer;
3931 end;
4032
4133 PMargins = ^_MARGINS;
4234 TMargins = _MARGINS;
4335
4436 DwmIsCompositionEnabledFunc = function(pfEnabled: PBoolean): HRESULT; stdcall;
4537 DwmExtendFrameIntoClientAreaFunc = function(destWnd: HWND; const pMarInset: PMargins): HRESULT; stdcall;
4638 SetLayeredWindowAttributesFunc = function(destWnd: HWND; cKey: TColor; bAlpha: Byte; dwFlags: DWord): BOOL; stdcall;
4739
4840 const
4941 WS_EX_LAYERED = $80000;
5042 LWA_COLORKEY = 1;
5143
5244 procedure GlassForm(frm: TForm; tmpMargins: TMargins; cBlurColorKey: TColor = clFuchsia);
5345 function WindowsAeroGlassCompatible: Boolean;
5446
5547 implementation
5648
5749 function WindowsAeroGlassCompatible: Boolean;
5850 var
5951 osVinfo: TOSVERSIONINFO;
6052 begin
6153 ZeroMemory(@osVinfo, SizeOf(osVinfo));
6254 OsVinfo.dwOSVersionInfoSize := SizeOf(TOSVERSIONINFO);
6355 if (
6456 (GetVersionEx(osVInfo) = True) and
6557 (osVinfo.dwPlatformId = VER_PLATFORM_WIN32_NT) and
6658 (osVinfo.dwMajorVersion >= 6)
6759 )
6860 then Result:=True
6961 else Result:=False;
7062 end;
7163
7264 procedure GlassForm(frm: TForm; tmpMargins: TMargins; cBlurColorKey: TColor = clFuchsia);
7365 var
7466 hDwmDLL: Cardinal;
7567 fDwmIsCompositionEnabled: DwmIsCompositionEnabledFunc;
7668 fDwmExtendFrameIntoClientArea: DwmExtendFrameIntoClientAreaFunc;
7769 fSetLayeredWindowAttributesFunc: SetLayeredWindowAttributesFunc;
7870 bCmpEnable: Boolean;
7971 mgn: TMargins;
8072 begin
8173 { Continue if Windows version is compatible }
8274 if WindowsAeroGlassCompatible then begin
8375 { Continue if 'dwmapi' library is loaded }
8476 hDwmDLL := LoadLibrary('dwmapi.dll');
8577 if hDwmDLL <> 0 then begin
8678 { Get values }
8779 @fDwmIsCompositionEnabled := GetProcAddress(hDwmDLL, 'DwmIsCompositionEnabled');
8880 @fDwmExtendFrameIntoClientArea := GetProcAddress(hDwmDLL, 'DwmExtendFrameIntoClientArea');
8981 @fSetLayeredWindowAttributesFunc := GetProcAddress(GetModulehandle(user32), 'SetLayeredWindowAttributes');
9082 { Continue if values are <> nil }
9183 if (
9284 (@fDwmIsCompositionEnabled <> nil) and
9385 (@fDwmExtendFrameIntoClientArea <> nil) and
9486 (@fSetLayeredWindowAttributesFunc <> nil)
9587 )
9688 then begin
9789 { Continue if composition is enabled }
9890 fDwmIsCompositionEnabled(@bCmpEnable);
9991 if bCmpEnable = True then begin
10092 { Set Form Color same as cBlurColorKey }
10193 frm.Color := cBlurColorKey;
10294 { ... }
10395 SetWindowLong(frm.Handle, GWL_EXSTYLE, GetWindowLong(frm.Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
10496 { ... }
10597 fSetLayeredWindowAttributesFunc(frm.Handle, cBlurColorKey, 0, LWA_COLORKEY);
10698 { Set margins }
10799 ZeroMemory(@mgn, SizeOf(mgn));
108100 mgn.cxLeftWidth := tmpMargins.cxLeftWidth;
109101 mgn.cxRightWidth := tmpMargins.cxRightWidth;
110102 mgn.cyTopHeight := tmpMargins.cyTopHeight;
111103 mgn.cyBottomHeight := tmpMargins.cyBottomHeight;
112104 { Extend Form }
113105 fDwmExtendFrameIntoClientArea(frm.Handle,@mgn);
114106 end;
115107 end;
116108 { Free loaded 'dwmapi' library }
117109 FreeLibrary(hDWMDLL);
118110 end;
119111 end;
120112 end;
121113
122114 end.
123115```
124116
125117Copy the "glass.pas" file to the main folder of your project:
126118```
127119MyProject\glass.pas
128120```
129121
130122In the "uses" section of your project you need to add "glass":
131123```
132124unit form1;
133125
134126 {$mode objfpc}{$H+}
135127
136128 interface
137129
138130 uses
139131 Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs
140132 glass; // This includes GlassForm procedure
141133```
142134
143135OnActivate event of each form call the procedure in this way:
144136```
145137procedure TForm1.FormActivate(Sender: TObject);
146138 var
147139 tmpMargins: TMargins;
148140 begin
149141 { If all margins are -1 the whole form will be aero glass}
150142 tmpMargins.cxLeftWidth := -1;
151143 tmpMargins.cxRightWidth := -1;
152144 tmpMargins.cyBottomHeight := -1;
153145 tmpMargins.cyTopHeight := -1;
154146 { FormName ; Margins ; TransparentColor }
155147 GlassForm(Self, tmpMargins, clFuchsia);
156148 end;
157149```
158150
159151Also you need to enable Themes to use this procedure, go to Options > Project Options > then select "Use Manifest to Enable Themes (Windows)".
160152
161153## Windows 10
162154
163155[![aeroglasswin10.png](/wiki-images/8/84/aeroglasswin10.png)](</File:aeroglasswin10.png>)
164156```
165157{
166158 author: vhanla
167159 http://vhanla.codigobit.info
168160 }
169161 unit Unit1;
170162
171163 interface
172164
173165 uses
174166 Windows, Messages, SysUtils, Variants, Classes, Graphics,
175167 Controls, Forms, Dialogs, DWMApi, png, IntfGraphics, FPImage, GraphType,
176168 StdCtrls, ExtCtrls, BCButtonFocus, BCLabel, Registry, LMessages, LCLType, LCLIntf;
177169
178170 type
179171
180172 { TForm1 }
181173
182174 TForm1 = class(TForm)
183175 BCButtonFocus1: TBCButtonFocus;
184176 BCLabel1: TBCLabel;
185177 Image1: TImage;
186178 Image2: TImage;
187179 Panel1: TPanel;
188180
189181 procedure BCButtonFocus1Click(Sender: TObject);
190182 procedure FormCreate(Sender: TObject);
191183 procedure Button1Click(Sender: TObject);
192184 procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton;
193185 Shift: TShiftState; X, Y: Integer);
194186 private
195187 { Private declarations }
196188 function TaskbarAccented:boolean;
197189 function TaskbarTranslucent:boolean;
198190 procedure EnableBlur;
199191 procedure AeroGlass;
200192 procedure UpdateColorization;
201193 function GetAccentColor:TColor;
202194 public
203195 { Public declarations }
204196 end;
205197
206198 AccentPolicy = packed record
207199 AccentState: Integer;
208200 AccentFlags: Integer;
209201 GradientColor: Integer;
210202 AnimationId: Integer;
211203 end;
212204
213205 TWinCompAttrData = packed record
214206 attribute: THandle;
215207 pData: Pointer;
216208 dataSize: ULONG;
217209 end;
218210
219211
220212 var
221213 Form1: TForm1;
222214
223215 var
224216 SetWindowCompositionAttribute: function (Wnd: HWND; const AttrData: TWinCompAttrData): BOOL; stdcall = Nil;
225217 implementation
226218
227219 {$R *.lfm}
228220
229221 procedure SetAlphaColorPicture(
230222 const Col: TColor;
231223 const Alpha: Integer;
232224 Picture: TPicture;
233225 const _width: Integer;
234226 const _height: Integer
235227 );
236228 var
237229 IM: TLazIntfImage;
238230 x,y: integer;
239231 sl: pByteArray;
240232 I, J, W, H: Integer;
241233 FC: TFPColor;
242234 begin
243235 IM := TLazIntfImage.Create(0, 0, [riqfRGB, riqfAlpha]);
244236 try
245237 IM.SetSize(_width, _height);
246238 for I := 0 to _width - 1 do
247239 begin
248240 for J := 0 to _height - 1 do
249241 begin
250242 FC.red := (128 + I) shl 8;
251243 FC.green := (128 + J) shl 8;
252244 FC.blue := 128 shl 8;
253245 FC.alpha := 128 shl 8; // now works fine
254246 IM.Colors[I, J] := FC;
255247 end;
256248 end;
257249 Picture.Assign(IM);
258250
259251
260252 finally
261253 IM.Free;
262254
263255 end;
264256 end;
265257
266258 procedure TForm1.Button1Click(Sender: TObject);
267259 begin
268260 Close;
269261 end;
270262
271263 procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
272264 Shift: TShiftState; X, Y: Integer);
273265 begin
274266 ReleaseCapture;
275267 SendMessage(Form1.Handle, LM_SYSCOMMAND, 61458, 0) ;
276268 end;
277269
278270 procedure TForm1.AeroGlass;
279271 var
280272 Aero: BOOL;
281273 Area: TRect;
282274 hDWM: THandle;
283275 begin
284276 hDWM:=LoadLibrary('dwmapi.dll');
285277 try
286278 @DwmIsCompositionEnabled:=GetProcAddress(hDWM,'DwmIsCompositionEnabled');
287279 if @DwmIsCompositionEnabled<>nil then
288280 DwmIsCompositionEnabled(Aero);
289281 if Aero then
290282 begin
291283 Area:=Rect(-1,-1,-1,-1);
292284 Color:=clBlack;
293285 @DwmExtendFrameIntoClientArea:=GetProcAddress(hDWM,'DwmExtendFrameIntoClientArea');
294286 if @DwmExtendFrameIntoClientArea<>nil then
295287 DwmExtendFrameIntoClientArea(Handle,@Area);
296288
297289 end
298290 else ShowMessage('Aero is Disabled');
299291 finally
300292 FreeLibrary(hDWM);
301293 end;
302294 end;
303295
304296 procedure TForm1.EnableBlur;
305297 const
306298 WCA_ACCENT_POLICY = 19;
307299 ACCENT_ENABLE_BLURBEHIND = 3;
308300 ACCENT_ENABLE_ACRYLICBLURBEHIND = 4;
309301 DrawLeftBorder = $20;
310302 DrawTopBorder = $40;
311303 DrawRightBorder = $80;
312304 DrawBottomBorder = $100;
313305 var
314306 dwm10: THandle;
315307 data : TWinCompAttrData;
316308 accent: AccentPolicy;
317309 begin
318310
319311 dwm10 := LoadLibrary('user32.dll');
320312 try
321313 @SetWindowCompositionAttribute := GetProcAddress(dwm10, 'SetWindowCompositionAttribute');
322314 if @SetWindowCompositionAttribute <> nil then
323315 begin
324316 accent.AccentState := ACCENT_ENABLE_BLURBEHIND ;
325317 //accent.AccentState := ACCENT_ENABLE_ACRYLICBLURBEHIND;
326318 accent.GradientColor := (100 SHL 24) or ($00E3E0DE);
327319 accent.AccentFlags := DrawLeftBorder or DrawTopBorder or DrawRightBorder or DrawBottomBorder;
328320
329321 data.Attribute := WCA_ACCENT_POLICY;
330322 data.dataSize := SizeOf(accent);
331323 data.pData := @accent;
332324 SetWindowCompositionAttribute(self.Handle, data);
333325 end
334326 else
335327 begin
336328 ShowMessage('Not found Windows 10 blur API');
337329 end;
338330 finally
339331 FreeLibrary(dwm10);
340332 end;
341333
342334 end;
343335
344336 procedure TForm1.FormCreate(Sender: TObject);
345337 begin
346338 DoubleBuffered := True;
347339 Color := clBlack;
348340 BorderStyle := bsnoNe;
349341 BorderIcons := [biSystemMenu, biMinimize, biMaximize];
350342 //AeroGlass;
351343 if TaskbarTranslucent then
352344 EnableBlur;
353345
354346 UpdateColorization;
355347 end;
356348
357349 procedure TForm1.BCButtonFocus1Click(Sender: TObject);
358350 begin
359351 close;
360352 end;
361353
362354 function TForm1.TaskbarAccented: boolean;
363355 var
364356 reg: TRegistry;
365357 begin
366358 Result := False;
367359 reg := TRegistry.Create;
368360 try
369361 reg.RootKey := HKEY_CURRENT_USER;
370362 reg.OpenKeyReadOnly('SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize');
371363 try
372364 if reg.ReadInteger('ColorPrevalence') = 1 then
373365 Result := True;
374366 except
375367 Result := False;
376368 end;
377369 reg.CloseKey;
378370
379371 finally
380372 reg.Free;
381373 end;
382374 end;
383375
384376 function TForm1.TaskbarTranslucent: boolean;
385377 var
386378 reg: TRegistry;
387379 begin
388380 Result := False;
389381 reg := TRegistry.Create;
390382 try
391383 reg.RootKey := HKEY_CURRENT_USER;
392384 reg.OpenKeyReadOnly('SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize');
393385 try
394386 if reg.ReadInteger('EnableTransparency') = 1 then
395387 Result := True;
396388 except
397389 Result := False;
398390 end;
399391 reg.CloseKey;
400392
401393 finally
402394 reg.Free;
403395 end;
404396 end;
405397
406398
407399
408400 procedure TForm1.UpdateColorization;
409401 begin
410402 if TaskbarTranslucent then
411403 begin
412404 SetAlphaColorPicture(clblack, 200, Image1.Picture, 10,10 );
413405 Image1.Align := alClient;
414406 Image1.Stretch := True;
415407 Image1.Visible := True;
416408 end
417409 else
418410 Image1.Visible := False;
419411
420412 if TaskbarAccented then
421413 begin
422414 SetAlphaColorPicture(9338482, 110, Image2.Picture, 10, 10);
423415 Image2.Visible := True;
424416 Image2.Align := alClient;
425417 Image2.Stretch := True;
426418 end
427419 else
428420 Image2.Visible := False;
429421 end;
430422
431423 function TForm1.GetAccentColor:TColor;
432424 var
433425 col: cardinal;
434426 opaque: longbool;
435427 newcolor: TColor;
436428 a,r,g,b: byte;
437429 begin
438430 DwmGetColorizationColor(col, opaque);
439431 a := Byte(col shr 24);
440432 r := Byte(col shr 16);
441433 g := Byte(col shr 8);
442434 b := Byte(col);
443435
444436
445437 newcolor := RGB(
446438 round(r*(a/255)+255-a),
447439 round(g*(a/255)+255-a),
448440 round(b*(a/255)+255-a)
449441 );
450442
451443 Result := newcolor;
452444
453445
454446 end;
455447
456448
457449 initialization
458450 SetWindowCompositionAttribute := GetProcAddress(GetModuleHandle(user32), 'SetWindowCompositionAttribute');
459451 end.
460452```
461453
462454## Bugs
463455
464456As 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":
465457
466458 * [GlowLabel for Delphi](<http://development.mwcs.de/glowlabel.html>)
467459 * [Aero Glass - ein Text (Label) hintergrund "machen"](<http://www.delphipraxis.net/953968-post4.html>)
468460
469461Also if you clic the transparent part of the window the back window / desktop is selected (focus is lost in the form with aero glass).
470462
471463## About
472464
473465This was converted to Lazarus using "{$mode delphi}" from "Aero Glass Effekt für Delphi-Forms, Delphi-Unit von Daniel Mitte (2006)":
474466
475467 * [Aero Glass Effekt für Delphi-Forms](<http://www.delphipraxis.net/74538-aero-glass-effekt-fuer-delphi-forms.html>)
476468
477469There is a Delphi component here (to be ported in Lazarus):
478470
479471 * [D. Mitte in Torry's Delphi Page](<http://www.torry.net/authorsmore.php?id=6179>)
480472
481473---
482474*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