经常某些输入的文本要求只能是数字等,比如qq登陆框上的qq帐号,如果按键不是数字,则没有反应。原理当然是很简单的,只需要在相应消息到来时阻止控件去处理消息即可。
这种例子很多,当然可以override keypress事件。也可以从textbox继承一个类,然后重写wndpro,从而无视某些消息。
最重要的消息是WM_CHAR。此外,还有几个特殊按键是永远不能屏蔽的,分别是backspace, delete,此外还有快捷键,ctrl-a,
ctrl-c,ctrl-x,ctrl-v.再此外,我们还要在执行粘贴时对文本做一次判断,不合法文本则被忽略。
可以用一个FilterString的string来记录合法字符,不在此字符串中认为是不接受的字符,
今天有些迷糊,主要是发现只处理wm_char时,ctrl-a快捷键失效了,于是在keydown里面手工实现了全选。具体原因也没认真去研究,另外一个问题是发现对小数点的屏蔽‘.’无效,原因也不详,好像按'.'的时候没产生wm_char消息就直接被处理掉了。郁闷。先就这样吧,不是很优美。
这种例子很多,当然可以override keypress事件。也可以从textbox继承一个类,然后重写wndpro,从而无视某些消息。
最重要的消息是WM_CHAR。此外,还有几个特殊按键是永远不能屏蔽的,分别是backspace, delete,此外还有快捷键,ctrl-a,
ctrl-c,ctrl-x,ctrl-v.再此外,我们还要在执行粘贴时对文本做一次判断,不合法文本则被忽略。
可以用一个FilterString的string来记录合法字符,不在此字符串中认为是不接受的字符,
/// <summary>
/// 覆盖窗口过程!处理WM_CHAR消息!
/// </summary>
/// <param name="m"></param>
protected override void WndProc(ref Message m)
{
int charcode = (int)m.WParam;
switch (m.Msg)
{
case WM_CHAR:
// 遇到非法字符,直接return即可过滤非法字符!break表示处理该字符
//屏蔽小数点
if (charcode == (int)Keys.Decimal)
return;
// 注意delete,backspace字符不能过滤!!!
// ctrl-a,ctrl-c,ctrl-v快捷键操作不能屏蔽!
if (charcode == (int)Keys.Back || charcode == (int)Keys.Delete)
break;
//如果按下了CTRL键
if (charcode == 1 //ctrl a
|| charcode == 3 //ctrl c
|| charcode == 22 //ctrl v
|| charcode == 24 //ctrl x
)
break;
if (this.m_FilterStr.IndexOf((char)charcode) < 0)
return;
break;
case WM_KEYDOWN:
//ctrl-A 全选
if (Control.ModifierKeys == Keys.Control)
{
if(charcode==(int)Keys.A)
this.SelectAll();
}
break;
case WM_PASTE:
//粘贴消息
IDataObject obj = Clipboard.GetDataObject();
if (obj == null)
return;
if (obj.GetDataPresent(DataFormats.Text))
{
string text = obj.GetData(DataFormats.Text) as string;
if (text == null)
return;
foreach (char c in text)
{
//查看是否含有过滤字符以外的字符!
if (this.m_FilterStr.IndexOf(c) < 0)
return;
}
}
break;
}
//处理消息
base.WndProc(ref m);
}
/// 覆盖窗口过程!处理WM_CHAR消息!
/// </summary>
/// <param name="m"></param>
protected override void WndProc(ref Message m)
{
int charcode = (int)m.WParam;
switch (m.Msg)
{
case WM_CHAR:
// 遇到非法字符,直接return即可过滤非法字符!break表示处理该字符
//屏蔽小数点
if (charcode == (int)Keys.Decimal)
return;
// 注意delete,backspace字符不能过滤!!!
// ctrl-a,ctrl-c,ctrl-v快捷键操作不能屏蔽!
if (charcode == (int)Keys.Back || charcode == (int)Keys.Delete)
break;
//如果按下了CTRL键
if (charcode == 1 //ctrl a
|| charcode == 3 //ctrl c
|| charcode == 22 //ctrl v
|| charcode == 24 //ctrl x
)
break;
if (this.m_FilterStr.IndexOf((char)charcode) < 0)
return;
break;
case WM_KEYDOWN:
//ctrl-A 全选
if (Control.ModifierKeys == Keys.Control)
{
if(charcode==(int)Keys.A)
this.SelectAll();
}
break;
case WM_PASTE:
//粘贴消息
IDataObject obj = Clipboard.GetDataObject();
if (obj == null)
return;
if (obj.GetDataPresent(DataFormats.Text))
{
string text = obj.GetData(DataFormats.Text) as string;
if (text == null)
return;
foreach (char c in text)
{
//查看是否含有过滤字符以外的字符!
if (this.m_FilterStr.IndexOf(c) < 0)
return;
}
}
break;
}
//处理消息
base.WndProc(ref m);
}
今天有些迷糊,主要是发现只处理wm_char时,ctrl-a快捷键失效了,于是在keydown里面手工实现了全选。具体原因也没认真去研究,另外一个问题是发现对小数点的屏蔽‘.’无效,原因也不详,好像按'.'的时候没产生wm_char消息就直接被处理掉了。郁闷。先就这样吧,不是很优美。