1.按键的类型

  Windows窗体将键盘输入标识为由按位Keys枚举表示的虚拟键代码。使用Keys枚举,可以综合一系列按键以生成单个值,这些值与WM_KEYDOWN和WM_SYSKEYDOWNWindows消息所伴随的值相对应。另外,程序开发人员可通过处理KeyDown或KeyUp 事件来检测大多数物理按键操作。字符键是Keys枚举的子集,它们与WM_CHAR和WM_SYSCHAR Windows消息所伴随的值相对应,如果通过组合按键得到一个字符,则可以通过处理KeyPress事件来检测该字符。

2. 定义

KeyDown:在控件有焦点的情况下按下键时发生。

KeyPress:在控件有焦点的情况下按下键时发生。(下面会说和KeyDown 的区别)

KeyUp:在控件有焦点的情况下释放键时发生。

注意:KeyDown触发后,不一定触发KeyUp,当KeyDown 按下后,拖动鼠标,那么将不会触发KeyUp事件。

3.键盘事件的顺序

  一个控件上可能出现3个与键盘相关的事件,下面是这些事件发生的常规顺序:

  用户按“a”键,该键将被预处理和调度,而且会发生KeyDown事件。 
  用户按住“a”键,该键将被预处理和调度,而且会发生KeyPress事件。 
  用户松开“a”键,该键将被预处理和调度,而且会发生KeyUp事件。
 
4.键的预处理

  像其他消息一样,键盘消息是在窗体或控件的WndProc方法中处理的。窗体或控件在处理键盘消息之前,PreProcessMessage方法会调用一个或多个方法,这些方法可被重写以处理特殊的字符键和物理按键。

5. KeyPress 和KeyDown 、KeyPress之间的区别

KeyPress主要用来捕获数字(注意:包括Shift+数字的符号)、字母(注意:包括大小写)、小键盘等除了F1-12、SHIFT、Alt、Ctrl、Insert、Home、PgUp、Delete、End、PgDn、ScrollLock、Pause、NumLock、{菜单键}、{开始键}和方向键外的ANSI字符。
KeyDown 和KeyUp 通常可以捕获键盘除了PrScrn所有按键(这里不讨论特殊键盘的特殊键)。 
KeyPress 只能捕获单个字符 
KeyDown 和KeyUp 可以捕获组合键(任何时候都可用Control.ModifierKeys属性获取SHIFT、Alt、Ctrl的状态,这对于不支持KeyDown 事件的控件非常有用)。 
KeyPress 可以捕获单个字符的大小写 
KeyDown和KeyUp 对于单个字符捕获的KeyValue 都是一个值,也就是不能判断单个字符的大小写。 (可通过.net 2.0中新增Control.IsKeyLocked(Keys.CapsLock)方法判断CapsLock的状态,类似,Scroll Lock和Num Lock也可通过Control.IsKeyLocked()方法来判断)。 
KeyPress 不区分小键盘和主键盘的数字字符。 
KeyDown 和KeyUp 区分小键盘和主键盘的数字字符。 
其中PrScrn 按键KeyPress、KeyDown和KeyUp 都不能捕获。

以上说明可以通过一些简单代码测试,例如:

private void txtKey_KeyPress(object sender, KeyPressEventArgs e)
{
  label1.Text = "key press:" + e.KeyChar.ToString();
}

private void txtKey_KeyDown(object sender, KeyEventArgs e)
{
  label2.Text = "key code:" + e.KeyCode.ToString();
  label2.Text += "\nkey value:" + e.KeyValue.ToString();
  label2.Text += "\nkey data:" + e.KeyData.ToString();
}

6. 获取按键状态

需获取各键状态,要用到GetKeyState()及GetAsyncKeyState()方法,如下:

[DllImport("User32.dll")]
private static extern short GetKeyState(System.Windows.Forms.Keys key);

......
if (GetKeyState(Keys.Insert) == 1)
{
  // Overwrite mode is on.
}
else
{
  // Insert mode is on.
}

[DllImport("User32.dll")]
private static extern short GetAsyncKeyState(System.Windows.Forms.Keys key);

...........

short state = GetAsyncKeyState(Keys.D);
switch (state)
{
  case 0:
  lbl.Text = "D has not been pressed since the last call.";
  break;
  case 1:
  lbl.Text = "D is not currently pressed, but has been pressed since the last call.";
  break;
  case -32767:
  lbl.Text = "D is currently pressed.";
  break;
}

那么两者有什么区别呢?查了下,有人提到说:GetKeyState得到的结果是在获取到当前消息时的键盘上按键状态的一个映像,也就是说,这个状态不会随着按键真实按键状态的改变而改变。其实通常情况下得到这样非实时的结果就足够了。由于只是查表,所以速度较快,但是决不能写出下面的代码

while(GetKeyState(nVirKey))

