Windows 輸入法編輯器 (IME)

Windows 輸入法編輯器 (IME)

原著 :Microsoft

一、關於 Windows 混合語言 IME Windows ,IME 是一個動態鏈接庫 (DLL), Windows 3.1 遠東版本 IME 不同的是 ,每一個運行的 IME 相當於混合語言鍵盤佈局中的一種。與 Windows 3.1 IME 相比較 ,Windows 混合語言 IME 提供下列增強功能 :

運行時相當於混合語言環境的一個部件
爲每一個應用程序任務提供多重輸入上下文

爲每一個應用程序線程提供一個活動的 IME

通過應用程序消息循環給應用程序提供信息 ( 消息順序不能改變 )●爲無 IME 支持應用程序和部分 IME 支持應用程序提供有力的支持
要得到全部的增強功能 ,應用程序需要支持 Windows IME 應用程序 I / F

本文檔描述了 Windows 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

發佈了97 篇原創文章 · 獲贊 5 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章