為編輯控件(Edit/ComboBox)加入自動完成功能,Windows Shell 提供了分層級的 API。本文由淺入深,涵蓋一行碼啟用、自定義來源實作 IEnumString、以及大量資料時的 IACList 效能優化。
SHAutoComplete(GetDlgItem(hDlg, IDC_EDIT2),
SHACF_FILESYSTEM | SHACF_AUTOSUGGEST_FORCE_ON);
SHACF_FILESYSTEM(檔案系統)、SHACF_URLHISTORY、SHACF_URLMRU 等。行為:SHACF_AUTOSUGGEST_FORCE_ON 強制開啟下拉建議、SHACF_AUTOAPPEND_FORCE_ON 強制開啟自動補全。HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\AutoComplete 控制。CoInitialize 初始化 COM。適用於固定、中小規模字串集合(如關鍵字、歷史輸入、特定代碼)。
IAutoComplete 物件:CoCreateInstance(CLSID_AutoComplete, ..., IID_IAutoComplete, &pac)。pac->Init(hwndEdit, pEnumString, NULL, NULL)。IAutoComplete2 設定選項:pac2->SetOptions(ACO_AUTOSUGGEST | ACO_AUTOAPPEND | ACO_UPDOWNKEYDROPSLIST)。
STDMETHOD(Next)(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched) {
ULONG i = 0;
if (pceltFetched) *pceltFetched = 0;
for (; m_idx < (int)m_vec.GetCount() && i < celt; ++i, ++m_idx) {
// 必須用 CoTaskMemAlloc 配置記憶體,Shell 會負責釋放
rgelt[i] = (LPOLESTR)CoTaskMemAlloc(2 + m_vec[m_idx].GetLength() * 2);
wcscpy(rgelt[i], m_vec[m_idx]);
if (pceltFetched) ++(*pceltFetched);
}
return (i == celt) ? S_OK : S_FALSE;
}
Skip, Reset, Clone 依標準實作。CoTaskMemAlloc(非 new/malloc),否則 Shell 釋放時會崩潰。當候選清單極大(如檔案系統、資料庫查詢),IEnumString::Next 逐筆產生太慢。IACList 僅有一方法:
HRESULT Expand(LPCWSTR pszExpand);
機制:
Expand(L"C:\\")。IEnumString::Next 直接從快取返回,極大提升回應速度。這是 Shell 檔案系統 AutoComplete 的內部運作模式。