2015-01-09 5 views
1

У меня в настоящее время проблема с обработчиком события OnNMCustomdrawlistctrlvalues ​​(), который вызывается без остановок, как только я нарисовал строку CListCtrl красным цветом (код застревает), в результате чего мое приложение чтобы заморозить один раз, когда я пытаюсь выполнить другое событие, например, нажать кнопку.MFC CListCtrl CustomDraw() код обработчика события застревает

У меня есть следующий код:

void CSPID_FQA_Test_ClientDlg::OnNMCustomdrawlistctrlvalues(NMHDR *pNMHDR, LRESULT *pResult) 
{ 
    LPNMLVCUSTOMDRAW lpLVCustomDraw = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR); 
    int itemCnt = 0; 
    CString text; 
    RECT rc; 

    switch(lpLVCustomDraw->nmcd.dwDrawStage) 
    { 
    case CDDS_ITEMPREPAINT: 
    case CDDS_ITEMPREPAINT | CDDS_SUBITEM: 
     //get each row text for 2nd column 
     itemCnt = mListCtrl.GetItemCount(); 
     for (int i = 0; i < itemCnt; i++) 
     { 
      text = mListCtrl.GetItemText(i, 2); 
      if (text.Compare("No") == 0) 
      { 
       if (i == (lpLVCustomDraw->nmcd.dwItemSpec)) 
       { 
        lpLVCustomDraw->clrTextBk = RGB(255,50,50); 
        mListCtrl.GetItemRect(i,&rc,LVIR_BOUNDS); 
        mListCtrl.InvalidateRect(&rc, 0); 
       } 
      } 
     } 
     break; 
    default: break; 
    } 

    *pResult = 0; 
    *pResult |= CDRF_NOTIFYITEMDRAW; 
    *pResult |= CDRF_NOTIFYSUBITEMDRAW; 
    *pResult |= CDRF_NOTIFYPOSTPAINT; 
} 

что приводит:

result1

В рамках CListCtrl, если я выделите область, которая не окрашены в красный цвет, мое приложение хорошо.

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


EDIT: Я изменил мой код ниже, но я испытываю эту проблему (только вторая и третья колонна цвета, но когда я перерисовки контрольный список т.е. прокрутки вниз, а затем обратно вверх, все столбцы затем вытягивают):

result2

void CSPID_FQA_Test_ClientDlg::OnNMCustomdrawlistctrlvalues(NMHDR *pNMHDR, LRESULT *pResult) 
{ 
    LPNMLVCUSTOMDRAW lpLVCustomDraw = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR); 
    int itemCnt = 0; 
    CString text; 
    RECT rc; 

    CDC* pDC = CDC::FromHandle (lpLVCustomDraw->nmcd.hdc); 

    switch(lpLVCustomDraw->nmcd.dwDrawStage) 
    { 
    case CDDS_ITEMPOSTPAINT: 
    //case CDDS_ITEMPREPAINT: 
    //case CDDS_ITEMPREPAINT | CDDS_SUBITEM: 
     //get each row text for 2nd column 
     itemCnt = mListCtrl.GetItemCount(); 
     for (int i = 0; i < itemCnt; i++) 
     { 
      text = mListCtrl.GetItemText(i, 2); 
      if (text.Compare("No") == 0) 
      { 
       if (i == (lpLVCustomDraw->nmcd.dwItemSpec)) 
       { 
        //lpLVCustomDraw->clrTextBk = RGB(255,50,50); 
        mListCtrl.GetItemRect(i,&rc,LVIR_BOUNDS); 
        pDC->FillSolidRect (&rc, RGB (0, 255, 0)); 

        //mListCtrl.InvalidateRect(&rc, 0); 
       } 
      } 
     } 
     break; 
    default: break; 
    } 

    *pResult = 0; 
    *pResult |= CDRF_NOTIFYITEMDRAW; 
    *pResult |= CDRF_NOTIFYSUBITEMDRAW; 
    *pResult |= CDRF_NOTIFYPOSTPAINT; 
} 

EDIT2: я изменил код ниже, но я все еще получаю один и тот же вопрос:

LPNMLVCUSTOMDRAW lpLVCustomDraw = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR); 
CString text; 
RECT rc; 

CDC* pDC = CDC::FromHandle (lpLVCustomDraw->nmcd.hdc); 

