1

我刚刚向在旧 MFC 应用程序中调用的派生类 添加了一个Item-Filter-Feature 。CComboBoxComboBoxFbp

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 的文本时,DropDown 的高度只有 1 个项目(在某些用户工作流程中会发生这种情况,即用户手动关闭和打开 DropDown)。

现在,当用户现在更改文本以使多个项目适合时,高度保持为 1 项,并且看起来很奇怪,因为即使滚动条看起来也不正确,因为它不适合。

到目前为止我尝试过的

  1. 我不能使用CComboBox::SetMinVisibleItems(或它背后的 MSG),因为它只能在 Unicode CharacterSet(我无法在这个旧应用程序中更改)和从 WinVista 开始(应用程序在 WinXP 上运行)中工作。
  2. 唯一的其他选择是关闭并打开 DropDown,以便它以正确的高度正确重绘(请参阅//这使得 DropDown在上面的源代码中“闪烁”)。

现在使用选项 2,我不希望用户在按下每个键后看到 DropDown 的关闭和打开(“闪烁”)。

为了防止这种情况,我尝试了一些我发现的解决方案,但在我的情况下没有一个适用于 ComboBox-DropDown。这是我在 . 之前ShowDropDown(false)和 . 之后放置的方法列表ShowDropDown(true)

  1. 启用窗口(假/真);
  2. (Un)LockWindowUpdate();
  3. SendMessage(WM_SETREDRAW, FALSE/TRUE, 0)

在所有三个电话中,我仍然看到 DropDown 关闭/打开。

你们有其他想法如何防止这种闪烁吗?

在此先感谢索科

4

1 回答 1

1

这是一个 XY 问题。

使用以下方法调整 ComboBox 的高度应该更容易

  1. 用于GetComboBoxInfo获取列表控件的句柄。
  2. 使用OnChildNotifyorON_CONTROL_REFLECT和捕获CBN_DROPDOWN
  3. 在消息的处理程序中,根据需要调整窗口大小 使用SetWindowPos并更改大小。
于 2018-09-20T08:09:56.370 回答