IME输入法相关

在了解工作原理前,必先清楚几个概念。

IME输入法相关_第1张图片

IME输入法相关_第2张图片

        以下为输入法工作原理,如果不知道工作原理,只看输入法程序,那很难理解,同时,只知道工作原理,而不清楚程序是如何实现,也无法深入理解输入法。二者相辅相成,共同参照,方可加深理解。

       输入法工作原理 如下图:

IME输入法相关_第3张图片

以下结合IME转换接口 分别对其说明:

输入法初始化:

ImeInquire : 刚选择某输入法时,IMM调用此函数,获得输入法相关信息,并根据用户界面类UICLASSNAME,自动创建用户界面。

ImeSelect  : 打开或关闭输入法时被调用,在此函数中对输入法上下文进行初始化或恢复释放

IMM将键盘消息传递给IME:

IMM 通过IME 转换接口ImeProcessKey 将键盘消息发动到IME

此函数对键盘消息进行筛选处理,用以判断此消息是发送给IME 还是直接发送给应用程序。

如果返回TRUE 则发送给IME  否则,直接发送给应用程序

IME将键盘消息转换为相应汉字:

IME 通过ImeToAsciiEx 函数来处理ImeProcessKey发送过来的键盘消息,并最终转换为输出的结果串

IME 将汉字以字符消息的形式返回给IMM:

IME将使用WM_IME_CHAR或 WM_IME_COMPOSITION/GCS_RESULT消息把组合好的字符发送给窗体中的应用程序。如果应用程序没有处理这些消息,DefWindowProc函数会把它们翻译成一条或多条WM_CHAR消息

示例:

MakeResultString 将转换结果保存在输入上下文中将

GenerateMessage   发送WM_IME_COMPOSITION/GCS_RESULT消息给应用程序,从而使得应用程序获得结果串

[cpp] view plain copy print ?
  1. BOOL MakeResultString(BOOL fFlag) 
  2.     HIMC                hIMC; 
  3.     LPINPUTCONTEXT      lpIMC           = NULL; 
  4.     LPCOMPOSITIONSTRING lpIMECompStr    = NULL; 
  5.     LPTSTR          lpResultStr         = NULL; 
  6.     GENEMSG         GnMsg               = {0}; 
  7.  
  8.     GetIMC(&hIMC, &lpIMC); 
  9.     lpIMECompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr); 
  10.  
  11.     if (fFlag)  
  12.     { 
  13.         lpResultStr = GetResultStr(); 
  14.         if (!lpResultStr) return FALSE; 
  15.         _tcscpy((LPTSTR)((LPBYTE)(lpIMECompStr) + (lpIMECompStr)->dwResultStrOffset), lpResultStr); 
  16.         lpIMECompStr->dwResultStrLen = _tcslen(lpResultStr); 
  17.     } 
  18.     else 
  19.     { 
  20.         *((LPTSTR)((LPBYTE)(lpIMECompStr) + (lpIMECompStr)->dwResultStrOffset)) = _T('\0');  
  21.         lpIMECompStr->dwResultStrLen = 0; 
  22.     } 
  23.  
  24.     InitBMStr(); 
  25.     InitCandStrPage(); 
  26.     InitCandList(); 
  27.  
  28.     ImmUnlockIMCC(lpIMC->hCompStr); 
  29.     GenerateMessage(WM_IME_COMPOSITION,0,GCS_RESULTSTR); 
  30.     GenerateMessage(WM_IME_ENDCOMPOSITION,0,0); 
  31.     ImmUnlockIMC(hIMC); 
  32.     return TRUE; 
  33.  
  34. BOOL GenerateMessage(UINT message,WPARAM wParam,LPARAM lParam) 
  35.     HIMC                hIMC            = {0}; 
  36.     LPINPUTCONTEXT      lpIMC           = NULL; 
  37.     LPDWORD             lpdwTransBuf    = NULL; 
  38.  
  39.     GetIMC(&hIMC, &lpIMC); 
  40.     if (IsWindow(lpIMC->hWnd)) 
  41.     { 
  42.         // re-allocate the memory block for the message buffer. 
  43.         lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf + 1) *  sizeof(DWORD) * 3); 
  44.         if (!lpIMC->hMsgBuf) goto Error; 
  45.  
  46.         // Lock the memory for the message buffer. 
  47.         lpdwTransBuf = (LPDWORD)ImmLockIMCC(lpIMC->hMsgBuf); 
  48.         if (!lpdwTransBuf) goto Error; 
  49.          
  50.         // Set the messages that the IME wants to generate. 
  51.         *(lpdwTransBuf++) = message; 
  52.         *(lpdwTransBuf++) = wParam; 
  53.         *(lpdwTransBuf++) = lParam; 
  54.  
  55.         // Set the number of the messages. 
  56.         (lpIMC->dwNumMsgBuf)++; 
  57.          
  58.         // Unlock the memory for the message buffer and the Input Context. 
  59.         ImmUnlockIMCC(lpIMC->hMsgBuf); 
  60.  
  61.         // Call ImmGenerateMessage function. 
  62.         ImmGenerateMessage(hIMC); 
  63.     } 
  64.  
  65. Error: 
  66.     ImmUnlockIMC(hIMC); 
  67.     return TRUE; 

 

 

 

