虚拟列表控件是具有LVS_OWNERDATA样式的列表视图控件。 此样式使控件能够支持项计数最多为 DWORD (默认项计数仅扩展到一个 int
)。 但是,此样式提供的最大优势是一次只能有一部分数据项。 这样,虚拟列表视图控件就可以与大型信息数据库一起使用,其中已准备好访问数据的特定方法。
注释
除了提供虚拟列表功能之外 CListCtrl
,MFC 还在 CListView 类中提供相同的功能。
开发虚拟列表控件时,应注意一些兼容性问题。 有关详细信息,请参阅 Windows SDK 中 List-View 控件主题的“兼容性问题”部分。
处理LVN_GETDISPINFO通知
虚拟列表控件维护的项信息很少。 除项目选择和焦点信息外,所有项目信息均由控件的所有者管理。 框架通过LVN_GETDISPINFO通知消息请求信息。 若要提供请求的信息,虚拟列表控件(或控件本身)的所有者必须处理此通知。 这可以使用 类向导 轻松完成(请参阅 “将消息映射到函数”)。 生成的代码应类似于以下示例(其中 CMyDialog
拥有虚拟列表控件对象和对话框正在处理通知):
ON_NOTIFY(LVN_GETDISPINFO, IDC_LIST3, &CMyDialog::OnLvnGetdispinfoList3)
在LVN_GETDISPINFO通知消息的处理程序中,必须检查请求的信息类型。 可能的值为:
LVIF_TEXT
必须填充 pszText 成员。LVIF_IMAGE
必须填充 iImage 成员。LVIF_INDENT
必须填充 iIndent 成员。LVIF_PARAM
必须填充 lParam 成员。 (子项不存在)。LVIF_STATE
必须填写状态成员。
然后,应向框架提供请求的任何信息。
以下示例(从列表控件对象的通知处理程序正文中获取)通过提供项的文本缓冲区和图像的信息演示了一种可能的方法:
NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO *>(pNMHDR);
LVITEM *pItem = &(pDispInfo)->item;
int iItem = pItem->iItem;
if (pItem->mask & LVIF_TEXT) //valid text buffer?
{
switch (pItem->iSubItem)
{
case 0: //fill in main text
_tcscpy_s(pItem->pszText, pItem->cchTextMax,
m_Items[iItem].m_strItemText);
break;
case 1: //fill in sub item 1 text
_tcscpy_s(pItem->pszText, pItem->cchTextMax,
m_Items[iItem].m_strSubItem1Text);
break;
case 2: //fill in sub item 2 text
_tcscpy_s(pItem->pszText, pItem->cchTextMax,
m_Items[iItem].m_strSubItem2Text);
break;
}
}
if (pItem->mask & LVIF_IMAGE) //valid image?
{
pItem->iImage = m_Items[iItem].m_iImage;
}
缓存和虚拟列表控件
由于这种类型的列表控件适用于大型数据集,因此建议缓存请求的项数据以提高检索性能。 该框架提供缓存提示机制,通过发送LVN_ODCACHEHINT通知消息来帮助优化缓存。
以下示例使用传递给处理程序函数的范围更新缓存。
void CMyDialog::OnLvnOdcachehintList3(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMLVCACHEHINT pCacheHint = reinterpret_cast<LPNMLVCACHEHINT>(pNMHDR);
// Update the cache with the recommended range.
for (int i = pCacheHint->iFrom; i <= pCacheHint->iTo; i++)
{
m_Items[i].m_iImage = i % 2;
m_Items[i].m_strItemText.Format(_T("Item %d"), i);
m_Items[i].m_strSubItem1Text = _T("Sub 1");
m_Items[i].m_strSubItem2Text = _T("Sub 2");
}
*pResult = 0;
}
有关准备和维护缓存的详细信息,请参阅 Windows SDK 中 List-View 控件主题的“缓存管理”部分。
查找特定项
需要找到特定列表控件项时,虚拟列表控件会发送LVN_ODFINDITEM通知消息。 当列表视图控件收到快速密钥访问或收到LVM_FINDITEM消息时,将发送通知消息。 搜索信息以 LVFINDINFO 结构的形式发送,该结构是 NMLVFINDITEM 结构的成员。 通过重写 OnChildNotify
列表控件对象的函数并在处理程序的正文中检查LVN_ODFINDITEM消息来处理此消息。 如果找到,请执行相应的作。
应准备好搜索与列表视图控件提供的信息匹配的项。 如果成功,则应返回项的索引;如果未找到匹配项,则应返回 -1。