Forum > Windows
Dark mode class...
Espectr0:
Hola,
I was thinking of making a class to implement "dark mode" in our applications in Windows 10 as I show in the images below (first image normal, second image dark mode).
For controls that don't support dark mode, maybe a custom paint can be implemented?
I await your comments, Greetings.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit UWSystem.DarkTheme; // ----------------------------------------------------------------------------- {$mode ObjFPC}{$H+} interface uses Windows, Forms, Classes, SysUtils, dynlibs, Controls, StdCtrls; const dwmapi = 'dwmapi.dll'; DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19; DWMWA_USE_IMMERSIVE_DARK_MODE = 20; uxtheme = 'uxtheme.dll'; BackColor: Integer = $1E1E1E; TextColor: Integer = $9B9B9B; type { TUWDarkMode } TUWDarkMode = class private FDWMlib : TLibHandle; FDWMfunc : function(hwnd: HWND; dwAttribute: DWORD; pvAttribute: Pointer; cbAttribute: DWORD): HRESULT; stdcall; FUXlib : TLibHandle; FUXfunc : function(hwnd: HWND; pszSubAppName: LPCWSTR; pszSubIdList: LPCWSTR): HRESULT; stdcall; function IsWindows10OrGreater(const ABuild: Integer = -1): Boolean; public constructor Create(const AForm: TForm); destructor Destroy; override; function Loaded: Boolean; function SetDarkMode(const AForm: TForm; const AValue: Bool = True): Boolean; end; // ----------------------------------------------------------------------------- implementation // ----------------------------------------------------------------------------- { TUWDarkMode } // ----------------------------------------------------------------------------- constructor TUWDarkMode.Create(const AForm: TForm);begin FDWMfunc := NIL; FUXfunc := NIL; FDWMlib := LoadLibrary(dwmapi); if FDWMlib <> 0 then Pointer(FDWMfunc) := GetProcAddress(FDWMlib, 'DwmSetWindowAttribute'); FUXlib := LoadLibrary(uxtheme); if FUXlib <> 0 then Pointer(FUXfunc) := GetProcAddress(FUXlib, 'SetWindowTheme'); SetDarkMode(AForm);end; // ----------------------------------------------------------------------------- destructor TUWDarkMode.Destroy;begin if FDWMfunc <> NIL then FDWMfunc := NIL; if FDWMlib <> 0 then FreeLibrary(FDWMlib); if FUXfunc <> NIL then FUXfunc := NIL; if FUXlib <> 0 then FreeLibrary(FUXlib); inherited Destroy;end; // ----------------------------------------------------------------------------- function TUWDarkMode.Loaded: Boolean;begin Result := (FDWMlib <> 0) and (FUXlib <> 0) and Assigned(FDWMfunc) and Assigned(FUXfunc);end; // ----------------------------------------------------------------------------- function TUWDarkMode.SetDarkMode(const AForm: TForm; const AValue: Bool = True): Boolean;var attr: DWord; i: Integer;begin Result := False; if AForm = NIL then Exit; if IsWindows10OrGreater(17763) then begin attr := DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1; if IsWindows10OrGreater(18985) then attr := DWMWA_USE_IMMERSIVE_DARK_MODE; FDWMfunc(AForm.Handle, attr, @AValue, SizeOf(AValue)); end; with AForm do begin Color := BackColor; Font.Color := TextColor; end; for i := 0 to AForm.ComponentCount-1 do begin if AForm.Components[i] is TWinControl then FUXfunc((AForm.Components[i] as TWinControl).Handle, 'DarkMode_Explorer', NIL); end; Result := True;end; // ----------------------------------------------------------------------------- function TUWDarkMode.IsWindows10OrGreater(const ABuild: Integer = -1): Boolean;begin Result := (Win32MajorVersion >= 10) and (Win32BuildNumber >= ABuild);end; // ----------------------------------------------------------------------------- end.
AlexTP:
For MainMenu you can use:
https://wiki.freepascal.org/Win32MenuStyler
Espectr0:
Gracias @AlexTP, I will check it later.
Thinking about the other controls (not menu), I have modified the class a bit and managed more colors except the CheckBox and RadioButton, can't change the font color?
AlexTP:
See the info here
https://stackoverflow.com/questions/12248571/how-to-change-caption-font-color-on-tcheckbox-tradiobutton-tgroupbox
Wallaby:
I was able to implement nearly full dark mode support for my applications.
For certain theme-drawn controls such as CheckBox/Radio, GroupBox, TabSeet, StatusBar and Progress bar you will need to go deeper and subclass them with SetWindowSubclass.
In the subclass routine you'd need to intercept WM_PAINT and WM_ERASEBKGND and custom-draw these controls.
Navigation
[0] Message Index
[#] Next page