Introduction
I often need a combobox that makes suggestions about what I intend to write, but I didn't find anything 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.
Description
My class, CComboBoxExt
(ComboBox Extended) is derived from a standard CComboBox
(one reason for this solution is to keep the standard look and behaviour), where I use an internal CItemData
class to keep and handle all combobox item data:
class CItemData : public CObject
{
public:
DWORD m_dwItemData;
CString m_sItem;
BOOL m_bState;
public:
CItemData();
CItemData(DWORD dwItemData, LPCTSTR lpszString, BOOL bState);
virtual ~CItemData();
};
The internal functionality is solved in the following way: every time the user adds a string into the combobox, it is created as a new CItemData
item, which keeps all the information about the combobox item. When the user deletes a string from the combobox, it deletes the CItemData
object associated with it. When the user types the letters inside of edit, the combobox deletes the items that don't fit with the typed letters, but only from the combobox, not from the CItemData
associated object.
Another particularity is that the list of the combobox is subclassed:
void CComboBoxExt::PreSubclassWindow()
{
COMBOBOXINFO cbi = {0};
cbi.cbSize = sizeof(COMBOBOXINFO);
BOOL bRet = SendMessage(CB_GETCOMBOBOXINFO, 0, (LPARAM)&cbi);
if(bRet && NULL != cbi.hwndList)
m_ListBox.SubclassWindow(cbi.hwndList);
....
CComboBox::PreSubclassWindow();
}
m_ListBox
is of type CComboBoxExtList
, derived from CListBox
.
Features
ComboBoxExt
can operate in three different ways:
MODE_STANDARD
, where the list functions like a standard CComboBox
control. MODE_DROPDOWN
, where combobox shows a dropdown list with the items that begin with letters typed in the edit box.
This working mode, MODE_DROPDOWN
, can be activated through the CComboBoxExt::SetMode(CComboBoxExt::MODE_DROPDOWN);
method.
MODE_AUTOCOMPLETE
where combobox shows a dropdown list that fits with the letter typed in the edit box, and autocompletes the word that fits with letters typed inside of the edit box.
This working mode, MODE_AUTOCOMPLETE
, can be activated through the CComboBoxExt::SetMode(CComboBoxExt::MODE_AUTOCOMPLETE);
method.
The control can adjust the drop down list to the longest item inserted, a feature available in the CComboBoxExt::AdjustDroppedWidth();
method.
Also, the color of the edit box text or background can be changed with CComboBoxExt::AlertBkg();
and CComboBoxExt::AlertText();
methods.
Another feature of CComboBoxExt is to show a tooltip text on the list and edit. This tooltip can be configured in order be shown in several ways:
to show the item text, when the item don't fit the combo, or to show an different text than item text. In order to have another tooltip text than item text, you have few
methods to setup this tooltip text:
virtual int AddStringWithInfo(LPCTSTR lpszString, LPCTSTR lpszInfo, BOOL bShowItemTooltip = TRUE);<br />virtual int InsertStringWithInfo(int nIndex, LPCTSTR lpszString, LPCTSTR lpszInfo, BOOL bShowItemTooltip = TRUE);<br />virtual void SetLBInfo(int nIndex, LPCTSTR lpszInfo, BOOL bShowItemTooltip = TRUE);<br />virtual void GetLBInfo(int nIndex, LPCTSTR lpszInfo) const;<br />virtual void GetLBInfo(int nIndex, CString& rInfo) const;<br />virtual void SetLBShowItemTooltip(int nIndex, const BOOL bShow = TRUE);<br />virtual BOOL GetLBShowItemTooltipState(int nIndex) const;<br />virtual int FindInfo(int nStartAfter, LPCTSTR lpszString) const;
virtual int FindInfoExact(int nIndexStart, LPCTSTR lpszFind) const;
virtual int SelectInfo(int nStartAfter, LPCTSTR lpszString);
you can even find or select an combo item by tooltip info text. Another feature is that you can setup tooltip item in order to being shown at item level, I mean you can say which item show tooltip, and which item will not show tooltip. Also, you can setup the position of tooltip: over item or right alongside him:
void SetEditTooltip(const BOOL bShowTooltip, BOOL bTooltipOnInfo = FALSE, BOOL bShowEditTooltipOverItem = FALSE)<br />void SetListTooltip(const BOOL bShowTooltip, BOOL bTooltipOnInfo = FALSE, BOOL bShowListTooltipOverItem = FALSE)
as you can see, you can setup edit combo tooltip, and/or list combo tooltip separately.
This combination of tooltip configuration can be seen in demo project: combobox with listbox tooltip in alongside:
and combobox with list info tooltip over listbox items:
When you setup the control in order to had tooltip over edit, you can also setup where the tooltip can be shown: right over edit boxes, or above:
This can be done by using CComboBoxExt::SetEditTooltipOverItemPosition(const BOOL bAbove = TRUE).
Using the control
In order to use this control, you can simply add the ComboBoxExt.h, ComboBoxExt.cpp, ComboBoxExtList.h, and ComboBoxExtList.cpp files in your project, and where you want to use this control, just type #include "ComboBoxExt.h"
. This control can be used as a dynamically (or not) created control.
Demo project
The demo project includes an SDI demo application which uses the CComboBoxExt
control. The working mode of CComboBoxExt
could be changed from the radio buttons on the test application form (there you have some tooltips which explain the working mode), and the color of the edit box can be toggled through the Alert text and Alert background buttons from the form.
Known issues
Because of the way CBN_EDITCHANGE
is reflected, when you are going to use this control inside of CDialogBarr
, in order to use MODE_AUTOCOMPLETE
, you must treat ON_CBN_EDITCHANGE
inside of your derived CDialogBar
class. Example:
class CYourDlgBar : public CDialogBar
....
afx_msg void OnEditchangeCombo();
DECLARE_MESSAGE_MAP()
and in your implementation file:
BEGIN_MESSAGE_MAP(CYourDlgBar, CDialogBar)
ON_CBN_EDITCHANGE(IDC_COMBO_FILE, OnEditchangeCombo)
END_MESSAGE_MAP()
.....
.....
void CYourDlgBar::OnEditchangeCombo()
{
}
At the end ...
An actual implementation opens up new possibilities to customize the dropdown list of the control ... that I hope is coming next ...
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.
- 10th June 2013: Bug solved: when the list was spread up, and became shorter, the list didn't stay closed by edit.
- 29 August 2013: Updated the drop down list working mode.
- 11 November 2013: Dropdown list of the control is subclassed.
- 28 January 2014: Added info tooltip, updated control archive.
- 17 February 2014: Solved bug: on Win7 and control has style, tooltip is flickering
- 21 March 2014: Updated and simplified the code.
- 11 December 2015: The tooltip does not appear when is compiled with VS2008; Bug fixed.
- 12 December 2022: The tooltip does not appear when is compiled as UNICODE; Bug fixed.
- 14 February 2023: The control throws errors when create dynamically: Bug fixed.