Проблема здесь в том, что 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;
}
}
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;
}
Показанный код обрабатывает как отключенные комбинации, так и выбранные элементы в списке;Вы можете пропустить некоторые из них, если хотите упростить операцию.
Не стесняйтесь просить дальнейших объяснений и / или разъяснений.