常用函数

BOOL WINAPI ImmGenerateMessage( //将汉字串法发送到与当前输入法相关联的应用软件中

HIMC hIMC

);//成功为TRUE,否则为FALSE

 

LRESULT WINAPI ImmRequestMessage( //向应用程序发送WM_IME_REQUEST消息

HIMC hIMC, //与当前输入法相关联的应用软件的句柄

WPARAM wParam, //与WM_IME_REQUEST相关的wP

LPARAM lParam //与WM_IME_REQUEST相关的LP

);

 

LPINPUTCONTEXT WINAPI ImmLockIMC( //获取当前IMC的INPUTCONTEXT结构信息,增加IMC 计数器

HIMC hIMC

);//成功返回INPUTCONTEXT 结构指针,否则为NULL

 

BOOL WINAPI ImmUnlockIMC( //释放IMC计数器

HIMC hIMC );//返回:如果IMC计数器被减少到0了,返回FALSE,否则为TRUE.

注意:ImmLockIMC与ImmUnlockIMC必须成对出现,必须是相同的HIMC

 

HIMCC WINAPI ImmGetIMCLockCount( //取计数器值

HIMC hIMC );//如果成功返回HIMC的计数器值,否则为NULL.

 

HIMCC WINAPI ImmCreateIMCC( //创建INPUTCONTEXT结构的一个成员

DWORD dwSize //成员的缓冲区长度

);//如果成功返回IMC的成员句柄,否则为NULL

 

HIMCC WINAPI ImmDestroyIMCC( //删除IMC成员缓冲区

HIMCC hIMCC

);//如果成功返回NULL,否则等于该HIMCC.

 

LPVOID WINAPI ImmLockIMCC( //取IMCC缓冲地址,同时使IMCC的计数器值增加

HIMCC hIMCC );

 

BOOL WINAPI ImmUnlockIMCC( //递减IMCC计数器

HIMCC hIMCC );//如果IMCC的计数器值为零,则返回 FALSE,否则为TRUE.

 

10、HIMCC WINAPI ImmReSizeIMCC( //重新设置IMC的成员的缓冲区大小

HIMCC hIMCC, //IMC的成员句柄

DWORD dwSize //新缓冲区大小

);//如果成功,返回新的HIMCC,否则为 NULL.

 

DWORD WINAPI ImmGetIMCCSize( //取IMC成员的缓冲区大小

HIMCC hIMCC );//返回IMC成员的缓冲区大小

 

12、DWORD WINAPI ImmGetIMCCLockCount( //返回IMC计数器值

HIMCC hIMCC

);//成功返回该IMCC的计数器值,否则为0

 

BOOL WINAPI ImmGetHotKey( //取输入法状态键,该函数供控制面板使用

DWORD dwHotKeyID,

LPUINT lpuModifiers,

LPUINT lpuVKey,

LPHKL lphKL

)

 

BOOL WINAPI ImmSetHotKey( //设置输入法的热键

DWORD dwHotKeyID,

UINT uModifiers,

UINT uVKey,

hKL hKL

)

HWND WINAPI ImmCreateSoftKeyboard( //产生一个软键盘

UINT uType, //软件盘上的键码含义的定义方式

UINT hOwner, //该输入法的UI窗口

int x, //x坐标

int y //y坐标

);//成功返回软键盘的窗口句柄

 

BOOL WINAPI ImmDestroySoftKeyboard( //销毁软键盘

HWND hSoftKbdWnd //软键盘窗口句柄

);//成功为TRUE,法哦则为FALSE.

 

17、BOOL WINAPI ImmShowSoftKeyboard( //显示或隐藏软键盘

HWND hSoftKbdWnd, //软键盘窗口句柄

int nCmdShow //SW_HIDE=隐藏,SW_SHOWNOACTIVATE=显示

);//如构成功返回 TRUE. 否则为 FALSE.


 IME  文件中的常用结构

 

1、IMEINFOstruct tagIMEInfo { //输入法的接口信息

DWORD dwPrivateDataSize;//用户设计的数据结构的字节数

DWORD fdwProperty; //输入法对键盘事件的相应特性

DWORD fdwConversionCaps;//当前输入法具有的功能特性,如有软键盘、标点、中西文切换等功能

DWORD fdwSentenceCaps;

DWORD fdwUICaps; // 用户界面能力:支持软键盘等

DWORD fdwSCSCaps; // 用户设置编码串的能力

DWORD fdwSelectCaps; // 输入法切换时是否使用以前输入法的模式

} IIMEINFO;