switch(lpLVCustomDraw->nmcd.dwDrawStage) 
{ 
case CDDS_ITEMPOSTPAINT: 

    mListCtrl.GetItemRect(lpLVCustomDraw->nmcd.dwItemSpec,&rc,LVIR_BOUNDS); 
    text = mListCtrl.GetItemText(lpLVCustomDraw->nmcd.dwItemSpec, 2); 

    if (text.Compare("No") == 0) 
    { 
     pDC->FillSolidRect (&rc, RGB(0, 0, 255)); 
    } 

    break; 
default: break; 
} 

result3

+5

Этот код который вызывается как часть чертежа элемента списка; вызывая 'InvalidateRect', вы вызываете повторное выполнение чертежа. Бесконечная петля! –

+0

Привет @MarkRansom, спасибо за ответ! Ах, конечно. Я прокомментировал строку 'InvalidateRect' и остановился. Я получаю следующий результат при рисовании (но правильно перерисовывается, если я прокручиваю вниз и снова возвращаюсь) - http://i.imgur.com/umiH6zI.png Любая идея, как это исправить? – LKB

+0

Если бы я знал, как это исправить, я бы оставил ответ вместо комментария. Небольшое экспериментирование должно привести вас к решению. –

ответ

1

Я думаю, что ваш дизайн немного не используя CDDS_ITEMPREPAINT. Я использую пользовательскую покраску, чтобы выделить строку в CListCtrl, чтобы цвет был желтым. Я делаю это, используя CDDS_ITEMPOSTPAINT и используя FillSolidRect и DrawText методы CDC. Как отмечал Марк, некоторые простые эксперименты (с тем, что я опубликовал в этом ответе) должны помочь.

Edit: Используя CDDS_ITEMPOSTPAINT, вы можете получить контекст устройства с помощью

CDC* pDC = CDC::FromHandle (pNMLVCD->nmcd.hdc); 

Получение строки corodinates, что вы хотите, чтобы нарисовать можно сделать

GetItemRect (row, &rect, LVIR_BOUNDS); 

Rendering цвет строка сделано по

pDC->FillSolidRect (&rect, RGB (0, 255, 0)); 

И, наконец, нарисуйте текст каждого столбца на

// draw each column's text into the corresponding CRect. 
for (col=0; col<nCols; ++col) 
    { 
    GetSubItemRect (row, col, LVIR_BOUNDS, rect); 
    rect.left += 6; 
    CString text = pRow->GetColumnText (col); 
    pDC->DrawText (text, &rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE); 
    } 

Необходимо выполнить необходимые корректировки вышеуказанного кода в соответствии с вашими потребностями.

+0

Спасибо за ваш ответ! Можете ли вы поделиться некоторыми фрагментами кода? – LKB

+1

@LBran См. Обновление для ответа. – rrirower

+0

Спасибо за это! Я выполнил некоторые из ваших кодов (см. Мой обновленный пост), я не беспокоился о текстовом чертеже, но это то, что я получаю (это та же проблема, что и у меня выше). http://i.imgur.com/4RREvcp.png С этим тоже случается? – LKB

1

Попробуйте это:

void ColorListCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult) 
{ 
    NMLVCUSTOMDRAW *pNMLVCUSTOMDRAW = (NMLVCUSTOMDRAW *) pNMHDR; 
    *pResult = CDRF_DODEFAULT; 
    switch (pNMLVCUSTOMDRAW->nmcd.dwDrawStage) 
    { case CDDS_PREPAINT: 
      *pResult |= CDRF_NOTIFYITEMDRAW; 
      break; 
     case CDDS_ITEMPREPAINT: 
      // compare text in column 2 
      // set background to special color if matches 
      INT nItem = pNMLVCUSTOMDRAW->nmcd.dwItemSpec; 
      CString strText = GetItemText(nItem, 2); 
      if (strText==_T("No")) pNMLVCUSTOMDRAW->clrTextBk = RGB(255,0,0); 
      break; 
    } 
} 
+0

Спасибо за ваш ответ! Я реализовал ваш код, и он отлично работает, за исключением того, что я все еще получаю ту же проблему, что и выше, аналогично этому: i.imgur.com/4RREvcp.png – LKB

+0

@LBran. Ваше изображение показывает, что текст в столбцах отсутствует , это может произойти только с «FillSolidRect» в событии после крашения, как указано в вашем коде в EDIT2 исходного сообщения. Требование отмечать элементы с другим цветом на самом деле довольно просто, нужно только изменить цвет в структуре пользовательского рисования, рисование/заполнение не требуется, потому что следующий рисунок по умолчанию будет обрабатывать остальные. Есть ли другой код чертежа где-то еще, что вы забыли? – mfc