我刚刚向在旧 MFC 应用程序中调用的派生类
添加了一个Item-Filter-Feature 。CComboBox
ComboBoxFbp
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 项,并且看起来很奇怪,因为即使滚动条看起来也不正确,因为它不适合。
到目前为止我尝试过的
- 我不能使用
CComboBox::SetMinVisibleItems
(或它背后的 MSG),因为它只能在 Unicode CharacterSet(我无法在这个旧应用程序中更改)和从 WinVista 开始(应用程序在 WinXP 上运行)中工作。 - 唯一的其他选择是关闭并打开 DropDown,以便它以正确的高度正确重绘(请参阅//这使得 DropDown在上面的源代码中“闪烁”)。
现在使用选项 2,我不希望用户在按下每个键后看到 DropDown 的关闭和打开(“闪烁”)。
为了防止这种情况,我尝试了一些我发现的解决方案,但在我的情况下没有一个适用于 ComboBox-DropDown。这是我在 . 之前ShowDropDown(false)
和 . 之后放置的方法列表ShowDropDown(true)
。
- 启用窗口(假/真);
- (Un)LockWindowUpdate();
- SendMessage(WM_SETREDRAW, FALSE/TRUE, 0)
在所有三个电话中,我仍然看到 DropDown 关闭/打开。
你们有其他想法如何防止这种闪烁吗?
在此先感谢索科