MFC / C ++ ComboBox: отключить рисование закрытия и открытия Dropdown (заморозка пользовательского интерфейса) - PullRequest
0 голосов
/ 20 сентября 2018

Я только что добавил Item-Filter-Feature к CComboBox производному классу с именем ComboBoxFbp в старом приложении MFC.

BOOL CComboBoxFbp::OnEditChange()
{
    CString csText;

    if (m_wFbpMode & _FbpMode_UserTextFiltersList) {
        GetWindowText(csText);

        // This makes the DropDown "flicker"
        // ShowDropDown(false);

        // Just insert items that match
        FilterItems(csText);

        // Open DropDown (does nothing if already open)
        ShowDropDown(true);
    }

    return FALSE;   // Notification weiterleiten
}

void CComboBoxFbp::FilterItems(CString csFilterText)
{
    CString csCurText;
    int nCurItem;
    DWORD wCurCursor;

    // Text/selection/cursos restore
    GetWindowText(csCurText);
    nCurItem = GetCurSel();
    if (nCurItem != CB_ERR && nCurItem >= 0 && nCurItem < GetCount()) {
        CString csCurItemText;
        GetLBText(nCurItem, csCurItemText);
        if (csCurItemText == csCurText)     csCurText = csCurItemText;
        else                                nCurItem = CB_ERR;
    } else {
        nCurItem = CB_ERR;
    }

    wCurCursor = GetEditSel();

    // Delete all items
    ResetContent();

    csFilterText.MakeLower();

    // Add just the items (from the vector of all possibles) that fit
    for (auto item : m_vItems)
    {
        CString csItemText = item.first;
        csItemText.MakeLower();
        if (!csFilterText.IsEmpty() && csItemText.Find(csFilterText) < 0)
            continue;

        const int i = AddString(item.first);
        SetItemData(i, item.second);
    }

    // Text/selection/cursos restore
    if (nCurItem != CB_ERR)     SelectString(-1, csCurText);
    else                        SetWindowText(csCurText);
    SetEditSel(LOWORD(wCurCursor), HIWORD(wCurCursor));
}

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

Размер / высота ListBox / DropDown не меняется после его открытия. изменяется соответственно при открытии DropDown.Это означает, что если есть только 2 элемента, DropDown имеет высоту только 2 элемента.

Моя проблема

Когда пользователь вводит текст, где только один элемент соответствует DropDown,Высота 1 элемента (это происходит с некоторыми пользовательскими рабочими процессами, т. Е. Пользователь вручную закрывает и открывает DropDown).

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

То, что я пробовал до сих пор

  1. Я не могу использовать CComboBox::SetMinVisibleItems(или MSG за ним), так как он работает только в Unicode CharacterSet (который я не могу изменить в этом старом приложении) и начиная с WinVista (приложение работает на WinXP).
  2. Единственный другой вариантэто закрыть и открыть DropDown, чтобы он правильно перерисовывался с правильной высотой (см. // Это делает DropDown "мерцающим" в исходном коде выше).

Сейчас происходитс вариантом 2 я не хочу, чтобы пользователь виделЗакрытие и открытие («мерцание») DropDown после каждого нажатия клавиши.

Чтобы предотвратить это, я попробовал пару решений, которые нашел, но ни одно не работает в моем случае с ComboBox-Падать.Вот список методов, которые я поместил перед ShowDropDown(false) и сразу после ShowDropDown(true).

  1. EnableWindow (false / true);
  2. (Un) LockWindowUpdate ();
  3. SendMessage (WM_SETREDRAW, FALSE / TRUE, 0)

При всех трех вызовах я все еще вижу закрытие / открытие DropDown.

У вас, ребята, естьДругие идеи, как я могу предотвратить это мерцание?

Заранее спасибо Soko

1 Ответ

0 голосов
/ 20 сентября 2018

Это вопрос XY.

Должно быть проще использовать следующий подход для регулировки высоты ComboBox

  1. Используйте GetComboBoxInfo, чтобы получить ручкуlist control.
  2. Используйте OnChildNotify или ON_CONTROL_REFLECT и захватывайте CBN_DROPDOWN.
  3. В обработчике сообщения измените размер окна по мере необходимости. Используйте SetWindowPos и просто измените размер.
...