虚拟列表控件

虚拟列表控件是具有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。

另请参阅

使用 CListCtrl
控件