首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

Windows Shell AutoComplete 全攻略:從 SHAutoComplete 到自定義 IEnumString 與 IACList

     編輯:組合語言

為編輯控件(Edit/ComboBox)加入自動完成功能,Windows Shell 提供了分層級的 API。本文由淺入深,涵蓋一行碼啟用、自定義來源實作 IEnumString、以及大量資料時的 IACList 效能優化。

層級一:SHAutoComplete — 最簡單啟用


SHAutoComplete(GetDlgItem(hDlg, IDC_EDIT2),
    SHACF_FILESYSTEM | SHACF_AUTOSUGGEST_FORCE_ON);
  • 參數一:編輯控件 HWND。
  • 參數二:旗標組合。來源:SHACF_FILESYSTEM(檔案系統)、SHACF_URLHISTORY、SHACF_URLMRU 等。行為:SHACF_AUTOSUGGEST_FORCE_ON 強制開啟下拉建議、SHACF_AUTOAPPEND_FORCE_ON 強制開啟自動補全。
  • 預設行為由登錄檔 HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\AutoComplete 控制。
  • 記得呼叫 CoInitialize 初始化 COM。

層級二:自定義來源 — 實作 IEnumString

適用於固定、中小規模字串集合(如關鍵字、歷史輸入、特定代碼)。

步驟

  1. 建立 IAutoComplete 物件:CoCreateInstance(CLSID_AutoComplete, ..., IID_IAutoComplete, &pac)。
  2. 初始化:pac->Init(hwndEdit, pEnumString, NULL, NULL)。
  3. 查詢 IAutoComplete2 設定選項:pac2->SetOptions(ACO_AUTOSUGGEST | ACO_AUTOAPPEND | ACO_UPDOWNKEYDROPSLIST)。

IEnumString 關鍵實作細節


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 釋放時會崩潰。

層級三:大量動態資料 — 實作 IACList

當候選清單極大(如檔案系統、資料庫查詢),IEnumString::Next 逐筆產生太慢。IACList 僅有一方法:


HRESULT Expand(LPCWSTR pszExpand);

機制:

  1. 使用者輸入 "C:\" → Shell 呼叫 Expand(L"C:\\")。
  2. 實作者於此枚舉 C:\ 目錄下所有檔案/目錄,建立內部快取清單。
  3. 後續 IEnumString::Next 直接從快取返回,極大提升回應速度。

這是 Shell 檔案系統 AutoComplete 的內部運作模式。

進階組件

  • Compound AutoComplete:整合多個來源(如檔案系統 + 歷史 URL + 自定義)。
  • 參考 MSDN "Using Autocomplete" 文件深入擴充。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved