ClistCtrl установить цвет элемента

У меня есть элемент управления ClistView в моем приложении MFC. Мне нужно раскрасить некоторые элементы в соответствии с их содержимым. Например, если он начинается с «Нет ответа на», мне нужно сделать его красным.

До сих пор я пытался

BEGIN_MESSAGE_MAP(CMessageView, CListView)
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW,customDraw)
END_MESSAGE_MAP()

void CMessageView::Update()
{
CListCtrl& refCtrl = GetListCtrl();   
refCtrl.InsertItem(LVIF_TEXT|LVIF_PARAM,0,CTime::GetCurrentTime().Format("%H:%M:%S"),0,0,0,42);
refCtrl.SetItemText(0,1,"some text");
refCtrl.SetItemText(0,2,"No response to open");
}

void CMessageView::customDraw(NMHDR * pNMHDR, LRESULT * pResult)
{
_ASSERTE(*pResult == 0);

NMLVCUSTOMDRAW * pnmlvcd = (NMLVCUSTOMDRAW *)pNMHDR;

DWORD dwDrawStage = pnmlvcd->nmcd.dwDrawStage;

BOOL bSubItem = dwDrawStage & CDDS_SUBITEM;
dwDrawStage &= ~CDDS_SUBITEM;

switch (dwDrawStage)
{
case CDDS_PREPAINT:
    {
        *pResult = CDRF_NOTIFYITEMDRAW;
        break;
    }
case CDDS_ITEMPREPAINT:
case CDDS_SUBITEM:
    {
            if(pnmlvcd->nmcd.lItemlParam == 42)
            {
                pnmlvcd->clrText = RGB(255,0,0);            

            }               
            *pResult = 0;               
        break;
    }
default:
    {
        *pResult = 0;
        break;
    }
}
}

Но это не работает. Цвет не меняется. Я что-то упускаю или делаю что-то не так?


person gorkem    schedule 15.03.2013    source источник
comment
Я делал это с большим успехом в прошлом, но мои дни MFC давно позади. Попробуйте прочитать это и дать вашему обработчику аналогичный код: codeproject.com/Articles/79/   -  person Chad    schedule 15.03.2013
comment
Это проще сделать с помощью CMFCListCtrl   -  person sergiol    schedule 19.12.2016


Ответы (2)


Этот код в простом примере приложения у меня работал. Мой элемент управления списком имеет два столбца и два элемента. Второй элемент, второй столбец имеет данные элемента, установленные на 42, в этом случае только для этого конкретного подэлемента текст был изменен на красный.

void CMFCTestDlg::OnNMCustomdrawList1(NMHDR *pNMHDR, LRESULT *pResult)
{
   NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
   // TODO: Add your control notification handler code here

   *pResult = CDRF_DODEFAULT;

   switch(pLVCD->nmcd.dwDrawStage)
   {
   case CDDS_PREPAINT:
      *pResult = CDRF_NOTIFYITEMDRAW;
      break;

   case CDDS_ITEMPREPAINT:
      *pResult = CDRF_NOTIFYSUBITEMDRAW;
      break;

   case (CDDS_ITEMPREPAINT | CDDS_SUBITEM):
      {
         if(1 == pLVCD->iSubItem)
         {
            if(pLVCD->nmcd.lItemlParam == 42)
            {
               pLVCD->clrText = RGB(255, 0, 0);
            }
         }
      }
      break;
   }
}
person Chad    schedule 15.03.2013
comment
во время отладки мой код доходит только до блока CDDS_ITEMPREPAINT. он никогда не переходит в блок (CDDS_ITEMPREPAINT | CDDS_SUBITEM). Когда я помещаю pLVCD->clrText = RGB(255, 0, 0); в блок CDDS_ITEMPREPAINT ничего не происходит. Кроме того, когда я использую SetTextColor(RGB(255,255,255)) чтобы сделать все записи красными, они остаются черными. - person gorkem; 18.03.2013

Если у вас VS2008 SP1, гораздо проще использовать CMFCListCtrl — у него есть виртуальные функции, которые вы можете переопределить, чтобы установить цвета переднего плана и фона для каждой строки.

person Roger Rowland    schedule 15.03.2013