Changeset 115 for trunk/Packages/Common/Theme.pas
- Timestamp:
- Dec 11, 2024, 10:26:02 AM (11 days ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Packages/Common/Theme.pas
r113 r115 5 5 uses 6 6 Classes, SysUtils, Graphics, ComCtrls, Controls, ExtCtrls, Menus, StdCtrls, 7 Spin, Forms, Generics.Collections, Grids ;7 Spin, Forms, Generics.Collections, Grids, Registry, LCLType; 8 8 9 9 type … … 30 30 private 31 31 FTheme: TTheme; 32 FActualTheme: TTheme; 32 33 function Gray(C: TColor): Byte; 33 34 procedure SetTheme(AValue: TTheme); 34 procedure SetThemeName(AValue: TTheme); 35 procedure SetThemeName(Name: string); 36 procedure SetThemedTitleBar(AForm: TForm; Active: Bool); 37 function IsWindows10OrGreater(BuildNumber: Integer): Boolean; 35 38 public 36 39 Used: Boolean; … … 42 45 procedure UseTheme(Form: TForm); 43 46 property Theme: TTheme read FTheme write SetTheme; 47 property ActualTheme: TTheme read FActualTheme; 44 48 end; 45 49 … … 105 109 106 110 function TThemeManager.IsDarkTheme: Boolean; 107 begin 108 Result := Gray(ColorToRGB(clWindow)) < Gray(ColorToRGB(clWindowText)); 109 end; 110 111 procedure TThemeManager.SetThemeName(AValue: TTheme); 111 {$IFDEF WINDOWS} 112 var 113 LightKey: Boolean; 114 Registry: TRegistry; 115 const 116 KeyPath = '\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize'; 117 KeyName = 'AppsUseLightTheme'; 118 {$ELSE} 119 var 120 ColorWindow: TColor; 121 ColorWindowText: TColor; 122 {$ENDIF} 123 begin 124 Result := False; 125 {$IFDEF WINDOWS} 126 Registry := TRegistry.Create; 127 try 128 Registry.RootKey := HKEY_CURRENT_USER; 129 if Registry.OpenKeyReadOnly(KeyPath) then begin 130 if Registry.ValueExists(KeyName) then 131 LightKey := Registry.ReadBool(KeyName) 132 else LightKey := True; 133 end else LightKey := True; 134 Result := not LightKey; 135 finally 136 Registry.Free; 137 end; 138 {$ELSE} 139 ColorWindow := ColorToRGB(clWindow); 140 ColorWindowText := ColorToRGB(clWindowText); 141 Result := Gray(ColorWindow) < Gray(ColorWindowText); 142 {$ENDIF} 143 end; 144 145 procedure TThemeManager.SetThemeName(Name: string); 146 begin 147 Theme := Themes.FindByName(Name); 148 end; 149 150 function TThemeManager.IsWindows10OrGreater(BuildNumber: Integer): Boolean; 151 begin 152 {$IFDEF WINDOWS} 153 Result := (Win32MajorVersion >= 10) and (Win32BuildNumber >= BuildNumber); 154 {$ELSE} 155 Result := False; 156 {$ENDIF} 157 end; 158 159 procedure TThemeManager.SetThemedTitleBar(AForm: TForm; Active: Bool); 160 type 161 TDwmSetWindowAttribute = function(hwnd: HWND; dwAttribute: DWORD; pvAttribute: Pointer; cbAttribute: DWORD): HRESULT; stdcall; 162 const 163 DwmapiLibName = 'dwmapi.dll'; 164 DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19; 165 DWMWA_USE_IMMERSIVE_DARK_MODE = 20; 166 var 167 DwmapiLib: TLibHandle; 168 DwmSetWindowAttribute: TDwmSetWindowAttribute; 169 Attr: DWord; 170 begin 171 DwmapiLib := LoadLibrary(DwmapiLibName); 172 if DwmapiLib <> 0 then DwmSetWindowAttribute := GetProcAddress(DwmapiLib, 'DwmSetWindowAttribute') 173 else DwmSetWindowAttribute := nil; 174 175 if Assigned(DwmSetWindowAttribute) and IsWindows10OrGreater(17763) then begin 176 Attr := DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1; 177 if IsWindows10OrGreater(18985) then Attr := DWMWA_USE_IMMERSIVE_DARK_MODE; 178 179 DwmSetWindowAttribute(AForm.Handle, Attr, @Active, SizeOf(Active)); 180 end; 181 if DwmapiLib <> 0 then FreeLibrary(DwmapiLib); 182 end; 183 184 procedure TThemeManager.SetTheme(AValue: TTheme); 112 185 begin 113 186 if FTheme = AValue then Exit; 114 187 FTheme := AValue; 115 end; 116 117 procedure TThemeManager.SetTheme(AValue: TTheme); 118 begin 119 if FTheme = AValue then Exit; 120 FTheme := AValue; 188 FActualTheme := FTheme; 189 {$IFDEF WINDOWS} 190 if Assigned(FTheme) and (FTheme = Themes.FindByName(ThemeNameSystem)) and IsDarkTheme then 191 FActualTheme := Themes.FindByName(ThemeNameDark); 192 {$ENDIF} 121 193 end; 122 194 … … 132 204 ColorControlSelected := clWindow; 133 205 end; 134 Theme := TTheme(Themes.First);135 206 with Themes.AddNew(ThemeNameDark) do begin 136 207 ColorWindow := RGBToColor($20, $20, $20); … … 147 218 ColorControlSelected := RGBToColor(196, 225, 255); 148 219 end; 220 Theme := TTheme(Themes.First); 149 221 end; 150 222 … … 170 242 (Control is TMemo) or (Control is TListView) or (Control is TCustomDrawGrid) or 171 243 (Control is TCheckBox) or (Control is TPageControl) or (Control is TRadioButton) then begin 172 Control.Color := F Theme.ColorWindow;173 Control.Font.Color := F Theme.ColorWindowText;244 Control.Color := FActualTheme.ColorWindow; 245 Control.Font.Color := FActualTheme.ColorWindowText; 174 246 end else begin 175 Control.Color := F Theme.ColorControl;176 Control.Font.Color := F Theme.ColorControlText;247 Control.Color := FActualTheme.ColorControl; 248 Control.Font.Color := FActualTheme.ColorControlText; 177 249 end; 178 250 179 251 if Control is TCustomDrawGrid then begin 180 (Control as TCustomDrawGrid).Editor.Color := F Theme.ColorWindow;181 (Control as TCustomDrawGrid).Editor.Font.Color := F Theme.ColorWindowText;252 (Control as TCustomDrawGrid).Editor.Color := FActualTheme.ColorWindow; 253 (Control as TCustomDrawGrid).Editor.Font.Color := FActualTheme.ColorWindowText; 182 254 end; 183 255 … … 195 267 procedure TThemeManager.UseTheme(Form: TForm); 196 268 begin 197 if not Used and (F Theme.Name = ThemeNameSystem) then Exit;269 if not Used and (FActualTheme.Name = ThemeNameSystem) then Exit; 198 270 ApplyTheme(Form); 271 SetThemedTitleBar(Form, FActualTheme.Name = ThemeNameDark); 199 272 Used := True; 200 273 end;
Note:
See TracChangeset
for help on using the changeset viewer.