輸入法編程指南(根據msdn翻譯)

Windows 95輸入法編輯器(IME)

原著:Microsoft 翻譯:TBsoft Software Studio

一、關於Windows 95混合語言IME

在Windows 95中,IME是一個動態鏈接庫(DLL),與Windows 3.1遠東版本IME不同 的是,每一個運行的IME相當於混合語言鍵盤佈局中的一種。與Windows 3.1 IME相 比較,Windows 95混合語言IME提供下列增強功能: ●運行時相當於混合語言環境的一個部件 ●爲每一個應用程序任務提供多重輸入上下文 ●爲每一個應用程序線程提供一個活動的IME ●通過應用程序消息循環給應用程序提供信息(消息順序不能改變) ●爲無IME支持應用程序和部分IME支持應用程序提供有力的支持 要得到全部的增強功能,應用程序需要支持Windows 95 IME應用程序I/F。 本文檔描述了Windows 95 IME體系結構的應用程序I/F。

1、IME的結構

Windows 95 IME必須提供兩個部件:IME轉換接口和IME用戶接口。IME轉換接口由 一組IME模塊引出函數提供,這些函數被IMM(輸入法管理器——譯者注)調用。 IME用戶接口由一組窗口提供,這些窗口接收消息並提供IME的用戶界面。

2、IME支持應用程序(IME感知應用程序——譯者注)

應用程序有下列類型: ●無IME支持應用程序:這種應用程序不控制IME,然而,如果應用程序接受DBCS字 符,用戶可以通過IME在應用程序中輸入DBCS字符。 ●部分IME支持應用程序:這種應用程序只控制不同的IME上下文,例如打開和關閉 IME、寫作窗口等等,但是不重新顯示任何IME用戶界面。 ●完全IME支持應用程序:這種應用程序負責管理通過IME顯示給應用程序的任何信 息。 在Windows 95中,一個無IME支持應用程序有一個缺省的IME窗口和一個缺省的輸入 上下文。 部分IME支持應用程序使用預定義的“IME”類創建自己的IME窗口,可以管理或者 不管理自己的輸入上下文。 完全IME支持應用程序自己管理輸入上下文,顯示輸入上下文給出的任何需要的信 息,不使用IME窗口。

二、IME用戶界面

IME用戶界面包括IME窗口、用戶界面(UI)窗口以及UI窗口的部件。

1、特徵

IME類是實現IME用戶界面部分的預定義全局窗口類。“IME”類與預定義的公共控 制窗口類有許多相同的特點,IME窗口實例與靜態控制一樣通過CreateWindowEx函 數創建,IME類窗口自己不響應用戶輸入,取而代之的是接收不同類型的控制消息 實現全部IME用戶接口。應用程序可以使用IME類創建自己的IME窗口,還可以使用 ImmGetDefaultIMEWnd函數獲取缺省IME窗口。創建自己的IME窗口或者使用缺省 IME窗口的應用程序被稱爲IME支持應用程序,具有以下優點(與對應的Windows 3.1應用程序比較): ●包括候選字列表窗口(候選窗口),每一個應用程序可以有自己的用戶界面窗口 實例,使得用戶可以在任何輸入過程的中途停止並切換到另一個應用程序。在 Windows 3.1日文版本中,用戶切換到另一個應用程序是必須放棄當前輸入過程。 ●因爲IME用戶界面窗口包括應用程序窗口句柄,IME用戶界面窗口可以爲應用程序 提供缺省行爲。例如當應用程序移動時IME用戶界面窗口自動移動,自動跟隨窗口 中的插入符號位置,爲每一個應用程序標示模式等等。 即使系統僅僅只提供一個IME類,IME窗口仍然有兩種類型。一種類型是系統爲無 IME支持應用程序創建的IME窗口,DefWindowProc函數爲該窗口處理消息, DefWindowProc函數的IME用戶接口被線程的所有無IME支持窗口共享,在文檔中, 這種窗口稱爲缺省IME窗口。另一種類型是IME支持應用程序創建的IME窗口,在文 檔中,IME支持應用程序創建的IME窗口稱作應用程序IME窗口。

