Motivation
I was looking around for a CComboBox
derived class that would combine some features I needed - multiple columns, colors, icons and more.
Some of these features are found in other controls, but not under one roof, so I've decided to put them all together, in a simple way that will also have room for future growth.
Introduction
This class is a CComboBox
derived class that enhances its functionalities:
- Multi-columns, when each column's width is controllable.
- An optional image-list can be supplied and an image can be set to the left of each row.
- Color of each row can be set.
- Each row can be bolded.
The code is based on Alex Hazanov's ComboBox Bold, just took it a bit further... thanks Alex.
Implementation
The WIN32/MFC implementation of a CComboBox
provides DWORD
element - Item Data, accessed via the SetItemData()
and GetItemData()
for storing extra information for each item of the combo-box. I used this member to store all the extra data I need to know of each row. This data is stored in the nested ItemData
structure which is constructed for each element in the combo-box:
struct ItemData
{
ItemData() : crTextColor(RGB(0,0,0)),nImageIndex(-1),bBold(FALSE),dwItemData(0){}
COLORREF crTextColor;
int nImageIndex;
std::map<int,CString> mapStrings;
BOOL bBold;
DWORD dwItemData;
};
All the new interface functions are added for setting the extra attributes of the combo-box by modifying the ItemData
structure, and invalidating the combo-box.
For not loosing the original functionality of the CComboBox
's SetItemData()
and GetItemData()
, the ItemData
contains a DWORD
member as well, that is accessed via the CComboBoxSuper
.
A vector of all columns' width stores the width of all columns, and the size of this vector is also the number of columns in the combo-box.
Most of the job is done in the DrawItem
function. This function is called for each item's drawing, and reads its item data, and draw the item accordingly.
Another function implemented is the virtual OnDeleteItem
, which is called each time an element is removed from the combo-box, and deletes the ItemData
of the element deleted from the combo-box, including ResetContent()
.
Usage
To use in a dialog - add a normal combo to the dialog, and replace the class from CComboBox
to CComboBoxSuper
.
Make sure to change the combo style to Owner Drawn Fixed and Has String in the resource editor, or by code.
To create on the fly - call create
of the CComboBoxSuper
object, and don't forget the styles.
Note: I always used the combo as a drop-list, in dropdown you get the first column's text only for editing.
During init
function or all around the code, the following functions can be called:
-
Setting to column number, and column width:
void SetColumnCount(int nColumnCount);
void SetColumnWidth(int nColumnIndex, int nWidth);
m_ctrlSuperCombo.SetColumnCount(5);
m_ctrlSuperCombo.SetColumnWidth(0, 100);
-
Adding rows the combo (normal CComboBox function):
m_ctrlSuperCombo.AddString("Row 1");
m_ctrlSuperCombo.AddString("Row 2");
-
Adding sub-item strings:
void SetItemText(int nItemIndex, int nColumn, CString str);
m_ctrlSuperCombo.SetItemText(1,1,"Yes");
m_ctrlSuperCombo.SetItemText(2,1,"No");
-
Setting a row color:
void SetItemColor(int nItemIndex, COLORREF rcTextColor);
m_ctrlSuperCombo.SetItemColor(1, RGB(255,0,0));
m_ctrlSuperCombo.SetItemColor(2, RGB(0,128,0));
-
Setting a row to bold (default is not bolded for all added rows):
void SetItemBold(int nItemIndex, BOOL bBold = TRUE);
m_ctrlSuperCombo.SetItemBold(2);
m_ctrlSuperCombo.SetItemBold(1, FALSE);
-
Setting images:
void SetImageList(CImageList* pImageList);
void SetItemImage(int nItemIndex, int nImageIndex);
void SetUseImage(BOOL bUseImage=TRUE)
m_ctrlSuperCombo.SetImageList(&m_ImageList);
m_ctrlSuperCombo.SetUseImage();
m_ctrlSuperCombo.SetItemImage(1, 1);
History
- 20-03-2004 : Version 1.0 - First release.
- 03-04-2004 : Change in documentations according to readers' requests.