SHAutoComplete
要最簡單地實現AutoComplete,只要下面那樣調用ShAutoComplete函數即可:
SHAutoComplete(GetDlgItem (hDlg,IDC_EDIT2),SHACF_FILESYSTEM|SHACF_AUTOSUGGEST_FORCE_ON);
SHAutoComplete的第一個參數,是edit控件的句柄(或者是ComboBox中edit控件的句柄)。第二個參 數是一些flag,來控制提示的內容來自於文件系統(SHACF_FILESYSTEM等)還是歷史url地址 (SHACF_URLHISTORY,SHACF_URLMRU等),或者全部。同時,還可以控制是否強制啟用或關閉AutoAppend 和AutoSuggest功能。這兩種功能的默認設置在ie的設置程序中或在注冊表中:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\AutoComplete
AutoAppend 指的是根據你當前輸入的內容,自動插入剩余的部分。例如:在AutoComplete的系統中 存在apple這個詞條,那麼當你鍵入app的時候,則系統會自動插入剩下的le,並將le以選中的方式顯示 。類似於:app|le
AutoSuggest 啟用的話,會自動出現下列表框顯示候選的內容。
最後,不要忘記在程序開頭調用CoInitialize,因為這東西和com有關。
自定義AutoComplete
SHAutoComplete的功能是十分的局限的,只能提供文件系統或url地址的自動完成。在大部分情況下 ,我們需要對自動完成的內容自定義。這時,我們需要的是shell提供的AutoComplete對象,並實現 IEnumString接口。簡單的代碼如下:
IAutoComplete * pac;
CoCreateInstance(CLSID_AutoComplete,NULL,CLSCTX_INPROC_SERVER,IID_IAutoComplete,(void**) &pac);
pac->Init(GetDlgItem(IDC_EDIT3),<你實現的IEnumString指針>,0,0);
然後,設置一些參數,比如:是否啟用AutoAppend,AutoSuggest等:
IAutoComplete * pac2;
pac->QueryInterface(IID_IAutoComplete2,(void**)&pac2);
pac2->SetOptions(ACO_AUTOSUGGEST|ACO_AUTOAPPEND|ACO_UPDOWNKEYDROPSLIST);
最後,說明一下IEnumString的實現。IEnumString類似於大部分的IEnumXXXX本身非常簡單,唯一需 要提一下的就是IEnumString::Next返回字符串需要調用CoTaskMemAlloc分配內存。代碼如下:
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接受的參數是字節數,GetLength是返回的字符數。並要加上結尾'\0'的 字節
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;
}
這樣,遍完成了自定義的AutoComplete。很簡單,不是嗎?
更進一步
如果候選的內容比較多,為了提高性能,可以再實現IACList接口。IACList只有一個方法:
HRESULT Expand(LPCWSTR pszExpand);
每次Expand被調用的時候,便生成一個pszExpand開頭的候選列表。之後IEnumString接口的方法被調 用的時候,就從這個列表中取字符串。
例如:做一個文件系統的自動完成。用戶輸入"C:\",然後Expand(L"C:\\")被 調用,則枚舉C:\下面所有文件保存起來,然後IEnumString的方法則返回這些文件的路徑。
另外,windows還提供的Compound AutoComplete等等這些組件。關於這些,請看Using Autocomplete 。