2、缺省和應用程序IME窗口

當線程初始化時系統創建缺省IME窗口,這就是說,線程自動獲取缺省IME窗口。缺 省IME窗口爲無IME支持應用程序提供IME用戶界面,當IME或者IMM生成一個IME消息 (WM_IME_*)時,無IME支持應用程序傳遞該消息到DefWindowProc函數, DefWindowProc函數發送需要的消息到爲應用程序提供缺省IME用戶界面的缺省IME 窗口。IME支持應用程序當不從IME獲取消息時也可以使用缺省IME窗口,需要時可 以使用自身的IME窗口。

3、IME類

IME類是Windows 95遠東版本預定義的窗口類,就像Edit是預定義的窗口類一樣。 預定義的IME類實現全部的IME用戶接口,處理所有來自IME和包含IMM函數的應用程 序的消息,應用程序使用IME類創建自己的IME窗口。系統IME類不能被被任何IME替 換。 窗口過程與IME類通過WM_IME_SELECT消息交互,該消息包括新選中的IME的鍵盤布 局,IME類使用鍵盤佈局查找到每一個IME定義的類名。使用類名,IME類爲當前活 動的IME創建IME用戶界面窗口。

4、IME UI類

每一個IME必須向系統註冊自己的用戶界面(UI)類,UI類提供IME相關功能。當 IME附加在進程上時IME註冊自己的UI類,這就是說,當DLLEntry函數被調用 DLL_PROCESS_ATTACH功能時,IME必須在對ImeInquire函數的調用過程中指定UI類 名。UI類應該使用CS_IME窗口風格註冊以使得每一個應用程序都可以使用UI類。 UI類名(包括空終結符)可以使用16位的TCHAR字符,這個限制可能延續到 Windows的未來版本。 當註冊一個UI類時,應該指定8個字節的窗口附加數據(這就是說,設置 WNDCLASSEX類的cbWndExtra成員的值爲2*sizeof(LONG)),系統使用該窗口附加數 據。 IME可以在爲應用程序執行任務時註冊任何類和創建任何窗口。 下面的實例顯示了怎樣註冊IME窗口類:

BOOL WINAPI DLLEntry ( HINSTANCE hInstDLL, DWORD dwFunction, LPVOID lpNot) { switch (dwFunction) { case DLL_PROCESS_ATTACH: hInst= hInstDLL;

wc.style = CS_MYCLASSFLAG | CS_IME; wc.lpfnWndProc = MyUIServerWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 2 * sizeof(LONG); wc.hInstance = hInst; wc.hCursor = LoadCursor( NULL, IDC_ARROW); wc.hIcon = NULL; wc.lpszMenuName = (LPSTR) NULL; wc.lpszClassName = (LPSTR) szUIClassName; wc.hbrBackground = NULL;

if(!RegisterClass((LPWNDCLASS)&wc)) return FALSE;

wc.style = CS_MYCLASSFLAG | CS_IME; wc.lpfnWndProc = MyCompStringWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = cbMyWndExtra; wc.hInstance = hInst;

wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hIcon = NULL; wc.lpszMenuName = (LPSTR) NULL; wc.lpszClassName = (LPSTR) szUICompStringClassName; wc.hbrBackground = NULL;

if(!RegisterClass((LPWNDCLASS)&wc)) return FALSE;

break;

case DLL_PROCESS_DETACH: UnregisterClass(szUIClassName,hInst); UnregisterClass(szUICompStringClassName,hInst); break; } return TRUE; }

5、UI窗口

IME類對應的IME窗口被應用程序或者系統創建,當IME窗口被創建時,IME自身提供 的UI窗口被創建並被IME窗口所擁有。每一個UI窗口有一個當前的輸入上下文,當 UI窗口接收到IME消息(WM_IME_*)時,可以通過調用GetWindowLong函數和指定 IMMGWL_IMC索引值查找到輸入上下文,UI窗口可以根據輸入上下文處理消息,UI窗 口可以在除響應WM_CREATE消息以外的任何時間查找到輸入上下文。 IME不允許改變UI窗口的窗口附加數據,如果UI窗口的某個實例需要窗口附加數據 ,可以使用IMMGWL_PRIVATE參數值調用SetWindowLong和GetWindowLong函數, IMMGWL_PRIVATE參數值提供爲UI窗口的某個實例存取附加數據中LONG類型值的能力 ,如果需要大於LONG類型值的附加數據,可以保存一個內存塊的句柄到 IMMGWL_PRIVATE域。 UI窗口過程可以使用DefWindowProc函數,但是UI窗口不允許傳遞IME消息給 DefWindowProc函數,即使某個IME消息沒有被處理,UI窗口也不允許傳遞該消息給 DefWindowProc函數。

