Click here to Skip to main content
Full site     10M members (41.6K online)    

Extended CComboBox

Introduction

I often need a combobox that makes suggestions about what I intend to write, but I didn't find something that fits my needs, so I decided to implement one myself and share it. I tried to keep it simple, standard and easy to use.

Using the Code

My class, CComboBoxExt (Combo Box Extended) is derived from a standard CComboBox (one reason for this solution is to keep standard look behaviour), where I use an internal ItemData structure to keep and handle all data:

 typedef struct ItemData
 {
  DWORD dwItemData;
  CString sItem;
  BOOL bState;
  ItemData();
  ItemData(DWORD dwItemDataInit,LPCTSTR lpszStringInit,BOOL bStateInit);
  virtual ~ItemData();
 };

The issue was to get rid of good (or not) automatically selecting item feature when list is dropped down, that CComboBox has standard. After reading a good article from this site, one solution was to replace LB_FINDSTRING list message with LB_FINDSTRINGEXACT message of dropdown window:

extern "C" LRESULT FAR PASCAL ComboBoxExtListBoxProc
    (HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
    if(nMsg == LB_FINDSTRING)nMsg = LB_FINDSTRINGEXACT;

    return CallWindowProc(m_pWndProc, hWnd, nMsg, wParam, lParam);
}

but to catch these messages, I subclass dropdown list:

HBRUSH CComboBoxExt::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
    HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);

    // TODO: Change any attributes of the DC here

    if(nCtlColor == CTLCOLOR_LISTBOX)
    {
        if(m_ListBox.GetSafeHwnd() == NULL)
        {
            m_ListBox.SubclassWindow(pWnd->GetSafeHwnd());
            m_pWndProc = reinterpret_cast
                <wndproc>(GetWindowLong(m_ListBox, GWL_WNDPROC));
            SetWindowLong(m_ListBox, GWL_WNDPROC, 
                reinterpret_cast<long>(ComboBoxExtListBoxProc));
        }
    }

    // TODO: Return a different brush if the default is not desired

    return hbr;
}

The control can be used in the same way that you use a standard CComboBox, but a new feature added must turn it on, like in the illustrated demo project.

The code is simple and self explanatory, but I want to underline something here: maybe the code could be slightly simpler, but my control needs a function on Windows NT and more. (I mean, subclassing of dropdown list can be complete with COMBOBOXINFO structure, but that is available only from Windows 2000 and more). Of course, the control has a few more features: enable/disable drop down mode, find mode all / begin with..., adjust dropdown width, etc.

Update

I optimized the code and added another functional mode: AutoComplete mode, when user is assisted (complete in advance) after every character that is typed in CComboBox.

Enjoy it!

History

 
You must Sign In to use this message board.
Search 
Per page   
QuestionMouse cursor disappeared Pin
magicpapacy
1 May '12 - 21:14 
Suggestion"Short and sweet" article is hard to understand Pin
DavidCrow
18 Jul '11 - 8:58 
QuestionA few function prototypes neeed to be changed to make your code compile under VS8 Pin
Dezhi Zhao
13 Jul '11 - 17:20 

Last Updated 10 May 2013 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2013