如下內容摘自http://msdn.microsoft.com/zh-cn/goglobal/bb688135.aspx
Microsoft Developer Network (MSDN) 文檔(位於 http://msdn.microsoft.com)和編程 API 用一種名爲「輸入法區域設置標識符」的變量類型表明輸入語言,它在先前的文檔中被稱爲「鍵盤佈局處理」(HKL) 而且如今仍被用做類型標識符。HKL 是一種古老的名稱,當時只能從鍵盤進行輸入。輸入法區域設置標識符名稱是一個 32 位的值,它由語言標識符(低 WORD)和設備標識符(高 WORD)的十六進制值組成。(參見下方的圖 7。)例如,美國英語的語言標識符爲 0x0409,所以美國英語主佈局被命名爲 "00000409"。美國英語佈局的變體(例如 Dvorak 佈局)被命名爲 "00010409"、"00020409" 等。設備標識符並不只限於鍵盤和 IME;如今可經過一些較複雜的機制(例如語音和文字識別引擎)來輸入數據。例如,在 Windows XP 中做爲一種系統服務提供的 Microsoft Windows Text Services Framework (TSF),它能夠實現與來源無關的高級文字輸入。(有關 TSF 的更多信息,請參閱 Text Services Framework)。算法
圖 7:表明輸入語言的 HKL 變量。編程
處理輸入語言最簡單的方式是在須要用戶輸入的全部場合都使用操做系統提供的標準控件。例如,經過使用 Unicode 編輯控件或 Rich edit 控件,可使應用程序可以處理多種語言的文字輸入。操做系統會以一種對應用程序透明的方式自動處理輸入語言。文字 API 使用的是一種標準的多行編輯控件,它能夠避免處理輸入語言時的麻煩。安全
對於一些須要徹底控制輸入語言處理方式的高級應用程序(例如文本編輯器),它們應該監視(並可以響應)用戶的改動。當用戶經過單擊任務欄上的語言指示符或按下「左邊 Alt+Shift」鍵來選擇某種輸入語言時,輸入語言不會自動改變 – 兩個操做都會生成一個活動的應用程序必須接受或拒絕的請求。爲了響應熱鍵組合或鼠標單擊任務欄上的語言指示符後產生的事件,系統會向焦點窗口發送一個 WM_INPUTLANGCHANGEREQUEST 消息,以下圖所示。若是應用程序接受該消息並將其傳遞給DefWindowProc,系統將啓動切換輸入語言的操做併發送一個 WM_INPUTLANGCHANGE 消息。若是輸入法是 Text Services Framework (TSF) 的一部分,則此過程會略有不一樣,這時只發送 WM_INPUTLANGCHANGE。當系統成功完成改變後,會生成一個 WM_INPUTLANGCHANGE 消息。WM_INPUTLANGCHANGE 消息的 lParam 變量包含新輸入語言的輸入法區域設置標識符(即 HKL)。併發
圖 8:WM_INPUTLANGCHANGEREQUEST 和 WM_INPUTLANGCHANGE 消息傳播流程圖。編輯器
不支持多語言的應用程序會拒絕 WM_INPUTLANGCHANGEREQUEST 消息。它可能會拒絕任何或所有 WM_INPUTLANGCHANGEREQUEST 消息,也可能會先執行一些測試。例如,此消息的 wParam 變量是一個 Boolean 值 bLangInSystemCharset,它將指出請求的輸入語言是否可以在當前的系統區域設置中呈現出來。在處理 Unicode 應用程序時呈現輸入語言並不麻煩,可是,非 Unicode 應用程序應該監視此值(實際上也是如此),不然它們會顯示錯誤的字符。函數
與生成 WM_INPUTLANGCHANGEREQUEST 消息來響應用戶請求的系統相似,應用程序也會經過調用 ActivateKeyboardLayout API 來啓動改變輸入語言的操做。若是用戶編輯包含拉丁文和希臘文的文檔,當用戶將插入點從拉丁文字移動到希臘文字時,將會自動激活希臘文輸入法。(參見下方的表 4。)一樣,當此用戶將插入點移回拉丁文字時,應用程序將激活默認的基於拉丁文的輸入法。佈局
圖 9:當光標被定位到希臘文文本流中時,活動的鍵盤佈局會切換到希臘文。測試
處理輸入法的其餘 Win32 API 以下方的表 4 所示:字體
表 4spa
在設計容許用戶切換鍵盤佈局的功能時,要清楚因爲不一樣佈局的鍵盤上字母排列各不相同,所以用來生成快捷鍵組合的按鍵可能也會有所變化。例如,法語鍵盤默認爲 AZERTY 佈局,而英語佈局採用 QWERTY 映射。所以,建議您在快捷鍵組合中使用數字和功能鍵(F四、F5 等),而不要使用字母。
除了使您的應用程序可以處理各類輸入語言外,您還須要使其可以支持 IME。(請注意,若是您使用標準 API 進行輸入,您的應用程序將會自動處理 IME。)經過啓用 IME 支持,您的用戶將能夠輸入象形文字,例如,從各類東亞書寫系統輸入。如下各節將探究 IME 的用途,並提供支持 IME 的最佳實際示例和技術解決方案。
Windows 2000 和 Windows XP 中的 IME 模塊適合於嚮應用程序傳遞用戶輸入信息的大型機制,並且像其餘輸入法同樣,最簡單、最安全的輸入內容處理方式是使用標準系統控件,例如編輯字段和 Rich edit 控件等。若是您不是要編寫 IME 軟件包或自定義本身的 IME 用戶界面 (UI),您可使用標準輸入 API,它能夠爲您處理 IME 的全部複雜狀況。
對某種輸入語言來講,是使用 IME 仍是使用鍵盤來輸入對用戶而言都徹底透明。不管用戶是切換 IME 仍是西方鍵盤佈局,過程都徹底相同。這兩種操做都是經過單擊任務欄上的語言指示符或輸入某個快捷鍵組合來完成。並且,應用程序不關心使用的輸入法,由於切換 IME 與切換鍵盤佈局會生成一樣的消息:WM_INPUTLANGCHANGEREQUEST(若是 IME 不是 TSF 的一部分)和 WM_INPUTLANGCHANGE。應用程序可經過調用 ActivateKeyboardLayout 來激活特定的 IME。IMM 能夠做爲中介來管理 IME 與應用程序之間的通訊。當用戶使用 IME 鍵入信息時,每一個按鍵都發出一條帶有 GCS_COMPSTR 標記的 WM_IME_COMPOSITION 消息,指出合成字符串有更新。消息的 WPARAM 值將返回字符串的第一個字符,其他字符能夠經過帶有相同 GCS_COMPSTR 標記的 ImmGetCompositionString API 進行檢索。而後當用戶按下 Enter 鍵或單擊某個字符在文檔中放置它時,默認狀況下,IME 會發出一條帶有 GCS_RESULTSTR 標記的 WM_IME_COMPOSITION 消息。(您可使用相同的 API 和 GCS_RESULTSTR 標記來檢索提交的字符串。)若是後面的 WM_IME_COMPOSITION 消息被髮送到 DefWindowProc,則對於所提交字符串中的每一個字符,它都會發出一條包含實際字符的 WM_IME_CHAR 消息。對於非 Unicode 窗口,若是 WM_IME_CHAR 消息包括一個雙字節字符而且應用程序將此消息傳遞給 DefWindowProc,則 IME 會將此消息轉換爲兩條 WM_CHAR 消息,每條包含雙字節字符中的一個字節。若是應用程序略過任何一條消息,則它將由應用程序的 DefWindowProc 函數進行處理,此函數會通知 IMM 該消息被忽略。IME 而後會經過多個 WM_CHAR 消息逐字節從新發送字符或字符串。對於 Unicode 窗口,WM_IME_CHAR 和 WM_CHAR 是相同的。
如下各節將討論對於 Windows 中所運行應用程序的三個離散的 IME 支持級別:不支持、部分支持和徹底自定義的支持。應用程序能夠小規模自定義 IME 支持(例如經過從新定位窗口),也能夠完全改變 IME UI 的外觀。
無 IME 支持:不識別 IME 的應用程序一般會忽略全部特定於 IME 的 Windows 消息。大多數針對單字節語言的應用程序不能識別 IME。
不識別 IME 的應用程序會經過預約義的全局類(對應被稱爲 "IME")來繼承活動 IME 的默認 UI。這一全局類具備與基於 Windows 的任何其餘經常使用控件相同的特性。對於每一個線程而言,Windows 2000 和 Windows XP 都會根據 IME 全局類自動建立一個窗口,全部不識別 IME 的線程窗口都會共用此默認的 IME 窗口。不識別 IME 的應用程序將關於 IME 的消息傳遞給 DefWindowProc 函數時,DefWindowProc 會將其發送到默認 IME 窗口。
部分 IME 支持:識別 IME 的應用程序能夠建立其本身的 IME 窗口。部分支持 IME 的應用程序可使用此應用程序 IME 窗口來控制特定的 IME 行爲。例如,經過調用函數 ImmIsUIMessage,應用程序能夠將與 IME 的 UI 相關的消息傳遞給應用程序的 IME 窗口,應用程序能夠在這裏處理這些消息。下列代碼(包括適當的錯誤處理和可能更多已處理的消息)會出如今應用程序的 IME 窗口的窗口過程當中:
HIMC hIMC; LPVOID lpBufResult; COMPOSITIONFORM cf; DWORD dwBufLen; if (ImmIsUIMessage(hIMEWnd, uMsg, wParam, lParam) == TRUE) { switch(uMsg) { case WM_IME_COMPOSITION: if (lParam & GCS_RESULTSTR { hIMC = ImmGetContext(hWnd); dwBufLen = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, NULL) + sizeof(TCHAR); lpBufResult =?malloc(dwBufLen); if(ImmGetCompositionString(hIMC, GCS_RESULTSTR, lpBufResult, dwBufLen) > 0) { // ... // process the text in lpBufResult // ... } else // a negative error value was returned { // ... // handle an error // ... } free(lpBufResult); ImmReleaseContext(hWnd, hIMC); } break; } } return 0; }
一樣的窗口過程可能會調用 SendMessage 來從新配置狀態、複合或候選窗口,或打開、關閉狀態窗口。
SendMessage(hIMEWnd, WM_IME_CONTROL,
IMC_SETCOMPOSITIONWINDOW, "cf);
容許應用程序變動窗口位置或屬性的其餘 API 函數包括ImmSetCandidateWindow、ImmSetCompositionFont、ImmSet-CompositionString、ImmSetCompositionWindow 以及 ImmSetStatusWindowPos。包含部分 IME 支持的應用程序可以使用這些函數來設置 IME UI 窗口的樣式和位置,可是 IME 動態連接庫 (DLL) 仍負責繪製這些窗口 – IME UI 的常規外觀將保持不變。
徹底 IME 支持則大相徑庭,徹底識別 IME 的應用程序將接管經過 IME DLL 繪製 IME 窗口(狀態、複合以及候選窗口)的工做。此類應用程序能夠徹底自定義這些窗口的外觀,包括肯定其屏幕位置以及選擇使用哪些字體和字體樣式來顯示窗口中的字符。對於文字處理程序以及主要功能是文字處理的相似程序,這會使它們從流暢的 IME 交互以及建立「天然的」用戶交互界面中受益,所以顯得特別方便和有效。IME DLL 仍將決定在 IME 複合窗口和候選窗口中顯示的字符,而且它還會運用算法來猜想字符並在 IME 字典中查找它們。FULLIME 是一個自定義 IME UI 的示例,能夠在 Microsoft Windows Platform SDK 中找到它,網址爲http://msdn.microsoft.com。
徹底識別 IME 的應用程序將經過下列方式捕獲與 IME 相關的消息
您已確信您的應用程序能夠處理不一樣的輸入語言和方法。確保您的應用程序能夠支持多語言輸入、輸出以及顯示的另外一項任務是知足複雜腳本提出的固有要求。在隨後的各節中,您將會看到與複雜腳本相關聯的各類語言特色,並將瞭解到 Windows 對處理複雜腳本所提供的支持。