Page 1 of 1

ApplyDarkModeToWindow() [Windows]

Posted: Wed Dec 11, 2024 12:57 pm
by Zapman
Apply the current Windows theme to the title bar of a window.

Code: Select all

;**************************************************************************
;
;                         ApplyDarkModeToWindow()
;                     Zapman - Dec 2024 - Windows only
;
;      Apply the current Windows theme to the title bar of a window.
;
;**************************************************************************
;
; Prototype for the DwmSetWindowAttribute_ function
Prototype.i DwmSetWindowAttribute(hWnd.i, dwAttribute.i, pvAttribute.i, cbAttribute.i)
;

Procedure.i IsDarkModeEnabled()
  ;
  ; Detects if dark mode is enabled in Windows
  ;
  Protected key = 0
  Protected darkModeEnabled = 0
  
  If RegOpenKeyEx_(#HKEY_CURRENT_USER, "Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", 0, #KEY_READ, @key) = #ERROR_SUCCESS
    Protected value = 1
    Protected valueSize = SizeOf(value)
    If RegQueryValueEx_(key, "AppsUseLightTheme", 0, #Null, @value, @valueSize) = #ERROR_SUCCESS
      darkModeEnabled = Abs(value - 1) ; 0 = dark, 1 = light
    EndIf
    RegCloseKey_(key)
  EndIf
  
  ProcedureReturn darkModeEnabled
EndProcedure


Procedure ApplyDarkModeToWindow(Window)
  ;
  ; Applies dark theme to a window if dark theme is enabled in Windows.
  ;
  Protected hWnd = WindowID(Window)
  ;
  If hWnd And OSVersion() >= #PB_OS_Windows_10
    Protected hDwmapi = OpenLibrary(#PB_Any, "dwmapi.dll")
    ;
    If hDwmapi
      Protected DwmSetWindowAttribute_.DwmSetWindowAttribute = GetFunction(hDwmapi, "DwmSetWindowAttribute")
      ; Enable dark mode if possible
      If DwmSetWindowAttribute_
        Protected darkModeEnabled = IsDarkModeEnabled()
        If darkModeEnabled
          #DWMWA_USE_IMMERSIVE_DARK_MODE = 20
          DwmSetWindowAttribute_(hWnd, #DWMWA_USE_IMMERSIVE_DARK_MODE, @darkModeEnabled, SizeOf(darkModeEnabled))
          SetWindowColor(Window, $202020)
          ;
          ; Force the window to repaint:
          HideWindow(Window, #True)
          HideWindow(Window, #False)
        EndIf
      EndIf
      ;
      CloseLibrary(hDwmapi)
    EndIf
  EndIf
EndProcedure
;
CompilerIf #PB_Compiler_IsMainFile
  ; Example usage
  WWidth = 400
  WHeight = 300
  If OpenWindow(0, 0, 0, WWidth, WHeight, "Window with theme", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ApplyDarkModeToWindow(0) ; Apply theme to the main window
    Margins = 10
    Msg$ = "This is a demo of the ApplyDarkModeToWindow() function." + Chr(13) + Chr(13)
    Msg$ + "If your computer is set to 'Dark theme mode', this window will also be set to dark mode." + Chr(13) + Chr(13)
    Msg$ + "If your computer is set to 'Light theme mode', the colors of this window will stay as default ones." + Chr(13) + Chr(13)
    Msg$ + "Please note that ApplyDarkModeToWindow() doesn't modify the gadgets colors." + Chr(13)
    Msg$ + "It only modifes the title bar of the window." + Chr(13)
    TextGadget(1, Margins, Margins, WWidth - Margins * 2, WHeight - Margins * 2, Msg$, #PB_Text_Center)
    If IsDarkModeEnabled()
      SetGadgetColor(1, #PB_Gadget_BackColor, $202020)
      SetGadgetColor(1, #PB_Gadget_FrontColor, $C0C0C0)
    EndIf
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Break
      EndSelect
    ForEver
  EndIf
CompilerEndIf