如何说服 CListCtrl 查看每列(子项)的选择

发布于 2025-01-13 00:04:00 字数 2520 浏览 7 评论 0 原文

我有自己的 CListCtrl (MyList : public CListCtrl) 并且我想显示每列的选择,而不是整行。 我更改了 WM_LBUTTONDOWN 消息和 WM_KEYDOWNMESSAGE 并将当前列设置为 m_iCurCol。 然后我有 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;
}

我显式绘制每一列(仅针对选定的行),但我自己绘制的文本的位置与原始绘制的文本不同。看图片:

“CMyList

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文