日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

KeyDown,KeyPress和KeyUp详解(转)

發(fā)布時間:2025/3/15 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 KeyDown,KeyPress和KeyUp详解(转) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.按鍵的類型

  Windows窗體將鍵盤輸入標識為由按位Keys枚舉表示的虛擬鍵代碼。使用Keys枚舉,可以綜合一系列按鍵以生成單個值,這些值與WM_KEYDOWN和WM_SYSKEYDOWNWindows消息所伴隨的值相對應。另外,程序開發(fā)人員可通過處理KeyDown或KeyUp 事件來檢測大多數(shù)物理按鍵操作。字符鍵是Keys枚舉的子集,它們與WM_CHAR和WM_SYSCHAR Windows消息所伴隨的值相對應,如果通過組合按鍵得到一個字符,則可以通過處理KeyPress事件來檢測該字符。

2. 定義

KeyDown:在控件有焦點的情況下按下鍵時發(fā)生。

KeyPress:在控件有焦點的情況下按下鍵時發(fā)生。(下面會說和KeyDown 的區(qū)別)

KeyUp:在控件有焦點的情況下釋放鍵時發(fā)生。

注意:KeyDown觸發(fā)后,不一定觸發(fā)KeyUp,當KeyDown 按下后,拖動鼠標,那么將不會觸發(fā)KeyUp事件。

3.鍵盤事件的順序

  一個控件上可能出現(xiàn)3個與鍵盤相關的事件,下面是這些事件發(fā)生的常規(guī)順序:

  用戶按“a”鍵,該鍵將被預處理和調(diào)度,而且會發(fā)生KeyDown事件。?
  用戶按住“a”鍵,該鍵將被預處理和調(diào)度,而且會發(fā)生KeyPress事件。?
  用戶松開“a”鍵,該鍵將被預處理和調(diào)度,而且會發(fā)生KeyUp事件。
?
4.鍵的預處理

  像其他消息一樣,鍵盤消息是在窗體或控件的WndProc方法中處理的。窗體或控件在處理鍵盤消息之前,PreProcessMessage方法會調(diào)用一個或多個方法,這些方法可被重寫以處理特殊的字符鍵和物理按鍵。


5. KeyPress 和KeyDown 、KeyPress之間的區(qū)別

KeyPress主要用來捕獲數(shù)字(注意:包括Shift+數(shù)字的符號)、字母(注意:包括大小寫)、小鍵盤等除了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的狀態(tài),這對于不支持KeyDown 事件的控件非常有用)。?
KeyPress 可以捕獲單個字符的大小寫?
KeyDown和KeyUp 對于單個字符捕獲的KeyValue 都是一個值,也就是不能判斷單個字符的大小寫。 (可通過.net 2.0中新增Control.IsKeyLocked(Keys.CapsLock)方法判斷CapsLock的狀態(tài),類似,Scroll Lock和Num Lock也可通過Control.IsKeyLocked()方法來判斷)。?
KeyPress 不區(qū)分小鍵盤和主鍵盤的數(shù)字字符。?
KeyDown 和KeyUp 區(qū)分小鍵盤和主鍵盤的數(shù)字字符。?
其中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. 獲取按鍵狀態(tài)

需獲取各鍵狀態(tài),要用到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;
}

那么兩者有什么區(qū)別呢?查了下,有人提到說:GetKeyState得到的結果是在獲取到當前消息時的鍵盤上按鍵狀態(tài)的一個映像,也就是說,這個狀態(tài)不會隨著按鍵真實按鍵狀態(tài)的改變而改變。其實通常情況下得到這樣非實時的結果就足夠了。由于只是查表,所以速度較快,但是決不能寫出下面的代碼

while(GetKeyState(nVirKey))

{

  //code here

}

  而要得到某一個鍵實時的狀態(tài),則應該使用GetAsyncKeyState,這個函數(shù)通過查詢Driver而得到實時的信息。但是這個函數(shù)較GetKeyState慢。(這點還不大明白···)


7. 系統(tǒng)組合鍵的判定

  在使用鍵盤的時候,通常會使用到CTRL+SHIFT+ALT 類似的組合鍵功能。對于此,我們?nèi)绾蝸砼卸?#xff1f;

通過KeyUp 事件能夠來處理(這里說明一下為什么不用KeyDown,因為在判定KeyDown的時候,CTRL、SHIFT和ALT 屬于一直按下狀態(tài),然后再加另外一個鍵是不能準確捕獲組合鍵,所以使用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是都要發(fā)生的,而且兩個人看上去沒有什么區(qū)別。但是其實兩者還是有實質(zhì)的區(qū)別的。

  例如:在一個多行文本框里面輸入字符,為什么我們沒有定義一個鍵盤響應事件,但是鍵盤卻響應了,把字符輸入到了文本框呢?其實我覺得因為這個事件就是系統(tǒng)默認的一個消息響應,它就KeyPress。如果你自己還給KeyPress定義了自己的響應的話,那么程序會先執(zhí)行你定義的程序,然后完成系統(tǒng)要求的顯示字符事件的響應過程,但是如果你在自己定義KeyPress事件如:private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)里面增加語句:e.Handled=true;那么系統(tǒng)要求的顯示字符響應過程就不會被執(zhí)行,原因就是這個語句的意思就是這個消息響應已經(jīng)完成。但是如果你在KeyDown,KeyUp里面加這條語句,顯示字符串等消息還是會發(fā)生,這說明系統(tǒng)的顯示字符串和KeyDown,KeyUp是沒有關系的,而對于回車和退格消息響應則是由KeyDown控制,增加那條語句則回車換行不會執(zhí)行,退格響應也不會執(zhí)行。

  綜上:要屏蔽鍵盤上的一個字符的輸入,可以在KeyPress里面進行增加語句,而要屏蔽回車和退格則可以在KeyDown里面進行增加語句。

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

1.這三個事件的順序是怎么樣的?

2.KeyDown 觸發(fā)后,KeyUp是不是一定觸發(fā)?

3.三個事件的定義

4.KeyDown、KeyUp 和KeyPress 之間的區(qū)別

5.如何區(qū)分是否按的是小鍵盤?

6.PrScrn按鍵三個事件能夠捕獲嗎?

7.{菜單鍵}和{開始鍵}KeyPress能夠捕獲嗎?

(一)鍵事件按下列順序發(fā)生:

KeyDown

KeyPress

KeyUp

(二)KeyDown觸發(fā)后,不一定觸發(fā)KeyUp,當KeyDown 按下后,拖動鼠標,那么將不會觸發(fā)KeyUp事件。

(三)定義

KeyDown:在控件有焦點的情況下按下鍵時發(fā)生。

KeyPress:在控件有焦點的情況下按下鍵時發(fā)生。(下面會說和KeyDown 的區(qū)別)

KeyUp:在控件有焦點的情況下釋放鍵時發(fā)生。

(四)KeyPress 和KeyDown 、KeyPress之間的區(qū)別

  1.KeyPress主要用來捕獲數(shù)字(注意:包括Shift+數(shù)字的符號)、字母(注意:包括大小寫)、小鍵盤等除了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 不區(qū)分小鍵盤和主鍵盤的數(shù)字字符。
    KeyDown 和KeyUp 區(qū)分小鍵盤和主鍵盤的數(shù)字字符。

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

轉載于:https://www.cnblogs.com/hello-web/p/7532134.html

總結

以上是生活随笔為你收集整理的KeyDown,KeyPress和KeyUp详解(转)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。