Win32程序状态栏等控件深色模式适配问题求助
解决Win32控件深色模式适配问题
1. 状态栏适配修正
你调用SetWindowTheme时参数错误,标准状态栏的深色模式主题应使用L"Explorer"而非L"DarkMode_Explorer",正确调用:
SetWindowTheme(m_StatusBar.GetSafeHwnd(), L"Explorer", nullptr);
同时要在窗口初始化(如OnInitDialog)和主题切换时,给状态栏发送主题变更消息:
m_StatusBar.SendMessage(WM_THEMECHANGED, 0, 0);
2. 菜单栏适配
给主窗口设置主题即可让菜单栏继承深色样式,若为弹出菜单可单独设置:
// 主窗口主题设置 SetWindowTheme(m_hWnd, L"Explorer", nullptr); // 弹出菜单单独设置 CMenu* pMenu = GetMenu(); if (pMenu) SetWindowTheme(pMenu->GetSafeHwnd(), L"Explorer", nullptr);
另外需响应WM_DWMCOLORIZATIONCOLORCHANGED消息,同步菜单颜色变化。
3. 工具栏适配
给工具栏设置主题并强制刷新样式:
SetWindowTheme(m_ToolBar.GetSafeHwnd(), L"Explorer", nullptr); m_ToolBar.SendMessage(WM_THEMECHANGED, 0, 0);
若工具栏有自定义按钮,需在OnDrawItem中手动适配深色背景与文本颜色。
4. 复选框、分组框、下拉组合框
这类标准控件需结合OnCtlColor处理与主题设置:
- 在
OnCtlColor中添加对应分支:
case CTLCOLOR_BTN: // 匹配目标复选框、分组框ID if (pWnd->GetDlgCtrlID() == IDC_CHECKBOX || pWnd->GetDlgCtrlID() == IDC_GROUPBOX) { pDC->SetTextColor(darkTextColor); pDC->SetBkColor(darkBkColor); hbr = hbrBackground; } break; case CTLCOLOR_COMBOBOX: pDC->SetTextColor(darkTextColor); pDC->SetBkColor(darkBkColor); hbr = hbrBackground; break;
- 给控件设置主题:
SetWindowTheme(GetDlgItem(IDC_CHECKBOX)->GetSafeHwnd(), L"Explorer", nullptr); SetWindowTheme(GetDlgItem(IDC_COMBO)->GetSafeHwnd(), L"Explorer", nullptr);
5. 日期选择器、日历控件
使用专属深色主题字符串,并处理下拉通知:
// 日期选择器 SetWindowTheme(m_DatePicker.GetSafeHwnd(), L"DarkMode_Calendar", nullptr); // 日历控件 SetWindowTheme(m_Calendar.GetSafeHwnd(), L"DarkMode_Calendar", nullptr);
同时在WM_NOTIFY中响应DN_DROPDOWN通知,确保下拉日历部分应用深色模式。
6. 属性网格(CPropertyGridCtrl)
属性网格为MFC自定义控件,需手动适配:
- 在
OnCtlColor中单独处理:
if (pWnd->IsKindOf(RUNTIME_CLASS(CPropertyGridCtrl))) { pDC->SetTextColor(darkTextColor); pDC->SetBkColor(darkBkColor); hbr = hbrBackground; }
- 重写
OnDrawItem方法,手动绘制深色背景与浅色文本; - 设置主题:
SetWindowTheme(m_PropertyGrid.GetSafeHwnd(), L"Explorer", nullptr);
7. 全局主题同步
在应用启动或主题切换时,发送全局设置变更消息,确保所有控件收到通知:
SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)L"ImmersiveColorSet");
修正后的OnCtlColor函数
移除冗余代码并补充控件分支:
HBRUSH CResizingDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = __super::OnCtlColor(pDC, pWnd, nCtlColor); if (theApp.GetNumberSetting(L"Options", L"Theme_UseDarkMode", false)) { constexpr COLORREF darkBkColor = 0x383838; constexpr COLORREF darkTextColor = 0xFFFFFF; static HBRUSH hbrBackground = CreateSolidBrush(darkBkColor); hbr = hbrBackground; switch (nCtlColor) { case CTLCOLOR_DLG: case CTLCOLOR_STATIC: case CTLCOLOR_EDIT: case CTLCOLOR_LISTBOX: case CTLCOLOR_COMBOBOX: pDC->SetTextColor(darkTextColor); pDC->SetBkColor(darkBkColor); break; case CTLCOLOR_BTN: pDC->SetTextColor(darkTextColor); pDC->SetBkColor(darkBkColor); break; case CTLCOLOR_SCROLLBAR: default: break; } // 单独处理属性网格 if (pWnd->IsKindOf(RUNTIME_CLASS(CPropertyGridCtrl))) { pDC->SetTextColor(darkTextColor); pDC->SetBkColor(darkBkColor); } } return hbr; }
内容的提问来源于stack exchange,提问作者Andrew Truckle
相关产品推荐
相关产品推荐

