为了账号安全,请及时绑定邮箱和手机立即绑定

Windows 10 上的 WinForms 深色标题栏

Windows 10 上的 WinForms 深色标题栏

C#
12345678_0001 2023-07-09 10:01:30
我有一个 WinForms 应用程序,它会自动调整为 Windows 10 上的深色/浅色主题。我的问题是,无论用户选择哪个主题,窗口的标题栏始终保持白色。顶部是当前的,底部是我想要的(用 Photoshop 模拟)参见explorer例如。这不是 UWP 应用程序,但它在 Windows 1903 及更高版本上使用深色标题栏(当选择深色主题时)。我怎样才能实现同样的目标?我不想使用任何自定义标题栏,因为我希望应用程序的外观和行为也像旧 Windows 版本上的任何本机应用程序一样。
查看完整描述

3 回答

?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

因此,经过长时间的搜索,我终于找到了这个问题的答案。技巧是使用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;

}


查看完整回答
反对 回复 2023-07-09
?
潇湘沐

TA贡献1816条经验 获得超6个赞

最快的方法:


[DllImport("DwmApi")] //System.Runtime.InteropServices

private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, int[] attrValue, int attrSize);


protected override void OnHandleCreated(EventArgs e)

{

    if (DwmSetWindowAttribute(Handle, 19, new[] { 1 }, 4) != 0)

        DwmSetWindowAttribute(Handle, 20, new[] { 1 }, 4);

}


查看完整回答
反对 回复 2023-07-09
?
精慕HU

TA贡献1845条经验 获得超8个赞

请记住,对于 .net fw 4.8.1 及之前版本,返回的版本不好,在 .Net6 中修复,这里是一个片段(.Net 5 不受管理):


    private static bool IsWindows10OrGreater(int build = -1)

    {

        return WindowsVersion() >= 10 && WindowsBuildNumber() >= build;

    }


    public static int WindowsVersion()

    {

     //for .Net4.8 and Minor

     #if NETFRAMEWORK

        int result = 10;

        var reg = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");

        string[] productName = reg.GetValue("ProductName").ToString().Split((char)32);

        int.TryParse(productName[1], out result);

        return result;

     #else

        //fixed in .Net6

        return System.Environment.OSVersion.Version.Major;

     #endif

    }


    public static int WindowsBuildNumber()

    {

        //for .Net4.8 and Minor

    #if NETFRAMEWORK

        int result = 22000;

        var reg = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");

        string buildNumber = reg.GetValue("CurrentBuildNumber").ToString();

        int.TryParse(buildNumber, out result);

        return result;

    #endif


    #if NET

        //fixed in .Net6

        return System.Environment.OSVersion.Version.Build;

    #endif

    }


查看完整回答
反对 回复 2023-07-09
  • 3 回答
  • 0 关注
  • 475 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号