在應用程序中集成自動完成功能
發表于:2007-07-01來源:作者:點擊數:
標簽:
在應用程序中集成自動完成功能 本文的很多內容來自這篇文章。 介紹 自動完成功能,就是用戶在輸入時,程序自動提示匹配用戶輸入的條目,并且/或者自動輸入剩余部分,自從IE提供了表單和地址欄的自動完成功能之后,很多程序在用戶界面中集成了這個功能。在適
在應用程序中集成自動完成功能
本文的很多內容來自這篇文章。
介紹
自動完成功能,就是用戶在輸入時,程序自動提示匹配用戶輸入的條目,并且/或者自動輸入剩余部分,自從IE提供了表單和地址欄的自動完成功能之后,很多程序在用戶界面中集成了這個功能。在適當使用時,它可以大大減少用戶輸入的時間。盡管這個功能如此有用,但是在平臺開發工具包中甚至連一個示例都找不到。Paul DiLascia在中使用子類化窗口類完成了這個功能,但是他的方法太依賴于MFC了,以至于不能很好的移植到非MFC的程序。這里是他的程序的圖示:
他的文章中最后比較了使用COM接口和他的方法之間的異同,有興趣可以去看看。
Windows外殼中的自動完成
Windows的文件打開和保存對話框,以及運行對話框,IE的地址欄都具有自動完成功能。
這個功能也在Windows API中提供。Windows Shell Light API提供函數,可以把系統內建的自動完成資源CLSID_ACLHistory 、CLSID_ACLMRU和CLSID_ACListISF(說明見后)綁定到編輯框。這個函數使得你不必處理COM接口就可以提供自動完成功能,但是如果你想要更好地控制自動完成的行為或者列表條目,那么你需要使用一些COM接口,例如和。
創建一個簡單的自動完成對象
你可以采用下列步驟創建一個簡單自動完成對象。簡單自動完成對象從一個資源來提取自動完成所需的字符串。為使代碼明確起見,錯誤檢查的代碼被省略,下同。
- 創建自動完成對象
IAutoComplete *pac;
CoCreateInstance(CLSID_AutoComplete,
NULL,
CLSCTX_INPROC_SERVER,
IID_IAutoComplete,
(LPVOID*)&pac);
- 創建自動完成資源
你可以使用預定義的自動完成資源,或者編寫你自己的自動完成資源。
- 使用預定義的自動完成資源
IUnknown *punkSource;
CoCreateInstance(clsidSource,
NULL,
CLSCTX_INPROC_SERVER,
IID_IACList,
(LPVOID*)&punkSource);
下列外殼對象具有IAutoComplete接口,可以用創建之后給你的應用程序提供自動完成功能。
CLSID_ACLHistory
- IE維護,匹配當前用戶的歷史記錄。
CLSID_ACLMRU
- 也是IE維護,匹配當前用戶的最近文檔記錄。
- CLSID_ACListISF -匹配外殼命名空間(包括文件系統和虛擬目錄,例如我的電腦和控制面板)
- 編寫你自己的自動完成資源
IUnknown *punkSource;
CCustomAutoCompleteSource *pcacs = new CCustomAutoCompleteSource();
hr = pcacs->QueryInterface(IID_IUnknown,
(void **) &punkSource);
pcacs->Release();
你可以編寫實現IEnumString接口的自動完成資源對象。IACList和的實現是可選的。
- 實現接口
和其他IEnumXXXX接口一樣,IEnumString接口有如下四個方法
HRESULT Next(ULONG celt, LPOLESTR * rgelt, ULONG * pceltFetched);
HRESULT Skip(ULONG celt);
HRESULT Reset(void);
HRESULT Clone(IEnumString ** ppenum);
你可以用或者的 方法快速構造實現IEnumString接口的對象,也可以自己手動實現IEnumString接口。通常,列表項來自字符串數組或者數據庫。下面是這兩種情況下IEnumString的實現方法的建議
- 字符串數組(以CStringArray為例)
- Next:提取指定數量字符串,并且增加當前字符串索引。
- Skip:增加當前字符串索引
- Reset:當前字符串索引復位為0
- Clone:復制字符串數組和當前字符串索引
- 數據庫
- Next:提取指定數量字符串,并且向后移動當前記錄位置。
- Skip:向后移動當前記錄位置
- Reset:復位當前記錄位置到記錄集開頭
- Clone:復制記錄集或者記錄集參數和/或復位當前記錄位置。
- 設置自動完成資源
如果需要,你可能通過IACList或者IACList2接口設置一些選項來自定義自動完成資源,例如過濾某些列表條目。這對CLSID_ACListISF
對象特別有用??梢圆榭吹奈臋n來查看有效的選項。
IACList2 *pal2;
if (SUCCEEDED(punkSource->QueryInterface(IID_IACList2, (LPVOID*)&pal2))){
pal2->SetOptions(ACLO_FILESYSONLY);
pal2->Release();
}
對于某些特定資源,你可能需要查詢其他接口來進行更加復雜的設置,例如在資源管理器或者IE瀏覽到一個新的目錄時,自動完成的列表內容也隨之變化。對于CLSID_ACListISF對象,你可以設置ACLO_CURRENTDIR讓它來枚舉當前目錄的內容,這樣你需要查詢它的IACList接口,并且設置它的當前 位置。
有兩種方法可以設置當前目錄。如果傳遞的只是目錄的話,它們是等價的。
- 使用
你可以用這個接口來告訴自動完成對象當前的位置。因為當前位置可以不是真實的目錄,例如是桌面或者是我的電腦所以這個方法比下一個更加靈活。
IPersistFolder *ppf;
extern LPITEMIDLIST pidlCurrentDirectory;//這個是有效的命名空間位置
if (SUCCEEDED(pal->QueryInterface(IID_IPersistFolder, (LPVOID*)&ppf))){
ppf->Initialize(pidlCurrentDirectory);
ppf->Release();
}
- 使用
你可以通過對象的這個接口把當前目錄傳遞給對象。
ICurrentWorkingDirectory *pcwd;
if (SUCCEEDED(pal->QueryInterface(IID_ICurrentWorkingDirectory, (LPVOID*)&pcwd))){
pcwd->SetDirectory(pwszDirectory);
pcwd->Release();
}
如果你編寫了自定義的自動完成資源,那么你可以自行編寫修改設置的方法,例如限制最大枚舉條目數目,或者根據用戶的輸入和上下文過濾枚舉條目(這在枚舉數據庫記錄時特別有用)。
- 綁定到編輯框
將自動完成資源綁定到一個編輯框。有一些未公開的方法可以獲得COMBOBOX控件中的編輯框的句柄,但是COMBOBOXEX控件提供了直接訪問其中的編輯框的方法 (),所以推薦使用COMBOBOXEX控件。
extern HWND hwndEdit;//要添加自動完成的目標窗口
extern LPUNKNOWN punkSource;//第二步創建的自動完成資源的IUnknown接口指針。
pac->Init(hwndEdit, punkSource, NULL, NULL);
可以查看IAutoComplete::Init來的文檔了解其他參數的含義。
IAutoComplete::Init將會增加對象的引用計數,并且在編輯框銷毀時減少對象的引用計數,見步驟6。
一個自動完成對象一次只能綁定到一個窗口。
- 設置自動完成對象的行為
如果需要的話,可以通過IAutoComplete2接口設置選項來更改自動完成對象的行為??梢圆榭吹奈臋n來了解其他參數。
IAutoComplete2 *pac2;
if (SUCCEEDED(pac->QueryInterface(IID_IAutoComplete2, (LPVOID*)&pac2))){
pac2->SetOptions(ACO_AUTOSUGGEST);
pac2->Release();
}
- 釋放對象
pac->Release();
punkSource->Release();
自動完成對象在釋放后仍綁定到編輯框(因為IAutoComplete::Init增加了對象的引用計數),并且在編輯框銷毀時自動釋放。在還需要訪問對象的時候不應該提前銷毀對象。例如,你可能在自動完成對象綁定到對話框之后,仍需要通過步驟3的方法設置自動完成資源。
創建復合自動完成對象
復合自動完成對象從多個自動完成資源中查找匹配的項目。例如,IE的地址欄查找訪問過的URL和當前目錄中的內容??梢圆捎孟铝胁襟E創建一個復合自動完成對象。
- 創建自動完成對象
IAutoComplete *pac;
CoCreateInstance(CLSID_AutoComplete,
NULL,
CLSCTX_INPROC_SERVER,
IID_IAutoComplete,
(LPVOID*)&pac);
- 創建復合自動完成資源對象管理器。它將多個自動完成資源組合成一個自動完成資源。
*pom;
CoCreateInstance(CLSID_ACLMulti,
NULL,
CLSCTX_INPROC_SERVER,
IID_IObjMgr,
(LPVOID*)&pom);
- 對每一個簡單自動完成對象進行前面一個例子的步驟2和3,完成創建和初始化工作。
- 連接簡單自動完成對象到復合自動完成資源對象管理器。
extern LPUNKNOWN punkSource;//第3步創建的自動完成資源的IUnknown接口指針。
pom->Append(punkSource);
- 綁定到編輯框
這個步驟和前面一個例子的步驟4一樣,除了把自動完成資源的IUnknown接口指針換成了復合自動完成資源對象管理器的IUnknown接口指針之外。
pac->Init(hwndEdit, pom, NULL, NULL);
- 設置自動完成的選項
同前面一個例子。
- 釋放對象
pac->Release();
pom->Release();
punkSource->Release(); /* 每一個步驟3的創建對象都要釋放 */
你可以在使用對象之后立刻釋放對象,但是你可能需要保留對象接口指針以便以后修改選項。
自動完成的模式
自動完成具有兩種互相獨立的模式:自動擴展和自動建議。你可以調用IAutoComplete2::SetOptions來分別啟用/禁用這兩種模式。
- 自動擴展:在此模式下,自動完成功能自動將最可能的候選字符串添加到當前子復制或并且高亮顯示。編輯框表現得和擴展的字符串已經輸入并高亮顯示一樣。如果用戶繼續輸入字符,那么它們被添加到已經輸入的部分字符串。如果用戶輸入的字符和擴展的部分的首字符一致,那么這個字符的高亮顯示被關閉,剩余的擴展字符串繼續保持高亮顯示狀態;否則自動完成試圖用用戶輸入的新字符串產生一個新的候選擴展字符串,并和前面一樣添加到當前字符串末尾并高亮顯示。如果沒找到候選擴展字符串,那么編輯框的行為和沒有自動完成功能時一樣。這個過程持續到用戶完成輸入。
- 自動提示:在此模式下,自動提示顯示一個下拉列表,顯示一個或多個建議的完成字符串。用戶可以選擇其中一個,通常是用鼠標,或者繼續輸入以減少匹配的列表項數目。在輸入過程中,列表內容可能根據輸入的字符串更改。如果你在IAutoComplete2::SetOptions的dwFlag參數中設置了ACO_SEARCH標志,那么自動完成在列表末尾提供根據當前的部分字符串搜索的選項。這個選項甚至在沒有提示的候選字符串時也顯示。如果用戶選擇了這個選項,應用程序應該啟動一個搜索引擎來幫助用戶。
盡管可以通過字符串匹配來判斷用戶是否選擇了搜索選項,但是由于語言的不同,搜索選項的前綴也不一樣。你應該考慮如何去掉“Search for”或者“搜索”這樣的前綴
原文轉自:http://www.kjueaiud.com