Click here to Skip to main content
15,860,972 members
Articles / Desktop Programming / MFC
Article

CheckComboBox Control

Rate me:
Please Sign up or sign in to vote.
4.81/5 (55 votes)
24 Nov 19992 min read 514.3K   15.8K   121   109
A combo box with check boxes.

Sample Image

Introduction

What does a CheckComboBox control do? A combo box has always been a way of selecting one item from a list of several. If you need to select one or more items, you have to either use a multiple selection listbox or use the MFC's CCheckListBox. The only problem is that it takes up space in your dialog or form. What you need is a CCheckComboBox!

When I started to develop the control, I was planning to design a composite control consisting of a static control along with a small button. When clicking the button, a popup window would be displayed where the user could select or unselect the items. The problem was that it took too much code to implement. I wanted the look and feel just like a standard combo box and that was not possible with a reasonable amount of code.

So I decided to subclass the combo box. A problem when subclassing the combo box is that you have no window handle to the list portion of the combo box that you may subclass. You only have the combo box window handle and that doesn't help.

The trick is to listen to the WM_CTLCOLORLISTBOX message. When the WM_CTLCOLORLISTBOX message is sent, lParam contains the window handle of the list box. This is the time to do the subclassing.

The code below shows how this is done:

BEGIN_MESSAGE_MAP(CCheckComboBox, CComboBox)
    ...
    ON_MESSAGE(WM_CTLCOLORLISTBOX, OnCtlColorListBox)
    ...
END_MESSAGE_MAP()

...
LRESULT CCheckComboBox::OnCtlColorListBox(WPARAM wParam, LPARAM lParam) 
{
    // If the listbox hasn't been subclassed yet, do so...
    if (m_hListBox == 0) {
        HWND hWnd = (HWND)lParam;

        if (hWnd != 0 && hWnd != m_hWnd) {
           // Save the listbox handle
           m_hListBox = hWnd;

           // Do the subclassing
           m_pWndProc = (WNDPROC)GetWindowLong(m_hListBox, GWL_WNDPROC);
           SetWindowLong(m_hListBox, GWL_WNDPROC, (LONG)ComboBoxListBoxProc);
        }
    }


    return DefWindowProc(WM_CTLCOLORLISTBOX, wParam, lParam);
}

After this is done, the rest is fairly straight forward. The ComboBoxListBoxProc() routine takes care of selecting/unselecting items and key down events. The overridden DrawItem() routine draws both the list items and the static portion of the combo box. If it is an item, it draws a checkmark followed by the text. If it is the static portion, it draws the text from all selected items separated by the standard list separator.

Please note that the CCheckComboBox must be created with the CBS_DROPDOWNLIST and the CBS_OWNERDRAWVARIABLE styles set. Also the CBS_HASSTRINGS style must be specified since I let the combo box handle the item strings (sorting etc.).

Since the check mark information is stored in the combo box item data, this may not be used by the application. Setting it to zero unselects the item otherwise it selects the item. But use the GetCheck() and SetCheck() routines instead since they handle redrawing correctly. If you need your own item data, you must implement this yourself.

It is easy to use this control since it is derived from the MFC CComboBox. Add CheckComboBox.h and CheckComboBox.cpp to your project and use it as a standard CComboBox. When used inside a dialog, simply select the category "Control" and variable type "CCheckComboBox" under the "Member Variables" page of the Class Wizard. This will declare a member variable in your dialog of type CCheckComboBox ready for you to use.

Well, I hope someone finds this useful. At least I did.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Sweden Sweden
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralGetCurSel() failed to return item idex based zero, It's a nut! Pin
will00726-Aug-02 2:43
will00726-Aug-02 2:43 
GeneralDisplay checked items in another color Pin
philippe dykmans28-Apr-02 23:25
philippe dykmans28-Apr-02 23:25 
GeneralRe: Display checked items in another color Pin
5-Aug-02 22:06
suss5-Aug-02 22:06 
GeneralRe: Display checked items in another color Pin
philippe dykmans9-Oct-02 22:38
philippe dykmans9-Oct-02 22:38 
GeneralNeed a control to include in web page Pin
23-Apr-02 10:21
suss23-Apr-02 10:21 
GeneralRe: Need a control to include in web page Pin
Marlin24-May-02 9:25
Marlin24-May-02 9:25 
GeneralRe: Need a control to include in web page Pin
f0tisx10-Nov-02 11:43
f0tisx10-Nov-02 11:43 
GeneralSubclassing one(certaint) Combo box in Dialog with more than one ComboBox Pin
Jiri Tesar6-Mar-02 22:30
Jiri Tesar6-Mar-02 22:30 
GeneralRe: Subclassing one(certaint) Combo box in Dialog with more than one ComboBox Pin
Magnus Egelberg, Lundalogik10-Mar-02 21:25
Magnus Egelberg, Lundalogik10-Mar-02 21:25 
GeneralRe: Subclassing one(certaint) Combo box in Dialog with more than one ComboBox Pin
Jiri Tesar10-Mar-02 21:42
Jiri Tesar10-Mar-02 21:42 
GeneralRe: Subclassing one(certaint) Combo box in Dialog with more than one ComboBox Pin
Jiri Tesar10-Mar-02 22:54
Jiri Tesar10-Mar-02 22:54 
GeneralRe: Subclassing one(certaint) Combo box in Dialog with more than one ComboBox Pin
s.jain14-Jan-07 18:51
s.jain14-Jan-07 18:51 
GeneralRe: Here you go. Subclassing one(certaint) Combo box in Dialog with more than one ComboBox Pin
TheFlashback13-Feb-03 19:36
TheFlashback13-Feb-03 19:36 
GeneralMore CheckBoxes in one dialog Pin
6-Mar-02 21:37
suss6-Mar-02 21:37 
Generaladd Enable(Gray) control Pin
31-Jan-02 1:13
suss31-Jan-02 1:13 
GeneralSetItemData Pin
Natacha28-Jan-02 22:55
Natacha28-Jan-02 22:55 
GeneralRe: SetItemData Pin
Magnus Egelberg, Lundalogik10-Mar-02 21:42
Magnus Egelberg, Lundalogik10-Mar-02 21:42 
GeneralModify the WM_LBUTTONUP. Pin
Bassam Abdul-Baki9-Nov-01 1:57
professionalBassam Abdul-Baki9-Nov-01 1:57 
Generalhttp://www.exontrol.com/sg.jsp?content=products/excombobox Pin
12-Oct-01 8:42
suss12-Oct-01 8:42 
QuestionHow to get horizontal scroll functionality? Pin
stephan21-Aug-01 23:56
stephan21-Aug-01 23:56 
GeneralNot keyboard-operable Pin
13-Mar-01 23:05
suss13-Mar-01 23:05 
GeneralRe: Not keyboard-operable Pin
14-Mar-01 9:18
suss14-Mar-01 9:18 
GeneralRe: Not keyboard-operable Pin
14-Mar-01 22:57
suss14-Mar-01 22:57 
GeneralRe: Not keyboard-operable Pin
30-Mar-01 11:50
suss30-Mar-01 11:50 
GeneralRe: Not keyboard-operable Pin
bill free14-Jul-02 22:30
bill free14-Jul-02 22:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.