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;
}

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);
}

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
? ? }
- 3 回答
- 0 關注
- 249 瀏覽
添加回答
舉報