CComboBox class in MFC is used for manipulating the
combo box. MFC allows achieving any custom behaviors on
controls by inheriting from its own classes. This article
illustrates an owner-draw
combo box class, which inherits from the CComboBox class.
The
class uses an abstract object to draw the items. In this case
a class derived from the abstract object is created to make
the control list colors. This abstract c++ mfc class can also
be used as a parent class to derive a new class and implement
new or different functionalities.
Abstract class for implementing
CComboBox owner draw:
The abstract class
CDrawC contains methods that are called from the combo box
class only. They are
virtual void DrawItem(LPDRAWITEMSTRUCT lpdis, bool bHasFocus)
= 0;
This DrawItem function
actually draws the items inside the mfc combo boxes using the
Win32 DRAWITEMSTRUCT.
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpmis) = 0;
This function sets the item size once or every time
depending of the owner-draw style: fixed or variable on the
CComboBox derived combo box class.
virtual void InitCombo(CComboBox* pCombo) = 0;
Initializes the control holding the class if it is a
CComboBox (or derived from it)
virtual int AddItemCmb(CComboBox* pCombo, UINT nItem) = 0;
Adds an item to the control holding the class if it is
a CComboBox (or derived from it).
Using the CcomboBox derived owner
draw class:
-
This class is attached to the combo
box via it?s method SetDrawC. It must be added before the control is created, so it is better called in the parent
dialog class constructor.
-
The Init() method of the control
should be called immediately after it?s creation.
-
Items are added with the AddItem
function of the control.
-
Combo boxes using from this type can
be created either dynamically or using the dialog editor
and after adding a variable of type CComboBox just rename
it with CODrawCombo.
-
Don?t forget to call SetDrawC and
Init.
-
Combo boxes must be created with the
following styles: CBS_DROPDOWNLIST, CBS_HASSTRINGS,
CBS_OWNERDRAWFIXED or CBS_OWNERDRAWVARIABLE.
In this particular
example a combo box listing colors is implemented. The init
method is obsolete for there is no initialization needed for
this case. The AddItem implementation inserts a not used
string in the control and sets the item data to the color
needed:
virtual int
AddItemCmb(CComboBox* pCombo, UINT nItem) {
int n;
n = pCombo->AddString("nu");
pCombo->SetItemData(n, nItem);
return n;
}
After that in the
drawing function the color is received as item data and drawn
in a black rectangle like this:
CPen
pen(PS_SOLID, 1, RGB(0,0,0));
CBrush brush;
?.
dc.SelectObject(pen);
dc.SelectObject(brush);
dc.Rectangle(ColRect);
?.
//lpszText is the number
dc.DrawText(lpszText, strlen(lpszText), TextRect,
DT_SINGLELINE|DT_VCENTER);
When the selection in
the combo box is changed an event is raised. We catch this
event to update the sample text with Invalidate. But the
function that actually changes the color of the sample text is
OnCtlColor. There you can see how to get the currently
selected color from the control ie:
m_colorCombo.GetItemData(m_colorCombo.GetCurSel())
Read more on general MFC
Owner draw issues. This might help in reducing the general
complexities of programming owner draw controls.
Find the source
files and project
files here.