【问题标题】:How do I create a keybinding to the backslash key in WPF?如何在 WPF 中创建与反斜杠键的键绑定?
【发布时间】:2014-05-16 08:34:39
【问题描述】:

尝试为我们的 WPF 命令定义 CTRL-\(反斜杠)键绑定,但我们遇到了两个问题:

  1. 反斜杠键没有任何预定义的常量,只有 OemBackslash 和

  2. OemBackslash 似乎也没有一致的数字代码

例如,如果您在 Dell 上与在 Mac 上启动 Windows 时,Dell 会为 e.Key 返回不同的值。然而,两者都正确输入了反斜杠。

让我感到沮丧的是,而不是继续这些代码在驱动程序中映射到什么——即键面上的实际内容--MS 基于键码的键盘快捷键,如上所述,不一定一致。

我的想法不是使用键绑定,而是使用 PreviewKeyDown 事件,然后检查键代码,以某种方式将其传递给驱动程序以确定将代表什么类型的键(即驱动程序会说键代码 X 代表反斜杠关键面)然后将该值用于我们的逻辑。但是,可以这么说,我不知道如何从 KeyCode 转到 key-face。

那么...关于如何做/处理这个的想法?

【问题讨论】:

    标签: wpf key-bindings keycode


    【解决方案1】:

    编辑

    我强烈建议你不要向下滚动到编辑结束,我知道键盘图片很诱人,但为了获得更好的体验,请阅读所有内容:D

    正如我所说,绝对尝试是没有意义的,这种方法是不可靠的,所以 你怎么能期望不可靠的东西能够可靠地工作? 甚至尝试逆向工程也绝对没有意义驱动程序或破译 USB 流,任何理智的人都会告诉你:D

    即使您可以实现其中任何一项(IMO 非常不确定),您也可以针对特定品牌的键盘完成此操作。另一件事是时间因素,对于结果来说这是一个巨大的浪费时间。

    我发现在 C# 中最接近金属的是:

    Using Raw Input from C# to handle multiple keyboards

    RawInputProcess.RawKeyboard.ProcessRawInput 从 User32 调用 GetRawInputData 即使是这种低级的东西也确实返回 0xDC 或 220(即了不起的 Oem5)。这会调用 VirtualKeyCorrection 来纠正一些键,你可以在那里做一些事情,尽管它也很丑陋并且尽可能不可靠。

    另外,还有一堆关于 HID 库的链接here

    我的明确答案:

    你绝对希望能够绑定?

    您将在此处获得与 Ctrl+\ 的默认绑定。

    现在是一些历史和一些你可能还没有掌握的东西!

    如果您仔细查看 MSDN 文档 -> Keys Enumeration

    OemBackslash

    RT 102 键键盘(Windows 2000 或更高版本)上的 OEM 尖括号或反斜杠键。

    我很确定你知道这件事,但甚至没有注意它。

    我个人在 86 年 5 岁的时候就在 IBM XT 克隆上玩过它。

    现在你可能开始明白了,但我会说得很清楚:

    OemBackslash 是 80 年代的遗迹,与 Windows 中的许多其他东西非常相似(尽管大多数(如果不是全部)在当前版本中已被删除)

    所以除非您确实拥有这些键盘之一,否则您将永远不会收到此KeyCode

    除非有人在 2000/XP 下使用 DIN 到 PS/2 适配器测试 RT-102,否则我不能 100% 确定,看看结果会很有趣; 但让我有信心这么说的原因是,第一个文档,第二个一般微软的人知道他们在做什么,他们写了那个东西。如果这是假的,我会吃掉我的帽子。

    希望您对我的编辑感到满意,最后哀悼 OemBackslash,我完全理解您希望在屏幕上看到这样的东西的愿望,但没有什么是完美的,尤其是在计算方面。我给了你一个伪解决方法,它是字面意思,试一试!

    图片来源:


    我一直在阅读your previous question,我会像 Hans 所说的那样告诉你:绑定它不是一个好主意,因为它不一定是反斜杠。

    例如在法语键盘中要获得反斜杠你必须按AltGr8AltGr只不过是 Alt+Ctrl 这意味着另外按 Alt 以使此布局执行您的命令。

    http://en.wikipedia.org/wiki/AltGr_key

    简而言之,这个快捷方式是不可靠的,因为它根据布局和/或制造商不是恒定的。

    在 WPF 中有 KeyInterop.VirtualKeyFromKey 但它也返回 Oem5 :(

    查看文档给出明确的答案:Virtual-Key Codes

    VK_OEM_5
    0xDC
    Used for miscellaneous characters; it can vary by keyboard.
    For the US standard keyboard, the '\|' key
    

    但这里有一个解决方案:D

    点击 \ 将带来 Oem5,但通过将事件发送到 TextBox 例如,您的系统将使用所有魔法将其转换为 \。然后,您可以获取 TextBox.Text 并根据与修饰符一起键入的键进行相应的操作。

    private bool _done;
    private void MainWindow_OnKeyDown(object sender, KeyEventArgs e)
    {
        if (_done) return;
        _done = true;
    
        var presentationSource = PresentationSource.FromDependencyObject(this);
        var keyEventArgs = new KeyEventArgs(Keyboard.PrimaryDevice, presentationSource, 0, e.Key)
        {
            RoutedEvent = KeyDownEvent
        };
        TextBox1.Focus();
        TextBox1.RaiseEvent(keyEventArgs);
    }
    
    private void TextBox1_OnTextChanged(object sender, TextChangedEventArgs e)
    {
        var text = TextBox1.Text;
    }
    

    注意 1:boolean 用于防止 StackOverflow:D

    注意 2:这可能和 key 一样不可靠,如果用户打开了 Shift 怎么办?我没试过

    这只是概念上的证明,它是可能的,但我个人不会走这条路,这太丑陋了 IMO;我宁愿允许用户将命令映射到他想要的任何手势。显然不允许他绑定到 \ :)

    编辑

    我有一个 MS 键盘和there is mskey.exe 可以诊断您的键盘:

    它确实导入了诸如HidP_GetValueCaps 之类的 HID.DLL 函数,因此您可以通过一些 P/Invoke 以更简洁的方式实现这一点,但它似乎需要做很多工作。

    【讨论】:

    • 投票支持 a) 找到我的旧帖子(我知道我写过一篇但找不到!) b) 你提供的详细信息量,c) 你展示了我不知道的酷 X 技巧! :) 如果您对 pinvoke 的最后评论有效,我会回来并将其标记为答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多