输入法(IME)实现原理

输入法(IME)实现原理一、实现原理1.中文输入法的组成微软 Windows 系统中输入法由程序(DLL)名称为:*.ime文件和码表文件(字典)名称为*.mb文件组成。2.中文输入法的界面http://wjy.hanwenhua.com/images/Projec6.gif3.在 Windows 任务栏“EN图标”中增加输入法名称这也就是 Setup 程序的关键,实际上,可以利用 Win32Api 函数 ImmInstallIME() 。该函数的原形是:HKL ImmInstallIME( LPCTSTR lpszIMEFileName, LPCTSTR lpszLayoutText);前一个参数 lpszIMEFileName 是“.ime”文件的路径,Win9x 为“\System”下,WinNT/2000为“\System32”下。后一个参数 lpszLayoutText 是输入法的明称。如 HKL MyIme=ImmInstallIME("Windows\\system\\3jaja.ime","3++输入法"); 如果 MyIme 不返回 NULL ,则调用成功。4.“.ime”文件的实现程序中的输出函数(必须)即文件“.def”中的函数,以下为函数的名称和原形,部分函数给出了原函数,希望对你能有所帮助。BOOL WINAPI ImeInquire(LPIMEINFO lpImeInfo,LPTSTR lpszWndCls,DWORD lpszOptions) { lpImeInfo->dwPrivateDataSize = sizeof(PRIVCONTEXT); lpImeInfo->fdwProperty = IME_PROP_KBD_CHAR_FIRST | IME_PROP_CANDLIST_START_FROM_1 | IME_PROP_IGNORE_UPKEYS; lpImeInfo->fdwConversionCaps = IME_CMODE_NATIVE|IME_CMODE_NATIVE|IME_CMODE_FULLSHAPE|IME_CMODE_CHARCODE | IME_CMODE_SOFTKBD | IME_CMODE_NOCONVERSION; lpImeInfo->fdwSentenceCaps = 0; lpImeInfo->fdwUICaps = UI_CAP_ROT90 | UI_CAP_SOFTKBD; lpImeInfo->fdwSCSCaps = SCS_CAP_COMPSTR | SCS_CAP_MAKEREAD; lpImeInfo->fdwSelectCaps = (DWORD)0; lstrcpy(lpszWndCls, (LPTSTR)szUIClassName); } DWORD WINAPI ImeConversionList(HIMC hIMC,LPCTSTR lpszSrc,DWORD uBufLen,UINT uFlag) { } BOOL WINAPI ImeConfigure(HKL hKL,HWND hAppWnd,DWORD dwMode,LPVOID lpData) { { DialogBox(hInst, MAKEINTRESOURCE(SETIME), (HWND)hAppWnd, (DLGPROC)ImeSetDlgProc); } } BOOL WINAPI ImeDestroy(UINT uReserved) { } LRESULT WINAPI ImeEscape(HIMC hIMC,UINT uSubFunc,LPVOID lpData) { { case IME_ESC_QUERY_SUPPORT: { case IME_ESC_QUERY_SUPPORT: case IME_ESC_GETHELPFILENAME: case IME_ESC_SEQUENCE_TO_INTERNAL: case IME_ESC_GET_EUDC_DICTIONARY: case IME_ESC_SET_EUDC_DICTIONARY: case IME_INPUTKEYTOSEQUENCE: } case IME_ESC_SEQUENCE_TO_INTERNAL: case IME_ESC_GET_EUDC_DICTIONARY: case IME_ESC_SET_EUDC_DICTIONARY: case IME_INPUTKEYTOSEQUENCE: case IME_ESC_GETHELPFILENAME: { TCHAR szIMEGUDHlpName[MAXSTRLEN]; szIMEGUDHlpName[0] = 0; GetWindowsDirectory((LPTSTR)szIMEGUDHlpName, MAXSTRLEN); lstrcat((LPTSTR)szIMEGUDHlpName, TEXT("file://HELP//3JaJa.hlp")); lstrcpy((char*)lpData, (char*)szIMEGUDHlpName); } } } BOOL WINAPI ImeSelect(HIMC hIMC,BOOL fSelect) { LPINPUTCONTEXT lpIMC; lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); fRet = Select(hIMC, lpIMC, fSelect); ImmUnlockIMC(hIMC); } BOOL WINAPI ImeSetActiveContext(HIMC hIMC,BOOL fOn) { { LPINPUTCONTEXT lpIMC; lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); InitContext(lpIMC); ImmUnlockIMC(hIMC); } } BOOL WINAPI ImeProcessKey(HIMC hIMC,UINT uVirtKey,LPARAM lParam,CONST LPBYTE lpbKeyState); BOOL WINAPI ImeSetCompositionString(HIMC hIMC,DWORD dwIndex,LPVOID lpComp,DWORD dwCompLen,LPVOID lpRead,DWORD dwReadLen); UINT WINAPI ImeToAsciiEx(UINT uVirtKey,UINT uScanCode,CONST LPBYTE lpbKeyState,LPTRANSMSGLIST lpTransBuf,UINT fuState,HIMC hIMC) BOOL WINAPI NotifyIME(HIMC hIMC,DWORD dwAction,DWORD dwIndex,DWORD dwValue); BOOL WINAPI ImeRegisterWord(LPCTSTR lpszReading,DWORD dwStyle,LPCTSTR lpszString) { } BOOL WINAPI ImeUnregisterWord(LPCTSTR lpszReading,DWORD dwStyle,LPCTSTR lpszString) { } UINT WINAPI ImeGetRegisterWordStyle(UINT nItem,LPSTYLEBUF lpStyleBuf) { } UINT WINAPI ImeEnumRegisterWord(REGISTERWORDENUMPROC lpfnRegisterWordEnumProc, LPCTSTR lpszReading,DWORD dwStyle,LPCTSTR lpszString,LPVOID lpData) { } LRESULT CALLBACK UIWndProc(HWND hUIWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { { CreateUIWindow(hUIWnd); DestroyUIWindow(hUIWnd); case WM_IME_STARTCOM } } LRESULT CALLBACK StatusWndProc(HWND hStatusWnd,UINT uMsg,WPARAM wParam,LPARAM lParam); LRESULT CALLBACK CompWndProc(HWND hCompWnd,UINT uMsg,WPARAM wParam,LPARAM lParam); LRESULT CALLBACK CandWndProc(HWND hCandWnd,UINT uMsg,WPARAM wParam,LPARAM lParam); BOOL WINAPI ImeInquire(LPIMEINFO lpImeInfo,LPTSTR lpszWndCls,DWORD lpszOptions) { lpImeInfo->dwPrivateDataSize = sizeof(PRIVCONTEXT); lpImeInfo->fdwProperty = IME_PROP_KBD_CHAR_FIRST | IME_PROP_CANDLIST_START_FROM_1 | IME_PROP_IGNORE_UPKEYS; lpImeInfo->fdwConversionCaps = IME_CMODE_NATIVE|IME_CMODE_NATIVE|IME_CMODE_FULLSHAPE|IME_CMODE_CHARCODE | IME_CMODE_SOFTKBD | IME_CMODE_NOCONVERSION; lpImeInfo->fdwSentenceCaps = 0; lpImeInfo->fdwUICaps = UI_CAP_ROT90 | UI_CAP_SOFTKBD; lpImeInfo->fdwSCSCaps = SCS_CAP_COMPSTR | SCS_CAP_MAKEREAD; lpImeInfo->fdwSelectCaps = (DWORD)0; lstrcpy(lpszWndCls, (LPTSTR)szUIClassName); } DWORD WINAPI ImeConversionList(HIMC hIMC,LPCTSTR lpszSrc,DWORD uBufLen,UINT uFlag) { } BOOL WINAPI ImeConfigure(HKL hKL,HWND hAppWnd,DWORD dwMode,LPVOID lpData) { { DialogBox(hInst, MAKEINTRESOURCE(SETIME), (HWND)hAppWnd, (DLGPROC)ImeSetDlgProc); } } BOOL WINAPI ImeDestroy(UINT uReserved) { } LRESULT WINAPI ImeEscape(HIMC hIMC,UINT uSubFunc,LPVOID lpData) { { case IME_ESC_QUERY_SUPPORT: { case IME_ESC_QUERY_SUPPORT: case IME_ESC_GETHELPFILENAME: case IME_ESC_SEQUENCE_TO_INTERNAL: case IME_ESC_GET_EUDC_DICTIONARY: case IME_ESC_SET_EUDC_DICTIONARY: case IME_INPUTKEYTOSEQUENCE: } case IME_ESC_SEQUENCE_TO_INTERNAL: case IME_ESC_GET_EUDC_DICTIONARY: case IME_ESC_SET_EUDC_DICTIONARY: case IME_INPUTKEYTOSEQUENCE: case IME_ESC_GETHELPFILENAME: { TCHAR szIMEGUDHlpName[MAXSTRLEN]; szIMEGUDHlpName[0] = 0; GetWindowsDirectory((LPTSTR)szIMEGUDHlpName, MAXSTRLEN); lstrcat((LPTSTR)szIMEGUDHlpName, TEXT("file://HELP//3JaJa.hlp")); lstrcpy((char*)lpData, (char*)szIMEGUDHlpName); } } } BOOL WINAPI ImeSelect(HIMC hIMC,BOOL fSelect) { LPINPUTCONTEXT lpIMC; lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); fRet = Select(hIMC, lpIMC, fSelect); ImmUnlockIMC(hIMC); } BOOL WINAPI ImeSetActiveContext(HIMC hIMC,BOOL fOn) { { LPINPUTCONTEXT lpIMC; lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); InitContext(lpIMC); ImmUnlockIMC(hIMC); } } BOOL WINAPI ImeProcessKey(HIMC hIMC,UINT uVirtKey,LPARAM lParam,CONST LPBYTE lpbKeyState); BOOL WINAPI ImeSetCompositionString(HIMC hIMC,DWORD dwIndex,LPVOID lpComp,DWORD dwCompLen,LPVOID lpRead,DWORD dwReadLen); UINT WINAPI ImeToAsciiEx(UINT uVirtKey,UINT uScanCode,CONST LPBYTE lpbKeyState,LPTRANSMSGLIST lpTransBuf,UINT fuState,HIMC hIMC) BOOL WINAPI NotifyIME(HIMC hIMC,DWORD dwAction,DWORD dwIndex,DWORD dwValue); BOOL WINAPI ImeRegisterWord(LPCTSTR lpszReading,DWORD dwStyle,LPCTSTR lpszString) { } BOOL WINAPI ImeUnregisterWord(LPCTSTR lpszReading,DWORD dwStyle,LPCTSTR lpszString) { } UINT WINAPI ImeGetRegisterWordStyle(UINT nItem,LPSTYLEBUF lpStyleBuf) { } UINT WINAPI ImeEnumRegisterWord(REGISTERWORDENUMPROC lpfnRegisterWordEnumProc, LPCTSTR lpszReading,DWORD dwStyle,LPCTSTR lpszString,LPVOID lpData) { } LRESULT CALLBACK UIWndProc(HWND hUIWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { { CreateUIWindow(hUIWnd); DestroyUIWindow(hUIWnd); case WM_IME_STARTCOM } } LRESULT CALLBACK StatusWndProc(HWND hStatusWnd,UINT uMsg,WPARAM wParam,LPARAM lParam); LRESULT CALLBACK CompWndProc(HWND hCompWnd,UINT uMsg,WPARAM wParam,LPARAM lParam); LRESULT CALLBACK CandWndProc(HWND hCandWnd,UINT uMsg,WPARAM wParam,LPARAM lParam); 5.头文件及链接文件记得要定义 IMM32.h 及链接文件 IMM32.lib。至于有关“ .ime”程序中必须用到的结构,大家可参考 MSDN 中的有关文档。二、常用函数BOOL WINAPI ImmGenerateMessage( //将汉字串法发送到与当前输入法相关联的应用软件中HIMC hIMC);//成功为TRUE,否则为FALSELRESULT WINAPI ImmRequestMessage( //向应用程序发送WM_IME_REQUEST消息HIMC hIMC, //与当前输入法相关联的应用软件的句柄WPARAM wParam, //与WM_IME_REQUEST相关的wPLPARAM lParam //与WM_IME_REQUEST相关的LP);LPINPUTCONTEXT WINAPI ImmLockIMC( //获取当前IMC的INPUTCONTEXT结构信息,增加IMC 计数器HIMC hIMC);//成功返回INPUTCONTEXT 结构指针,否则为NULLBOOL WINAPI ImmUnlockIMC( //释放IMC计数器HIMC hIMC );//返回:如果IMC计数器被减少到0了,返回FALSE,否则为TRUE.注意:ImmLockIMC与ImmUnlockIMC必须成对出现,必须是相同的HIMCHIMCC WINAPI ImmGetIMCLockCount( //取计数器值HIMC hIMC );//如果成功返回HIMC的计数器值,否则为NULL.HIMCC WINAPI ImmCreateIMCC( //创建INPUTCONTEXT结构的一个成员DWORD dwSize //成员的缓冲区长度);//如果成功返回IMC的成员句柄,否则为NULLHIMCC 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的计数器值,否则为0BOOL 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、GUIDELINEtypedef 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 hGuideLineHIMCC hPrivate; DWORD dwNumMsgBuf; //存放在hMsgBuf中的消息数HIMCC hMsgBuf; //存放的消息DWORD fdwInit //系统根据此值来初始本结构相应的信息DWORD dwReserve[3]; //未定义} INPUTCONTEXT;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值