VirtualList的使用方法

VirtualList的使⽤⽅法
Virtual List(虚拟列表)是LVS_OWNERDATA 样式的List Ctrl.默认的List Ctrl在插⼊⼤量的数据时会变得很慢.在我的破机器上插⼊不到⼀万⾏的数据要⼏⼗秒,⾮常令⼈不爽.⽽⽤Virtual List可以⼤⼤加快速度。Virtual List不拥有数据,当需要显⽰⼀⾏时才发消息向⽗窗⼝查询显⽰内容。Virtual List的使⽤⽅法与普通List Ctrl稍微有点不同。它有三个重要的消息LVN_GETDISPINFO,LVN_ODCACHEHINT和
LVN_ODFINDITEM。响应这三个消息是关键。
1.创建Virtual List
只需添加LVS_OWNERDATA风格到List Ctrl就⾏了。
m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_OWNERDATA);
2.添加,删除和更改⼀⾏
添加:因为Virtual List不拥有数据,数据存在外部(如:数据库),所以你只需将数据添加到外部,然后m_list.SetItemCount(list_size+1)告诉Virtual List⾏数加⼀。这样Virtual List会更改滚动条的样⼦,以便看上去添加了⼀⾏.
删除:先在外部数据中删除⾏,然后m_list.SetItemCount(list_size-1)更改滚动条.
更改:直接修改在外部数据中的⾏.
如果这些⾏是正在显⽰的⾏,则需要调⽤m_list.RedrawItems(nFirst,nLast)
3.响应LVN_GETDISPINFO消息
当Virtual List需要显⽰⼀⾏数据时,它发送这个消息给⽗窗⼝询问数据内容.⽗窗⼝收到消息后从传过来参数中知道Virtual List现在显⽰的是第⼏项,第⼏列,内容是什么类型.然后⽗窗⼝在外部数据中到数据内容,将它返回给Virtual List.
先添加消息映射,这⾥⽤的是反射消息,可以减少控件于⽗窗⼝之间的耦合度
BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetdispinfo)
END_MESSAGE_MAP()
相应的响应函数
void CMyListCtrl::OnGetdispinfo(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
LV_ITEM* pItem= &(pDispInfo)->item;
int iItemIndx= pItem->iItem;
北京德科岛金if (pItem->mask & LVIF_TEXT)
{
switch(pItem->iSubItem)
{
case 0:
{
memcpy(pItem->pszText,(find_index + iItemIndx)->code,8);
*(pItem->pszText+8) = 0;
}
break;
case 1:
{
memcpy(pItem->pszText,(find_index + iItemIndx)-
>description,INDEX_DESLEN);
*(pItem->pszText+INDEX_DESLEN) = 0;
}
电子蜡烛灯break;
}
}
dingx*pResult = 0;
}
4.响应LVN_ODCACHEHINT消息甲基化学式
这个消息⽤来缓存请求项的数据.我没⽤到这个消息,因为我已⼀次将所有数据读⼊内存.
5.响应LVN_ODFINDITEM消息
在资源管理器中浏览⽂件时,让焦点list上,然后在键盘上输⼊⽂件名.资源管理器会⾃动到并选中与之最相近的⽂件.LVN_ODFINDITEM就是实现这个功能的.当焦点在list上时,按键操作会使Virtual List发送LVN_ODFINDITEM给⽗窗⼝.⽗窗⼝到相应项并将它选中.
BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
ON_NOTIFY_REFLECT(LVN_ODFINDITEM, OnOdfinditemList)
END_MESSAGE_MAP()
豆奶机void CMyListCtrl::OnOdfinditemList(NMHDR* pNMHDR, LRESULT* pResult)
{
// pNMHDR has information about the item we should find
// In pResult we should save which item that should be selected
NMLVFINDITEM* pFindInfo = (NMLVFINDITEM*)pNMHDR;
*pResult = -1; // *pResult = -1 表明没有到
if( (pFindInfo->lvfi.flags & LVFI_STRING) == 0 )
return;
int nlen = _tcslen(pFindInfo->lvfi.psz);
int startPos = pFindInfo->iStart;
/
/Is startPos outside the list (happens if last item is selected)
if(startPos >= m_list.GetItemCount())
startPos = 0;
int currentPos=startPos;
do
{
if(memcmp((find_index + startPos ),pFindInfo->lvfi.psz,nlen) == 0)
{
*pResult = currentPos;
break;
}
currentPos++;
if(currentPos >= m_list.GetItemCount())
currentPos = 0;27.5g bt
}while(currentPos != startPos);
}
使⽤Virtual List后的效果令我很满意,但我还是不明⽩普通list ctrl为什么插⼊速度这么慢?普通list ctrl的插⼊操作做了些什么呢?

本文发布于:2024-09-21 15:38:21,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/4/161293.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数据   消息   找到   内容   添加   功能   拥有   资源管理
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议