You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 20:26:14