How to enable dark title bar in Windows Forms and WPF (Windows Presentation Foundation) apps

Windows has had a dark mode feature for a long time now, however, as a Windows Forms and/or WPF developer, you may have noticed that the Windows dark mode does not affect your app at all automatically - in fact the Windows dark mode only affects UWP, WinUI and Chromium based user interfaces - there's no support for Windows dark mode in Windows Forms and WPF.

Luckily, it is very easy to determine if dark mode is currently enabled and be notified any time dark mode is switched on or off - from there it's just a matter of updating your UI to match which mode Windows is in. While this may work fine for the client area of your app (i.e. the area of your app that does not include the title bar and border), you don't have a lot of control over the non-client area of your app and you'll notice that by default, the title bar and border of any Windows Forms or WPF window will not adjust to dark mode regardless of the user's dark mode settings. Luckily, Windows includes a function that you can use to tell the DWM (Desktop Window Manager), which is responsible for drawing your app windows' title bars, to draw the title bar and border in dark mode like so:

WPF app with dark title bar

How to enable dark title bar

To set the title bar to dark mode, you need to use the 'DwmSetWindowAttribute' function from dwmapi.dll. This can be defined in C# as:

using System.Runtime.InteropServices;

 [DllImport("dwmapi.dll", PreserveSig = true)]

 public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref bool attrValue, int attrSize);


And in VB:

Imports System.Runtime.InteropServices

<DllImport("dwmapi.dll", PreserveSig:=True)>

Public Shared Function DwmSetWindowAttribute(hwnd As IntPtr, attr As Integer, ByRef attrValue As Boolean, attrSize As Integer) As Integer

End Function


Once you've defined the function, you can call it from your code to change various DWMWINDOWATTRIBUTEs. Specifically, we want to change 'DWMWA_USE_IMMERSIVE_DARK_MODE' which has a value of 20. This value can be set as either true or false - when it's set to true, the title bar and border will be drawn in dark mode, and when set to false, the title bar will use the default behvaiour (which currently defaults to white). Note that although Microsoft's documentation states that this attribute is only available in Windows 11, I have tested and it is available in Windows 10 as well (Though it is not available in older versions of Windows 10 - I'm not sure when exactly it was added).

So to set the title bar to dark mode in C#, just call the DwmSetWindowAttribute with the following parameters (Note: 'System.Windows.Interop.WindowInteropHelper(this).Handle' assumes that this code is being called from a WPF Window class, if being called from a Windows Forms Form class, you can just use this.Handle. If it's being called from somewhere else, just replace 'this' with a reference to the window, or replace that entire argument with your own code for getting the handle of the window - the handle is the unique identifier of a window which in this case is used to tell Windows what window you want to change the DWM attributes of.):

var value = true;

InteropHelper.DwmSetWindowAttribute(new System.Windows.Interop.WindowInteropHelper(this).Handle, 20, ref value, System.Runtime.InteropServices.Marshal.SizeOf(true));


And call it like so in VB (Note: 'System.Windows.Interop.WindowInteropHelper(Me).Handle' assumes that this code is being called from a WPF Window class, if being called from a Windows Forms Form class, you can just use Me.Handle. If it's being called from somewhere else, just replace 'Me' with a reference to the window, or replace that entire argument with your own code for getting the handle of the window - the handle is the unique identifier of a window which in this case is used to tell Windows what window you want to change the DWM attributes of.):

InteropHelper.DwmSetWindowAttribute(New System.Windows.Interop.WindowInteropHelper(Me).Handle, 20, True, Runtime.InteropServices.Marshal.SizeOf(True))

To change the title bar back to light mode, simply call the same code by replace 'True' with 'False.

Before:

WPF app with light title bar

After:

WPF app with dark title bar


How to check if Windows is in dark mode

If you would like your window's title bar to match the Windows colour mode, one way to check if Windows is in dark mode or light mode is to read the registry value at 'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize\AppsUseLightTheme', this value will be 0 if Windows is in dark mode and 1 if it's in light mode. You can use the functions in Microsoft.Win32.Registry to read values from the registry. Alternatively, if your app uses UWP or WinUI via XAML Islands, you can simply check the value of ActualTheme of any UI Element so long as the UI Element's RequestedTheme is Default.

To run code when the colour mode changes, you can simply handle the Microsoft.Win32.SystemEvents.UserPreferenceChanged event - this event will be fired whenever Windows switches between light and dark mode so can check again which mode Windows is in whenever that event fires. Alternatively, if your app uses UWP or WinUI via XAML Islands, you can use the ActualThemeChanged event of any UI Element so long as the UI Element's RequestedTheme is Default.

This snippet is available in Codly. Click the appropriate link below to download the snippet. If you don't have Codly, it is available here in the Microsoft Store.

Testing

Note: If you have 'show accent colour on title bars and windows borders' enabled in Windows Settings, you may not be able to see a difference between the title bar and border being in light and dark mode.
You can use our app Window Commander to check and change the value of DWMWA_USE_IMMERSIVE_DARK_MODE, making it easier to experiment with this attribute. Window Commander is available here: https://www.microsoft.com/store/productId/9P8316P3V63P.


Our app AutoColourMode might also come in useful here as it allows you to quickly switch between light and dark mode from the taskbar. AutoColourMode is available here: https://www.microsoft.com/store/productId/9PL4MS6C2VPC.

If you found this article useful or if you have any questions, let us know in the comments!

Follow us to be notified when we release new guides:

Comments

Popular posts from this blog

How to show placeholder text in a WPF textbox

How to enable precision scrolling in a WPF app on Windows