Click here to Skip to main content
Click here to Skip to main content

Extended CComboBox

By , 10 May 2013
 

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

  • 26th April, 2011: Initial version
  • 13th July, 2011: Article updated
  • 10th October, 2011: Updated control archive
  • 10th May, 2013: Updated control archive

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Flaviu2
Romania Romania
Member
No Biography provided

Comments and Discussions

Comment 8 messages have been posted for this article Visit http://www.codeproject.com/Articles/187753/Extended-CComboBox to post and view comments on this article, or click here to get a print view with messages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130513.1 | Last Updated 10 May 2013
Article Copyright 2011 by Flaviu2
Everything else Copyright © CodeProject, 1999-2013
Terms of Use