tags:

views:

55

answers:

3

I have a CComboBox control with several items and I need to remove some of them, but the indexes of the remaining items should be preserved.

When the combo box is populated, the item data is set like so:

index = mycombo.AddString(temp);
mycombo.SetItemData(index, static_cast<DWORD>(count));

where count is a loop counter, and should be equal to index

Now I want to remove some of the items later, but I need the index of each remaining item to stay the same. Is CComboBox::DeleteString(UINT nIndex) what I should use? Its documentation says:

All items following nIndex now move down one position. For example, if a combo box contains two items, deleting the first item will cause the remaining item to now be in the first position. nIndex=0 for the item in the first position.

Is that talking about the physical location in the drop-down menu, or the index value associated with the item?

Is there another function that does what I need? Another solution altogether?

+1  A: 

Adding or removing items does not change the number you passed to SetItemData(). GetItemData() returns the same number. You however need to pass the index of the item to DeleteString(). When lower numbered items were deleted before then the index will no longer match GetItemData(). If you lost track of the index of a specific item you want to delete then you need to iterate the items to find it back.

Hans Passant
I'm not sure I follow, as your fourth sentence seems to contradict the first two. Are you saying that the second parameter passed to SetItemData will still be returned by GetItemData on the same element, but the parameter passed to GetItemData will be different?
Travis Christian
Yes, that's what I'm saying. If you delete item index 0 then the index of the 2nd item becomes 0. And GetItemData(0) returns 1.
Hans Passant
by iterating items he means `for (int i=0; i<cmb.GetCount(); i++) if (cmb.GetItemData(i) == myvar) cmb.DeleteString(i);`
djeidot
+2  A: 

Is that talking about the physical location in the drop-down menu, or the index value associated with the item?

For a ComboBox (as well as ListBox, List Control, and probably many other such things) the location of an item on the control is directly tied to its index. The index is the location. Really, just think of it as if ComboBox was implemented internally using a simple std::vector. You can't remove an entry from a vector without affecting the indexes of all subsequent entries, and it is just the same with these controls.

However, the Item Data of an entry in a ComboBox (and other such controls) sticks with that entry no matter what index it is reassigned to.

Say you created two entries: the first at index 0 has text="A" and ItemData=0; while the second at index 1 has text="B" and ItemData=1. If you then remove that first entry, the second entry will shift down the claim the index and its ItemData will travel along. So you would be left with a single entry at index 0 having text="B" and ItemData=1.

TheUndeadFish
+1  A: 

In a combobox you have items which have a string and an integer value associated. Normally, you just see the string. Those items are referenced by an index, which just represents the location of each item in the list. If you remove an item, all the items below it are "relocated", so the index changes. The same happens in you insert an element anywhere between two items, or at the beginning.

The index always goes from 0 to (number_of_items-1), and there's nothing you can do about it.

That said, the item data always stays with the item, and it's this what you should look at when looking for a specific item. Not its index, and neither its string. Look at the item data. The index can change if you add, remove or resort the items. The strings will change if you localize the software. So use the data to properly identify each element.

You can take a look at http://www.flounder.com/combobox.htm, where you can find a better explanation, with some examples and code to do work with comboboxes more easily.

MikMik