多管齊下,解決dotNet FrameWork全形問題麗水市汽車運輸集團有限公司資訊中心苟安廷用C#編寫winform程式時,IME經常自動變成全形,給使用者的輸入帶來極的不便,微軟至今沒有解決這一BUG,網上有較多相關的討論,但始終不盡人意,本文根據實際工作情況,找到一種較完美的解決方案。方案一:繼承法首先開啟VS2005,建立一個項目,再添加一個Form,取名為ImeForm,因為要用到API函數,故在ImeForm中添加引用:using System.Runtime.InteropServices;再聲明IME相關的API函數: #region 聲明一些API函數 [DllImport("imm32.dll")] private static extern IntPtr ImmGetContext(IntPtr hwnd); [DllImport("imm32.dll")] private static extern bool ImmGetOpenStatus(IntPtr himc); [DllImport("imm32.dll")] private static extern bool ImmSetOpenStatus(IntPtr himc, bool b); [DllImport("imm32.dll")] private static extern bool ImmGetConversionStatus(IntPtr himc, ref int lpdw, ref int lpdw2); [DllImport("imm32.dll")] private static extern int ImmSimulateHotKey(IntPtr hwnd, int lngHotkey); private const int IME_CMODE_FULLSHAPE = 0x8; private const int IME_CHOTKEY_SHAPE_TOGGLE = 0x11; #endregion定義一個變數,以保證相關委託只執行一次:private bool m_FirstStart = true;將下面的代碼複製進去:///<summary> /// 首次載入視窗時,設定各控制項的事件,使其成為半形 ///</summary> ///<param name="e"></param> protected override void OnLoad(EventArgs e) { base.OnLoad(e); IntPtr HIme = ImmGetContext(this.Handle); if (ImmGetOpenStatus(HIme)) //如果IME處於開啟狀態 { int iMode = 0; int iSentence = 0; bool bSuccess = ImmGetConversionStatus(HIme, ref iMode, ref iSentence); //檢索IME資訊 if (bSuccess) { //if ((iMode & IME_CMODE_FULLSHAPE) > 0) //如果是全形 ImmSimulateHotKey(this.Handle, IME_CHOTKEY_SHAPE_TOGGLE); //轉換成半形 } } if (m_FirstStart) { SetFormImeToHangul(this); m_FirstStart = false; } } private void SetFormImeToHangul(Form p_Form) { foreach (System.Windows.Forms.Control ctl in p_Form.Controls) { SetControlImeToHangul(ctl); } } ///<summary> /// 通過遞迴,遍曆當前視窗的全部控制項 ///</summary> ///<param name="p_Control">容器</param> private void SetControlImeToHangul(System.Windows.Forms.Control p_Control) { if (p_Control.HasChildren) { foreach(Control ctl in p_Control.Controls) SetControlImeToHangul(ctl); } p_Control.KeyDown+=new KeyEventHandler(p_Control_KeyDown); p_Control.KeyPress+=new KeyPressEventHandler(p_Control_KeyPress); p_Control.Enter+=new EventHandler(p_Control_Enter); } private void p_Control_KeyDown(object sender, KeyEventArgs e) { (sender as Control).ImeMode = ImeMode.Hangul; } private void p_Control_KeyPress(object sender, KeyPressEventArgs e) { //防止其他情況可能出現的全形 int nIndex = "0123456789。.".IndexOf(e.KeyChar); if (nIndex > -1) e.KeyChar = "0123456789.."[nIndex]; } private void p_Control_Enter(object sender, EventArgs e) { (sender as Control).ImeMode = ImeMode.Hangul; }最後,將其他所有視窗的基本類有預設的System.Windows.Foms.Form改為上面的ImeForm,再運行一下程式,是不是全形問題解決了?方案二:類方法如果已有項目,要修改基類可能會出現問題,故你將方案一的方法寫到一個類裡面去,在Load事件中調用SetFormImeToHangul(this);就可以了。