ItemDataCombo






2.42/5 (6 votes)
Jun 1, 2000

92652

1456
An extremely simple but useful CComboBox entension
If you use CComboBox
(in Drop List mode), you know it's sometimes awkward
to use in situations where you need the user to pick from a set of enumerated values. You need
to prevent the list box strings from being sorted and keep track of which string is in which
position, or worse, do string comparisions to find out which item is selected.
Our traditional method was to load up the list box with the strings in a fixed order - one
string per enumerated value, in the same order as the enumerated values. Then we would use
CComboBox::GetCurSel()
to get the currently selected item; this value would
tell us which string was selected.
For example
typedef enum eEnumeratedFruit {eApple, eOrange, eCherry}; const char *pStrings[] = {"Apple", "Orange", "Cherry"}; for (int i=0; i < numStrings; i++) m_combo.AddString(pStrings[i]); ... // find out which was selected eEnumeratedFruit eSelFruit = (eEnumeratedFruit)m_combo.GetCurSel();
This works fine... until we want to re-order the strings without changing the order of the enumerated values. For example, if we wanted to put the fruits into the list box in alphabetical order (Apple, Cherry, Orange) this code would fail because the enum is ordered Apple, Orange, Cherry. Even worse, if we only wanted to skip items in the middle of the enumeration (ex. Apple, Cherry, not Orange)... Using CComboBox, there is simply no way to handle that situation in an elegant and generic fashion - without doing exactly what CItemDataCombo does, of course.
So, we wrote the CItemDataCombo
box.
CItemDataCombo
is a very simple class. There are only three functions:
// a specialized AddString int AddString(const char *pString, DWORD dwData); // get the item data for the currently selected item DWORD GetCurSelData(); // select the string that has dwData for its item data int SelectItemData(DWORD dwData);For example:
typedef enum eEnumeratedFruit {eBanana, eApple, eOrange, eCherry, eGrape, eBlueberry}; ... // add the strings, along with their associated enum value m_combo.AddString("Banana", (DWORD)eBanana); m_combo.AddString("Apple", (DWORD)eApple); m_combo.AddString("Orange", (DWORD)eOrange); m_combo.AddString("Grape", (DWORD)eGrape); m_combo.AddString("Blueberry", (DWORD)eBlueberry); m_combo.AddString("Cherry", (DWORD)eCherry); ... // select the item that corresponds to the eApple value m_combo.SelectItemData((DWORD)eApple); ... // which value has the user selected? eEnumeratedFruit eSelFruit = (eEnumeratedFruit)m_combo.GetCurSelData();
Using CItemDataCombo
, you can add the strings in any order, use any
subset of possible enumerated values in the box, etc..
It has simplified CComboBox
usage tremendously. No more worrying about
the order of the list box strings! Plus, we can leave the "Sort" property on in the dialog
editor, which sometimes makes things nice for users.
The only annoying part of the whole thing is the need to cast to and from the enumerated value when setting, getting data. But, this could be easily solved with a templated class.