views:

2044

answers:

4

I have an array of 1000 strings how to load them in to combo box faster like kind of dumping in to rather than iterating it? And to copy the combo box data to some 10 other combo box?

+2  A: 

I'm not aware of any way to load multiple strings atomically, but there are a couple of things that you can do to make the process more efficient:

  • Call CComboBox::InitStorage before adding items to pre-allocate memory
  • Use InsertString instead of AddString to prevent triggering a sort on each addition (assuming the CBS_SORT style is enabled)
Stu Mackellar
A: 

I will consider using a pick list instead of a combo box for performance.

A general rule of thumb to improve performance when inserting many item in a UI list is to call before the insertion and setting it back to true after.

Here's the correct syntax

#define NB_ITEM 1000
#define ITEM_LENGTH 10

void CMFCComboDlg::InitMyCombo()
{
    CString _strData;
    m_cbMyCombo.SetRedraw( FALSE );

    m_cbMyCombo.Clear();

    m_cbMyCombo.InitStorage(NB_ITEM, ITEM_LENGTH); 

    for( int i = 0; i < NB_ITEM; i++ )
    {
     _strData.Format( L"Test %ld", i );
     m_cbMyCombo.InsertString( i, _strData );
    }

    m_cbMyCombo.SetCurSel(0);

    m_cbMyCombo.SetRedraw( TRUE );
}

EDIT: Improve the solution to include smacl suggestion

Hapkido
This question specifically refers to MFC, which has no such mechanism.
Stu Mackellar
@nusonic - Yes it does, CWnd::SetRedraw (or WM_SETREDRAW). Which is actually a good suggestion. Too bad Hapkido is speaking a different language then Win32/MFC (What the check is a "pick list" anyway?)
Aardvark
A pick list is a kind of search dialog optimized to get the data you want quickly. Browsing through over a thousand record is really not effective.
Hapkido
@Hapkido, simple mod to improve your above code would be to add an m_cbMyCombo.InitStorage(1000,10000); after SetRedraw, Agreed that 1000 items is too big for a Combo box and an alternate UI would be a good idea.
Shane MacLaughlin
InitStorage is a good suggestion, I included it in my solution. However, the syntax is int InitStorage(int nNbItems, UINT nBytesPerItem );
Hapkido
I'll second the SetRedraw function call. Even for small combo box lists (40 items), it makes a difference if you disable redraw before updating the combo.
bsruth
+3  A: 

If you have 1,000 strings repeated in 10 comboboxes, you may want to consider using an owner drawn combobox, which draws the strings on the fly based on indices into your array, rather than storing them in the combobox at all. Way faster, way more memory efficient. Check out the DrawItem method and DRAWITEMSTRUCT structure in the on-line help. Basically, you would do something like using InitStorage and InsertString (as mentioned by NuSonic) to create your 1000 blank items in your combobx, and override DrawItem to extract and draw the required string, based on index, as it needs to be drawn.

Shane MacLaughlin
This is a pain, but this is the fast way... +1
Aardvark
It will get the job done.. I wouldn't have thought of this. Bravo
baash05
A: 

Possibly faster than CComboBox with DrawItem would be an owner data CListCtrl. This would also serve your goal of duplicating a subset of the items into other lists, since a common data source could be used.

I suggest this because a 1000-item CComboBox isn't going to be very usable.

Aidan Ryan