LRESULT UIWndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { HIMC hIMC; HGLOBAL hMyExtra;

switch(msg){ case WM_CREATE: // Allocate the memory bloack for the window instance. hMyExtra = GlobalAlloc(GHND,size_of_MyExtra); if (!hMyExtra) MyError();

// Set the memory handle into IMMGWL_PRIVATE SetWindowLong(hWnd, IMMGWL_PRIVATE, (LONG)hMyExtra); . . . break;

case WM_IME_xxxx: // Get IMC; hIMC = GetWindowLong(hWnd,IMMGWL_IMC);

// Get the memory handle for the window instance. hMyExtra = GetWindowLong(hWnd, IMMGWL_PRIVATE);

lpMyExtra = GlobalLock(hMyExtra); . . .

GlobalUnlock(hMyExtra);

break;

. . .

case WM_DESTROY: // Get the memory handle for the window instance. hMyExtra = GetWindowLong(hWnd, IMMGWL_PRIVATE);

// Free the memory block for the window instance. GlobalFree(hMyExtra); break;

default: return DefWindowProc(hWnd, msg, wParam, lParam);

} }

UI窗口必須在當前選定的輸入上下文中執行動作,當一個窗口被激活時,UI窗口接 收到提供當前輸入上下文的消息,此後,UI窗口運行在當前選中的輸入上下文上。 輸入上下文必須包括UI窗口顯示寫作窗口、狀態窗口等需要的所有信息。 UI窗口要求輸入上下文,但是窗口不必自己更新輸入上下文。當UI窗口需要更新輸 入上下文時,應該調用IMM函數,因爲輸入上下文由IMM函數管理,當輸入上下文更 新時,IMM和IME接收到通知消息。 例如,有時UI窗口當鼠標單擊時需要改變輸入上下文的轉換模式,爲了設置轉換模 式,UI窗口調用ImmSetConversionMode函數,該函數爲NotifyIME生成一個通知消 息併發送WM_IME_NOTIFY消息到UI窗口,如果UI窗口改變轉換模式的顯示,UI窗口 會等待處理WM_IME_NOTIFY消息。

6、UI窗口的部件

UI窗口可以根據輸入上下文註冊和顯示寫作窗口和狀態窗口,UI窗口的部件類的窗 口風格必須包括CS_IME。UI窗口的一個窗口實例從當前輸入上下文接收例如寫作字 符串、字體、位置等信息,當應用程序的一個窗口獲得焦點時,系統獲取該窗口自 己的輸入上下文並將當前輸入上下文傳遞給UI窗口,系統發送WM_IME_SETCONTEXT 消息和輸入上下文的句柄給應用程序,應用程序傳遞該消息給UI窗口。如果當前輸 入上下文被更新,UI窗口應該重新繪製寫作窗口,無論何時輸入上下文改變,UI窗 口都應該顯示正確的寫作窗口,可以保證IME的狀態。 UI窗口可以創建子窗口或者彈出式窗口顯示狀態、寫作字符串或者候選字列表,這 些窗口必須是UI窗口的附屬窗口,而且必須創建爲不可接收輸入(Disable)窗口 ,任何IME創建的窗口都不應該獲取焦點。

三、輸入上下文

1、缺省輸入上下文

缺省情況下系統給每個線程一個輸入上下文,該輸入上下文被線程的所有無IME支 持窗口共享。

2、輸入上下文與窗口的交互

