Win32 C++中如何修改DropDownList(仅列表组合框)背景色?
Win32 C++ DropDownList组合框背景色修改问题及解决办法
问题概述
在Win32 C++应用中,DropDownList类型的组合框顶部区域的背景色始终为灰色,无法通过常规方法修改:
- 已通过监听父窗口的
WM_CTLCOLORLISTBOX消息成功修改了下拉列表部分的背景色 - 可编辑组合框的编辑区域能通过
WM_CTLCOLOREDIT消息修改背景色,但DropDownList的顶部并非编辑控件,该方法无效 - 尝试针对
COMBOBOXINFO中的hwndItem处理WM_CTLCOLOREDIT消息,同样没有效果
尝试过的代码
有效修改下拉列表背景色的代码(仅针对下拉部分)
// 这段代码可以正常修改下拉列表的背景色 case WM_CTLCOLORLISTBOX: { HWND hWndCombo = GetDlgItem(hWndDlg, IDC_COMBO); COMBOBOXINFO info; info.cbSize = sizeof(info); SendMessage(hWndCombo, CB_GETCOMBOBOXINFO, 0, (LPARAM)&info); if ((HWND)lParam == info.hwndList) { HDC dc = (HDC)wParam; SetBkMode(dc, OPAQUE); SetTextColor(dc, RGB(255, 255, 0)); SetBkColor(dc, 0x383838); //0x383838 HBRUSH comboBrush = CreateSolidBrush(0x383838); return (LRESULT)comboBrush; } else { return DefWindowProc(hWndDlg, message, wParam, lParam); } }
对DropDownList无效的编辑区着色代码
// 这段代码仅对可编辑组合框有效,对DropDownList无效 case WM_CTLCOLOREDIT: { HWND hWndCombo = GetDlgItem(hWndDlg, IDC_COMBO); COMBOBOXINFO info; info.cbSize = sizeof(info); SendMessage(hWndCombo, CB_GETCOMBOBOXINFO, 0, (LPARAM)&info); HWND hWnd = (HWND)lParam; HDC hDC = (HDC)wParam; // 尝试匹配组合框窗口和hwndItem,均无效 if ((HWND)lParam == hWndCombo || (HWND)lParam == info.hwndItem) { SetBkMode(hDC, TRANSPARENT); SetTextColor(hDC, RGB(255, 0, 255)); SetBkColor(hDC, 0x383838); //0x383838 return (LRESULT)CreateSolidBrush(RGB(255, 255, 0)); } else { return DefWindowProc(hWndDlg, message, wParam, lParam); } }
可行的变通方案
改用可编辑类型的组合框,通过以下步骤模拟DropDownList的行为并实现背景色自定义:
- 将编辑区域设置为只读
- 子类化编辑控件,在获得焦点时隐藏光标
实现代码
初始化组合框的代码
HWND hComboBox = GetDlgItem(hWndDlg, IDC_COMBO); COMBOBOXINFO ci = { sizeof(COMBOBOXINFO) }; GetComboBoxInfo(hComboBox, &ci); if (ci.hwndItem) { // 将编辑框设置为只读 SendMessage(ci.hwndItem, EM_SETREADONLY, TRUE, 0); // 子类化编辑控件,处理焦点时隐藏光标 SetWindowSubclass(ci.hwndItem, EditableComboBoxListOnlyProc, 0, 0); }
子类化回调函数(隐藏光标)
LRESULT CALLBACK EditableComboBoxListOnlyProc(HWND hWndComboBox, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { LRESULT lRes = DefSubclassProc(hWndComboBox, message, wParam, lParam); if (message == WM_SETFOCUS) HideCaret(hWndComboBox); return lRes; }
内容的提问来源于stack exchange,提问作者gene b.
相关产品推荐
相关产品推荐