{

  //code here

}

  而要得到某一个键实时的状态,则应该使用GetAsyncKeyState,这个函数通过查询Driver而得到实时的信息。但是这个函数较GetKeyState慢。(这点还不大明白···)

7. 系统组合键的判定

  在使用键盘的时候,通常会使用到CTRL+SHIFT+ALT 类似的组合键功能。对于此,我们如何来判定?

通过KeyUp 事件能够来处理(这里说明一下为什么不用KeyDown,因为在判定KeyDown的时候,CTRL、SHIFT和ALT 属于一直按下状态,然后再加另外一个键是不能准确捕获组合键,所以使用KeyDown 是不能准确判断出的,要通过KeyUp 事件来判定 )

这里简单的列举出CTRL+其它7键的组合判定代码:
private void Form3_KeyUp(object sender, KeyEventArgs e)
{
  if (e.Control)
  {
    MessageBox.Show("KeyUp:Ctrl+" + e.KeyValue.ToString());
  }
}

8. 捕获PrScrn按键事件

  通过一种钩子的方式可以判定PrScrn 按键事件,钩子可以获取任何键盘事件。

这里给出CodeProject 上面的开源代码的解决方案。大家有兴趣自己研究吧:Global System Hooks in .NET 。

  其实我们按下一个键时,KeyDown和KeyPress是都要发生的,而且两个人看上去没有什么区别。但是其实两者还是有实质的区别的。

  例如:在一个多行文本框里面输入字符,为什么我们没有定义一个键盘响应事件,但是键盘却响应了,把字符输入到了文本框呢?其实我觉得因为这个事件就是系统默认的一个消息响应,它就KeyPress。如果你自己还给KeyPress定义了自己的响应的话,那么程序会先执行你定义的程序,然后完成系统要求的显示字符事件的响应过程,但是如果你在自己定义KeyPress事件如:private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)里面增加语句:e.Handled=true;那么系统要求的显示字符响应过程就不会被执行,原因就是这个语句的意思就是这个消息响应已经完成。但是如果你在KeyDown,KeyUp里面加这条语句,显示字符串等消息还是会发生,这说明系统的显示字符串和KeyDown,KeyUp是没有关系的,而对于回车和退格消息响应则是由KeyDown控制,增加那条语句则回车换行不会执行,退格响应也不会执行。

  综上:要屏蔽键盘上的一个字符的输入,可以在KeyPress里面进行增加语句,而要屏蔽回车和退格则可以在KeyDown里面进行增加语句。

==============================================================

1.这三个事件的顺序是怎么样的?

2.KeyDown 触发后,KeyUp是不是一定触发?

3.三个事件的定义

4.KeyDown、KeyUp 和KeyPress 之间的区别

5.如何区分是否按的是小键盘?

6.PrScrn按键三个事件能够捕获吗?

7.{菜单键}和{开始键}KeyPress能够捕获吗?

(一)键事件按下列顺序发生:

KeyDown

KeyPress

KeyUp

(二)KeyDown触发后,不一定触发KeyUp,当KeyDown 按下后,拖动鼠标,那么将不会触发KeyUp事件。

(三)定义

KeyDown:在控件有焦点的情况下按下键时发生。

KeyPress:在控件有焦点的情况下按下键时发生。(下面会说和KeyDown 的区别)

KeyUp:在控件有焦点的情况下释放键时发生。

(四)KeyPress 和KeyDown 、KeyPress之间的区别

  1.KeyPress主要用来捕获数字(注意:包括Shift+数字的符号)、字母(注意:包括大小写)、小键盘等除了F1-12、SHIFT、Alt、Ctrl、Insert、Home、PgUp、Delete、End、PgDn、ScrollLock、Pause、NumLock、{菜单键}、{开始键}和方向键外的ANSI字符
    KeyDown 和KeyUp 通常可以捕获键盘除了PrScrn所有按键(这里不讨论特殊键盘的特殊键)

  2.KeyPress 只能捕获单个字符
    KeyDown 和KeyUp 可以捕获组合键。

  3.KeyPress 可以捕获单个字符的大小写

  4.KeyDown和KeyUp 对于单个字符捕获的KeyValue 都是一个值,也就是不能判断单个字符的大小写。

  5.KeyPress 不区分小键盘和主键盘的数字字符。
    KeyDown 和KeyUp 区分小键盘和主键盘的数字字符。

  6.其中PrScrn 按键KeyPress、KeyDown和KeyUp 都不能捕获。