2、COMPOSITIONSTR 用于编码管理

typedef struct tagCOMPOSITIONSTR {

DWORD dwSize; //当前编码信息需要的存储空间

DWORD dwCompReadAttrLen;   //读入的编码属性长度

DWORD dwCompReadAttrOffset; //读入的编码的位置

DWORD dwCompReadClsLen;     //读入的子串长度

DWORD dwCompReadClsOffset; //读入的子串的位置

DWORD dwCompReadStrLen;    //读入的编码长度

DWORD dwCompReadStrOffset; //读入的编码的位置

DWORD dwCompAttrLen; //编码属性长度

DWORD dwCompAttrOffset; //编码属性在内存的位置

DWORD dwCompClsLen; //编码子串长度

DWORD dwCompClsOffset; //编码子串在内存的位置

DWORD dwCompStrLen; //编码串长度

DWORD dwCompStrOffset; //编码串在内存的位置

DWORD dwCursorPos; //当前光标位置

DWORD dwDeltaStart; //被修改编码的位置

DWORD dwResultReadClsLen; //读入结果子串长度

DWORD dwResultReadClsOffset; //读入结果子串在内存的位置

DWORD dwResultReadStrLen; //读入的编码长度

DWORD dwResultReadStrOffset;  //读入的编码在内存的位置

DWORD dwResultClsLen; //结果子串长度

DWORD dwResultClsOffset; //结果子串在内存的位置

DWORD dwResultStrLen; //结果串长度

DWORD dwResultStrOffset; //结果串在内存的位置

DWORD dwPrivateSize; //用户自定义数据长度

DWORD dwPrivateOffset; //用户自定义数据在内存的位置

} COMPOSITIONSTR;

3、CANDIDATEINFO 用于编码选择管理

typedef struct tagCANDIDATEINFO {

DWORD dwSize; //数据所占内存大小

DWORD dwCount; //数据个数

DWORD dwOffset[32]; //各个编码列表的内存位置

DWORD dwPrivateSize; //自定义数据尺寸

DWORD dwPrivateOffset; //缓冲区位置

} CANDIDATEINFO;

4、GUIDELINE

typedef struct tagGUIDELINE {

DWORD dwSize;

DWORD dwLevel;

DWORD dwIndex;

DWORD dwStrLen;

DWORD dwStrOffset;

DWORD dwPrivateSize;

DWORD dwPrivateOffset;

} GUIDELINE;

5、CANDIDATELIST 编码选择列表信息

typedef struct tagCANDIDATELIST {

DWORD dwSize; // 用字节表示的内存大小

DWORD dwStyle; // 列表串的取值方式

DWORD dwCount; // 当前列表个数

DWORD dwSelection; // 当前选择的列表序号

DWORD dwPageStart; // 在列表窗口中所显示的列表的起始序号

DWORD dwPageSize; // 一页显示的列表个数

DWORD dwOffset[]; // 列表数据存放区地址

} CANDIDATELIST;

6、COMPOSITIONFORM 窗口位置、大小信息:

typedef tagCOMPOSITIONFORM {

DWORD dwStyle; //管理窗口方式

POINT ptCurrentPos; //给定坐标

RECT rcArea;

}COMPOSITIONFORM;

7、CANDIDATEFORM 列表窗口信息

typedef tagCANDIDATEFORM {

DWORD dwIndex; //列表窗口序号

DWORD dwStyle; //属性:

POINT ptCurrentPos; //坐标位置

REC rcArea;

} CANDIDATEFORM;

12、INPUTCONTEXT IMC 数据存放区

typedef struct tagINPUTCONTEXT {

HWND hWnd; //使用该IMC的窗口

BOOL fOpen; //IME的打开与关闭状态

POINT ptStatusWndPos; //状态窗口的位置

POINT ptSoftKbdPos; //软键盘的位置

DWORD fdwConversion; //IME状态(活动、不活动,全角等)

DWORD fdwSentence; //编码方式

union {

LOGFONTA A;

LOGFONTW W;

} lfFont; //字体

COMPOSITIONFORM cfCompForm; //编码格式结构

CANDIDATEFORM cfCandForm[4]; //列表选择结构

HIMCC hCompStr;HIMCC hCandInfo;

HIMCC hGuideLine

HIMCC hPrivate;

DWORD dwNumMsgBuf; //存放在hMsgBuf中的消息数

HIMCC hMsgBuf; //存放的消息

DWORD fdwInit //系统根据此值来初始本结构相应的信息

DWORD dwReserve[3]; //未定义

} INPUTCONTEXT;      

 

你可能感兴趣的:(IME输入法相关)