CComboBox не выбирает CurSel, когда выпадает

У меня есть сортировка по алфавиту в диалоговом окне. Эта комбинация содержит несколько строк, но некоторые дублируются в разных случаях. то есть у нас есть "On" и "ON", "Off" и "OFF". Это может показаться излишним, но есть причина, хотя сейчас это не важно.

Дубликаты, очевидно, появляются в списке одна за другой, строки с заглавными буквами в первую очередь. то есть:

OFF

от

НА

На

Когда пользователь выбирает "Вкл." (Нижний регистр), правильный индекс устанавливается как CurSel, и отображается правильная строка. Однако, когда я щелкаю стрелку в выпадающем списке, чтобы раскрыть список, он выделяет не CurSel, а предыдущую строку с заглавной строкой. Смотрите изображения ниже.

Это было выбрано в выпадающем списке:

Выбранный элемент перед выпадающим

Это то, что выбирается в выпадающем списке при раскрытии раскрывающегося списка.

Выбранный элемент после выпадающего

Я захватил сообщение ON_CBN_DROPDOWN и проверил значение курсора, и оно соответствует ожиданиям.

Я также уже подклассил этот комбинированный список, так что я могу искать строки в этом списке с учетом регистра, так как я знаю, что он не реализован нормально, поэтому это может быть причиной моей проблемы.

Но я не понимаю, почему строка будет переопределять значение курсора на этом этапе? Разве значение CurSel не должно быть тем, которое используется для выбора соответствующего элемента?

Любые идеи о том, как я могу это исправить, будут с благодарностью.

РЕДАКТИРОВАТЬ: я попытался перехватить сообщение CBN_DROPDOWN, переписав OnWndMsg. Когда появляется это сообщение, я получаю выбранный в данный момент элемент (который является правильным элементом) перед выпадением меню. Затем я опускаю меню и вызываю SetCurSel к тому, что я извлек раньше.

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);
}

Это работает, но когда я убиваю фокус или нажимаю стрелку раскрывающегося меню, чтобы скрыть раскрывающийся список, в текстовом поле отображается неправильный элемент. Это действительный метод, или я полностью не в курсе? Какое сообщение отправляется, когда раскрывающийся список свернут?

РЕДАКТИРОВАТЬ 2: Я реализовал регистр с учетом регистра из кода проекта, и он прекрасно работает.

1 ответ

Решение

В дополнение к моему комментарию. Я думаю, вы обнаружите, что внутренняя механика использует SelectString для установки индекса, когда это стиль выпадающего списка.

Побочным эффектом является то, что он может не выбрать нужную запись для вас из списка. Поэтому, учитывая характер содержания в вашей комбо, попробуйте это:

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

Или же

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

Однако, имейте в виду, в документе для FindStringExact говорится, что поиск не чувствителен к регистру. Но SelectString (поведение по умолчанию) еще хуже.

Альтернатива, которая может разрешить все это, - использовать SetWindowText и делать это таким образом. Таким образом, не имеет значения, что находится в компоненте списка. Например:

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

И получите значение для переменной либо путем сопоставления со строкой, либо непосредственно с помощью GetWindowText.

ОБНОВЛЕНИЕ: Кто-то уже сделал работу! Вот класс чувствительного к регистру ComboBox:

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

Другие вопросы по тегам