zoukankan      html  css  js  c++  java
  • 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得到更详细的信息。

  • 相关阅读:
    陈天桥:重点布局影音文娱业务及海内市场
    瑞信维持新浪跑赢大盘评级
    快讯:空中网第四季度净利501万美元同比涨148%
    传高盛与德劭前合伙人组5亿美元私募基金
    CodeFirst 关系创建——Fluent API配置多重关系,关闭级联删除的方法
    笔记:IE下 jquery的fadeIn与fadeOut方法失效的BUG
    Codefirst Fluent API创建关系
    javascript拖动效果的一个注意事项:拖动图片时,mousemove事件会被中断
    通过下拉菜单筛选GridPanel的数据【转】
    as3.0学习笔记——坐标轴、并记录画图所犯的两个低级错误
  • 原文地址:https://www.cnblogs.com/walterlv/p/previewkeydown-is-not-seeing-alt-modifiers.html
Copyright © 2011-2022 走看看