KeyDown,KeyPress和KeyUp详解(转)的更多相关文章

  1. KeyDown,KeyPress 和KeyUp

    研究了一下KeyDown,KeyPress 和KeyUp ,发现之间还是有点学问的.让我们带着如下问题来说明,如果你看到这些问题你都知道,那么这篇文章你就当复习吧:) 1.这三个事件的顺序是怎么样的? ...

  2. 详解键盘事件(keydown,keypress,keyup)

    一.键盘事件基础 1.定义 keydown:按下键盘键 keypress:紧接着keydown事件触发(只有按下字符键时触发) keyup:释放键盘键 顺序为:keydown -> keypre ...

  3. 键盘事件keydown、keypress、keyup随笔整理总结(摘抄)

    原文1:http://www.cnblogs.com/silence516/archive/2013/01/25/2876611.html 原文2:http://www.cnblogs.com/leo ...

  4. keydown - > keypress - > keyup 用法和区别

    英文输入法:   事件触发顺序:keydown - > keypress - > keyup   中文输入法:   firfox:输入触发keydown,回车确认输入触发keyup chr ...

  5. keydown,keypress,keyup三者之间的区别

    最近看了Javascript高级教程中对过滤输入的介绍,想实现比如电话号码中不能包好非数值的字符,而相应文本中插入字符的操作是keypress事件,所以就想通过阻止这个事件的默认事件行为来阻止这个事件 ...

  6. C#控件中的KeyDown、KeyPress 与 KeyUp事件浅谈

    研究了一下KeyDown,KeyPress 和 KeyUp 的学问.让我们带着如下问题来说明: 1.这三个事件的顺序是怎么样的? 2.KeyDown 触发后,KeyUp是不是一定触发? 3.三个事件的 ...

  7. 2019-3-22KeyDown,KeyPress 和 KeyUp 事件

    研究了一下KeyDown,KeyPress 和 KeyUp 的学问.让我们带着如下问题来说明: 1.这三个事件的顺序是怎么样的? 2.KeyDown 触发后,KeyUp是不是一定触发? 3.三个事件的 ...

  8. js keyup、keypress和keydown事件 详解

    js keyup.keypress和keydown事件  详解 js keyup.keypress和keydown事件都是有关于键盘的事件 当一个按键被pressed 或released在每一个现代浏 ...

  9. 键盘事件之keydown keypress keyup区别

    经过测试,显然事件执行的顺序是: keydown->keypress->keyup. 但是连续按一个按键的话,会一直触发:keydown keypress.直到你提起按键,会触发keyup ...

随机推荐

  1. “我爱淘”第二冲刺阶段Scrum站立会议3

    完成任务: 完成了注册界面的设计,以及部分代码,但是还没有完成服务器端的添加功能. 计划任务: 将注册功能实现了它,可以对数据库进行添加,在客户端实现分类功能,通过学院的分类查看书籍. 遇到问题: 分 ...

  2. Visual C++ 8.0对象布局

    哈哈,从M$ Visual C++ Team的Andy Rich那里又偷学到一招:VC8的隐含编译项/d1reportSingleClassLayout和/d1reportAllClassLayout ...

  3. Kettle 使用Json输入

    import java.math.BigDecimal; private static final String JD="jd"; private static final Str ...

  4. 利用vs10和opencv识别图片类型身份证的号码

    遇到的问题: 1 持续灰色图像框 waitkey()要在imshow()之前调用. 2 CvRect 和Rect CvXXX是C语言的接口,cv::XXX是C++语言的接口.两者混在一起容易出错 3 ...

  5. PHP执行原理

    简单解释:PHP执行原理 客户端向服务器发送一个请求,如果请求的是一个HTML页面,服务器直接将HTML页面发送到客户端给浏览器解析,如果请求的是PHP页面,则服务器会运行PHP页面然后生成标准的HT ...

  6. android Eclipse there no select

    点mainactivity类 右键  run as 进行 配置 就可运行

  7. php 单文件测试代码时必加入的代码

    有时候为了解决BUG,需要测试一些函数或代码最终实现的效果,来排除一些影响因素.这时候需要把代码单独拎出来,放在一个php单文件中来测试.在头部最好加上三句代码如下: <?php ini_set ...

  8. BZOJ 2118 墨墨的等式(最短路)

    很开拓眼界的题.. 题意:给出一个n元一次方程形如a1*x1+a2*x2...+an*xn=B,求满足解集为非负整数的B值在[L,R]范围内的种数.(n<=12,ai<=5e5,L< ...

  9. WEB测试基础

    一.输入框1.字符型输入框:(1)字符型输入框:英文全角.英文半角.数字.空或者空格.特殊字符“~!@#¥%……&*?[]{}”特别要注意单引号和&符号.禁止直接输入特殊字符时,使用“ ...

  10. OpenGL 加载DDS文件(压缩纹理)

    想必很多人都见过DDS这种文件,它是一个“图片文件”,如果你安装了某些看图软件,你可以直接双击打开它来进行预览. 那么,这种DDS文件和我们常见的TGA/PNG之类的文件有何不同呢? DDS和TGA/ ...