首页 > 解决方案 > Windows 10 上的 WinForms 深色标题栏

问题描述

我有一个 WinForms 应用程序,它会自动适应 Windows 10 上的深色/浅色主题。我的问题是我的窗口的标题栏始终保持白色,无论用户选择哪个主题。

在此处输入图像描述
顶部是当前的,底部是我想要的(用 Photoshop 模拟)

explorer例如参见。That is not an UWP app, however it uses a dark title bar on Windows 1903 and newer (when a dark theme is selected).

我怎样才能达到同样的目的?我不想使用任何自定义标题栏,因为我希望应用程序的外观和行为也像旧 Windows 版本上的任何本机应用程序一样。

标签: c#winformswindows-10

解决方案


所以经过长时间的搜索,我终于找到了这个问题的答案。诀窍是使用dwmapi.dll'sDwmSetWindowAttribute并将未记录的常量传递给DWMWA_USE_IMMERSIVE_DARK_MODE函数。在 C# 中,此代码看起来有点像这样(适用于 WinForms 和 WPF):

/*
using System.Runtime.InteropServices;
*/

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

private const int DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19;
private const int DWMWA_USE_IMMERSIVE_DARK_MODE = 20;

private static bool UseImmersiveDarkMode(IntPtr handle, bool enabled)
{
    if (IsWindows10OrGreater(17763))
    {
        var attribute = DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1;
        if (IsWindows10OrGreater(18985))
        {
            attribute = DWMWA_USE_IMMERSIVE_DARK_MODE;
        }

        int useImmersiveDarkMode = enabled ? 1 : 0;
        return DwmSetWindowAttribute(handle, (int)attribute, ref useImmersiveDarkMode, sizeof(int)) == 0;
    }

    return false;
}

private static bool IsWindows10OrGreater(int build = -1)
{
    return Environment.OSVersion.Version.Major >= 10 && Environment.OSVersion.Version.Build >= build;
}

推荐阅读