以下函数只能让标题栏变成深色模式,但我想要实现IDM那样的完整的Win32窗口的深色模式。
DwmSetWindowAttribute(hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));
经过一番搜索,下面的函数可以实现这个效果,放在这里记录一下
typedef BOOL(WINAPI* AllowDarkModeForWindowProc)(HWND, BOOL);
typedef void(WINAPI* RefreshImmersiveColorPolicyStateProc)();
typedef BOOL(WINAPI* AllowDarkModeForAppProc)(BOOL);
typedef DWORD(WINAPI* SetPreferredAppModeProc)(DWORD);
enum PreferredAppMode { Default, AllowDark, ForceDark, ForceLight };
void ApplyDarkModeSettings(HWND hWnd) {
HMODULE hUxtheme = LoadLibraryEx(L"uxtheme.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!hUxtheme) return;
DWORD buildNumber = GetWindowsBuildNumber();
// 适配不同系统版本的全局深色模式
if (buildNumber < 18362) { // Windows 10 1809 及以下
auto AllowDarkModeForApp = (AllowDarkModeForAppProc)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(135));
if (AllowDarkModeForApp) AllowDarkModeForApp(TRUE);
} else { // Windows 10 1903 及以上
auto SetPreferredAppMode = (SetPreferredAppModeProc)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(135));
if (SetPreferredAppMode) SetPreferredAppMode(AllowDark);
}
// 刷新颜色策略并允许窗口深色模式
auto RefreshImmersiveColorPolicyState = (RefreshImmersiveColorPolicyStateProc)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(104));
auto AllowDarkModeForWindow = (AllowDarkModeForWindowProc)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(133));
if (RefreshImmersiveColorPolicyState) RefreshImmersiveColorPolicyState();
if (AllowDarkModeForWindow) AllowDarkModeForWindow(hWnd, TRUE);
FreeLibrary(hUxtheme);
}