Win32程序如何检测窗口是否处于深色模式(Windows 10+)
检测Win32宿主窗口实际深色模式的方案
优先用DwmGetWindowAttribute直接查询(Windows 10 1809+)
从Win10 1809(版本17763)开始,系统提供了DwmGetWindowAttribute函数,能直接获取目标窗口是否启用了沉浸式深色模式——这和你提到的macOSeffectiveAppearance逻辑一致,直接反映窗口实际生效的外观,不用管宿主有没有遵循系统注册表设置。
你只需要拿到宿主的窗口句柄(插件一般能通过宿主API或者GetParent这类函数拿到顶层窗口),然后调用这个函数:
#include <dwmapi.h> #pragma comment(lib, "dwmapi.lib") bool IsWindowInDarkMode(HWND hWnd) { if (!hWnd) return false; BOOL isDark = FALSE; HRESULT hr = DwmGetWindowAttribute(hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &isDark, sizeof(isDark)); // 旧系统不支持这个属性,调用失败就默认非深色 if (FAILED(hr)) { return false; } return isDark != FALSE; }
兼容旧系统的 fallback 方案
如果要支持Win10更早版本,或者宿主没用到沉浸式深色模式但自己实现了深色主题,可以通过窗口的实际背景色来判断:
- 先尝试获取窗口的主题句柄,读取主题定义的背景色
- 没有主题的话,直接用系统默认窗口颜色
- 最后根据颜色亮度判断——亮度低于128就认定是深色模式
代码示例:
#include <uxtheme.h> #pragma comment(lib, "uxtheme.lib") #include <algorithm> // 计算RGB颜色的亮度值(0-255) int GetColorBrightness(COLORREF color) { int r = GetRValue(color); int g = GetGValue(color); int b = GetBValue(color); return static_cast<int>(std::max({r, g, b})); } bool IsWindowInDarkMode_Fallback(HWND hWnd) { if (!hWnd) return false; HTHEME hTheme = OpenThemeData(hWnd, L"Window"); COLORREF bgColor = 0; if (hTheme) { GetThemeColor(hTheme, WP_WINDOW, CS_ACTIVE, CLR_BACKGROUND, &bgColor); CloseThemeData(hTheme); } else { // 无主题时用系统默认窗口颜色 bgColor = GetSysColor(COLOR_WINDOW); } // 亮度阈值设128,可根据实际需求调整 return GetColorBrightness(bgColor) < 128; }
综合使用两种方法
把两个逻辑结合起来,优先用DwmGetWindowAttribute(更准确),失败了就自动用fallback方案,这样不管宿主是新是旧,都能准确检测实际的深色状态,完全不用维护版本列表:
bool IsHostInDarkMode(HWND hHostWnd) { bool isDark = IsWindowInDarkMode(hHostWnd); if (!isDark) { isDark = IsWindowInDarkMode_Fallback(hHostWnd); } return isDark; }
内容的提问来源于stack exchange,提问作者rpatters1
相关产品推荐
相关产品推荐

