A customer was writing a Win32 program and was looking for something like a combo box, in that it gave the user a choice among various fixed options, but sometimes the program would come up with a new option that wasn’t on the list, and it would want to show that as the selection. On the other hand, the customer didn’t want to give the user the option to enter arbitrary text. Users still had to choose among the fixed items in the combo box or the new option that was generated on the fly. The customer didn’t want to add the new option to the dropdown list, which means that the CBS_ style would not be appropriate, since that forces the selection to come from the list. What they wanted was for the combo box to act like a traditional combo box with edit control, except that the user can’t change the text in the edit control.
The solution here is to make the edit control read-only.
You can get the edit control handle by calling GetÂComboÂBoxÂInfo and then sending the EM_ message to the window identified by the hwndItem member.
case WM_INITDIALOG:
{
HWND combo = GetDlgItem(hdlg, IDC_COMBO);
SendMessage(combo, CB_ADDSTRING, 0, (LPARAM)L"Fixed item 1");
SendMessage(combo, CB_ADDSTRING, 0, (LPARAM)L"Fixed item 2");
SendMessage(combo, CB_ADDSTRING, 0, (LPARAM)L"Fixed item 3");
COMBOBOXINFO info = { sizeof(info) };
GetComboBoxInfo(combo, &info);
SendMessage(info.hwndItem, EM_SETREADONLY, TRUE, 0);
}
return TRUE;
The GetÂComboÂBoxÂInfo function is admittedly a bit hard to find because it’s not a message or window style, so it’s not in a place that you naturally look when trying to find information about a combo box.
So, when are we reverting all the “mOdErN” UI back to Win32 so that Windows is usable again?
Relying on a COMBOBOX class to always use use an EDIT control internally seems like relying on an internal implementation detail.
And I appreciate that it’s been that way for 35 years, and probably is forbidden from ever changing due to critical levels of backwards compatibility.
Regardless, it gives me a twinge of guilt relying on it; I don’t want to be contributing to the problem!
It’s documented that it is EDIT and documentation is a contract. So you are not relying on an internal implementation detail, no need to feel any guilt.
What happens if the box displays a special option, the user chooses a fixed item (maybe by using the arrow keys, unaware that the advertised item isn’t in the list), then wants the special option? It appears there’s no way to revert the change, and sounds like it’s going to be used for some sales strategy of pressing people to “take it or leave it”.
Acknowledging we don’t have the full context, this seems like a rather strange UI design. If a user selects a different value of the combo box, but then wants to change back to the newly generated one, how do they do that if the program didn’t add the newly generated item to the list? In other words, does the customer have an X-Y problem, where they think their solution requires doing X, but the real problem is the self-imposed constraint Y?
I agree that this is an odd UI/UX choice not showing all the options in the list. Seems like there’s probably some custom current value that they want to display in the edit box and it is not part of the ‘standard’ list. One solution would have been to subclass the dropdown list control and show the ‘new/custom’ option or options at the top of the list, then a separator and a list of ‘standard’ options.
This way users can always go back to any value if they play around with the selection.
My guess is that there’s a list of valid values — but the current value is always valid even if not in the list, and they couldn’t figure out how to add the current value to the dropdown list without messing with whereever the list of valid values is defined.
Yup, this sounds like an “I bet someone got a nice bonus for that” story: Let’s take a standard UI element that everyone’s familiar with and everyone knows how to use and override its behaviour to make it work in a weird unexpected way that looks exactly like a bug in the program.