Jump to content

GUI Title bar Dark Theme, an elegant solution using DwmAPI


DK12000
 Share

Recommended Posts

I had a search around on how to do dark windows properly and found this elegant solution on GitHub, but did not see it posted here so thought I would connect the 2. 
SkyEmie is the creator and deserves a round of applause, also the first time I have seen If statements done this way. Yay for learning new things.
This little draft demonstrates how to switch from a light theme, to a dark application title bar with AutoIT, using DWM api. · GitHub

; This little draft demonstrates how to switch from a light theme, to a dark application title bar with AutoIT, using DwmAPI.
; It will probably be useful to someone who wants to do this, without any headache.
; Because windows does not have any official documentation on this subject today :s

#include <GUIConstantsEx.au3>
#notrayicon

opt('guioneventmode', 1)

#cs ----------------------------------------------------------------------------
 Function    : is_app_dark_theme()
 Description : returns if the user has enabled the dark theme for applications in the Windows settings (0 on / 1 off)
               if OS too old (key does not exist) the key returns nothing, so function returns False
#ce ----------------------------------------------------------------------------
func is_app_dark_theme()
    return(regread('HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize', 'AppsUseLightTheme') == 0) ? True : False
endfunc

#cs ----------------------------------------------------------------------------
 Function    : set_dark_theme($hwnd, $dark_theme = True)
 Description : set to the handle, the attribute to define whether dark/light theme
#ce ----------------------------------------------------------------------------
func set_dark_theme($hwnd, $dark_theme = True)
    ; before this build set to 19, otherwise set to 20, no thanks Windaube to document anything ??
    $DWMWA_USE_IMMERSIVE_DARK_MODE = (@osbuild <= 18985) ? 19 : 20
    $dark_theme = ($dark_theme == True) ? 1 : 0

    dllcall( _
        'dwmapi.dll', _
        'long',   'DwmSetWindowAttribute', _
        'hwnd',   $hwnd, _
        'dword',  $DWMWA_USE_IMMERSIVE_DARK_MODE, _
        'dword*', $dark_theme, _
        'dword',  4 _
    )
endfunc

; create gui
$gui_hwnd = guicreate('Tiny gui', 800, 450)
guisetonevent($GUI_EVENT_CLOSE, 'gui_close')

; if dark theme enabled for apps in windows settings, set dark theme to gui
if is_app_dark_theme() == True then
    set_dark_theme($gui_hwnd, True)
endif

; display gui
guisetstate(@sw_show)

while 1
    sleep(10)
wend

func gui_close()
    exit
endfunc

 

 

Link to comment
Share on other sites

you inspired me :)

#include <GUIConstantsEx.au3>
#notrayicon

opt('guioneventmode', 1)

; create gui
$gui_hwnd = guicreate('Tiny gui', 800, 450)
guisetonevent($GUI_EVENT_CLOSE, 'gui_close')

set_BorderColor($gui_hwnd, 0x00ff00) ; for Win 11 22H2 onwards
Func set_BorderColor($hwnd, $iBorderColor = 0xFFffffff) ; default is 0xffFFFFFF ; else use 0x00rrggbb
    $DWMWA_BORDER_COLOR = 34 ; https://www.purebasic.fr/english/viewtopic.php?t=78732
    dllcall( _
        'dwmapi.dll', _
        'long',   'DwmSetWindowAttribute', _
        'hwnd',   $hwnd, _
        'dword',  $DWMWA_BORDER_COLOR, _
        'dword*', $iBorderColor, _
        'dword', 4 )
EndFunc

; display gui
guisetstate(@sw_show)

while 1
    sleep(100)
wend

func gui_close()
    exit
endfunc

Set_BorderColor() 

Edit: ..I use IsDarkMode() instead of the registry for the dark mode setting.

Edited by argumentum
clarify

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

  • 2 weeks later...

The registry key does not exist in my machine but the set_dark_theme function works.

 

Saludos

Link to comment
Share on other sites

  • 5 months later...
Posted (edited)
On 12/13/2023 at 2:25 PM, Danyfirex said:

The registry key does not exist in my machine but the set_dark_theme function works.

You can also try an INI approach:

Or via a whole function that relies on DLL:

Func _WinAPI_ShouldAppsUseDarkMode()
    If @OSBuild < 17763 Then Return SetError(-1, 0, False)
    Local $fnShouldAppsUseDarkMode = 132
    Local $aResult = DllCall('uxtheme.dll', 'bool', $fnShouldAppsUseDarkMode)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[0]
EndFunc   ;==>_WinAPI_ShouldAppsUseDarkMode

Which is from the attached file in:

 

Edited by LWC
Added another alternative
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...