Mfc CComboBoxEx - 如何更改背景颜色

2024-02-22

我有一个派生自 CComboBoxEx 的类,我正在尝试更改背景颜色。我认为它会像 ComboBox 一样工作(使用 SetBkColor 函数),但它不会改变背景颜色。

这是我尝试过的:

    BEGIN_MESSAGE_MAP(CMyComboBoxEx, CComboBoxEx)   
       ON_WM_CTLCOLOR()
    END_MESSAGE_MAP()

     void CMyComboBoxEx::SetBkColor(COLORREF backgroundColor)
         {
            m_backgroundColor = backgroundColor;
            m_brBkgnd.DeleteObject();
            m_brBkgnd.CreateSolidBrush(backgroundColor);
         }    
     HBRUSH CMyComboBoxEx::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
         {
            HBRUSH brush = __super::OnCtlColor(pDC, pWnd, nCtlColor);
            pDC->SetBkColor(RGB(255,0,0));

            return brush;
         }

我尝试过OnEraseBkgnd()也是,但也没有用。

我是否需要子类化派生的 CComboBox 类并在该类中设置背景颜色?

Thx.


这里的问题是WM_CTLCOLOR消息被发送到parent组合控件的窗口(可能是对话框),而不是控件本身;另外,在组合的下拉“列表框”部分的情况下,不会发送此消息(因为对话框不需要绘制它,除非控件已被激活)。

我实现你想要的方法是通过使控件所有者绘制,然后(手动)绘制列表中的每个项目。

首先,您需要添加CBS_OWNERDRAWFIXED风格到你的控制.rc/.rc2脚本;像这样,对于一个典型的组合:

COMBOBOX  IDC_IGONG, 224, 68, 52,120,
    CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_OWNERDRAWFIXED | WS_VSCROLL | WS_TABSTOP

然后,您需要添加ON_WM_DRAWITEM()到您的对话框类的消息映射,并覆盖它的OnDrawItem()成员。请注意,该消息发送一次每一个项目在下拉列表中,当用户操作使列表可见时:

void MyDialog::OnDrawItem(int nIDCtl, DRAWITEMSTRUCT *pDIS)
{
    switch (pDIS->CtlType) { // You can switch on the ID if it's only one combo!
    case ODT_COMBOBOX:
        DrawDropDownBox(this, nIDCtl, pDIS);
        break;
    default:
        CDialogEx::OnDrawItem(nIDCtl, pDIS);
        break;
    }
}

The DrawDropDownBox()完成所有艰苦的工作:


void MyDialog::DrawDropDownBox(CWnd *box, int nID, DRAWITEMSTRUCT *pDIS)
{
    CComboBox *pCBC = dynamic_cast<CMyComboBoxEx *>(box->GetDlgItem(nID));
    if (pCBC == nullptr) return; // Skip if we can't get handle to the control
    CDC *pDC = CDC::FromHandle(pDIS->hDC);
    wchar_t buffer[4096]; // Or just char if you ain't using Unicode
    if (pCBC->GetLBText(int(pDIS->itemID), buffer) == CB_ERR) return; // Maybe called during WM_DELETEITEM
    int dcSave = pDC->SaveDC(); // Save DC state for later restoration
    CPen pen(PS_SOLID, 0, ListColor); // ListColor is COLORREF for your desired b/g
    if (pDIS->itemState & ODS_DISABLED) {
        pDC->SelectStockObject(NULL_PEN);
        pDC->SelectObject(BackBrush); // A CBrush for disabled: defined/created elsewhere
        pDC->SetBkMode(TRANSPARENT);
    }
    else {
        pDC->SelectObject(&pen);
        pDC->SelectObject(ListBrush); // A CBrush that draws your desired b/g
        pDC->SetBkMode(OPAQUE);
    }
    CRect rc(pDIS->rcItem); pDC->Rectangle(&rc); // This draws the b/g
    if (pDIS->itemState & ODS_DISABLED) {
        pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
    }
    else if (pDIS->itemState & ODS_SELECTED) { // Use Windows defaults if selected...
        pDC->SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
        pDC->SetBkColor(GetSysColor(COLOR_HIGHLIGHT));
    }
    else {
        pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
        pDC->SetBkColor(ListColor); // Custom b/g color
    }
    unsigned format = DT_SINGLELINE | DT_VCENTER; // You desired text alignment
    pDC->DrawText(CString(buffer), rc, format);
    pDC->RestoreDC(dcSave); // Restore DC's saved state...
    pDC->Detach();          // ...then 'release it'
    return;
}

显示的代码处理禁用的组合和列表中选定的项目;如果您想简化操作,您可以跳过其中一些。

请随时要求进一步解释和/或澄清。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mfc CComboBoxEx - 如何更改背景颜色 的相关文章

