1

我目前遇到问题,一旦我将 CListCtrl 行涂成红色(代码卡住),我的 OnNMCustomdrawlistctrlvalues() 事件处理程序就被不间断地调用,导致我的应用程序在我尝试执行另一个事件时冻结,例如单击一个按钮。

我有以下代码:

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;
}

结果是:

结果1

在 CListCtrl 中,如果我滚动到未涂成红色的区域,我的应用程序就可以了。

我不太确定如何阻止这种情况的发生......也许我需要另一种方法来动态地将一行画成红色?


编辑:我已将代码更改为以下,但遇到了这个问题(只有第 2 列和第 3 列被着色,但是当我重绘列表控件时,即向下滚动然后向上滚动,然后绘制所有列):

结果2

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;
}

结果3

4

2 回答 2

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;
    }
}
于 2015-02-02T05:09:31.603 回答
1

我认为您的设计因使用 CDDS_ITEMPREPAINT 而略有偏差。我使用自定义绘画将 CListCtrl 中的一行突出显示为黄色。我通过利用CDDS_ITEMPOSTPAINT并使用 CDC 的FillSolidRectDrawText方法来做到这一点。正如马克所暗示的那样,一些简单的实验(我在这个答案中发布的内容)应该会有所帮助。

编辑:使用 CDDS_ITEMPOSTPAINT,您可以通过以下方式获取设备上下文

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

获取要绘制的行坐标可以通过

GetItemRect (row, &rect, LVIR_BOUNDS);

渲染行颜色由

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);
    }

您需要对上述代码进行必要的调整以满足您的需求。

于 2015-01-09T15:23:18.537 回答