有一次,一個使用者埋怨,說我輸入的電子郵件内容是正常的,為什麼不允許輸入,儲存不成功,老是提示格式有問題。
又有一次,另外一個使用者埋怨,為輸入的數字式正确的,可以跳出數字輸入控件後,内容有變為0了,怎麼回事呢?
諸如此類的問題,你可能自己也會碰到,究其原因,就是在桌面程式中,當你在文本框或者數字輸入框中輸入内容的時候,輸入法莫名奇妙的由半角變為全角,你沒有發現,繼續填寫或者儲存,就會出現問題。
如果我們不注意這些細節,使用者輸入的内容部經過驗證,他們在資料查詢檢索的時候,就會找不到内容,或者出現莫名其妙的錯誤,這是我們不願意看到的。
其實解決這個問題,做好這個細節問題的處理預防,是很簡單的事情,下面我來介紹一個輔助類,調用一下他的函數就可以了,如下所示。
/// <summary>
/// 輸入法幫助,全角 轉換為半角
/// </summary>
public class ImeHelper
{
#region 聲明一些API函數
[DllImport("imm32.dll")]
public static extern IntPtr ImmGetContext(IntPtr hwnd);
public static extern bool ImmGetOpenStatus(IntPtr himc);
public static extern bool ImmSetOpenStatus(IntPtr himc, bool b);
public static extern bool ImmGetConversionStatus(IntPtr himc, ref int lpdw, ref int lpdw2);
public static extern int ImmSimulateHotKey(IntPtr hwnd, int lngHotkey);
public const int IME_CMODE_FULLSHAPE = 0x8;
public const int IME_CHOTKEY_SHAPE_TOGGLE = 0x11;
#endregion
/// <summary>
/// 重載SetIme,傳入Form
/// </summary>
/// <param name="frm"></param>
public static void SetIme(Form frm)
{
frm.Paint += new PaintEventHandler(frm_Paint);
ChangeAllControl(frm);
}
/// 重載SetIme,傳入Control
/// <param name="ctl"></param>
public static void SetIme(Control ctl)
ChangeAllControl(ctl);
/// 重載SetIme,傳入對象句柄
/// <param name="Handel"></param>
public static void SetIme(IntPtr Handel)
ChangeControlIme(Handel);
private static void ChangeAllControl(Control ctl)
//在控件的的Enter事件中觸發來調整輸入法狀态
ctl.Enter += new EventHandler(ctl_Enter);
//周遊子控件,使每個控件都用上Enter的委托處理
foreach (Control ctlChild in ctl.Controls)
{
ChangeAllControl(ctlChild);
}
static void frm_Paint(object sender, PaintEventArgs e)
/**/
/*有人問為什麼使用Pain事件,而不用Load事件或Activated事件,是基于下列考慮:
* 、在您的Form中,有些控件可能是運作時動态添加的
* 、在您的Form中,使用到了非.NET的OCX控件
* 、Form調用子Form的時候,Activated事件根本不會觸發 */
ChangeControlIme(sender);
/// 控件的Enter處理程式
/// <param name="sender"></param>
/// <param name="e"></param>
static void ctl_Enter(object sender, EventArgs e)
private static void ChangeControlIme(object sender)
Control ctl = (Control)sender;
ChangeControlIme(ctl.Handle);
/// 下面這個函數才是真正檢查輸入法的全角半角狀态
/// <param name="h"></param>
private static void ChangeControlIme(IntPtr h)
IntPtr HIme = ImmGetContext(h);
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(h, IME_CHOTKEY_SHAPE_TOGGLE); //轉換成半角
}
}
}