随机推荐

  • 将套接字绑定到网络接口

    如何将套接字绑定到特定的网络接口 我尝试使用setsockopt在服务器端 但客户端仍然可以通过 eth0 和 lo 接口访问服务 我可以通过使用设置特定的IP地址来实现这一点serv addr sin addr s addr 但我怀疑我们
  • 从代码加载 WPF 中的图像

    我一定在网上阅读了大量的解决方案 但由于某种愚蠢的原因我无法让它们工作 我的项目的 Resources 文件夹中有一个 jpg 图像 该图像设置为 构建操作 资源 不是嵌入资源 并且从不复制到输出文件夹 我的形象是not添加到我的 reso
  • EditText - 如何分隔在组或块中在 EditText 中键入的字符

    有没有一种方法可以在用户打字时将 EditText 中的字符分组到块中 示例 1234 4567 7890等等 我有一个支持数字且长度为 16 个字符的编辑文本 我想将它们分组在单独的块中以获得更好的可见性 editText addText
  • 现代版本的 WinDiff? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 VB6附带WinDiff 是否有免费的现代版本的 WinDiff 可以忽略大小写 除了最新 SDK 中
  • 使用PL/SQL删除大量记录

    我想使用PL SQL删除大量记录 这些记录由 DATE 字段标识 该字段标识上次修改记录的时间 我不想消耗太多资源 因此我认为应该限制要删除的记录数量 在我看来 伪列 ROWNUM 可以满足此目的 然后 我检查受更新影响的行数并重复 直到影
  • 是否可以对 Websocket 升级请求使用承载身份验证?

    打开WebSocket连接的升级请求是标准的HTTP请求 在服务器端 我可以像其他任何请求一样验证请求 就我而言 我想使用承载身份验证 不幸的是 在浏览器中打开 Websocket 连接时无法指定标头 这会让我相信不可能使用承载身份验证来验
  • 使用 sleep 和 wait -n 在 bash 中实现简单的超时,是否存在竞争条件?

    如果我在 bash 脚本中执行此操作 sleep 10 sleep pid some command wait n cmd pid if kill 0 sleep pid 2 gt dev null then all ok kill sle
  • 如何等待 ThreadPoolExecutor 中的所有任务完成而不关闭 Executor?

    我不能使用shutdown and awaitTermination 因为在等待时 新任务可能会被添加到 ThreadPoolExecutor 中 因此 我正在寻找一种方法来等待 ThreadPoolExecutor 清空其队列并完成所有任
  • 如何使用BetterAuthorizationSample? - 可可

    我正在尝试使用 BetterAuthorizationSample 而不是采用所谓的 恶意 方式使用 setuid 来获取 root 权限 目前我正在使用 AuthorizationCreate 使用 BLAuthentication 获得
  • 使用 docker 和主机文件

    我正在尝试让 hbase 容器运行 并且该容器需要一些stuff这意味着 docker 主机需要作为 docker 可用 我们通过使用 docker 在主机文件中设置 docker ip 来实现这一点 但是 当我运行时 docker ps
  • 获取当前语言 next-i18next

    我将 NextJS 与 next i18next 一起使用 这是我的主页 import withTranslation from config next i18next const Home function Home return div
  • 尝试在 google chrome 中使用 HTML5 文件 api 时出现 FileError

    我试图使用 chrome 中的文件系统 API 创建一个文件 最初我尝试了如下持久存储 window requestFileSystem window requestFileSystem window webkitRequestFileSy
  • 使用 distplot 绘制直方图时 y 轴的单位是什么?

    使用 distplot 绘制直方图时 y 轴的单位是什么 我用正常拟合绘制了不同的直方图 我发现在一种情况下 它的范围是 0 到 0 9 而在另一种情况下 它的范围是 0 到 4 5 From help sns distplot norm
  • 为什么函数调用称为“函数调用”?

    我知道什么是函数调用 我知道它的作用 我已经调试了很多了 我有some凭直觉理解为什么使用术语 函数调用 是有意义的 但归根结底 我无法像使用 函数调用 那样正确解释这一点return陈述 例如 用return陈述答案是 叫做 回归 因为你
  • 如何通过“合并前需要拉取请求审查”来保护分支

    我已将其发布在 github community 上 但尚未得出任何解决方案 我试图保护主分支免受单人直接推送的影响 每个更改都必须通过 功能 分支进行 然后通过拉取请求得到另一个 或特定 开发人员的批准 在存储库的设置中 此功能似乎可以执
  • tf.data.Iterator.get_next():如何在tf.while_loop中前进?

    目前 我尝试在 Tensorflow while 循环中实现所有训练 但我在使用 Tensorflow 数据集 API 的迭代器时遇到了问题 通常 当调用 sess run 时 Iterator get next 前进到下一个元素 但是 我
  • 使用 Dozer 的自定义转换器将对象列表映射到另一个列表

    我想做的是使用 Dozer 将实体列表映射到它们的字符串 ID 列表 或多或少 显然 它意味着自定义转换器 我的第一个想法是创建一个从 MyEntity 到 String 的转换器 然后对 Dozer 说 使用此转换器映射此集合的每个对象
  • 获取 foreach 中先前的数组值

    我的数组 arr array jan feb mar apr mei jun jul agu sep okt nov des 然后我做了一个 foreach foreach arr as ar echo ar 这会将 jan 输出到 des
  • Oracle 中的并发更新:锁定与否?

    我很困惑 我正在阅读有关 Oracle 中的 MVCC 的内容 我以为MVCC意味着没有锁 但是 我在其他地方读到这一切UPDATE无论隔离级别如何 都会执行自动锁定 有人可以解释一下 Oracle 更新期间会发生什么吗 当多个已提交读事务
  • Mfc CComboBoxEx - 如何更改背景颜色

    我有一个派生自 CComboBoxEx 的类 我正在尝试更改背景颜色 我认为它会像 ComboBox 一样工作 使用 SetBkColor 函数 但它不会改变背景颜色 这是我尝试过的 BEGIN MESSAGE MAP CMyComboBo