最近在用vs2005做项目的时候,一直忍受着vs2005输入法自动切换到全角的bug的作怪,一边等待着微软给我们一个解决的方案。但是,我的项目都要作为产品打包出去了,微软还是闷头不对这个bug出一个解决方法。怎么办?我可以忍受这个输入法来回切换之苦,可用户体验可不会饶过我们的。弄不好,来个集体罢用,让我们都到微软喝西北风去啊!
总不能就这么交出产品出去吧,只有自己动手了。下面我用两种方法来实现如何避免输入法的这个bug。
方法一:
form的pain和遍历control的enter方法。
首先,我们为了使您原有的代码更简洁,我们把所要做的步骤封装到一个单独的类中,类代码如下:
| 1using system; 2using system.runtime.interopservices; 3 4namespace mydemo 5{ 6 public static class clsime 7 { 8 //声明一些api函数 9 [dllimport("imm32.dll")] 10 public static extern intptr immgetcontext(intptr hwnd); 11 [dllimport("imm32.dll")] 12 public static extern bool immgetopenstatus(intptr himc); 13 [dllimport("imm32.dll")] 14 public static extern bool immsetopenstatus(intptr himc, bool b); 15 [dllimport("imm32.dll")] 16 public static extern bool immgetconversionstatus(intptr himc, ref int lpdw, ref int lpdw2); 17 [dllimport("imm32.dll")] 18 public static extern int immsimulatehotkey(intptr hwnd, int lnghotkey); 19 public const int ime_cmode_fullshape = 0x8; 20 public const int ime_chotkey_shape_toggle = 0x11; 21 //重载setime,传入form 22 public static void setime(form frm) 23 { 24 frm.paint += new painteventhandler(frm_paint); 25 changeallcontrol(frm); 26 } 27 //重载setime,传入control 28 public static void setime(control ctl) 29 { 30 changeallcontrol(ctl); 31 } 32 //重载setime,传入对象句柄 33 public static void setime(intptr handel) 34 { 35 changecontrolime(handel); 36 } 37 private static void changeallcontrol(control ctl) 38 { 39 //在控件的的enter事件中触发来调整输入法状态 40 ctl.enter += new eventhandler(ctl_enter); 41 //遍历子控件,使每个控件都用上enter的委托处理 42 foreach (control ctlchild in ctl.controls) 43 changeallcontrol(ctlchild); 44 } 45 46 static void frm_paint(object sender, painteventargs e) 47 { 48 /**//*有人问为什么使用pain事件,而不用load事件或activated事件,是基于下列考虑: 49 * 1、在您的form中,有些控件可能是运行时动态添加的 50 * 2、在您的form中,使用到了非.net的ocx控件 51 * 3、form调用子form的时候,activated事件根本不会触发 */ 52 changecontrolime(sender); 53 } 54 //控件的enter处理程序 55 static void ctl_enter(object sender, eventargs e) 56 { 57 changecontrolime(sender); 58 } 59 private static void changecontrolime(object sender) 60 { 61 control ctl = (control)sender; 62 changecontrolime(ctl.handle); 63 } 64 //下面这个函数才是真正检查输入法的全角半角状态 65 private static void changecontrolime(intptr h) 66 { 67 intptr hime = immgetcontext(h); 68 if (immgetopenstatus(hime)) //如果输入法处于打开状态 69 { 70 int imode = 0; 71 int isentence = 0; 72 bool bsuccess = immgetconversionstatus(hime, ref imode, ref isentence); //检索输入法信息 73 if (bsuccess) 74 { 75 if ((imode & ime_cmode_fullshape) > 0) //如果是全角 76 immsimulatehotkey(h, ime_chotkey_shape_toggle); //转换成半角 77 } 78 } 79 } 80 } 81} |
| clsime.setime(this); |
| 1using system; 2using system.collections.generic; 3using system.componentmodel; 4using system.data; 5using system.collections; 6using system.drawing; 7using system.text; 8using system.windows.forms; 9using system.runtime.interopservices; 10 11namespace mydemo 12{ 13 public class imeform:system.windows.forms.form 14 { 15 //声明一些api函数 16 [dllimport("imm32.dll")] 17 public static extern intptr immgetcontext(intptr hwnd); 18 [dllimport("imm32.dll")] 19 public static extern bool immgetopenstatus(intptr himc); 20 [dllimport("imm32.dll")] 21 public static extern bool immsetopenstatus(intptr himc, bool b); 22 [dllimport("imm32.dll")] 23 public static extern bool immgetconversionstatus(intptr himc, ref int lpdw, ref int lpdw2); 24 [dllimport("imm32.dll")] 25 public static extern int immsimulatehotkey(intptr hwnd, int lnghotkey); 26 private const int ime_cmode_fullshape = 0x8; 27 private const int ime_chotkey_shape_toggle = 0x11; 28 //重载form的onactivated 29 protected override void onactivated(eventargs e) 30 { base.onactivated(e); 31 intptr hime = immgetcontext(this.handle); 32 if (immgetopenstatus(hime)) //如果输入法处于打开状态 33 { 34 int imode = 0; 35 int isentence = 0; 36 bool bsuccess = immgetconversionstatus(hime, ref imode, ref isentence); //检索输入法信息 37 if (bsuccess) 38 { 39 if ((imode & ime_cmode_fullshape) > 0) //如果是全角 40 immsimulatehotkey(this.handle, ime_chotkey_shape_toggle); //转换成半角 41 } 42 43 } 44 } 45 } 46} 47 |
| public partial class form1 :form { ... } |
| public partial class form1 :imeform { ... } |
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器