KeyDown/PreviewKeyDown事件中監聽Alt鍵按下


一個坑

在WPF應用程序(或者其他Windows應用程序中),為了監聽Alt鍵按下,我們可以嘗試寫出這樣的代碼:

PreviewKeyDown += (s, e) =>
{
    if (e.Key == Key.LeftAlt || e.Key == Key.RightAlt)
    {
        // A: 做些什么。
    }
};

然而,運行一看,發現並沒有什么用。A處的代碼根本就沒執行。

打個斷點看下,會發現, e.Key 的值是 Key.System 。這就奇怪了, Key.System 是個什么鬼?

一段源碼

看看KeyEventArgs中的源碼,我們發現微軟寫了這么個注釋:

/// <summary>
///     The Key referenced by the event, if the key is not being 
///     handled specially.
/// </summary>
public Key Key
{
    get {return _key;}
}

如果按鍵沒有被特殊處理, Key 屬性才會返回正確的按鍵。這么說,當我們按下Alt鍵時,其實Windows或者WPF某一層特殊處理了這個按鍵。繼續閱讀源碼,發現這個屬性后面還有這樣一個屬性:

/// <summary>
///     The Key referenced by the event, if the key is going to be
///     processed by an system.
/// </summary>
public Key SystemKey
{
    get { return (_key == Key.System) ? _realKey : Key.None;}
}

跟剛剛的 Key 屬性相反,這個屬性指進行特殊處理時返回的按鍵。所以,截至這里,問題算是解決了,因為我們可以寫出這樣的代碼:

PreviewKeyDown += (s, e) =>
{
    Key key = (e.Key == Key.System ? e.SystemKey : e.Key);
    if (key == Key.LeftAlt || key == Key.RightAlt)
    {
        // A: 做些什么。
    }
};

一個解釋

然而事情肯定不能這樣就結束了,微軟為什么要設計這樣奇怪的機制?為什么Alt鍵要成為特殊系統按鍵?

經過一系列搜索,我找到了解釋:

在Windows系統中,Alt鍵會被特殊處理。當單獨按下Alt鍵,或者按下一個帶有Alt的組合鍵時,操作系統會將此事件視為“系統按鍵”(System keypress)。系統按鍵與普通按鍵相比,其處理過程是不同的。

首先,無論是系統按鍵還是普通按鍵,Windows都會將這些事件傳遞給應用程序。如果是普通按鍵,則傳遞 WM_KEYDOWN ,但如果是Alt鍵,則傳遞 WM_SYSKEYDOWN ;同理, WM_KEYUP 也會轉變成 WM_SYSKEYUP 。

在Windows中(包括WPF中),Alt鍵如此特殊是為了處理應用程序中那些帶有“特殊標記”文字的菜單項(MenuItems)、按鈕(Buttons)和其它標簽(Labels)的。舉個例子,如果按鈕的文字內容被設置成“Say _Hi”,那么Alt+H快捷鍵就會被轉變成為一次按鈕點擊(Click)事件。

這段解釋可以在這里http://stackoverflow.com/questions/3099472/previewkeydown-is-not-seeing-alt-modifiers得到更詳細的信息。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM