Нажатие клавиши WinForms работает неправильно - PullRequest
4 голосов
/ 09 июля 2009

обновление : я изменил код ниже, чтобы показать некоторую дополнительную информацию о нажатой клавише.

update # 2 : Я обнаружил основную причину проблемы: у нас есть HTML-элемент управления (движок рендеринга Gecko) в нашей форме. Когда этот движок рендеринга Gecko переходит к некоторому элементу управления Flash, внезапно ~ 2% нажатий клавиш не проходят, даже после того, как мы удалили элемент управления Gecko HTML. Ваху, я обвиняю в этом 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 ]

4 голосов
/ 09 июля 2009

РЕДАКТИРОВАТЬ Я обнаружил основную причину проблемы! Смотри ниже.

После дополнительных экспериментов я обнаружил, что если выполнить следующее, то все будет работать как положено:

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 голос
/ 09 июля 2009

Может быть, вы слишком долго ждете нажатия клавиши S и повторное нажатие клавиши Alt прекращается?

РЕДАКТИРОВАТЬ2: Я попытался вы опубликовали код, и я получил «Что, черт возьми», в тот момент, когда я касаюсь клавиши ALT, однако, если я отключаю эту проверку, Alt-S всегда проходит. В моей системе это код клавиши по умолчанию для клавиши Alt . Я могу игнорировать это, и Alt-S Пройдет потом.

РЕДАКТИРОВАТЬ: Согласно METADATA для перечисления ключей Keys.Menu равно 18. Чтобы увидеть это, нажмите F12 , когда курсор находится на перечислении ключей.

В документации указано, что Keys.Menu является ключом Alt .

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

Это говорит мне о том, что сообщается о нажатии клавиши Alt (18) с модификатором клавиши Alt (262144).

1 голос
/ 09 июля 2009

Из моего тестирования выяснилось, что клавиша "Alt" будет 262162.

Редактировать : Я переопределил 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.

0 голосов
/ 09 июля 2009

Просто из любопытства вы можете попробовать это:

    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 означает, что это не командный ключ.

...