如何为不可见的列优化 CListCtrl LVN_GETDISPINFO?

Posted

技术标签:

【中文标题】如何为不可见的列优化 CListCtrl LVN_GETDISPINFO?【英文标题】:How to optimize CListCtrl LVN_GETDISPINFO for non-visible columns? 【发布时间】:2014-10-20 23:15:59 【问题描述】:

使用 LVS_OWNERDATA CListCtrl 的列多于屏幕上可见的列,我如何优化 LVN_GETDISPINFO 回调以尽可能少地为当前不可见的列(子项)做一些工作,因为它们从左侧滚动或右边缘?

如果不转到 OwnerDraw,我可以阻止框架为不在屏幕上的列调用 LVN_GETDISPINFO 吗?

在 LVN_GETDISPINFO 或 LVN_ODCACHEHINT 回调中计算哪些列(子项)可见的最佳方法是什么?

【问题讨论】:

【参考方案1】:

不,您不能阻止 ListView 为非可视列请求数据。但是您可以使用LVM_GETSUBITEMRECT 来确定给定的子项是否超出了 ListView 可见客户区的范围。

【讨论】:

在 LVN_ODCACHEHINT 消息上使用 GetSubItemRect 添加对列可见性的检查效果很好,我应该能够处理重新排序的列。我遇到了一个建议,只对左右边缘使用 LVM_HITTEST,但这很好用。【参考方案2】:

检查 LVN_GETDISPINFO 中 iSubitem 的列标题项矩形,并与滚动位置进行比较以跳过不可见列的工作

// In LVN_GETDISPINFO handler...
NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
if (pDispInfo->item.mask & LVIF_TEXT) 
    CRect myListRect, headerRect; 
    myList.GetClientRect(&myListRect);
    myList.GetHeaderCtrl()->GetItemRect(pDispInfo->item.iSubitem,&headerRect);
    int hScrollPos = myList.GetScrollPos(SB_HORIZ);

    if(headerRect.right < hScrollPos || headerRect.left > hScrollPos + myListRect.right) 
        strcpy_s(pDispInfo->item.pszText,pDispInfo->item.cchTextMax,"");
        *pResult = 0;
        return;
    
    // else, build response string

【讨论】:

以上是关于如何为不可见的列优化 CListCtrl LVN_GETDISPINFO?的主要内容,如果未能解决你的问题,请参考以下文章

MFC中CListCtrl添加复选框,实现单选

MFC中CListCtrl添加复选框,实现单选

如何通过点击“取消”键取消 CListCtrl 中的编辑?

具有 LVS_EX_CHECKBOXES 样式的 CListCtrl

使用 LVS_OWNERDATA 模式的 LVN_GETDISPINFO 消息中没有 LVIF_TEXT

如何避免CListCtrl项部分可见?