Changeset 341
- Timestamp:
- Dec 21, 2024, 12:47:18 PM (22 hours ago)
- Location:
- trunk/Packages/Common
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Packages/Common/FormEx.pas
r332 r341 50 50 PersistentForm.Load(Self); 51 51 FullScreen := PersistentForm.FormFullScreen; 52 ThemeManager.UseTheme(Self); 52 53 end; 53 54 end; … … 75 76 76 77 Translator.TranslateComponentRecursive(Self); 77 ThemeManager.UseTheme(Self);78 78 Inc(FCounter); 79 79 inherited; -
trunk/Packages/Common/MetaCanvas.pas
r315 r341 150 150 procedure SetWidth(AValue: Integer); override; 151 151 function GetWidth: Integer; override; 152 procedure DoLine (x1,y1,x2,y2:integer); override;152 procedure DoLine(X1, Y1, X2, Y2: Integer); override; 153 153 procedure DoTextOut(X, Y: Integer; Text: string); override; 154 154 procedure DoRectangle(const Bounds: TRect); override; … … 563 563 end; 564 564 565 procedure TMetaCanvas.DoLine( x1, y1, x2, y2: integer);565 procedure TMetaCanvas.DoLine(X1, Y1, X2, Y2: integer); 566 566 var 567 567 NewObj: TCanvasLine; -
trunk/Packages/Common/RegistryEx.pas
r315 r341 36 36 function ReadFloatWithDefault(const Name: string; 37 37 DefaultValue: Double): Double; 38 function ReadDateTimeWithDefault(const Name: string; DefaultValue: TDateTime): TDateTime; 38 39 function DeleteKeyRecursive(const Key: string): Boolean; 39 40 function OpenKey(const Key: string; CanCreate: Boolean): Boolean; … … 110 111 end; 111 112 113 function TRegistryEx.ReadDateTimeWithDefault(const Name: string; 114 DefaultValue: TDateTime): TDateTime; 115 begin 116 if ValueExists(Name) then Result := ReadDateTime(Name) 117 else begin 118 WriteDateTime(Name, DefaultValue); 119 Result := DefaultValue; 120 end; 121 end; 122 112 123 function TRegistryEx.DeleteKeyRecursive(const Key: string): Boolean; 113 124 var -
trunk/Packages/Common/Theme.pas
r315 r341 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 … … 25 25 end; 26 26 27 TDwmSetWindowAttribute = function(hwnd: HWND; dwAttribute: DWORD; pvAttribute: Pointer; cbAttribute: DWORD): HRESULT; stdcall; 28 27 29 { TThemeManager } 28 30 … … 30 32 private 31 33 FTheme: TTheme; 34 FActualTheme: TTheme; 35 DwmapiLib: TLibHandle; 36 DwmSetWindowAttribute: TDwmSetWindowAttribute; 37 function Gray(C: TColor): Byte; 32 38 procedure SetTheme(AValue: TTheme); 33 procedure SetThemeName(AValue: TTheme); 39 procedure SetThemeName(Name: string); 40 procedure SetThemedTitleBar(AForm: TForm; Active: Bool); 41 function IsWindows10OrGreater(BuildNumber: Integer): Boolean; 34 42 public 35 43 Used: Boolean; 36 44 Themes: TThemes; 45 function IsDarkTheme: Boolean; 37 46 procedure ApplyTheme(Component: TComponent); 38 47 constructor Create(AOwner: TComponent); override; … … 40 49 procedure UseTheme(Form: TForm); 41 50 property Theme: TTheme read FTheme write SetTheme; 51 property ActualTheme: TTheme read FActualTheme; 42 52 end; 43 53 … … 46 56 ThemeNameLight = 'Light'; 47 57 ThemeNameDark = 'Dark'; 58 DwmapiLibName = 'dwmapi.dll'; 59 DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19; 60 DWMWA_USE_IMMERSIVE_DARK_MODE = 20; 48 61 49 62 procedure Register; … … 95 108 end; 96 109 97 procedure TThemeManager.SetThemeName(AValue: TTheme); 110 { TThemeManager } 111 112 function TThemeManager.Gray(C: TColor): Byte; 113 begin 114 Result := Trunc(Red(C) * 0.3 + Green(C) * 0.59 + Blue(C) * 0.11); 115 end; 116 117 function TThemeManager.IsDarkTheme: Boolean; 118 {$IFDEF WINDOWS} 119 var 120 LightKey: Boolean; 121 Registry: TRegistry; 122 const 123 KeyPath = '\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize'; 124 KeyName = 'AppsUseLightTheme'; 125 {$ELSE} 126 var 127 ColorWindow: TColor; 128 ColorWindowText: TColor; 129 {$ENDIF} 130 begin 131 Result := False; 132 {$IFDEF WINDOWS} 133 Registry := TRegistry.Create; 134 try 135 Registry.RootKey := HKEY_CURRENT_USER; 136 if Registry.OpenKeyReadOnly(KeyPath) then begin 137 if Registry.ValueExists(KeyName) then 138 LightKey := Registry.ReadBool(KeyName) 139 else LightKey := True; 140 end else LightKey := True; 141 Result := not LightKey; 142 finally 143 Registry.Free; 144 end; 145 {$ELSE} 146 ColorWindow := ColorToRGB(clWindow); 147 ColorWindowText := ColorToRGB(clWindowText); 148 Result := Gray(ColorWindow) < Gray(ColorWindowText); 149 {$ENDIF} 150 end; 151 152 procedure TThemeManager.SetThemeName(Name: string); 153 begin 154 Theme := Themes.FindByName(Name); 155 end; 156 157 function TThemeManager.IsWindows10OrGreater(BuildNumber: Integer): Boolean; 158 begin 159 {$IFDEF WINDOWS} 160 Result := (Win32MajorVersion >= 10) and (Win32BuildNumber >= BuildNumber); 161 {$ELSE} 162 Result := False; 163 {$ENDIF} 164 end; 165 166 procedure TThemeManager.SetThemedTitleBar(AForm: TForm; Active: Bool); 167 var 168 Attr: DWord; 169 begin 170 if Assigned(DwmSetWindowAttribute) and IsWindows10OrGreater(17763) then begin 171 Attr := DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1; 172 if IsWindows10OrGreater(18985) then Attr := DWMWA_USE_IMMERSIVE_DARK_MODE; 173 174 DwmSetWindowAttribute(AForm.Handle, Attr, @Active, SizeOf(Active)); 175 end; 176 end; 177 178 procedure TThemeManager.SetTheme(AValue: TTheme); 98 179 begin 99 180 if FTheme = AValue then Exit; 100 181 FTheme := AValue; 101 end; 102 103 procedure TThemeManager.SetTheme(AValue: TTheme); 104 begin 105 if FTheme = AValue then Exit; 106 FTheme := AValue; 182 FActualTheme := FTheme; 183 {$IFDEF WINDOWS} 184 if Assigned(FTheme) and (FTheme = Themes.FindByName(ThemeNameSystem)) and IsDarkTheme then 185 FActualTheme := Themes.FindByName(ThemeNameDark); 186 {$ENDIF} 107 187 end; 108 188 … … 110 190 begin 111 191 inherited; 192 {$IFDEF WINDOWS} 193 DwmapiLib := LoadLibrary(DwmapiLibName); 194 if DwmapiLib <> 0 then DwmSetWindowAttribute := GetProcAddress(DwmapiLib, 'DwmSetWindowAttribute') 195 else DwmSetWindowAttribute := nil; 196 {$ENDIF} 197 112 198 Themes := TThemes.Create; 113 199 with Themes.AddNew(ThemeNameSystem) do begin … … 118 204 ColorControlSelected := clWindow; 119 205 end; 120 Theme := TTheme(Themes.First);121 206 with Themes.AddNew(ThemeNameDark) do begin 122 207 ColorWindow := RGBToColor($20, $20, $20); … … 133 218 ColorControlSelected := RGBToColor(196, 225, 255); 134 219 end; 220 Theme := TTheme(Themes.First); 135 221 end; 136 222 … … 138 224 begin 139 225 FreeAndNil(Themes); 226 {$IFDEF WINDOWS} 227 if DwmapiLib <> 0 then FreeLibrary(DwmapiLib); 228 {$ENDIF} 140 229 inherited; 141 230 end; … … 156 245 (Control is TMemo) or (Control is TListView) or (Control is TCustomDrawGrid) or 157 246 (Control is TCheckBox) or (Control is TPageControl) or (Control is TRadioButton) then begin 158 Control.Color := F Theme.ColorWindow;159 Control.Font.Color := F Theme.ColorWindowText;247 Control.Color := FActualTheme.ColorWindow; 248 Control.Font.Color := FActualTheme.ColorWindowText; 160 249 end else begin 161 Control.Color := F Theme.ColorControl;162 Control.Font.Color := F Theme.ColorControlText;250 Control.Color := FActualTheme.ColorControl; 251 Control.Font.Color := FActualTheme.ColorControlText; 163 252 end; 164 253 165 254 if Control is TCustomDrawGrid then begin 166 (Control as TCustomDrawGrid).Editor.Color := F Theme.ColorWindow;167 (Control as TCustomDrawGrid).Editor.Font.Color := F Theme.ColorWindowText;255 (Control as TCustomDrawGrid).Editor.Color := FActualTheme.ColorWindow; 256 (Control as TCustomDrawGrid).Editor.Font.Color := FActualTheme.ColorWindowText; 168 257 end; 169 258 … … 181 270 procedure TThemeManager.UseTheme(Form: TForm); 182 271 begin 183 if not Used and (F Theme.Name = ThemeNameSystem) then Exit;272 if not Used and (FActualTheme.Name = ThemeNameSystem) then Exit; 184 273 ApplyTheme(Form); 274 SetThemedTitleBar(Form, FActualTheme.Name = ThemeNameDark); 185 275 Used := True; 186 276 end;
Note:
See TracChangeset
for help on using the changeset viewer.