
如何编写自己的输入法.doc
3页本文拟结合作者的亲身体验简要介绍一下在 Windows 环境下如何编写输入法程序一直想写一点关于输入法编程的东西,今天终于有点时间,希望对后来者有点帮助在此要特别感谢“ 自由拼音” 的作者李振春,我刚开始的几个问题都是在他的帮助下才解决首先我们需要明白输入法是什么东西目前常用的输入法基本上有两种类型:外挂式(如早期的万能五笔)及输入法接口式(Input Method Editor-IME) 外挂式比较简单,就是一个 exe 文件,通过模拟一些 Windows 输入消息来给当前处于活动状态的编辑窗口输入文字,一个显著的优点是输入法只要启动一次,就可以在所有进程中使用;但缺点不不容忽视,首先实现起来也不容易,一个更大的不足是兼容性不够好,通常一个 Windows 版本需要一人对应的输入法版本,此外这类输入法为了能够截获用户输入,通常需要挂接键盘钩子,容易造成系统不稳定或者效率不高大部分的输入法还是采用 IME 来实现,下面本文主要讨论一下 IME 编程需要注意的问题及解决办法IME 是什么? IME 是在 Windows 平台上使用的标准的输入法接口规范它实质是一个 DLL,Windows 为这个 DLL 定义一系列的接口,不同的接口实现指定的功能。
程序员在编写输入法程序时只需要实现这些接口并导出就可以作为输入法使用关于具体接口的定义不是本文的重点,如果您需要了解只需要在网络中搜索“输入法编程指 南”就可以明白 ,更多信息参考 MSDN刚开始输入法编程最棘手的问题通常是程序框架搭好了却不知道如何使用及调试这里涉及到一个很重要的问题就是输入法的安装输入法就是 Windows 的一个插件,需要先进行注册,Windows 才能识别并使用为此您需 要先将您生成的 DLL 复制到系统目录(Windows\System32)再调用 API ImmInstallIME 就可以实现了,在我的实践中是先编一个简单的程序来做安装工作,在每次输入法重新编译完成以后调用一次以完成输入法的注册这里还有一个需要注意的问题是:Windows 提供了一种机制,它允许输入法程序一旦启动就就不再退出,这就意味着如果你的程序代码经过修改需要重新安装时将不得不重新启动电脑在 IME 定义的接口中有一个接口是提供 IME 的初始化的,它就是 BOOL WINAPI ImeInquire(LPIMEINFO lpIMEInfo,LPTSTR lpszUIClass,LPCTSTR lpszOption),下面的代码来自我写的输入法:BOOL WINAPI ImeInquire(LPIMEINFOlpIMEInfo,LPTSTR lpszUIClass,LPCTSTR lpszOption){lpIMEInfo->dwPrivateDataSize = sizeof(CONTEXTPRIV);//系统根据它为INPUTCONTEXT.hPrivate 分配空间lpIMEInfo->fdwProperty = IME_PROP_KBD_CHAR_FIRST |#ifdef _UNICODE IME_PROP_UNICODE |#endifIME_PROP_SPECIAL_UI |IME_PROP_END_UNLOAD ;lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE |IME_CMODE_NATIVE;lpIMEInfo->fdwSentenceCaps = IME_SMODE_NONE;lpIMEInfo->fdwUICaps = UI_CAP_2700;lpIMEInfo->fdwSCSCaps = 0;lpIMEInfo->fdwSelectCaps = SELECT_CAP_CONVERSION;_tcscpy(lpszUIClass,CLSNAME_UI);return TRUE;}lpIMEInfo->fdwProperty 告诉 Windows 系统您编写的输入法的一些特征,注意一下IME_PROP_END_UNLOAD 这个标志,有了它您编写的输入法会随着启动您的输入法的应用程序(如 NotePad)的退出而退出,否则它将长驻于系统中,这也是为什么很多输入法在升级安装时需要首先重新启动电脑的原因。
在这个接口中还有一点需要特别注意,那就是 lpIMEInfo->dwPrivateDataSize,至少我是经过很多次测试才基本证实 Windows 根据该值为 INPUTCONTEXT.hPrivate 分配空间此外如果您修改了这个接口,按照我个人的经验是需要重新调用 ImmInstallIME 来安装在安装完成后,在输入法列表中应该已经有了您自己的输入法点击调试,由于它是一个 DLL,您需要先选择一个宿主程序,一般选择“ 记事本 ”,以调试方式启动“ 记事本”后,在这个“记事本 ”中打开您的输入法,您就可以在源代码中 设置断点了需要说明的是,VC6.0调试 DLL 不太好用,首先需要打上 SP5或者 SP6,这样也不能够在 DLL 启动的时候就设置断点,推荐使用.net 来调试输入法上下文(HIMC):HIMC 是什么?在输入法编程时必然要接触到输入法上下文这个术语,刚接触时听起来实在是半懂不懂由于输入法是一个插件,它需要和调用它的应用程序通讯,在输入法中生成的编码及重码信息保存在哪里应用程序才能正确的读取呢?答案就在于输入法上下文输入法上下文是由 User.exe(一个系统进程)为应用程序分配的内存句柄,在应用程序中启动的输入法在这块内存中写入数据,User.exe 再将数据传递到应用程序。
UIWnd:在 IME 中需要导出一个接口,原型如 LRESULT WINAPI UIWndProc(HWND hUIWnd, UINT message,WPARAM wParam, LPARAM lParam),hUIWnd 是由 User.exe 传过来的窗口句柄,它是输入法中创建的窗口如编码窗口,重码窗口,状态栏窗口的宿主(Owner),初学输入法编程的人可能会问这个窗口显示在哪里呢?其实它并不是一个普通的窗口,它只是一个用来传递 Windows 消息的窗口(Message Only),在使用时,您不需要关心它在哪里,只需要使用它就好了一个 IME 需要导出 19个(Win98版本)接口,但是对于一个只需要实现一般意义的文字输入的软件,您只需要实现几个基本的接口就可以让输入法正常工作了下面逐一介绍一下这几个接口。












