Link to home
Start Free TrialLog in
Avatar of MadSerb
MadSerb

asked on

Very long MFC CListCtrl lists ?

I want to use CListCtrl list with many items (e.g. more then 30000), but it is impossible or very slow. Is there any solution for this problem? I will accept solutions with some other control, but with similar functionality.
Avatar of inpras
inpras

Use Virtual list control instead
U will find relevent info on microsoft web site
Regards
You can turn the list control into a virtual list control. This is a new style implemented with the common controls version included with Internet Explorer 4.0 (among other places). It is also included with Visual C++ 6.0.
You simply have to handle two additional messages. On to provide feedback for a certain item requested by the control, and the other to manage a cache, in order to speed up things. YOu can find more information in http://msdn.microsoft.com, where they also have example code.
I can assure you the problem is not with the list control itself, simply your usage of it.

The most efficient use of a list control is via the Text Callback mechanism:

Using this mechanism in release code on a 500 MHz PII with 128M RAM and a fast Video Card  I can fill the list with 100,000 rows in less than 7 seconds, this is about 15,000 rows per second.  So for your 30,000 rows this would be about 2 seconds.

Note also, that I am using a relatively inefficient method for formatting the text on each row.  The speed could be dramatically improved by doing something more sensible, I suspect that you could fill a list ctrl with 100,000 entries using something 'smarter' than sprintf in less than 1 second.


void CListDlg::OnGetdispinfoList1(NMHDR* pNMHDR, LRESULT* pResult)
{
      LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;

      
      
      sprintf(pDispInfo->item.pszText, "Text line %d", pDispInfo->item.iItem);

      
      

      *pResult = 0;
}

void CListDlg::FillList()
{
      CWaitCursor o;

      m_List.SetRedraw(FALSE);
      
      for(int i = 0; i < 100000; i++)
            m_List.InsertItem(i, LPSTR_TEXTCALLBACK );

      m_List.SetRedraw(TRUE);
}

void CListDlg::OnOK()
{
      
      FillList();      
      
}
ASKER CERTIFIED SOLUTION
Avatar of mikeblas
mikeblas

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial