【问题标题】:How to Handle Both Short cut Keys and Press and Hold Keys on the Same Control如何处理两个快捷键并按住同一控件上的键
【发布时间】:2014-05-29 23:10:22
【问题描述】:

我的 WinForms 应用程序(面向 NET 3.5)使用我通过 ProcessCmdKey 处理的键盘快捷键。我也有少量的按键是按住的。比如用户按下R键拖出一个区域,或者按住D键临时显示一些对象。所有这些都与 Canvas 控件相关联。

我一直在通过画布 Key_Down 和 Key_Up 事件处理按住键。

我认为这一切都奏效了,因为其中大部分已经在代码中存在了一段时间。然而,很明显,按住动作是不稳定的并且不能保证。

我知道 ProcessCmdKey 在 Key_Down 事件之前被调用,我可以通过从 ProcessCmdKey 返回 true 来停止 Key_Down 事件以处理快捷方式。据我所知,我无法阻止 Key_Up 事件被触发

按住操作有时会起作用,但随后会停止。最可靠的停止方法是按下修改键。我在 Key_Down 和 Key_Up 事件中有与我怀疑应该负责的修饰键相关的代码。

作为替代方案,我尝试了 Hans 在回答此问题时提出的代码:ProcessCmdKey - wait for KeyUp? 我让它工作并禁用了 Key down 和 up 事件中的代码。这有效,但在按下修饰键后停止,因为在 Key_Down 和 Key_Up 事件中有它们的代码。删除它似乎可以让它工作,如果我使用 F8 等其他键,我的按住键仍然失败。

我检查了许多其他类似问题的答案:Skipping KeyDown On Override ProcessCmdKey EventHandllerKey Events: ProcessCmdKey

据我所知,我的 ProcessCmdKey 代码是标准的。我可以提供代码,但我只是在 switch 块中处理 KeyData 并对我想要的组合进行操作。

Key_Down 和 Key_Up 的代码遵循此模式

private void OnPCanvasKeyDown(object sender, KeyEventArgs e)
{
    if (e.Modifiers == Keys.Control)
    {
        controlDown = true;
        ctrlLabel.Text = "CTRL";
    }
    if (e.KeyCode == Keys.D)
    {
       if (!hiddenObjectsVisible)
       {
            hiddenObjectsVisible = true;
            services.ShowCustomHideObjects();
       }
     }
     OnKeyDown(e);
}

private void OnPCanvasKeyUp(object sender, KeyEventArgs e)
{
  if (e.KeyCode == Keys.ControlKey)
  {
      controlDown = false;
      ctrlLabel.Text = string.Empty;
  }

  if (e.KeyCode == Keys.D)
  {
      hiddenObjectsVisible = false;
      services.HideCustomHideObjects();
  }
   OnKeyUp(e);
}

我已尝试将表单 KeyPreview 属性设置为 true 和 false。这似乎不会改变行为。

因此,总而言之,我需要在单个画布上同时处理键盘快捷键和按住键。总的来说,我已经让它工作了,但代价是丢失了当修改键按下时向用户显示的代码,现在这一切似乎有点紧急。我确信一定有更好的方法,但我的想法已经不多了,所以希望得到一些建议。

编辑

我现在发现阻止按住键的键在某种程度上都是特殊的。 Esc、F1-F2、Home、End、PageUp、PageDown 和箭头键。点击其中之一以停止按住工作;点击其中之一以使其工作。任何和所有这些键都可以切换按住的工作。

我曾尝试将焦点强制放在画布上,但事实并非如此。我试图覆盖 IsInputKey 但这不起作用。所以除了知道是这些“特殊键”之外,我没有进一步前进

【问题讨论】:

  • 只是一个想法。使用计时器(间隔很小,例如 16 毫秒)并使用GetAsyncKeyState() 检查哪个键是向下或向上。它是可靠的,但有点丑。
  • 谢谢 - 我一定会看看的
  • 我尝试了您的建议,使用 GetAsyncKeyState() 可以获取键的状态。我现在完全感到困惑,因为切换此工作的特殊键的问题似乎也适用于此 - 所以我得出的结论是我的应用程序或计算机有一些非常奇怪的东西。我现在要构建一个测试应用程序...
  • 我已经在 c 中使用各种键(以及 Esc、F1-F2、Home、End、PageUp、PageDown)进行了测试,捕获了 WM_KEYDOWNWM_KEYUP 消息,一切都按预期工作。也许c# 与它有关。我也将使用c# 进行测试。
  • 感谢您的所有帮助。根据我在下面的回答,这似乎是与这台新开发 PC 上的键盘相关的硬件问题。我不知道为什么,接下来我需要做的是尝试另一个键盘。在我的笔记本电脑上,问题不存在。

标签: c# winforms keyboard-shortcuts


【解决方案1】:

我尴尬地回答这个问题。在另一台计算机上测试我的代码后,问题是键盘。由于我不理解这台计算机上键盘上的“特殊键”的原因,似乎负责阻止捕获按住键击。

据我所知,代码没问题,所以这里根本不存在 C# 或 WinForms 问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-02
    • 2012-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-05
    相关资源
    最近更新 更多