`
javababy1
  • 浏览: 1171709 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

list control的用法(三)--virtual List

 
阅读更多

    • LVIF_TEXTThepszTextmember must be filled in.
    • LVIF_IMAGETheiImagemember must be filled in.
    • LVIF_INDENTTheiIndentmember must be filled in.
    • LVIF_PARAMThelParammember must be filled in.
    • LVIF_STATEThestatemember must be filled in.
  • Virtual List Controls

    Visual Studio 2005

    Other Versions

    A virtual list control is a list view control that has theLVS_OWNERDATAstyle. This style enables the control to support an item count up to aDWORD(the default item count only extends to anint). However, the biggest advantage provided by this style is the ability to only have a subset of data items in memory at any one time. This allows the virtual list view control to lend itself for use with large databases of information, where specific methods of accessing data are already in place.

    Note

    In addition to providing virtual list functionality inCListCtrl, MFC also provides the same functionality in theCListViewclass.

    There are some compatibility issues you should be aware of when developing virtual list controls. For more information, see the Compatibility Issues section of the List-View Controls topic in thePlatform SDK.

    Handling the LVN_GETDISPINFO Notification

    Virtual list controls maintain very little item information. Except for the item selection and focus information, all item information is managed by the owner of the control. Information is requested by the framework via aLVN_GETDISPINFOnotification message. To provide the requested information, the owner of the virtual list control (or the control itself) must handle this notification. This can easily be done using the Properties window (seeMapping Messages to Functions). The resultant code should look something like the following example (whereCMyListCtrlis the virtual list control object and the control is handling the notification):

    Copy

    BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
    ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetdispinfo)
    END_MESSAGE_MAP()

    In the handler for theLVN_GETDISPINFOnotification message, you must check to see what type of information is being requested. The possible values are:

    You should then supply whatever information is requested back to the framework.

    The following example (taken from the body of the notification handler for the list control object) demonstrates one possible method by supplying information for the text buffers and image of an item:

    Copy

    LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
    LV_ITEM* pItem= &(pDispInfo)->item;

    int iItemIndx= pItem->iItem;

    if (pItem->mask & LVIF_TEXT) //valid text buffer?
    {
    switch(pItem->iSubItem){
    case 0: //fill in main text
    lstrcpy(pItem->pszText,
    m_Items[iItemIndx].m_strItemText);
    break;
    case 1: //fill in sub item 1 text
    lstrcpy(pItem->pszText,
    m_Items[iItemIndx].m_strSubItem1Text);
    break;
    case 2: //fill in sub item 2 text
    lstrcpy(pItem->pszText,
    m_Items[iItemIndx].m_strSubItem2Text);
    break;
    }
    }

    if pItem->mask & LVIF_IMAGE) //valid image?
    pItem->iImage=
    m_Items[iItemIndx].m_iImageIndex;

    Caching and Virtual List Controls

    Because this type of list control is intended for large data sets, it is recommended that you cache requested item data to improve retrieval performance. The framework provides a cache-hinting mechanism to assist in optimizing the cache by sending anLVN_ODCACHEHINTnotification message. However, you must use a slightly different method to handle this notification. Using the Properties window, override theOnChildNotifyfunction of your list control object. In the case of this example,CMyListCtrl.

    Inside the body of the handler, check for theLVN_ODCACHEHINTmessage and, if found, prepare your cache.

    The following example (taken from the body of theOnChildNotifyfunction) performs this check and calls thePrepCachemember function of theCMyListCtrlclass.

    Copy

    NMLVCACHEHINT* pcachehint=NULL;

    if (message == WM_NOTIFY)
    {
    NMHDR* phdr = (NMHDR*)lParam;

    switch(phdr->code)
    {
    case LVN_ODCACHEHINT:
    pcachehint= (NMLVCACHEHINT*) phdr;
    // Load the cache with the recommended range.
    PrepCache(pcachehint->iFrom, pcachehint->iTo);
    break;
    default:
    return CListCtrl::OnChildNotify(message, wParam, lParam, pLResult);
    }
    return FALSE;
    }
    else
    return CListCtrl::OnChildNotify(message, wParam, lParam, pLResult);

    Notice that the notification is passed on to the base class (CListCtrl) if the message type is notLVN_ODCACHEHINT. For more information on preparing and maintaining a cache, see the Cache Management section of the List-View Controls topic in thePlatform SDK.

    Finding Specific Items

    TheLVN_ODFINDITEMnotification message is sent by the virtual list control when a particular list control item needs to be found. The notification message is sent when the list view control receives quick key access or when it receives anLVM_FINDITEMmessage. Search information is sent in the form of anLVFINDINFOstructure, which is a member of theNMLVFINDITEMstructure. Handle this message by overriding theOnChildNotifyfunction of your list control object and inside the body of the handler, check for theLVN_ODFINDITEMmessage. If found, perform the appropriate action.

    You should be prepared to search for an item that matches the information given by the list view control. You should return the index of the item if successful, or -1 if no matching item is found.

    See Also

    Reference

    Using CListCtrl

    Concepts

    Controls (MFC)

    源文档 <http://msdn.microsoft.com/en-us/library/ye4z8x58(v=vs.80).aspx>

Virtual List的使用方法

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;

}

}

*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;

}while(currentPos != startPos);

}

使用Virtual List后的效果令我很满意,但我还是不明白普通list ctrl为什么插入速度这么慢?普通list ctrl的插入操作做了些什么呢?

源文档 <http://blog.vckbase.com/zgf/archive/2005/11/25/15271.aspx>

虚拟列表的使用 virtual list usage

使用listview 操作大量的数据的时候,使用virtual list 是必要的。使用方法比较简单。

1、创建控件的时候制定LVS_OWNERDATA

2、添加 notification LVN_GETDISPINFO 的响应函数 ,在消息映射处加入 ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetDispInfo)

3、 一个OnGetDispInfo 的例子:

void CVirtualListView::OnGetDispInfo(NMHDR* pNMHDR, LRESULT* pResult)

{

LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;

TCHAR szValue[MAX_PATH];

try

{

long index = pDispInfo->item.iItem;

long subItem = pDispInfo->item.iSubItem;

sprintf(szValue, "[%d].[%d]" , index , subItem );

strcpy (pDispInfo->item.pszText, szValue );

} catch (... ) {

}

*pResult = 0;

}

4. 通过 CListCtrl 的 SetItemCount 函数来设置Item 的数目。或者直接向控件发送LVM_SETITEMCOUNT 消息来完成设置,其实是一样的。 :)

5、

两个通知是虚列表特有的。第一个,LVN_ODFINDITEM,在控件要查找一个特定的项时被发送;例如当输入焦点在控件上时,用户输入了一些东西。这个通知的lParam 是一个指向NMLVFINDITEM结构的指针。这个结构包含一个NMHDR结构 (hdr)、一个查找起始项的索引和一个LVFINDINFO(以前的LV_FINDINFO)结构(lvfi)。这个信息提供给你,使得你可以查找指定的列表项。你应该返回找到的列表项的索引,或者-1(如果没有找到)。

第二个通知是LVN_ODCACHEHINT。 这个通知在列表将要显示某个范围内的列表项时发送。这个通知的lParam 是一个指向NMLVCACHEHINT结构的指针。这个结构包含一个NMHDR结构 (hdr)、一个指出范围的开始,的整数,和一个指出范围的结束的整数。处理这个通知,你需要载入指定的列表项到本地缓存,如果你正在维护一个的话。控件为未缓存的列表项仍可能发送LVN_GET-DISPINFO,所以你的应用程序必须考虑这种情况

6.响应LVN_ODCACHEHINT消息

这个消息用来缓存请求项的数据.我没用到这个消息,因为我已一次将所有数据读入内存.

7.响应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;

}while(currentPos != startPos);

源文档 <http://www.cnblogs.com/vingo888/archive/2006/01/10/314720.html>

分享到:
评论

相关推荐

    网格控件Virtual Grid Control 1.4

    It is a very simple grid.... If you don't understand my explanation of control's "virtuality", then I'd recommend you to read "Virtual list view description" of CListCtrl in the MSDN help

    Virtual-Grid-Control.rar_CVirtualGridCtrl_control_grid_vc grid_虚

    vc++的virtual grid control。和mfc的虚拟list control类似,但是是独立实现。对学习表格控件的设计与实现有帮助。

    MFC ListCtrl 虚表实现

    Virtual List的实现和使用例子; Virtual List 和List Ctrl的性能比较

    virtual listctrl

    当有大数据量要加载到Listctrl列表中时,Listctrl或加载,或刷新都会特别慢,虚拟列表可以加速其显示和刷新。

    test_list_control_mfc虚拟列表_MFClist_visualc++_MFClistctrl_listcont

    MFC虚拟列表 Virtual listctrl

    F5 GTM IControl 配置管理工具

    --datalist Get DataCenter List --dataserverlist Get Server Of DataCenter ,eg.(--dataserverlist DataCenterName) --datacreate DataCenter Create,eg.(--datacreate DataCenterName,Location,Contact) --...

    开源在线代理glype

    This package contains the source code files for the script, a control panel for managing your proxy site and a number of the additional files to help with customizing your proxy. /extras/ - ...

    qemu-0.13.0(编译过全处理器支持)

    for list) -cpu cpu select CPU (-cpu ? for list) -smp n[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets] set the number of CPUs to 'n' [default=1] maxcpus= maximum number of total ...

    Ezmlmmanager

    Displays a table with the lists already ... - Support for list virtual hosts. - Multi-idiom Web interface. - Web service interface with SOAP protocol to control mailing list subscriptions remotely.

    Qemu-1.0.1 for windows

    for list) property accel=accel1[:accel2[:...]] selects accelerator supported accelerators are kvm, xen, tcg (default: tcg) -cpu cpu select CPU (-cpu ? for list) -smp n[,maxcpus=cpus][,cores=cores]...

    Bochs - The cross platform IA-32 (x86) emulator

    - Ported most of Qemu's 'virtual VFAT' block driver (except runtime write support, but plus FAT32 suppport) - Added write protect option for floppy drives. - Bugfixes / improved internal debugger + ...

    FlexGraphics_V_1.79_D4-XE10.2_Downloadly.ir

    - ADD: Add TFlexPanel.InvalidateControl virtual method which calls from TFlexControl.Invalidate and can be overriden (it is possible now to catch all object invalidation calls). - FIX: The TFlexPanel....

    OpenStack Virtual Machine Image Guide

    List or get details for images (glance) Create or update an image (glance) Troubleshoot image creation Requirements External Requirements Affecting Glance Guideline to include your requirement in the ...

    Senfore_DragDrop_v4.1

    * Virtual File Stream formats can only be pasted from the clipboard with live data (i.e. FlushClipboard/OleFlushClipboard hasn't been called on the data source). This problem affects ...

    Android 8.0 compatibility list

    5.1.8. Video Codecs List 5.2. Video Encoding 5.2.1. H.263 5.2.2. H-264 5.2.3. VP8 5.2.4. VP9 5.3. Video Decoding 5.3.1. MPEG-2 5.3.2. H.263 5.3.3. MPEG-4 5.3.4. H.264 5.3.5. H.265 (HEVC) 5.3.6. VP8 ...

    PETools源码

    DDX_Control(pDX, IDC_LIST2, m_ListCtrl2); DDX_Control(pDX, IDC_LIST1, m_ListCtrl1); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CImportTable, CDialog) //{{AFX_MSG_MAP(CImportTable) ON_NOTIFY(NM_CLICK,...

    The Indispensable PC Hardware Book - rar - part1. (1/7)

    Virtual machines and virtual 8086 monitors. Addresses in virtual 8086 mode. Entering and leaving virtual 8086 mode. Tasks in virtual 8086 mode. 7. Quick buffering: caching. Cache principle and ...

    Visual C++ 编程资源大全(英文源码 控件)

    PropertyListCtrl.zip An object properties list control than can change based on the objects state.(64KB)&lt;END&gt;&lt;br&gt;87,supergrid.zip A combination list control and tree control with checkbox ...

    Devexpress agmenu &agDataGrid8.2.8 for silverlight3.0

    Submenu Scrolling - if a child list doesn't fit into the browser window, scroll buttons allow end-users to access all commands in that list. (Screenshot) Checked Items - menu items can support ...

    ProjectOZ

    %path% nmake -nologo x86= &lt;br&gt;To get on the list for notification of updates contact me directly, or if you'd rather poll -- just check the curriculum website periodically. &lt;br&gt; ...

Global site tag (gtag.js) - Google Analytics