應用程序的一個窗口可以使用窗口句柄與輸入上下文交互以維護任何IME狀態,包 括中間寫作字符串。一旦應用程序使得輸入上下文與窗口句柄交互,無論何時窗口 被激活,系統自動選中輸入上下文。使用這個特點,應用程序可以輕鬆地完成 Windows 3.1下必須的複雜切換處理。

3、使用輸入上下文

當應用程序或者系統創建新的輸入上下文時,系統準備新的輸入上下文,新的輸入 上下文已經包括IMCC,這個IMC的部件由hCompStr、hCandInfo、hGuideLine、 hPrivate和hMsgBuf組成。IME基本上不需要創建輸入上下文和輸入上下文的部件, 不過IME可以改變它們的大小,可以通過鎖定它們查找到部件的指針。

⑴存取HIMC

爲了存取輸入上下文,IME必須調用ImmLockIMC函數以查找到輸入上下文的指針, ImmLockIMC函數給IMC增加imm鎖定計數,ImmUnlockIMC函數減少之。

⑵存取HIMCC

爲了存取輸入上下文中的一個部件,IME必須調用ImmLockIMCC函數獲取IMCC的指針 ,ImmLockIMCC函數給IMCC增加imm鎖定計數,ImmUnlockIMCC函數減少之, ImmReSizeIMCC函數可以修改IMCC的大小以指定新的大小。 某些情況下,IME可能需要自己創建輸入上下文的一個部件,這種情況下,IME可以 調用ImmCreateIMCC函數獲取IMCC的句柄,這個IMCC可以是INPUTCONTEXT結構的成 員(hCompStr、hCandInfo、hGuideLine、hPrivate或者hMsgBuf)。 ImmDestroyIMCC清除輸入上下文的一個部件。

⑶怎樣使用輸入上下文

下面的實例顯示了怎樣使用輸入上下文

LPINPUTCONTEXT lpIMC; LPCOMOSITIONSTRING lpCompStr; HIMCC hMyCompStr;

