Home > Net >  Windows 11 WPF dark titlebar doesnt work 'interop helper missing'
Windows 11 WPF dark titlebar doesnt work 'interop helper missing'

Time:08-18

Hello I am trying to get the DarkMode titlebar in my WPF app to work but it says that InteropHelper is not found and I cant find anything online.

I followed this tutorial

[DllImport("dwmapi.dll", PreserveSig = true)]
        public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref bool attrValue, int attrSize);        
        
        public MainWindow()
        {
            var value = true;
            InteropHelper.DwmSetWindowAttribute(new System.Windows.Interop.WindowInteropHelper(this).Handle, 20, ref value, System.Runtime.InteropServices.Marshal.SizeOf(true));
            InitializeComponent();
        }      

Any ideas on why this doesn't work?

CodePudding user response:

Although not the proper solution to your problem, there is a way to control the color of the titlebar, and you could better match it to a theme if that is what you are looking for, this could also give you an idea of how to do the above correctly.

[DllImport("dwmapi.dll")]
private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, int[] attrValue, int attrSize);
const int DWWMA_CAPTION_COLOR = 35;

public MainWindow()
{
    IntPtr hWnd = new WindowInteropHelper(this).EnsureHandle();
    int[] colorstr = new int[] { 0x000 };
    DwmSetWindowAttribute(hWnd, DWWMA_CAPTION_COLOR, colorstr, 4);
}

CodePudding user response:

You need to learn P/Invoke a bit.

  1. You need to get the window handle of a WPF's Window typically by WindowInteropHelper.
  2. The window handle is not valid yet at the time of Window's constructor as AndrewS commented. So, you need to wait for Window.SourceInitialized event. OR you need to use WindowInteropHelper.EnsureHandle method if you want it inside the constructor.

The way to call DwmSetWindowAttribute function is briefly touched in Apply rounded corners in desktop apps for Windows 11, the attribute is different though.

A sample code would be:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;

public partial class MainWindow : Window
{
    [DllImport("Dwmapi.dll")]
    private static extern int DwmSetWindowAttribute(
        IntPtr hwnd,
        DWMWINDOWATTRIBUTE attribute,
        [In] ref bool pvAttribute,
        int cbAttribute);

    private enum DWMWINDOWATTRIBUTE
    {
        DWMWA_USE_IMMERSIVE_DARK_MODE = 20,
    }

    public MainWindow()
    {
        InitializeComponent();

        IntPtr hWnd = new WindowInteropHelper(this).EnsureHandle();
        bool value = true;
        int result = DwmSetWindowAttribute(
            hWnd,
            DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE,
            ref value,
            Marshal.SizeOf<bool>());

        Debug.WriteLine(result); // 0 means success.
    }
}
  • Related