5

I have my own CListCtrl (MyList : public CListCtrl) and I want to show selection for each column, not for entire row. I changed WM_LBUTTONDOWN message and WM_KEYDOWNMESSAGE and set current column to m_iCurCol. And then I have CMyList::OnNMCustomdraw:

void CMyList::OnNMCustomdraw(NMHDR* pNMHDR, LRESULT* pResult)
{
    LPNMLVCUSTOMDRAW pLVCD = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);
    *pResult = 0;
    int i = 0;
    if (pLVCD->nmcd.dwDrawStage == CDDS_PREPAINT)
        *pResult = CDRF_NOTIFYITEMDRAW;          // ask for subitem notifications.
    else if (pLVCD->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
    {
        if (pLVCD->nmcd.uItemState & CDIS_SELECTED)
            *pResult = CDRF_NOTIFYPOSTPAINT;
    }
    else if (pLVCD->nmcd.dwDrawStage == CDDS_ITEMPOSTPAINT)
    {
        LVITEM rItem;
        int    nItem = static_cast<int>(pLVCD->nmcd.dwItemSpec);

        ZeroMemory(&rItem, sizeof(LVITEM));
        rItem.mask = LVIF_IMAGE | LVIF_STATE;
        rItem.iItem = nItem;
        rItem.stateMask = LVIS_SELECTED;
        GetItem(&rItem);

        // If this item is selected, erase original selection and draw new selection rectangle only for selected column
        if (rItem.state & LVIS_SELECTED)
        {
            CDC* pDC = CDC::FromHandle(pLVCD->nmcd.hdc);
            CRect rcColumn, rcRow;

            // Get the rect that holds the item's icon.
            GetSubItemRect(nItem, m_iCurCol, LVIR_LABEL, rcColumn);
            GetItemRect(nItem, rcRow, LVIR_BOUNDS);
            pDC->FillSolidRect(rcRow, RGB(255, 255, 255));
            pDC->FillSolidRect(rcColumn, RGB(0, 191, 255));
            CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
            for (int iCol = 0; iCol < pHeader->GetItemCount(); ++iCol)
            {
                if (iCol == m_iCurCol)
                    pDC->SetTextColor(RGB(255, 255, 255));
                else
                    pDC->SetTextColor(RGB(0, 0, 0));
                GetSubItemRect(nItem, iCol, LVIR_LABEL, rcColumn);
                rcColumn.left += 5;
                pDC->DrawText(GetItemText(nItem, iCol), rcColumn, DT_VCENTER);
            }
            *pResult = CDRF_SKIPDEFAULT;
        }
    }
    else
        *pResult = CDRF_DODEFAULT;
}

I explicitly draw each column (for selected row only), but position of my own drawn text is different like original drawn text. See picture:

CMyList result

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
Michal Hadraba
  • 347
  • 1
  • 11
  • 3
    Use `CMFCListCtrl` instead and derive your own class from there. There are methods you can use for specifying the color of each cell. `OnGetCellBkColor` and `OnGetCellTextColor`. So in function of current cell being selected, you can go with your own colors. You will not even need to make it Custom Draw. – sergiol Mar 09 '22 at 20:03
  • [`The custom-drawn TreeList Control sample`](https://stackoverflow.com/a/20393973/15511041) doesn't have the problem. – YangXiaoPo-MSFT Mar 10 '22 at 02:47
  • 1
    But I wrote about CListCtrl, nor CTreeList – Michal Hadraba Mar 10 '22 at 06:59
  • I suppose custom draw is uniform such as content aligning, etc. – YangXiaoPo-MSFT Mar 10 '22 at 09:34
  • For example, According to that sample, It's needed to reposuition the viewport with SetViewportOrgEx. – YangXiaoPo-MSFT Mar 18 '22 at 09:47

0 Answers0