if (hIMC) { // It is not NULL context. lpIMC = ImmLockIMC(hIMC);

if (!lpIMC) { MyError( "Can not lock hIMC"); return FALSE; }

// Use lpIMC->hCompStr. lpCompStr = (LPCOMPOSITIONSTRING) ImmLockIMCC(lpIMC->hCompStr);

// Access lpCompStr. ImmUnlockIMCC(lpIMC->hCompStr);

// ReSize lpIMC->hCompStr. if (!(hMyCompStr = ImmReSizeIMCC(lpIMC->hCompStr,dwNewSize)) { MyError("Can not resize hCompStr"); ImmUnlockIMC(hIMC); return FALSE; } lpIMC->hCompStr = hMyCompStr; ImmUnlockIMC(hIMC); }

四、生成消息

IME需要生成IME消息。當IME開始轉換時,IME必須生成WM_IME_STARTCOMPOSITION 消息,如果IME改變了寫作字符串,IME必須生成WM_IME_COMPOSITION消息,IME引 發的事件導致生成消息給與輸入上下文進行交互的窗口。IME基本上使用 ImeToAsciiEx函數參數提供的lpdwTransKey緩衝區生成消息,當ImeToAsciiEx函數 被調用時IME存儲消息到lpdwTransKey緩衝區中,不過即使ImeToAsciiEx函數沒有 被調用,IME也可以生成消息給使用輸入上下文的消息緩衝區與輸入上下文交互的 窗口。輸入上下文有一個內存塊的句柄作爲消息緩衝區,IME存儲消息到被消息緩 衝區句柄提供的內存塊中,以後IME調用ImmGenerateMessage函數, ImmGenerateMessage函數發送保存在消息緩衝區中的消息到適當的窗口。

1、在ImeToAsciiEx函數中使用消息緩衝區

下面的實例顯示了怎樣通過傳遞緩衝區到ImeToAsciiEx函數生成消息:

UINT ImeToAsciiEx(uVirKey, uScanCode, lpbKeyState, lpdwTransBuf, fuState , hIMC ) { DWORD dwMyNumMsg = 0;

. . .

// Set the messages that the IME needs to generate. *lpdwTransBuf++ = (DWORD) msg; *lpdwTransBuf++ = (DWORD) wParam; *lpdwTransBuf++ = (DWORD) lParam;

// Count the number of the messages that the IME needs to generate. dwMyNumMsg++; . . .

return dwMyNumMsg; }

系統提供lpdwTransBuf參數指定的緩衝區,IMEToAsciiEx函數可以一次存儲所有的 消息到該緩衝區中,緩衝區的第一個雙字給出存儲在緩衝區中的消息個數。如果 ImeToAsciiEx函數需要生成比這個給定的個數更多的消息,函數可以存儲所有的消 息到輸入上下文的hMsgBuf域中,然後函數ImeToAsciiEx返回消息個數。當 ImeToAsciiEx函數的返回值大於lpdwTransBuf中指定的值時,系統不從 lpdwTransBuf中取出消息,系統查找作爲ImeToAsciiEx函數參數傳遞的輸入上下文 中的hMsgBuf域。

2、使用消息緩衝區

下面的實例顯示了怎樣使用消息緩衝區:

MyGenerateMesage(HIMC hIMC, UINT msg, WPARAM wParam, LPARAMlParam) { LPINPUTCONTEXT lpIMC; HGLOBAL hTemp; LPDWORD lpdwMsgBuf; DWORD dwMyNumMsg = 1;

// Lock the input context. lpIMC = ImmLockIMC(hIMC); if (!lpIMC) // Error!

// re-allocate the memory bloack for the message buffer. hTemp = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf + dwMyNumMsg) * sizeof(DWORD) * 3); if (!hTemp) // Error!

lpIMC->hMsgBuf = hTemp;

// Lock the memory for the message buffer. lpdwMsgBuf = ImmLockIMCC(lpIMC->hMsgBuf); if (!lpdwMsgBuf) // Error!

lpdwNumMsgBuf += 3 * lpIMC->dwNumMsgBuf. // Set the number of the messages. lpIMC->dwNumMsgBuf += dwMyNumMsg;

// Set the messages that the IME needs to generate. *lpdwMsgBuf++ = (DWORD) msg; *lpdwMsgBuf++ = (DWORD) wParam; *lpdwMsgBuf++ = (DWORD) lParam;

// Unlock the memory for the message buffer and the input context.

ImmUnlockIMCC(lpIMC->hMsgBuf); ImmLockIMC(hIMC);

// Call ImmGenerateMessage function. ImmGenerateMessage(hIMC); }

3、WM_IME_COMPOSITION消息

當IME生成WM_IME_COMPOSITION消息時,IME指定lParam參數爲GCS位。GCS位的意義 是COMPOSITIONSTRING結構中的有效成員,即使IME沒有更新,成員目前仍然有效, IME也會設置GCS位。

爲IME定義服務

當IME生成WM_IME_COMPOSITION消息時,IME可能會立刻改變字符串、屬性以及子句 信息。IME使用下列定義:

GCS_COMP GCS_COMPREAD GCS_RESULT GCS_RESULTREAD

五、關於ImeSetCompositionString函數

1、ImeSetCompositionString函數能力

如果IME沒有ImeSetCompositionString函數能力,IME將不能在IMEINFO結構中指定 任何SCS能力。如果IME可以處理ImeSetCompositionString函數,IME設置 SCS_COMPSTR位。如果IME可以通過寫作字符串生成解釋(本文中的“解釋”是單詞 “reading”的直譯,真正意義可能是“原始輸入的”,例如輸入的漢語拼音字母 字符串,下同)字符串,IME可以設置SCS_CAP_MAKEREAD位。 如果IME有SCS_CAP_COMPSTR能力,ImeSetCompositionString函數將被調用,IME從 應用程序獲取新的寫作字符串並生成WM_IME_COMPOSITION消息。 如果IME有SCS_CAP_MAKEREAD能力,IME可以通過寫作字符串建立解釋字符串。

2、關於SCS_SETSTR

如果ImeSetCompositionString函數的dwIndex參數值爲SCS_SETSTR,IME可以清除 hIMC中的COMPOSITIONSTR結構中所有的域。 如果IME需要,IME可以更新候選信息並生成候選消息IMN_OPENCANDIDATE、 IMN_CHANGECANDIDATE或者IMN_CLOSECANDIDATE。 如果ImeSetCompositionString函數的lpRead參數有效,IME應該通過lpRead參數中 的解釋字符串建立寫作字符串,另外IME爲新的寫作字符串和lpRead參數中的解釋 字符串建立屬性和子句信息,IME生成lParam參數爲(GCS_COMP|GCS_COMPREAD)的 WM_IME_COMPOSITION消息。有時IME需要自動確定建立上述信息,這種情況下, IME可以生成lParam參數以(GCS_RESULT|GCS_RESULTREAD)代替GCS_COMPxxx的消 息。 如果ImeSetCompositionString函數的lpComp參數有效,IME應該通過lpComp參數中 的寫作字符串建立寫作屬性和子句信息,IME生成lParam參數爲GCS_COMP的 WM_IME_COMPOSITON消息。如果IME有SCS_CAP_MAKEREAD能力,IME應該同時建立解 釋字符串,IME生成lParam參數爲(GCS_COMP|GCS_COMPREAD)的 WM_IME_COMPOSITION消息。有時IME需要自動確定建立上述信息,這種情況下, IME可以生成lParam參數以(GCS_RESULT|GCS_RESULTREAD)代替GCS_COMPxxx的消 息。 如果lpRead參數和lpComp參數同時有效,IME應該建立寫作字符串和解釋字符串, 這時IME不需要完全按照lpRead參數和lpComp參數。如果IME不能建立應用程序指定 的lpRead參數和lpComp參數之間的關係,IME應該修正寫作字符串,IME爲新的寫作 字符串和lpRead參數指定的解釋字符串建立屬性和子句信息,IME生成lParam參數 爲(GCS_COMP|GCS_COMPREAD)的WM_IME_COMPOSITION消息。有時IME需要自動完成 建立上述信息,這種情況下,IME可以生成lParam參數以( GCS_RESULT|GCS_RESULTREAD)代替GCS_COMPxxx的消息。

3、關於SCS_CHANGEATTR

SCS_CHANGEATTR隻影響屬性信息,IME不應該更新寫作字符串、寫作字符串的子句 信息、寫作字符串的解釋以及寫作字符串的解釋子句信息。 首先IME檢查新的屬性並判斷新的屬性是否可用,然後IME設置屬性到hIMC中的 COMPOSITIONSTRING結構中,最後IME生成WM_IME_COMPOSITION消息。 如果需要,IME可以更新候選信息並生成候選消息IMN_OPENCANDIDATE、 IMN_CHANGECANDIDATA、IMN_CLOSECANDIDATE。 IME不能確定寫作字符串。 如果ImeSetCompositionString函數的lpRead參數有效,IME使用lpRead參數中的新 屬性。IME也應該爲當前寫作字符串建立寫作字符串的新屬性,這時子句信息不被 修改。 寫作字符串、屬性、子句信息、解釋字符串、解釋屬性和解釋子句信息必須有效。 IME生成lParam參數爲(GCS_COMP|GCS_COMPREAD)的WM_IME_COMPOSITION消息,如 果IME不能接受lpComp參數中的新屬性,IME不需要生成任何消息並返回FALSE。 如果ImeSetCompositionString函數的lpComp參數有效,IME使用lpComp參數中的新 屬性,這時子句信息不被修改。 如果IME有SCS_CAP_MAKEREAD能力,並且解釋字符串有效,IME應該爲當前寫作字符 串的解釋建立寫作字符串的解釋的新屬性。 如果lpRead參數和lpComp參數同時有效,並且如果IME能夠接受新的信息,IME設置 新的信息到hIMC中的COMPOSITION結構中並生成lParam參數爲( GCS_COMP|GCS_COMPREAD)的WM_IME_COMPOSITION消息。

4、關於SCS_CHANGECLAUSE

SCS_CHANGECLAUSE影響寫作字符串和寫作字符串的解釋的字符串和屬性。 如果需要,IME可以更新候選信息並生成候選消息IMN_OPENCANDIDATE、 IMN_CHANGECANDIDATA、IMN_CLOSECANDIDATE。 IME不能確定寫作字符串。 如果ImeSetCompositionString函數的lpRead參數有效,IME使用lpRead參數中的解 釋子句信息。IME必須修正寫作字符串的解釋的屬性,IME可以更新寫作字符串、屬 性和寫作字符串的子句信息,IME生成lParam參數爲(GCS_COMP|GCS_COMPREAD)的 WM_IME_COMPOSITION消息。 如果ImeSetCompositionString函數的lpComp參數有效,IME使用新的子句信息。 IME必須修正寫作字符串和寫作字符串的屬性,IME可以更新解釋屬性和解釋的子句 信息,IME生成lParam參數爲(GCS_COMP|GCS_COMPREAD)的WM_IME_COMPOSITION消 息。 如果lpRead參數和lpComp參數同時有效,並且如果IME能夠接受新的信息,IME設置 新的信息到hIMC中的COMPOSITION結構中並生成lParam參數爲( GCS_COMP|GCS_COMPREAD)的WM_IME_COMPOSITION消息。

六、軟鍵盤

1、關於軟鍵盤

一些IME有特殊的解釋字符,例如一個IME可能使用注音符號作爲解釋字符(這裏指 臺灣中文版Windows 95,即CWin95中的注音符號,PWin95中可能指漢語拼音字母或 者音調符號——譯者注),另一個IME使用了一些字根符號(原文單詞是“ radials”,但實際可能是“radicals”——譯者注)作爲解釋字符,IME可以提供 一個軟鍵盤顯示這些特殊解釋字符使得用戶不必逐鍵記憶解釋字符。 IME需要根據不同的變換狀態改變鍵表示的解釋字符,使用軟鍵盤可以通知用戶鍵 的改變。在選擇候選字時,IME可以只顯示那些選擇鍵給用戶。

2、使用軟鍵盤

IME可能需要爲軟鍵盤創建一個更好的用戶界面,或者可能需要系統預定義的軟鍵 盤,如果IME需要使用系統預定義的軟鍵盤,IME需要在調用ImeInquire函數時將 IMEINFO結構的fdwUICaps成員指定爲UI_CAP_SOFTKBD。 IME可以調用ImmCreateSoftKeyboard函數爲軟鍵盤創建窗口,還可以調用 ImmShowSoftKeyboard函數顯示或者隱藏軟鍵盤。軟鍵盤窗口是UI窗口的一個組件 ,所以軟鍵盤窗口應該附屬於UI窗口。 IME可能需要決定是否在無論何時焦點移走的情況下刪除窗口,軟鍵盤可能佔有一 些系統資源(可能需要釋放——譯者注) 軟鍵盤有不同的類型,一種類型可能是爲特定的國家或者特定的目的設計的。爲每 一種類型的軟鍵盤改變解釋字符的方式可能不同,有兩種改變解釋字符的方式:使 用IMC_SETSOFKBDSUBTYPE或者IMC_SETSOFKBDDATA。不同類型的軟鍵盤有不同的窗 口過程並存在不同的用戶界面給用戶。

七、IME接口

在Windows 95中,IME與設備驅動程序一樣是動態鏈接庫(DLL),輸入法管理器( IMM)應該處理所有安裝的IME。因爲IME在運行時是可以改變的,不需要重新啓動 系統,IMM有一個結構用於維護每一個IME的所有入口點。 IME函數列表是所有遠東版本Windows 95公共IME功能函數的描述,這些函數不應該 在應用程序中直接調用。

UI窗口中的IMM函數

下面是可以在UI窗口中調用的IMM函數:

ImmGetCompositionWindow ImmSetCompositionWindow ImmGetCandidateWindow ImmSetCandidateWindow ImmGetCompositionString ImmSetCompositionString ImmGetCompositionFont ImmSetCompositionFont ImmGetNumCandidateList ImmGetCandidateList ImmGetGuideLine ImmGetConversionStatus ImmGetConversionList ImmGetOpenStatus ImmSetConversionStatus ImmSetOpenStatus ImmNotifyIME ImmCreateSoftKeyboard ImmDestroySoftKeyboard ImmShowSoftKeyboard

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章