RicH and FamouS

       Home         Glosar IT                                                                                                                                                                                                              SUBSCRIBE NOW!
        

11.06.2009

Liste virtuale (C++)

Atunci cand numarul de inregistrari ce trebuie incarcat intr-un control listview devine foarte mare, timpul necesar creste corespunzator. Ce optimizare s-ar putea face in acest caz?
Raspuns: o lista virtuala rezolva problema.

Pe scurt, o lista virtuala este un control listview care are setat stilul LVS_OWNERDATA. Aceasta nu mai trebuie sa tina intern informatiile pentru fiecare item ci doar, de fiecare data cand are nevoie (un item devine vizibil si trebuie afisat), cere aceste informatii ferestrei parinte trimitandu-i mesajul de notificare LVN_GETDISPINFO (via WM_NOTIFY).
Ceea ce avem de facut este:
  1. Setam stilul LVS_OWNERDATA.
  2. Setam numarul de item-uri cu CListCtrl::SetItemCountEx.
  3. Handluim LVN_GETDISPINFO pentru a-i da listei informatiile necesare.

Mai jos este un exemplu simplificat de lista virtuala implementata intr-o clasa derivata din CListView (MFC).

Exemplu
Cod:
// Override CListView::PreCreateWindow
// LVS_OWNERDATA style makes the list virtual
BOOL CVirtualListView::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style |= LVS_REPORT | LVS_OWNERDATA;
return CListView::PreCreateWindow(cs);
}


Cod:

// Just set the virtual list items count
void CVirtualListView::FillList()
{
CListCtrl& list = GetListCtrl();
list.DeleteAllItems();
//...
int nItemsCount = 999999; // this is just an example!
list.SetItemCountEx(dwRecordsCount,
LVSICF_NOSCROLL|LVSICF_NOINVALIDATEALL);
}


Cod:
// LVN_GETDISPINFO notification handler function
// Set the text and icon only for the items which are about to be drawn
void CVirtualListView::OnGetdispinfo(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
LV_ITEM* pItem = &(pDispInfo)->item;

if(pItem->mask & LVIF_TEXT)
{
// Set the text for the given item (use pItem->iItem, pItem->iSubItem, and pItem->pszText).
}
if(pItem->mask & LVIF_IMAGE)
{
// Set the icon for the given item (use pItem->iItem and pItem->iImage).
}
*pResult = 0;
}

    Blog din Moldova    FastCounter 

 
Copyright © 2008-2010 Foster1. All rights reserved.