I have an array of 1000 strings to load into a combo box. What is the fastest way to load the array of strings into the combo box?
Is there some way other than itera
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.
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:
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
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.
I had this issue and solved it in two ways, depending on the # items. Setting to not draw and init storage made no difference whatsoever to me. Making an owner draw one is also viable, but I had a ton of comboboxes. Assuming a fixed list for each combobox, that does not change contents, list is set once.
Very large # Items: Made the combo box just be Simple/Disabled with SetWindowText to set initial string, and a little button next to it opened a dialog that let you choose the item from a list control in Report mode of the data that would've been in the combo box (could be anything done in dialog).
Moderate # Items: Made a custom derived combobox class that overrides AddString, SelectString, and handles OnDropDown. When you add items, it puts them into a temporary vector, and then on SelectString (could do SetCurSel override too), it adds one item it finds and selects. When dropping down, then it resets the combobox and adds all the items the and selects currently selected one. There is slight slowdown on dropping the combobox, but on low amounts of items is not noticeable.
It made my dialogs load much faster and still be fully functional without owner draw.