多管齐下,解决
dotNet FrameWork
全角问题
丽水市汽车运输集团有限公司信息中心
苟安廷
用C#编写winform程序时,输入法经常自动变成全角,给用户的输入带来极的不便,微软至今没有解决这一BUG,网上有较多相关的讨论,但始终不尽人意,本文根据实际工作情况,找到一种较完美的解决方案。
方案一:继承法
首先打开VS2005,新建一个项目,再添加一个Form,取名为ImeForm,因为要用到API函数,故在ImeForm中添加引用:
using
System.Runtime.InteropServices;
再声明输入法相关的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)) //如果输入法处于打开状态
{
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); //转换成半角
}
}
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);就可以了。