C++ MFC/C++;组合框:禁用下拉菜单关闭和关闭的绘图;打开(UI冻结)

C++ MFC/C++;组合框:禁用下拉菜单关闭和关闭的绘图;打开(UI冻结),c++,winapi,combobox,mfc,ccombobox,C++,Winapi,Combobox,Mfc,Ccombobox,我刚刚在名为 ComboBoxFbp在旧的MFC应用程序中 BOOL CComboBoxFbp::OnEditChange() { CString csText; if (m_wFbpMode & _FbpMode_UserTextFiltersList) { GetWindowText(csText); // This makes the DropDown "flicker" // ShowDropDown(false

我刚刚在名为
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));
}
boolcomboxfbp::OnEditChange()
{
CString-csText;
if(m_wFbpMode&_FbpMode_UserTextFiltersList){
GetWindowText(csText);
//这会使下拉菜单“闪烁”
//决战(假);
//只需插入匹配的项目
过滤器项(csText);
//打开下拉列表(如果已打开,则不执行任何操作)
显示下拉列表(true);
}
返回FALSE;//通知weiterleiten
}
void CComboxFBP::FilterItems(CString csFilterText)
{
CString-csCurText;
国际货币基金组织;
德沃德·沃库索;
//文本/选择/光标还原
GetWindowText(csCurText);
nCurItem=GetCurSel();
如果(nCurItem!=CB_ERR&&nCurItem>=0&&nCurItem
因此,当用户键入时,下拉列表中的长项目列表将相应地过滤。到目前为止一切都很好

列表框/下拉列表的大小/高度在打开后不会改变。当模具下拉菜单打开时,它会相应地改变。这意味着,如果只有2项,则下拉列表仅为2项高

我的问题

当用户输入一个文本,其中只有一个项目适合下拉列表时,其高度仅为1个项目(在某些用户工作流中会出现这种情况,即用户手动关闭并打开下拉列表)

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

我到目前为止所做的尝试

  • 我不能使用
    CComboBox::SetMinVisibleItems
    (或其背后的MSG),因为它只在Unicode字符集(我无法在这个旧应用程序中更改)和WinVista以后(应用程序在WinXP上运行)中起作用
  • 唯一的其他选择是关闭和打开下拉列表,以便以正确的高度正确地重新绘制它(请参见//这会使上面的源代码中的下拉列表“闪烁”)
  • 现在使用选项2,我不希望用户在按下每个键后看到下拉菜单的关闭和打开(“闪烁”)

    为了防止这种情况发生,我尝试了一些我发现的解决方案,但在我的案例中,没有一个是使用组合框下拉列表的。下面是我在
    ShowDropDown(false)
    之前和
    ShowDropDown(true)
    之后放置的方法列表

  • 启用窗口(假/真)
  • (Un)LockWindowUpdate()
  • SendMessage(WM_SETREDRAW,FALSE/TRUE,0)
  • 在这三次通话中,我仍然可以看到下拉列表关闭/打开

    你们有没有其他办法来阻止这种闪烁

    提前谢谢
    索科

    这是一个XY问题

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

  • 使用
    GetComboBoxInfo
    获取列表控件的句柄
  • 在“控制”上使用
    OnChildNotify
    反映
    和捕获
    CBN\u下拉列表
  • 在消息的处理程序中,根据需要调整窗口大小,使用
    SetWindowPos
    ,只需更改大小即可

  • 您尝试重新实现的功能已可用。请特别注意。有了它,你只需要管理候选名单,让系统为你做其他一切。我已经看过了,但是
    Autoappend
    功能是我绝对不想要的。我不知何故错过了
    Autosuggest
    模式。。。我想尝试一下,如果你有心情的话,我会欢迎一些示例代码。。。我明白你的意思。。。我想。。。但是只有当下拉列表打开时(afaik),才会调用
    CBN_下拉列表的这个处理程序/捕获。当我添加更多项目时,我的下拉列表已经打开(并且只有1个项目高)。如果我没弄错的话,这是行不通的…只是将控件的大小默认调整为10或15个成员。当您动态地缩小和扩大内容时,这将是我所期望的行为。也许您知道元素的数量。在添加成员之前先调整大小。好的,我明白你的意思。基本上不允许尺寸小于10/15个项目。即使只有一对可以展示。是吗?所以你可以在Vista和更高版本中使用SetMinVisibleItems(应该也可以在非unicode版本中使用),并且调整大小的代码只能在XP中使用。因此,您可以在删除XP时轻松地清理代码(这应该很快就会发生!)