Windows 中文输入法的实现
本人设计了一个“3++输入法”,可运行操作系统 Windows95/98/NT/2000,“3++输入法”为纯形码,无需识别码,易学,易用,录入速度快,含“简体、繁体、专业”三种版本,字根量小,词组数大于26000个,全部重码数仅为73个,您可以在 http://www.csdn.net/cnshare/ 下搜索“3++输入法”下载软件,或在:http://www.anycities.com/user1/3jj/ 下载。欢迎各位试用并提出宝贵意见。如有问题可发Email:[email protected] 给我。 限于篇幅,Windows系统下汉字输入法的基本原理,大家可参考 MSDN 中的有关文档。本人仅对程序设计的实现方法说明如下: 一、在 Windows 任务栏中增加输入法名称 这也就是 Setup 程序的关键,实际上,可以利用 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 ,则调用成功。 当然你必须先设计好 DLL 程序“.ime”文件和码表原文件“.mb”文件。
二、“.ime”文件的实现 程序中的输出函数(必须)即文件“.def”中的函数,以下为函数的名称和原形,部分函数给出了原函数,希望对你能有所帮助。
//初始化输入法函数 BOOL WINAPI ImeInquire(LPIMEINFO lpImeInfo,LPTSTR lpszWndCls,DWORD lpszOptions) { if (!lpImeInfo) return (FALSE); 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); return (TRUE); } //自定义汉字编码格式,未作处理。 DWORD WINAPI ImeConversionList(HIMC hIMC,LPCTSTR lpszSrc,DWORD uBufLen,UINT uFlag) { return (0); }
//设置输入法状态函数,如光标跟随等 BOOL WINAPI ImeConfigure(HKL hKL,HWND hAppWnd,DWORD dwMode,LPVOID lpData) { switch (dwMode) { case IME_CONFIG_GENERAL: DialogBox(hInst, MAKEINTRESOURCE(SETIME), (HWND)hAppWnd, (DLGPROC)ImeSetDlgProc); break; default: return (FALSE); break; } return (TRUE); }
//退出 BOOL WINAPI ImeDestroy(UINT uReserved) { if (uReserved) return (FALSE); return (TRUE); } //应用接口函数 LRESULT WINAPI ImeEscape(HIMC hIMC,UINT uSubFunc,LPVOID lpData) { LRESULT lRet;
switch (uSubFunc) { case IME_ESC_QUERY_SUPPORT: if ( lpData == NULL ) return FALSE;
switch (*(LPUINT)lpData) { case IME_ESC_QUERY_SUPPORT: case IME_ESC_MAX_KEY: case IME_ESC_IME_NAME: case IME_ESC_GETHELPFILENAME: return (TRUE); case IME_ESC_SEQUENCE_TO_INTERNAL: case IME_ESC_GET_EUDC_DICTIONARY: case IME_ESC_SET_EUDC_DICTIONARY: case IME_INPUTKEYTOSEQUENCE: return (FALSE); default: return (FALSE); } break; case IME_ESC_SEQUENCE_TO_INTERNAL: case IME_ESC_GET_EUDC_DICTIONARY: case IME_ESC_SET_EUDC_DICTIONARY: case IME_INPUTKEYTOSEQUENCE: return (FALSE); case IME_ESC_MAX_KEY: return ((WORD) 4); case IME_ESC_GETHELPFILENAME: { TCHAR szIMEGUDHlpName[MAXSTRLEN]; if (lpData == NULL ) return FALSE;
szIMEGUDHlpName[0] = 0; GetWindowsDirectory((LPTSTR)szIMEGUDHlpName, MAXSTRLEN); lstrcat((LPTSTR)szIMEGUDHlpName, TEXT("\\HELP\\3JaJa.hlp")); lstrcpy((char*)lpData, (char*)szIMEGUDHlpName); return TRUE; }
default: return (FALSE); }
return (lRet); } //启动输入法设置功能 BOOL WINAPI ImeSelect(HIMC hIMC,BOOL fSelect) { LPINPUTCONTEXT lpIMC; BOOL fRet;
if (!hIMC) return (FALSE);
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); if (!lpIMC) return (FALSE);
fRet = Select(hIMC, lpIMC, fSelect); ImmUnlockIMC(hIMC); return (fRet); }
//设置输入活动状态 BOOL WINAPI ImeSetActiveContext(HIMC hIMC,BOOL fOn) { if (fOn&&hIMC) { LPINPUTCONTEXT lpIMC;
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); if (!lpIMC) return (FALSE);
InitContext(lpIMC); ImmUnlockIMC(hIMC); } return (TRUE); }
//用户按键处理函数,例如中英文状态,返回 FALSE 为英文状态,按键不作处理。 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) //处理IME消息函数 BOOL WINAPI NotifyIME(HIMC hIMC,DWORD dwAction,DWORD dwIndex,DWORD dwValue);
//自定义汉字编码格式,未作处理。 BOOL WINAPI ImeRegisterWord(LPCTSTR lpszReading,DWORD dwStyle,LPCTSTR lpszString) { return (FALSE); }
//自定义汉字编码格式,未作处理。 BOOL WINAPI ImeUnregisterWord(LPCTSTR lpszReading,DWORD dwStyle,LPCTSTR lpszString) { return (FALSE); }
//自定义汉字编码格式,未作处理。 UINT WINAPI ImeGetRegisterWordStyle(UINT nItem,LPSTYLEBUF lpStyleBuf) { return (FALSE); }
//自定义汉字编码格式,未作处理。 UINT WINAPI ImeEnumRegisterWord(REGISTERWORDENUMPROC lpfnRegisterWordEnumProc, LPCTSTR lpszReading,DWORD dwStyle,LPCTSTR lpszString,LPVOID lpData) { return (FALSE); }
//UI窗口过程 LRESULT CALLBACK UIWndProc(HWND hUIWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { switch (uMsg) { case WM_CREATE: CreateUIWindow(hUIWnd); break; case WM_DESTROY: DestroyUIWindow(hUIWnd); break; case WM_IME_STARTCOMPOSITION: …… }
//状态窗口过程 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);
三、头文件及链接文件 记得要定义 IMM32.h 及链接文件 IMM32.lib。至于有关“ .ime”程序中必须用到的结构,大家可参考 MSDN 中的有关文档。 
|