程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 輸入法編程指南

輸入法編程指南

編輯:關於C++

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支持應用程序,具有以下優點(與對應的Windows3.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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved