Download source files - 2 Kb
Download demo project - 12 Kb
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]);
...
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:
int AddString(const char *pString, DWORD dwData);
DWORD GetCurSelData();
int SelectItemData(DWORD dwData);
For example:
typedef enum eEnumeratedFruit {eBanana,
eApple,
eOrange,
eCherry,
eGrape,
eBlueberry};
...
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);
...
m_combo.SelectItemData((DWORD)eApple);
...
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.