今天遇到的一个输入法全/半角的问题,大致情形如下:用户注册界面中对用户名及邮箱进行验证、验证条件中有一项为“半角字符”,即全角字符不合法。
并且验证错误时的提示信息也做的比较粗糙,提示的是什么“用户名允许…字符,长度是多少 ”等等,而恰好没有提示到“半角字符”。
这时候某用户开始了一遍又一遍输入他那全角的英文字符,然而总是注册失败,弄的很郁闷。
唉,用户交互没做好啊!再言之:WinForm里用错误提示大多还是用那种“小红圈”[ErrorProvider],错误提示文本被隐藏了,不能被用户直接看到。
还有当时他似乎也没有看错误提示信息哦。仔细想想 这是用户的错吗? 似乎也不能责怪用户吧!
既然遇到问题了,那就解决吧。
解决思路:当满足以下三个条件中任意一个时便自动将输入法状态改为半角。
1、窗体Activated 事件发生时。
2、Form_Keyup 事件,按下Ctrl + Space时。
3、Form_KeyUp 事件,按下Shift+Space时,呵呵,这样做似乎不太好。
这样做基本上就可以保证用户输入法状态为半角了,不知是否还有疏漏呢?
至于将输入法状态改为半角,我们有相关的API可以调用。
为了使用方便,特将这些封装到工具类中,现与大家分享。
public class ControlTools
{
// 声明一些API函数
[DllImport("imm32.dll")]
public static extern IntPtr ImmGetContext(IntPtr hwnd);
[DllImport("imm32.dll")]
public static extern bool ImmGetOpenStatus(IntPtr himc);
// 暂时没有用到,觉得这个API似乎有问题。
[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;
private Form mFrm;
public ControlTools(Form frm)
{
this.mFrm = frm;
}
// 输入法全角转半角
public void FullToHalf()
{
this.mFrm.KeyPreview = true;
this.mFrm.Activated += new EventHandler(mFrm_Activated);
this.mFrm.KeyUp += new KeyEventHandler(mFrm_KeyUp);
}
private void mFrm_KeyUp(object sender, KeyEventArgs e)
{
if ((e.Control || e.Shift) && e.KeyCode == Keys.Space)
{
this.mFrm_Activated(null, null);
}
}
private void mFrm_Activated(object sender, EventArgs e)
{
try
{
IntPtr HIme = ImmGetContext(this.mFrm.Handle);
// 如果输入法处于打开状态
if (!ImmGetOpenStatus(HIme))
{
return;
}
int iMode = 0;
int iSentence = 0;
// 检索输入法信息
bool bSuccess = ImmGetConversionStatus(HIme, ref iMode, ref iSentence);
if (bSuccess)
{
// 如果是全角,转换成半角
if ((iMode & IME_CMODE_FULLSHAPE) > 0)
{
ImmSimulateHotKey(this.mFrm.Handle, IME_CHOTKEY_SHAPE_TOGGLE);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}