Hiding a combo's list after selection





5.00/5 (3 votes)
How to hide a combo's list after selection if the selection starts a long operation
Introduction
If you have an app where you use the selection of an item in a combobox to trigger a possibly long operation, it can be annoying to the user that the combo's list remains visible until the operation is complete. The code shown in this article will hide the list as soon as the user clicks to select a new item in the list.
Use
To use the code you will need to have your own override of CComboBox
.
I will assume you will already have one, or can make one. In the code the combo class is
CMyComboBox
.
In your override of CComboBox
, add a new virtual
function OnChildNotify
.
Then paste in the code below:
BOOL CMyComboBox::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult) { if (message == WM_COMMAND && (HWND)lParam == GetSafeHwnd()) { // if we get a SELENDOK then close up the list now, // before letting the app act on it if (HIWORD(wParam) == CBN_SELENDOK) { // if we are a dropdown (ie we have an edit control) // then the edit test doesn't get updated // until after the default handling has finished // so we need to explicitly set the edit control's // text to the selection if (GetStyle() & CBS_DROPDOWN) { // get selected text, and set window text so // the combo shows the text just selected int nIndex = GetCurSel(); if (nIndex != -1) { CString sText; GetLBText(nIndex, sText); SetWindowText(sText); } } ShowDropDown(FALSE); } } return CComboBox::OnChildNotify(message, wParam, lParam, pLResult); }
This causes the drop-down list to be hidden when the combo receives a
CBN_SELENDOK
notification. In addition to closing the list, we also
get the selected text and set it as the new window text for the combo.
This makes sure that the user sees the newly selected item and not the
previously selected item. (This is only necessary if the combo has the CBS_DROPDOWN
style,
as if it has CBS_DROPDOWNLIST
it will update immediately anyway.) That's it!