4

I have an alphabetically sorted combobox in a dialog. This combo contains multiple strings, but some are duplicated with different cases. i.e. we have an 'On' and an 'ON', an 'Off' and an 'OFF'. This may seem redundant but there is a reason, although this is not important right now.

The duplicates obviously appear one after the other in the list, with the capitalized strings first. i.e.:

OFF

Off

ON

On

When the user selects the 'On' (lower case), the correct index is set as CurSel and the correct string is displayed. However, when I click on the arrow of the combobox to drop down the list, it does not highlight the CurSel, but the one previous to it, the capitalized string. See images below.

This is was is selected in the dropdown:

Selected item before dropdown

This is what is selected in the combobox when expanding the dropdown.

Selected item after dropdown

I have captured the ON_CBN_DROPDOWN message, and checked the cursel value and it is as I expected.

I have also already subclassed this combobox so that I can search for strings in this list in a case-sensitive way, as I know its not implemented normally, so it may be what is causing my issue.

But I don't understand why the string would be overriding the cursel value at this stage? Should the CurSel value not be the one used to select the relevant item?

Any ideas on how I can fix this would be greatly appreciated.

EDIT: I have tried to capture the CBN_DROPDOWN message by overwriting the OnWndMsg. When this message occurs, I get the currently selected item (which is the correct item) before dropping down the menu. I then drop the menu, and call SetCurSel to what I retrieved before.

BOOL CMyComboBox::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam,    LRESULT *pResult)
{
    if(message == CBN_DROPDOWN)
    {
        int nCurSel = GetCurSel();
        if(nCurSel != CB_ERR)
        {
            ShowDropDown();
            SetCurSel(nCurSel);
            return TRUE;
        }

    }
    return CComboBox::OnWndMsg(message, wParam, lParam, pResult);
}

This kind of works but when I kill focus, or click on the dropdown arrow again to hide the dropdown, the wrong item is displayed in the text box. Is this a valid method, or am I completely off base here? What message is sent when the drop down is collapsed?

EDIT 2: I have implemented the case-sensitive combobox from code project and it works great.

Community
  • 1
  • 1
ChrisJ
  • 181
  • 14
  • Can you reproduce this behaviour with a standard non subclassed combobox ? Can you reproduce this behaviour with other completely non redundant strings such as e.g. "Apple", "Pie", "Foo", "Bar"? I suspect this issue is related to your subclassing stuff. – Jabberwocky Apr 08 '16 at 15:07
  • @MichaelWalz Yes, I can reproduce this with a non-subclassed combobox. Sorry, the wording isn't clear on that part of the question. I meant to say that since the functionality to find and select strings in the list is only done in a case insensitive way, maybe that's what is causing my issue. Not that subclassing the combobox is the cause. – ChrisJ Apr 08 '16 at 15:10
  • Il also could reproduce it with a freshly wizard generated dialog based app and a sorted combo box containing "OFF", "Off", "ON", "On". Looks like an MSBug. But only with the "dropdown" type. With the "droplist" type the behaviour is as expected. – Jabberwocky Apr 08 '16 at 15:14
  • You may look at [this SO question](http://stackoverflow.com/questions/36287605/hot-tracking-list-item-selection-in-a-combo-box), it deals with hot tracking the selection of a combobox, it could be a start for "fixing" this strange behaviour. – Jabberwocky Apr 08 '16 at 15:20
  • 2
    Recently I found out that the internal mechanism for selecting the entry is not using FindStringExact. It uses SelectString which means it will pick the first entry. So, rather than doing updatedata etc. use: FindStringExact and the SetCurSel with that index. See: http://stackoverflow.com/questions/36016759/ccombobox-ddx-cbstring-behavior-confusing/36084144#comment60066655_36084144 – Andrew Truckle Apr 08 '16 at 17:31
  • 1
    Try this: http://www.codeproject.com/Articles/1363/Case-sensitive-ComboBox – Andrew Truckle Apr 12 '16 at 12:48

1 Answers1

2

Further to my comment. I think you will find that the internal mechanics is using SelectString to set the index when it is a dropdown style.

The side effect is that it may not pick the right entry for you from the list. Therefore, given the nature of the content in your combo, please try this:

int iIndex = m_cbData.FindStringExact(-1, "On");
m_cbData.SetCurSel(iIndex);

Or

int iIndex = m_cbData.FindStringExact(-1, "OFF");
m_cbData.SetCurSel(iIndex);

However, be warned, the document for FindStringExact says the search is not case sensitive. But SelectString (default behaviour) is even worse.

An alternative, which may resolve all of this, is to use SetWindowText and do it that way. This way, it does not matter what is in the listbox component. Eg:

m_cbData.SetWindowText("On");
m_cbData.SetWindowText("ON");

And get the value for the variable by either mapping to a string, or directly using GetWindowText.

UPDATE: Someone has done the work already! Here is a Case Sensitive ComboBox class:

http://www.codeproject.com/Articles/1363/Case-sensitive-ComboBox

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
  • that's good to know, and explains why I'm seeing what I am. I know FindStringExact is not case-sensitive, and I've overridden this function in my custom combobox class so that it is. It returns the correct index for the string I pass in. But my problem is, that when I drop down the list, the wrong item is selected (due to SelectString not being case-sensitive), but what is placed in the edit box is correct based on this. Would overriding SelectString to make it case sensitive work? This may cause other issues though. – ChrisJ Apr 11 '16 at 10:00
  • Yes, I tend to leave existing methods working as they are advertised to work. – Andrew Truckle Apr 11 '16 at 10:11
  • I suppose the elegant solution is to derive from the list box and then override certain event handlers but it is out of my league now ... – Andrew Truckle Apr 11 '16 at 10:12
  • 1
    Please look here: http://www.codeproject.com/Articles/1363/Case-sensitive-ComboBox – Andrew Truckle Apr 12 '16 at 12:50
  • Thanks Andrew! I don't know how I haven't found that before with all my googling.. I'll give this a go. – ChrisJ Apr 12 '16 at 12:59
  • You are welcome. I just tried it with your 4 sets of values and it works a charm. – Andrew Truckle Apr 12 '16 at 13:00
  • 1
    That works great. Thanks again Andrew. I'll mark your answer as the solution. – ChrisJ Apr 12 '16 at 13:49