From cccf837dd3a84ace085c76856f7be6997c3b1aff Mon Sep 17 00:00:00 2001 From: "alinvip22@gmail.com" Date: Fri, 7 Apr 2023 11:04:43 +0500 Subject: [PATCH] Initial commit --- .gitattributes | 2 + .gitignore | 69 +++++++++++ DarkModeApi.Consts.pas | 35 ++++++ DarkModeApi.FMX.pas | 75 ++++++++++++ DarkModeApi.Types.pas | 101 ++++++++++++++++ DarkModeApi.Vcl.pas | 62 ++++++++++ DarkModeApi.pas | 255 +++++++++++++++++++++++++++++++++++++++++ LICENSE | 21 ++++ README.md | 2 + 9 files changed, 622 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 DarkModeApi.Consts.pas create mode 100644 DarkModeApi.FMX.pas create mode 100644 DarkModeApi.Types.pas create mode 100644 DarkModeApi.Vcl.pas create mode 100644 DarkModeApi.pas create mode 100644 LICENSE create mode 100644 README.md diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9532800 --- /dev/null +++ b/.gitignore @@ -0,0 +1,69 @@ +# Uncomment these types if you want even more clean repository. But be careful. +# It can make harm to an existing project source. Read explanations below. +# +# Resource files are binaries containing manifest, project icon and version info. +# They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files. +#*.res +# +# Type library file (binary). In old Delphi versions it should be stored. +# Since Delphi 2009 it is produced from .ridl file and can safely be ignored. +#*.tlb +# +# Diagram Portfolio file. Used by the diagram editor up to Delphi 7. +# Uncomment this if you are not using diagrams or use newer Delphi version. +#*.ddp +# +# Visual LiveBindings file. Added in Delphi XE2. +# Uncomment this if you are not using LiveBindings Designer. +#*.vlb +# +# Deployment Manager configuration file for your project. Added in Delphi XE2. +# Uncomment this if it is not mobile development and you do not use remote debug feature. +#*.deployproj +# +# C++ object files produced when C/C++ Output file generation is configured. +# Uncomment this if you are not using external objects (zlib library for example). +#*.obj +# + +# Delphi compiler-generated binaries (safe to delete) +*.exe +*.dll +*.bpl +*.bpi +*.dcp +*.so +*.apk +*.drc +*.map +*.dres +*.rsm +*.tds +*.dcu +*.lib +*.a +*.o +*.ocx + +# Delphi autogenerated files (duplicated info) +*.cfg +*.hpp +*Resource.rc + +# Delphi local files (user-specific info) +*.local +*.identcache +*.projdata +*.tvsconfig +*.dsk + +# Delphi history and backups +__history/ +__recovery/ +*.~* + +# Castalia statistics file (since XE7 Castalia is distributed with Delphi) +*.stat + +# Boss dependency manager vendor folder https://github.com/HashLoad/boss +modules/ diff --git a/DarkModeApi.Consts.pas b/DarkModeApi.Consts.pas new file mode 100644 index 0000000..425eefd --- /dev/null +++ b/DarkModeApi.Consts.pas @@ -0,0 +1,35 @@ +unit DarkModeApi.Consts; + +interface + +{$IFDEF MSWINDOWS} + +uses + System.UITypes; + +const + BackColor: TColor = $1E1E1E; + TextColor: TColor = $F0F0F0; + InputBackColor: TColor = $303030; + Dwmapi = 'DWMAPI.DLL'; + CDarkModeExplorer = 'DarkMode_Explorer'; + CModeExplorer = 'Explorer'; + CDarkModeControlCFD = 'DarkMode_CFD'; + DWM_CLOAKED_APP = $0000001; + DWM_CLOAKED_SHELL = $0000002; + DWM_CLOAKED_INHERITED = $0000004; + ODS_NOACCEL = $0100; + WM_UAHDESTROYWINDOW = $0090; // handled by DefWindowProc + WM_UAHDRAWMENU = $0091; // lParam is UAHMENU + WM_UAHDRAWMENUITEM = $0092; // lParam is UAHDRAWMENUITEM + WM_UAHINITMENU = $0093; // handled by DefWindowProc + WM_UAHMEASUREMENUITEM = $0094; // lParam is UAHMEASUREMENUITEM + WM_UAHNCPAINTMENUPOPUP = $0095; // handled by DefWindowProc + WM_UAHUPDATE = $0096; + +{$ENDIF} + +implementation + +end. + diff --git a/DarkModeApi.FMX.pas b/DarkModeApi.FMX.pas new file mode 100644 index 0000000..8d82dc6 --- /dev/null +++ b/DarkModeApi.FMX.pas @@ -0,0 +1,75 @@ +unit DarkModeApi.FMX; + +{$IFDEF MSWINDOWS} +interface + +uses + FMX.Forms, FMX.Types; + +type + TFormHelper = class helper for TForm + procedure SetWindowColorModeAsSystem; + procedure SetWindowColorMode(IsDark: Boolean); + class function SystemIsDarkMode: Boolean; + end; + + procedure SetWindowColorModeAsSystemFor(Handle: TWindowHandle); + + procedure SetWindowColorModeFor(Handle: TWindowHandle; IsDark: Boolean); + +implementation + +uses + DarkModeApi, FMX.Platform.Win, Winapi.Windows; + +procedure SetWindowColorModeAsSystemFor(Handle: TWindowHandle); +var + Value: LongBool; + WinHandle: HWND; +begin + Value := IsDarkMode; + WinHandle := FmxHandleToHWND(Handle); + DwmSetWindowAttribute(WinHandle, ImmersiveDarkMode, Value, SizeOf(Value)); + AllowDarkModeForWindow(WinHandle, Value); + AllowDarkModeForApp(Value); +end; + +procedure SetWindowColorModeFor(Handle: TWindowHandle; IsDark: Boolean); +var + Value: LongBool; + WinHandle: HWND; +begin + Value := IsDark; + WinHandle := FmxHandleToHWND(Handle); + DwmSetWindowAttribute(WinHandle, ImmersiveDarkMode, Value, SizeOf(Value)); + AllowDarkModeForWindow(WinHandle, Value); + AllowDarkModeForApp(Value); +end; + +{ TFormHelper } + +procedure TFormHelper.SetWindowColorMode(IsDark: Boolean); +begin + SetWindowColorModeFor(handle, IsDark); +end; + +procedure TFormHelper.SetWindowColorModeAsSystem; +begin + SetWindowColorModeAsSystemFor(Handle); +end; + +class function TFormHelper.SystemIsDarkMode: Boolean; +begin + Result := IsDarkMode; +end; + +{$ELSE} + +interface + +implementation + +{$ENDIF} + +end. + diff --git a/DarkModeApi.Types.pas b/DarkModeApi.Types.pas new file mode 100644 index 0000000..cc24f03 --- /dev/null +++ b/DarkModeApi.Types.pas @@ -0,0 +1,101 @@ +unit DarkModeApi.Types; + +{$IFDEF MSWINDOWS} +{$ALIGN ON} +{$MINENUMSIZE 4} +{$WEAKPACKAGEUNIT} +{$WARN SYMBOL_PLATFORM OFF} + +interface + +uses + Winapi.Windows; + +type + TWinRoundType = (wrtDEFAULT = 0, wrtDONOTROUND = 1, wrtROUND = 2, wrtROUNDSMALL = 3); + + TDwmWindowAttribute = (DWMWA_NCRENDERING_ENABLED = 1, DWMWA_NCRENDERING_POLICY, DWMWA_TRANSITIONS_FORCEDISABLED, DWMWA_ALLOW_NCPAINT, DWMWA_CAPTION_BUTTON_BOUNDS, DWMWA_NONCLIENT_RTL_LAYOUT, DWMWA_FORCE_ICONIC_REPRESENTATION, DWMWA_FLIP3D_POLICY, DWMWA_EXTENDED_FRAME_BOUNDS, DWMWA_HAS_ICONIC_BITMAP, DWMWA_DISALLOW_PEEK, DWMWA_EXCLUDED_FROM_PEEK, DWMWA_CLOAK, DWMWA_CLOAKED, DWMWA_FREEZE_REPRESENTATION, DWMWA_PASSIVE_UPDATE_MODE, DWMWA_USE_HOSTBACKDROPBRUSH, DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19, DWMWA_USE_IMMERSIVE_DARK_MODE = 20, DWMWA_WINDOW_CORNER_PREFERENCE = 33, DWMWA_BORDER_COLOR, DWMWA_CAPTION_COLOR, DWMWA_TEXT_COLOR, DWMWA_VISIBLE_FRAME_BORDER_THICKNESS, DWMWA_SYSTEMBACKDROP_TYPE, DWMWA_LAST); + + TDWMWindowCornerPreference = (DWMWCP_DEFAULT = 0, DWMWCP_DONOTROUND = 1, DWMWCP_ROUND = 2, DWMWCP_ROUNDSMALL = 3); + + TImmersiveHCCacheMode = (IHCM_USE_CACHED_VALUE, IHCM_REFRESH); + + TPreferredAppMode = (DefaultMode, AllowDarkMode, ForceDarkMode, ForceLightMode, ModeMax); + + TWindowCompositionAttribute = (WCA_UNDEFINED = 0, // + WCA_NCRENDERING_ENABLED = 1, // + WCA_NCRENDERING_POLICY = 2, // + WCA_TRANSITIONS_FORCEDISABLED = 3, // + WCA_ALLOW_NCPAINT = 4, // + WCA_CAPTION_BUTTON_BOUNDS = 5, // + WCA_NONCLIENT_RTL_LAYOUT = 6, // + WCA_FORCE_ICONIC_REPRESENTATION = 7, // + WCA_EXTENDED_FRAME_BOUNDS = 8, // + WCA_HAS_ICONIC_BITMAP = 9, // + WCA_THEME_ATTRIBUTES = 10, // + WCA_NCRENDERING_EXILED = 11, // + WCA_NCADORNMENTINFO = 12, // + WCA_EXCLUDED_FROM_LIVEPREVIEW = 13, // + WCA_VIDEO_OVERLAY_ACTIVE = 14, // + WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15, // + WCA_DISALLOW_PEEK = 16, // + WCA_CLOAK = 17, // + WCA_CLOAKED = 18, // + WCA_ACCENT_POLICY = 19, // + WCA_FREEZE_REPRESENTATION = 20, // + WCA_EVER_UNCLOAKED = 21, // + WCA_VISUAL_OWNER = 22, // + WCA_HOLOGRAPHIC = 23, // + WCA_EXCLUDED_FROM_DDA = 24, // + WCA_PASSIVEUPDATEMODE = 25, // + WCA_USEDARKMODECOLORS = 26, // + WCA_LAST = 27); + + TWindowCompositionAttrib = TWindowCompositionAttribute; + + WINDOWCOMPOSITIONATTRIBDATA = record + Attrib: TWindowCompositionAttribute; + pvData: Pointer; + cbData: SIZE_T; + end; + + TWindowCompositionAttribData = WINDOWCOMPOSITIONATTRIBDATA; + + PWindowCompositionAttribData = ^TWindowCompositionAttribData; + + TRtlGetNtVersionNumbers = procedure(var major, minor, build: DWORD); stdcall; + + TSetWindowCompositionAttribute = function(hWnd: HWND; pData: PWindowCompositionAttribData): BOOL; stdcall; + + TShouldAppsUseDarkMode = function: BOOL; stdcall; + + TAllowDarkModeForWindow = function(hWnd: HWND; allow: BOOL): BOOL; stdcall; + + TAllowDarkModeForApp = function(allow: BOOL): BOOL; stdcall; + + TRefreshImmersiveColorPolicyState = procedure; stdcall; + + TIsDarkModeAllowedForWindow = function(hWnd: HWND): BOOL; stdcall; + + TGetIsImmersiveColorUsingHighContrast = function(mode: TImmersiveHCCacheMode): BOOL; stdcall; + + TOpenNcThemeData = function(hWnd: HWND; pszClassList: LPCWSTR): THandle; stdcall; + + TShouldSystemUseDarkMode = function: BOOL; stdcall; + + TSetPreferredAppMode = function(appMode: TPreferredAppMode): TPreferredAppMode; stdcall; + + TIsDarkModeAllowedForApp = function: BOOL; stdcall; + +implementation + +{$ELSE} + +interface + +implementation + +{$ENDIF} + +end. + diff --git a/DarkModeApi.Vcl.pas b/DarkModeApi.Vcl.pas new file mode 100644 index 0000000..aa9a97a --- /dev/null +++ b/DarkModeApi.Vcl.pas @@ -0,0 +1,62 @@ +unit DarkModeApi.Vcl; + +interface + +uses + Vcl.Forms; + +type + TFormHelper = class helper for TForm + procedure SetWindowColorModeAsSystem; + procedure SetWindowColorMode(IsDark: Boolean); + class function SystemIsDarkMode: Boolean; + end; + + procedure SetWindowColorModeAsSystemFor(Handle: THandle); + + procedure SetWindowColorModeFor(Handle: THandle; IsDark: Boolean); + +implementation + +uses + DarkModeApi, FMX.Platform.Win, Winapi.Windows; + +procedure SetWindowColorModeAsSystemFor(Handle: THandle); +var + Value: LongBool; +begin + Value := IsDarkMode; + DwmSetWindowAttribute(Handle, ImmersiveDarkMode, Value, SizeOf(Value)); + AllowDarkModeForWindow(Handle, Value); + AllowDarkModeForApp(Value); +end; + +procedure SetWindowColorModeFor(Handle: THandle; IsDark: Boolean); +var + Value: LongBool; +begin + Value := IsDark; + DwmSetWindowAttribute(Handle, ImmersiveDarkMode, Value, SizeOf(Value)); + AllowDarkModeForWindow(Handle, Value); + AllowDarkModeForApp(Value); +end; + +{ TFormHelper } + +procedure TFormHelper.SetWindowColorMode(IsDark: Boolean); +begin + SetWindowColorModeFor(handle, IsDark); +end; + +procedure TFormHelper.SetWindowColorModeAsSystem; +begin + SetWindowColorModeAsSystemFor(Handle); +end; + +class function TFormHelper.SystemIsDarkMode: Boolean; +begin + Result := IsDarkMode; +end; + +end. + diff --git a/DarkModeApi.pas b/DarkModeApi.pas new file mode 100644 index 0000000..fcd5dc4 --- /dev/null +++ b/DarkModeApi.pas @@ -0,0 +1,255 @@ +unit DarkModeApi; + +{$IFDEF MSWINDOWS} + +{$WARN SYMBOL_PLATFORM OFF} + +interface + +// See also https://github.com/adzm/win32-custom-menubar-aero-theme + +uses + Winapi.Windows, DarkModeApi.Types; + +function DwmSetWindowAttribute(hwnd: HWND; dwAttribute: DWORD; pvAttribute: Pointer; cbAttribute: DWORD): HResult; stdcall; overload; + +function DwmSetWindowAttribute(hwnd: HWND; dwAttribute: TDwmWindowAttribute; var pvAttribute; cbAttribute: DWORD): HResult; stdcall; overload; + +function DwmSetWindowAttribute(hwnd: HWND; dwAttribute: TDwmWindowAttribute; var pvAttribute: TDWMWindowCornerPreference; cbAttribute: DWORD): HResult; stdcall; overload; + +/// +/// Enables dark context menus which change automatically depending on the theme. +/// +procedure AllowDarkModeForApp(allow: BOOL); stdcall; + +function AllowDarkModeForWindow(hWnd: HWND; allow: Boolean): Boolean; stdcall; + +// See https://en.wikipedia.org/wiki/Windows_10_version_history +function CheckBuildNumber(buildNumber: DWORD): Boolean; + +function IsWindows10OrGreater(buildNumber: DWORD = 10000): Boolean; + +function IsWindows11OrGreater(buildNumber: DWORD = 22000): Boolean; + +function IsDarkModeAllowedForWindow(hWnd: HWND): BOOL; stdcall; + +procedure RefreshImmersiveColorPolicyState; stdcall; + +procedure RefreshTitleBarThemeColor(hWnd: HWND); + +function ShouldAppsUseDarkMode: BOOL; stdcall; + +function ShouldSystemUseDarkMode: BOOL; stdcall; + +function ImmersiveDarkMode: TDwmWindowAttribute; + +/// +/// Checks the system registry to see if Dark mode is enabled +/// +function IsDarkMode: Boolean; + +const + LOAD_LIBRARY_SEARCH_SYSTEM32 = $00000800; + +implementation + +uses + System.Classes, System.SysUtils, DarkModeApi.Consts, System.Win.Registry; + +var + _AllowDarkModeForApp: TAllowDarkModeForApp = nil; + _AllowDarkModeForWindow: TAllowDarkModeForWindow = nil; + _GetIsImmersiveColorUsingHighContrast: TGetIsImmersiveColorUsingHighContrast = nil; + _IsDarkModeAllowedForWindow: TIsDarkModeAllowedForWindow = nil; + _OpenNcThemeData: TOpenNcThemeData = nil; + _RefreshImmersiveColorPolicyState: TRefreshImmersiveColorPolicyState = nil; + _SetPreferredAppMode: TSetPreferredAppMode = nil; + _SetWindowCompositionAttribute: TSetWindowCompositionAttribute = nil; + _ShouldAppsUseDarkMode: TShouldAppsUseDarkMode = nil; + _ShouldSystemUseDarkMode: TShouldSystemUseDarkMode = nil; + GDarkModeSupported: BOOL = False; // changed type to BOOL + GDarkModeEnabled: BOOL = False; + GUxTheme: HMODULE = 0; + +function DwmSetWindowAttribute(hwnd: hwnd; dwAttribute: DWORD; pvAttribute: Pointer; cbAttribute: DWORD): HResult; stdcall; overload; external Dwmapi name 'DwmSetWindowAttribute' delayed; + +function DwmSetWindowAttribute(hwnd: hwnd; dwAttribute: TDwmWindowAttribute; var pvAttribute: TDWMWindowCornerPreference; cbAttribute: DWORD): HResult; stdcall; overload; external Dwmapi name 'DwmSetWindowAttribute' delayed; + +procedure AllowDarkModeForApp(allow: BOOL); +begin + if Assigned(_AllowDarkModeForApp) then + _AllowDarkModeForApp(allow) + else if Assigned(_SetPreferredAppMode) then + begin + if allow then + _SetPreferredAppMode(TPreferredAppMode.AllowDarkMode) + else + _SetPreferredAppMode(TPreferredAppMode.DefaultMode); + end; +end; + +function DwmSetWindowAttribute(hwnd: hwnd; dwAttribute: TDwmWindowAttribute; var pvAttribute; cbAttribute: DWORD): HResult; +begin + Result := DwmSetWindowAttribute(hwnd, Ord(dwAttribute), @pvAttribute, cbAttribute); +end; + +function IsDarkModeAllowedForWindow(hWnd: hWnd): BOOL; +begin + Result := Assigned(_IsDarkModeAllowedForWindow) and _IsDarkModeAllowedForWindow(hWnd); +end; + +function GetIsImmersiveColorUsingHighContrast(mode: TImmersiveHCCacheMode): BOOL; +begin + Result := Assigned(_GetIsImmersiveColorUsingHighContrast) and _GetIsImmersiveColorUsingHighContrast(mode); +end; + +function ImmersiveDarkMode: TDwmWindowAttribute; +begin + if IsWindows10OrGreater(18985) then + Result := DWMWA_USE_IMMERSIVE_DARK_MODE + else + Result := DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1; +end; + +procedure RefreshImmersiveColorPolicyState; +begin + if Assigned(_RefreshImmersiveColorPolicyState) then + _RefreshImmersiveColorPolicyState; +end; + +function IsDarkMode: Boolean; +var + LRegistry: TRegistry; +begin + LRegistry := TRegistry.Create; + try + LRegistry.RootKey := HKEY_CURRENT_USER; + LRegistry.OpenKeyReadOnly('\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize'); + Result := not LRegistry.ReadBool('AppsUseLightTheme'); + finally + LRegistry.Free; + end; +end; + +function ShouldSystemUseDarkMode: BOOL; +begin + Result := Assigned(_ShouldSystemUseDarkMode) and _ShouldSystemUseDarkMode; +end; +function CheckBuildNumber(buildNumber: DWORD): Boolean; +begin + Result := + IsWindows10OrGreater(20348) or + IsWindows10OrGreater(19045) or // + IsWindows10OrGreater(19044) or // + IsWindows10OrGreater(19043) or // + IsWindows10OrGreater(19042) or // + IsWindows10OrGreater(19041) or // 2004 + IsWindows10OrGreater(18363) or // 1909 + IsWindows10OrGreater(18362) or // 1903 + IsWindows10OrGreater(17763); // 1809 +end; + +function IsWindows10OrGreater(buildNumber: DWORD): Boolean; +begin + Result := (TOSVersion.Major > 10) or ((TOSVersion.Major = 10) and (TOSVersion.Minor = 0) and (DWORD(TOSVersion.Build) >= buildNumber)); +end; + +function IsWindows11OrGreater(buildNumber: DWORD): Boolean; +begin + Result := IsWindows10OrGreater(22000) or IsWindows10OrGreater(buildNumber); +end; + +function AllowDarkModeForWindow(hWnd: hWnd; allow: Boolean): Boolean; +begin + Result := GDarkModeSupported and _AllowDarkModeForWindow(hWnd, allow); +end; + +function IsHighContrast: Boolean; +var + highContrast: HIGHCONTRASTW; +begin + highContrast.cbSize := SizeOf(highContrast); + if SystemParametersInfo(SPI_GETHIGHCONTRAST, SizeOf(highContrast), @highContrast, Ord(False)) then + Result := highContrast.dwFlags and HCF_HIGHCONTRASTON <> 0 + else + Result := False; +end; + +procedure RefreshTitleBarThemeColor(hWnd: hWnd); +var + LUseDark: BOOL; + LData: TWindowCompositionAttribData; +begin + LUseDark := _IsDarkModeAllowedForWindow(hWnd) and _ShouldAppsUseDarkMode and not IsHighContrast; + if TOSVersion.Build < 18362 then + SetProp(hWnd, 'UseImmersiveDarkModeColors', THandle(LUseDark)) + else if Assigned(_SetWindowCompositionAttribute) then + begin + LData.Attrib := WCA_USEDARKMODECOLORS; + LData.pvData := @LUseDark; + LData.cbData := SizeOf(LUseDark); + _SetWindowCompositionAttribute(hWnd, @LData); + end; +end; + +function ShouldAppsUseDarkMode: BOOL; +begin + Result := Assigned(_ShouldAppsUseDarkMode) and _ShouldAppsUseDarkMode; +end; + +procedure InitDarkMode; +begin + if ((TOSVersion.Major = 10) and (TOSVersion.Minor = 0) and CheckBuildNumber(TOSVersion.Build)) then + begin + GUxTheme := LoadLibraryEx('uxtheme.dll', 0, LOAD_LIBRARY_SEARCH_SYSTEM32); + if GUxTheme <> 0 then + begin + @_AllowDarkModeForWindow := GetProcAddress(GUxTheme, MAKEINTRESOURCEA(133)); + @_GetIsImmersiveColorUsingHighContrast := GetProcAddress(GUxTheme, MAKEINTRESOURCEA(106)); + @_IsDarkModeAllowedForWindow := GetProcAddress(GUxTheme, MAKEINTRESOURCEA(137)); + @_RefreshImmersiveColorPolicyState := GetProcAddress(GUxTheme, MAKEINTRESOURCEA(104)); + @_SetWindowCompositionAttribute := GetProcAddress(GetModuleHandle(user32), 'SetWindowCompositionAttribute'); + @_ShouldAppsUseDarkMode := GetProcAddress(GUxTheme, MAKEINTRESOURCEA(132)); + + var P := GetProcAddress(GUxTheme, MAKEINTRESOURCEA(135)); + if TOSVersion.Build < 18362 then + @_AllowDarkModeForApp := P + else + @_SetPreferredAppMode := P; + + if Assigned(_RefreshImmersiveColorPolicyState) and + Assigned(_ShouldAppsUseDarkMode) and Assigned(_AllowDarkModeForWindow) and + (Assigned(_AllowDarkModeForApp) or Assigned(_SetPreferredAppMode)) and + Assigned(_IsDarkModeAllowedForWindow) then + begin + GDarkModeSupported := True; + AllowDarkModeForApp(True); + _RefreshImmersiveColorPolicyState; + GDarkModeEnabled := ShouldAppsUseDarkMode and not IsHighContrast; + end; + end; + end; +end; + +procedure DoneDarkMode; +begin + if GUxTheme <> 0 then + FreeLibrary(GUxTheme); +end; + +initialization + InitDarkMode; + +finalization + DoneDarkMode; + +{$ELSE} + +interface + +implementation + +{$ENDIF} + +end. + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..36f0e7d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 alinvip22@gmail.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..f3cf38f --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# WindowDarkMode + Dark mode for Window frame (Win only)