您的位置:首页 > 其它

WTL - Virtual List Controls(WTL下使用虚拟列表)

2015-02-02 03:14 531 查看
普通的 CListCtrl 在其数据达到10000以上时,拖动滚动条已卡,很不好。。

Virtual List Controls,虚拟列表,我认为是一种列表的显示方式。。

普通列表:所有的列表数据加载完成再显示。

虚拟列表:只加载当前指定的要显示的数据(当收到 LVN_GETDISPINFO 消息时,会刷新列表,只刷新要显示的部分 )。

很明显,当数据量大的时候,谁优谁劣。。

比起 MFC,我更喜欢轻量级 WTL,就用 WTL 做个例子吧。。

1、新建 WTL 工程:



2、拖出列表控件 List Control:

我设其 ID 为 IDC_LIST_LOVE,View
为 Report,Owner Data
为 True



3、用 WTL 的 CListViewCtrl 去关联这个列表 IDC_LIST_LOVE,并插入列:

我设了个 CListViewCtrl 的成员变量 m_lvcLove

//set virtual list
m_lvcLove.Attach(GetDlgItem(IDC_LIST_LOVE));
m_lvcLove.AddColumn(_T("海誓山盟"), 0);
m_lvcLove.AddColumn(_T("往事如烟"), 1);
4、消息宏中关联 LVN_GETDISPINFO 消息、列表 ID 和响应函数:

NOTIFY_HANDLER(IDC_LIST_LOVE, LVN_GETDISPINFO, OnGetDispInfo)
5、完成响应函数:

pItem 在这里就是列表控件的单元格,要想列表的这个单元格显示什么,就对 pItem 进行什么样的操作,至于 pItem 是如何显示在列表上的,并不用我们写在代码中

pItem->mask 是显示内容的标志,指定要显示图标、文字或是其他

pItem->iItem 是列表控件的行号(从0开始)

pItem->iSubItem 是列表控件的列号(从0开始)

LRESULT CMainDlg::OnGetDispInfo(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pnmh);
LV_ITEM* pItem = &(pDispInfo)->item;
int nItem = pItem->iItem;

if (pItem->mask & LVIF_TEXT) //valid text buffer?
{
switch (pItem->iSubItem)
{
case 0: //fill in main text
lstrcpy(pItem->pszText, m_vtLove[nItem].strSaying);
break;
case 1: //fill in sub item 1 text
lstrcpy(pItem->pszText, m_vtLove[nItem].strHistory);
break;
}
}

return 0;
}
6、主动触发列表更新(SetItemCount 非常关键,这会触发 LVN_GETDISPINFO 消息):

我用了一个Add Data 的按钮,每按一次加入1000条数据

LRESULT CMainDlg::OnAddData(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
int nBase = m_vtLove.size();

for (int i = 0; i < ADD_COUNT_ONE_TIME; ++i)
{
CString strHistory;
strHistory.Format(_T("%d days"), nBase + i);
m_vtLove.push_back(LOVEITEM(_T("I love you"), strHistory));
}
m_lvcLove.SetItemCount(m_vtLove.size());

return 0;
}
7、看看效果吧:

我点了10次,加了10000条数据,随便拉滚动条,一点都不卡。。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: