C# 如何在同一控件上处理快捷键和按住键

C# 如何在同一控件上处理快捷键和按住键,c#,winforms,keyboard-shortcuts,C#,Winforms,Keyboard Shortcuts,我的WinForms应用程序(针对NET 3.5)使用我用ProcessCmdKey处理的键盘快捷键。我还有一小部分按键是按住的。例如,用户按下R键并拖出一个区域,或按住D键以临时显示一些对象。所有这些都与画布控件相关联 我一直在通过canvas Key_Down和Key_Up事件处理按住键 我认为所有这些都是有效的,因为它的大部分已经在代码中存在了一段时间。然而,很明显,按下并保持动作是不稳定的,不能保证 我知道ProcessCmdKey在Key_Down事件之前被调用,我可以通过从Proce

我的WinForms应用程序(针对NET 3.5)使用我用ProcessCmdKey处理的键盘快捷键。我还有一小部分按键是按住的。例如,用户按下R键并拖出一个区域,或按住D键以临时显示一些对象。所有这些都与画布控件相关联

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

我认为所有这些都是有效的,因为它的大部分已经在代码中存在了一段时间。然而,很明显,按下并保持动作是不稳定的,不能保证

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

按下并保持动作有时有效,但随后停止。最可靠的停止方法是按下修改键。我在Key_Down和Key_Up事件中有代码,这些事件与修改键有关,我怀疑这是我的责任

作为替代方案,我尝试了Hans在回答这个问题时提出的代码:我让它工作,并在按键向下和向上事件中禁用了代码。这起作用,但在按下修改器键后停止,因为在“向下键”和“向上键”事件中有它们的代码。删除它似乎使其工作,我留下的按住键仍然失败,如果我使用一些其他键,如F8

我已经检查了许多其他类似问题的答案:和

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

向下键和向上键的代码遵循此模式

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);
}
我已尝试将forms KeyPreview属性设置为true和false。这似乎不会改变行为

总之,我需要在一个画布上同时处理键盘快捷键和按住键。总的来说,我已经让它工作了,但代价是丢失了当修改键关闭时向用户显示的代码,而这一切现在看起来有点紧急。我相信一定有更好的办法,但我已经没有主意了,所以希望能给我一些建议

编辑

我现在发现,阻止按住键的键在某种程度上都是特殊的。Esc、F1-F2、Home、End、PageUp、PageDown和箭头键。点击其中一个按钮可停止压力机并保持工作状态;点击其中一个按钮,使其工作。所有这些键都可以切换按住按钮的工作状态


我试着把焦点放在画布上,但事实并非如此。我已尝试覆盖IsInputKey,但不起作用。因此,除了知道这是这些“特殊钥匙”之外,我不再向前迈进了。

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


据我所知,代码很好,因此这里根本没有C#或WinForms问题。

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