WinForms按键操作不正常

时间:2009-07-09 15:48:30

标签: c# winforms keyboard keyboard-shortcuts

更新:我修改了下面的代码,以显示有关所按键的其他信息。

更新#2 :我发现了问题的根本原因:我们在表单上有一个HTML控件(Gecko渲染引擎)。当Gecko渲染引擎导航到某个Flash控件时,即使在我们删除了Gecko HTML控件之后,突然有~2%的按键操作无法通过。 Wahoo,我得责怪Flash!现在的问题是,我该如何解决这个问题?

更新#3 :不,这不是Flash。这是Gecko渲染引擎。甚至导航到Google导致一些键无法通过我们的应用程序正确。 Hrmmm。

我们的WinForms应用程序中有一个奇怪的例子,用户按下一个组合键(在本例中, Alt + S ),WinForms告诉我们其他一些键按下组合(值262162):

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if(keyData == (Keys.S | Keys.Alt))
    {
       Console.WriteLine("You pressed Alt+S");
    }
    else if(keyData == (Keys.Menu | Keys.Alt))
    {
       Console.WriteLine("What the hell?"); // This sometimes gets hit when I press Alt+S
    }
}

90%的时间会显示You pressed Alt+S。但是在罕见的情况下,我们按下 Alt + S ,并说What the hell?

知道什么是错的吗?

4 个答案:

答案 0 :(得分:4)

编辑我发现了问题的根本原因!见下文。

经过更多的实验,我发现如果执行以下操作,它会按预期工作:

this.KeyPreview = true;
this.KeyDown += KeyDownHandler;
...
private void KeyDownHandler(object sender, KeyEventArgs e)
{
   if (e.KeyCode == Keys.S && e.Alt)
   {
        // This always works.
   }
}

我无法解释为什么ProcessCmdKey不起作用。我希望我知道。在此之前,这是一个可接受的解决方法。

我发现了这个问题。我们的表单上有一个HTML控件(Gecko渲染引擎)。当壁虎渲染引擎显示在表单上时,它必须安装一个钩子或某些更改某些键按下的东西,导致我们在某些情况下接收WM_Char而不是WM_KeyDown。

答案 1 :(得分:1)

从我的测试来看,似乎262162将成为“Alt”键。

编辑:我覆盖了ProcessCmdKey并在“X = 1;”上设置了一个断点语句:

    protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData)
    {
        int x = (int)keyData;
        if (x == 262162)
            x = 1;
        return true;
    }

只要我按下Alt键,它就会击中该断点。

答案 2 :(得分:1)

可能是你等待太长时间按 S 键并且 Alt 键重复被解雇了吗?

EDIT2:我试过你发布的代码,然后我接到了“地狱”,第二次触摸ALT键,但如果我禁用此检查,Alt-S总是会通过。在我的系统上,这似乎是 Alt 键的默认键代码。我可以忽略它,然后Alt-S将会出现。

编辑:根据METADATA的Keys枚举Keys.Menu是18.当光标在Keys Enumeration上时,看到这个命中 F12

文档说明Keys.Menu是 Alt 键。

http://msdn.microsoft.com/en-us/library/system.windows.forms.keys.aspx

这告诉我它正在报告 Alt 键被按下(18),并带有 Alt 键修饰符(262144)疯狂的东西。

答案 3 :(得分:0)

出于好奇,你可以试试这个:

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if (keyData == (Keys.S | Keys.Alt))
        {
            MessageBox.Show("You pressed Alt+S");
        }
        else if (keyData == (Keys.Menu | Keys.Alt))
        {
            return false;
        }

        return true;
    }

返回false表示这不是命令键。