WTL - Virtual List Controls(WTL下使用虛擬列表)

普通的 CListCtrl 在其數據達到10000以上時,拖動滾動條已卡,很不好。。

Virtual List Controls,虛擬列表,我認爲是一種列表的顯示方式。。

普通列表:所有的列表數據加載完成再顯示。

虛擬列表:只加載當前指定的要顯示的數據(當收到 LVN_GETDISPINFO 消息時,會刷新列表,只刷新要顯示的部分 )。

很明顯,當數據量大的時候,誰優誰劣。。

比起 MFC,我更喜歡輕量級 WTL,就用 WTL 做個例子吧。。

1、新建 WTL 工程:


2、拖出列表控件 List Control:

我設其 ID 爲 IDC_LIST_LOVE,View ReportOwner 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條數據,隨便拉滾動條,一點都不卡。。微笑


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章