情况是这样的:
有个form1,上面有一个文本筐,一个按扭。
按扭显示另外一个form2。form2有一个文本筐。
程序运行:
在form1中的文本筐中输入中文。
点几按扭。显示form2.在form2中的文本筐中输入中文。后关闭这个form2输入法自动转化为全角了大家可以试试看啊

解决方案 »

  1.   

    把控件的ImeMode设为'On'即可,偶尔会在第一次切换窗口时出现问题,可能和系统环境有关,一次性的手工切换为半角后就好了
      

  2.   

    VS2005中文输入法自动转换的解决方法
    作者:name-lh出处:博客园责任编辑: 方舟 [ 2006-04-15 10:04 ]http://dev.yesky.com/msdn/471/2370471.shtml最近在用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}   有人问为什么使用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;
    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   使用这个类的方法为:   修改所有的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)是不会触发的。
      

  3.   

    这是一个微软的一个大BUG,目前无好的解决办法,我通过如下办法处理:
    1、新建一个类:ImeForm,该类继承于Form,
    2、在Load事件中,通过递归循环,查找所有的文本框,处理文本框的Enter事件,自动将输入法转换为半角,当然,如果其他输入控件也有类似问题,无非是在递归循环中多一个判断分支而已.
    3、将程序中用到的Form的基类由System.Windows.Forms.Form改为ImeForm,如果以后微软解决了这个问题,改回去就可以了,ImeForm的全部代码如下:
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Forms;
    namespace Lqjt
    {
        /// <summary>
        /// 解决输入法全角的问题
        /// </summary>
        public class ImeForm : System.Windows.Forms.Form 
        {
            /// <summary>
            /// 做一个标记,避免重复设置Enter事件
            /// </summary>
            private bool m_AttachProcessed = false;
            /// <summary>
            /// 在Load事件中遍历控件,如果是文本框,自动切换到半角状态
            /// </summary>
            /// <param name="e"></param>
            protected override void OnLoad(EventArgs e)
            {
                base.OnLoad(e);
                if (!m_AttachProcessed)
                {
                    SetImeToHangul(this.Controls);
                    m_AttachProcessed = true;
                }
            }        /// <summary>
            /// 通过递归,遍历当前窗口的全部控件
            /// </summary>
            /// <param name="p_Controls">容器</param>
            private void SetImeToHangul(System.Windows.Forms.Control.ControlCollection p_Controls)
            {
                foreach (System.Windows.Forms.Control ctl in p_Controls)
                {
                    FlowLayoutPanel flpan = ctl as FlowLayoutPanel;
                    if (flpan != null)
                    {
                        SetImeToHangul(flpan.Controls);
                        continue;
                    }
                    GroupBox grp = ctl as GroupBox;
                    if (grp != null)
                    {
                        SetImeToHangul(grp.Controls);
                        continue;
                    }                Panel pan= ctl as Panel;
                    if (pan != null)
                    {
                        SetImeToHangul(pan.Controls);
                        continue;
                    }
                    TabControl tabcontrol = ctl as TabControl;
                    if (tabcontrol != null)
                    {
                        SetImeToHangul(tabcontrol.Controls);
                        continue;
                    }
                    TabPage tabpage = ctl as TabPage;
                    if (tabpage != null)
                    {
                        SetImeToHangul(tabpage.Controls);
                        continue;
                    }
                    TableLayoutPanel tlpan = ctl as TableLayoutPanel;
                    if(tlpan!=null)
                     {
                         SetImeToHangul(tlpan.Controls);
                        continue;
                    }
                    //文本框进入时,自动切换到半角,如果要控制其他可输入控件,参照下面的代码完成
                    TextBox txtbox = ctl as TextBox;
                    if (txtbox != null)
                    {
                        txtbox.Enter += new EventHandler(ControlEnter_Enter);
                    }
               }
            }
            private  void ControlEnter_Enter(object sender, EventArgs e)
            {
                Control ctl = sender as Control;
                if (ctl == null)
                    return;
                if (ctl.ImeMode != ImeMode.Hangul)
                    ctl.ImeMode = ImeMode.Hangul;
            }
        }//class
    }
      

  4.   

    根据网上内容,我又重新修改了ImeForm,修改后的效果更好,解决了在NumbericUpDown以及用户通过Ctrl+Shift切换不能变半角的问题,新的如下:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;namespace Lqjt
    {
        public partial class ImeForm : Form
        {
            public ImeForm()
            {
                InitializeComponent();
            }
            //声明一些API函数
            [DllImport("imm32.dll")]
            public static extern IntPtr ImmGetContext(IntPtr hwnd);
            [DllImport("imm32.dll")]
            public static extern bool ImmGetOpenStatus(IntPtr himc);
            [DllImport("imm32.dll")]
            public static extern bool ImmSetOpenStatus(IntPtr himc, bool b);
            [DllImport("imm32.dll")]
            public static extern bool ImmGetConversionStatus(IntPtr himc, ref int lpdw, ref int lpdw2);
            [DllImport("imm32.dll")]
            public static extern int ImmSimulateHotKey(IntPtr hwnd, int lngHotkey);
            private const int IME_CMODE_FULLSHAPE = 0x8;
            private const int IME_CHOTKEY_SHAPE_TOGGLE = 0x11;
            protected override void OnActivated(EventArgs e)
            {
                base.OnActivated(e);
                IntPtr HIme = ImmGetContext(this.Handle);
                if (ImmGetOpenStatus(HIme))  //如果输入法处于打开状态
                {
                    int iMode = 0;
                    int iSentence = 0;
                    bool bSuccess = ImmGetConversionStatus(HIme, ref iMode, ref iSentence);  //检索输入法信息
                    if (bSuccess)
                    {
                        if ((iMode & IME_CMODE_FULLSHAPE) > 0)   //如果是全角
                            ImmSimulateHotKey(this.Handle, IME_CHOTKEY_SHAPE_TOGGLE);  //转换成半角
                    }            }
            }
        }//form
    }