VS2005中文输入法自动转换为全角的两种解决方法

发布时间:2016-12-6 13:51:23 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"VS2005中文输入法自动转换为全角的两种解决方法",主要涉及到VS2005中文输入法自动转换为全角的两种解决方法方面的内容,对于VS2005中文输入法自动转换为全角的两种解决方法感兴趣的同学可以参考一下。

VS2005中文输入法自动转换为全角的两种解决方法 作者:南疯       最近在用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,传入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)是不会触发的。 posted on 2006-04-13 15:36 南疯 阅读(895) 评论(7)  编辑 收藏 收藏至365Key --> 评论   我用拼音加加,好想没有碰到lz所说的问题  回复    # re: VS2005中文输入法自动转换为全角的两种解决方法 2006-04-13 21:42 web 验证码被破解了 ?  回复    # re: VS2005中文输入法自动转换为全角的两种解决方法 2006-04-14 08:17 悟 谢谢! 带来的一个问题是窗体的Form_Activate不会触发。 要加上:base.onActivated(e);  回复    # re: VS2005中文输入法自动转换为全角的两种解决方法 2006-04-14 08:32 南疯 谢谢 @悟,确实是这样,现在已经加上!  回复    # re: VS2005中文输入法自动转换为全角的两种解决方法 2006-04-14 10:20 NeedForSleep @ningsia 你用拼音加加,并不代表客户都用拼音加加。 @南疯 谢谢,这个问题一直让我非常烦心。但是是初学者,不知道怎么改。   回复    # re: VS2005中文输入法自动转换为全角的两种解决方法 2006-04-14 16:09 网上购物 不错不错  回复    # re: VS2005中文输入法自动转换为全角的两种解决方法 2006-04-29 14:54 wxw 能不能提供一个vb版的   # re: VS2005中文输入法自动转换为全角的两种解决方法 2006-04-13 15:54 ningsia

上一篇:今日发工资。。。
下一篇:用meta标签实现网页变换效果

相关文章

相关评论