在 MFC 應用中,希望 CComboBox 能在使用者輸入文字時自動展開下拉清單,並即時過濾符合條件的項目,類似現代 UI 的自動完成體驗。
IAutoComplete 介面(推薦)Windows Shell 提供的標準自動完成功能,支援檔案系統、URL、自定義列表:
#include <shlobj.h>
#include <atlbase.h>
void EnableAutoComplete(CComboBox& combo) {
CComPtr<IAutoComplete> pAutoComplete;
HRESULT hr = pAutoComplete.CoCreateInstance(CLSID_AutoComplete);
if (SUCCEEDED(hr)) {
CComPtr<IEnumString> pEnumString;
// 建立自定義字串列舉器
CComObject<CStringEnum>* pStringEnum = nullptr;
CComObject<CStringEnum>::CreateInstance(&pStringEnum);
pStringEnum->AddString(L"Apple");
pStringEnum->AddString(L"Application");
pStringEnum->AddString(L"Banana");
pStringEnum->QueryInterface(IID_IEnumString, (void**)&pEnumString);
hr = pAutoComplete->Init(GetDlgItem(IDC_COMBO1)->GetWindow(GW_CHILD)->m_hWnd,
pEnumString, NULL, NULL);
}
}
處理 CBN_EDITUPDATE 通知訊息,動態重建下拉清單:
void CMyDialog::OnCbnEditupdateCombo1() {
CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO1);
CString str;
pCombo->GetWindowText(str);
pCombo->SetRedraw(FALSE);
int nSel = pCombo->GetCurSel();
pCombo->ResetContent();
// 從資料源過濾
for (const auto& item : m_allItems) {
if (item.Find(str) != -1) {
pCombo->AddString(item);
}
}
if (pCombo->GetCount() > 0) {
pCombo->SetCurSel(0);
pCombo->ShowDropDown(TRUE); // 自動展開
}
pCombo->SetRedraw(TRUE);
}
CBS_DROPDOWN(可編輯)而非 CBS_DROPDOWNLISTON_CBN_EDITUPDATE(IDC_COMBO1, &CMyDialog::OnCbnEditupdateCombo1)若需支援中文拼音首字母搜尋,可整合 PinyinIME 庫,在過濾邏輯中加入拼音比對。