这几天在做一个注册页面,其中有一个真实姓名字段要求必须输入中文,于是想能不能在该真实姓名编辑框得到焦点的时候就将输入法切换为中文输入法呢?
于是就开始寻找前辈们的成功案例,果然功夫不费有新人,虽然费了很长时间。
开始是不知道如何着手,接下来找到了一个遍历系统安装输入法的C++类,并且可以设置激活任何一种已经安装的C++类,因此这就简单了,但是需要判断我们激活的
输入法是不是中文输入法。下面是网上对控制输入法的一个描述:(链接地址: http://lauwd.blog.163.com/blog/static/7605696920092202496313/)
要想控制输入法,首先要解决的问题是如果获得系统已安装的输入法信息。在视窗系统平台下,每个安装的输入法都在注册表中注册了相关信息。在“HKEY_CURRENT_USER\keyboard layout\preload”键下就能找到这些信息,键下由以1为基的递增数字做为值名(暂取名为数字号),其值的内容是个由八个数字组成的字符串(暂取名为代号,如"e0040804"),其中左4位是设备代码(device identifier),右4位是语言代码(language identifier)。例如上面:左e004指智能ABC,右0804指大陆中文。在MSDN中对所有代码做了周详的说明,如感兴趣请浏览MSDN相关内容。另外要说明一点的是在视窗系统98版本中输入法注册信息和上面说明略有不同,他是将已安装的输入法的数字号做为…\Preload下面的子键,而视窗系统2000将数字号做为…\Preload键下的值。
根据上面文章中的类我整理出来后上传到http://download.csdn.net/detail/fengbangyue/4134857处,但是后来我在使用过程中发现即便切换到中文了,但是如果以前切换的时候中文是出于英文状态的,那么用户也需要在一次从英文状态切换回中文输入状态。于是想可以再程序中判断当前输入法是英文状态吗,可以的话就把他切换到中文啊。在一次发现了这个方法,
详细描述在这里有完整的代码例子:http://blog.csdn.net/gxj1680/article/details/5270352
在这里摘抄几个函数:
HIMC hIMC; DWORD dwConv, dwSent; hIMC=ImmGetContext(m_hWnd); ImmGetConversionStatus(hIMC,&dwConv,&dwSent); if((dwConv & IME_CMODE_LANGUAGE) != IME_CMODE_NATIVE) { dwConv &= ~IME_CMODE_LANGUAGE; dwConv |= IME_CMODE_NATIVE; //中文输入状态 }//标注1if (!(dwConv & IME_CMODE_FULLSHAPE)) dwConv |= IME_CMODE_FULLSHAPE; //全角 if (!(dwConv & IME_CMODE_SYMBOL)) dwConv |= IME_CMODE_SYMBOL; //中文标点 //标注2//若要切换输入法为半角,只需把上面的标注1判断改为如下即可(自己用到时有此要求,所以在原作者继承上自己改了下)/*if (dwConv & IME_CMODE_FULLSHAPE)dwConv &= ~IME_CMODE_FULLSHAPE;if (dwConv & IME_CMODE_SYMBOL)dwConv &= ~IME_CMODE_SYMBOL;*/ImmSetConversionStatus(hIMC,dwConv,dwSent); //对输入法状态进行设置ImmReleaseContext(m_hWnd,hIMC); //释放上下文资源
//另外
判断当前输入法是否打开(即是否非美式键盘的英文状态)
HKL hKL = GetKeyboardLayout(0);
BOOL bIme = ::ImmIsIME(hKL);
打开和禁止输入法
ImmAssociateContext(hWnd, hIMC); //hIMC是已保存的HIMChIMC = ImmAssociateContext(hWnd, NULL);
不知道为什么发表后会有HTML乱码,全改用C++代码格式吧另外是前面朋友使用的经验: 同样对于日文输入法而言,可以通过上面的方法进行全半角切换,不过还有个前提:上面的方法需要打开IME才行,因为在“直接入力”(Direct Input)状态上面的方法不能切换全半角等状态,如果需要由“直接入力”(Direct Input)切换到其他如"ひらがな"等状态,需要通过::ImmSetOpenStatus(hImc, TRUE);打开IME,同样如果想由其他状态切换到“直接入力”(Direct Input),只需::ImmSetOpenStatus(hImc, FALSE);即可其实像Windows中的密码框,不管切换何种输入法输入的都是半角英文状态,用的也是::ImmSetOpenStatus这个函数有了前面几个这些函数对输入法的操作基本上是可以了,至于还会有什么问题我也不知道,现在我也只是写了一个简单的测试代码而已。 在切换输入法时,一般会先保存先前的输入法,也方便我们后来恢复。 ActivateKeyboardLayout(hCurKL,KLF_SUBSTITUTE_OK); //切换输入法 写到这里忽然发现下面这两个函数不知道和前面封装的类有何区别,是不是要测试一下呢? HKL hKL[2]; HKL hCurKL; hCurKL=GetKeyboardLayout(0); //保存初始输入法 GetKeyboardLayoutList(2,hKL); //获取输入法列表,只获取两项 GetKeyboardLayoutList函数用于获取输入法列表,前面封装的那个类用了很大的篇幅去获取输入法表,难道那个作者没有发现这个API,那么他又使用了LoadKeyboardLayout和ActivateKeyboardLayout两个API。 这些就先不说了,在此记录了输入法的基本切换控制,如果项目真的有这个需求的话,有这些资料实现起来也基本上没问他了。当然使用上面的API需要投文件和库#include "imm.h" #pragma comment(lib,"imm32") 不知道需要#include <Ime.h>不。 有时间的话,把他封装一下,毕竟还是比较使用,刚开始的时候我真没有头绪哦。 文章很乱,头绪不清,可能第一次在公司发博客心不在焉的吧,回家了。。