KeyDown,KeyPress和KeyUp详解(转)
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 都不能捕獲。
轉載于:https://www.cnblogs.com/hello-web/p/7532134.html
總結
以上是生活随笔為你收集整理的KeyDown,KeyPress和KeyUp详解(转)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php 7.1安装教程
- 下一篇: XML具有哪些特点?相对于HTML的优势