VS2005中文输入法自动转换为全角的两种解决方法
来源:互联网 发布:ios11 蜂窝数据开关 编辑:程序博客网 时间:2024/05/04 15:36
原文地址:http://www.cnblogs.com/name-lh/archive/2006/04/13/374337.aspx
微软没出补丁前的解决方法如下,补丁见这里http://www.cnblogs.com/name-lh/archive/2007/02/06/642547.html。
方法一:
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,传入Form22 public static void SetIme(Form frm)23 {24 frm.Paint += new PaintEventHandler(frm_Paint);25 ChangeAllControl(frm);26 }27 //重载SetIme,传入Control28 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 }4546 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}
有人问为什么使用Pain事件,而不用Load事件或Activated事件,我是基于下列考虑:
1、在您的Form中,有些控件可能是运行时动态添加的
2、在您的Form中,使用到了非.NET的OCX控件
3、Form调用子Form的时候,Activated事件根本不会触发
使用这个类的方法为:
在您的界面中,在Load的时候,在里面加上这样一句话:
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;1011namespace MyDemo12{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的OnActivated29 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 }4243 }44 } 45 }46}47
使用这个类的方法为:
修改所有的Form的继承关系,比如,你有这样的一个Form类:
public partial class Form1 :Form
{
...
}
那么,把它改成:
public partial class Form1 :ImeForm
{
...
}
相信,这样的修改会很快,全项目查找替换一下即可。
记住,如果你的Form是多重继承下来的,例如:FormC派生于FormB,而FormB又派生于FormA,那么,仅仅需要FormA从imeForm派生即可。
方法二的使用优势是明显的,把Ime的事件从Form最上一层就截取了,避免了在您的Form中控件的多样性所带来的困扰。
还有,网上有一些说的调整ImeMode和使用ImeModeChanged方法来解决这个问题,建议你暂时(只是暂时)不要使用,因为修改ImeMode根本不能解决窗口切换时输入法自动变全角的问题,而且ImeModeChanged是在ImeMode改变的时候才触发,在用户手工操作输入法状态改变时(比如按Ctrl+Shift)是不会触发的。
- VS2005中文输入法自动转换为全角的两种解决方法
- VS2005中文输入法自动转换为全角的两种解决方法
- VS2005中文输入法自动转换为全角的两种解决方法
- VS2005中文输入法自动转换为全角的两种解决方法
- VS2005中文输入法自动转换为全角的两种解决方法[转自南疯的博客]
- (转)VS2005中文输入法自动转换为全角的问题
- VS2005中文输入法自动转换的解决方法
- VS2005中文输入法自动转换的解决方法
- 解决VS2005中文输入法半角/全角的补丁
- Vs2005 中文输入法全角问题 解决
- vs2005中文输入法全角bug补丁
- 输入法全角转换为半角(转)
- winform输入法全角转换为半角
- vs2005开发WinForm程序时,输入法自动变全角的问题!
- sql server 2005 输入法 不能输入中文 自动切换全角
- VS2005与紫光拼音输入法全角问题的解决办法
- JS全角自动转换成半角的几种方式
- java中文半角和全角的转换
- GEM制作和发布教程
- MATLAB Implementation: light-weight vs. heavy-weight
- 小结 C++与Objective-c的编写代码的一些区别
- win7,Xp搭建Java环境
- objective-c 引用计数
- VS2005中文输入法自动转换为全角的两种解决方法
- VS2008中C++与CUDA混合编程的方法
- 黑马程序员-学习日记26 ( 交通灯管理系统 )
- 当excel表中的某个单元格的值小于某个值时,如何实现该单元格的底色或者内容改变颜色?
- Android ContentProvider 使用limit
- Android Nand Flash 分区
- android 设置支持pad等大屏幕、大分辨率的设备!!
- 第2周:结构体处理
- SQL中ROUND()函数解析