![](/img/trans.png)
[英]Title in Windows 10 Task Bar changes when not on main form in winforms c#
[英]WinForms Dark title bar on Windows 10
所以经过长时间的搜索,我终于找到了答案。 诀窍是使用dwmapi.dll
的DwmSetWindowAttribute
并将未记录的常量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;
}
最快的方法:
[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);
}
对于 Jonas Kohl 的解决方案,请记住,对于 .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
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.