Как я могу напечатать, какие клавиши нажаты?

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

введите здесь описание изображения

Как я могу реализовать что-то подобное? Событие, которое я читаю, имеет тип System.Windows.Forms.KeyEventArgs. Есть много ключей, у которых нет описания их фактического значения, и несколько других, которые имеют неточные значения. Нет ли решения, кроме как узнать код для каждой клавиши и отобразить их вручную?

Редактировать: для пояснения я хочу получить удобное строковое представление клавиш, которые были нажаты, как показано на скриншоте выше.


person Lunyx    schedule 13.02.2013    source источник


Ответы (4)


Событие имеет логические свойства для Alt, Control и Shift.

Тип KeyCodeSystem.Windows.Forms.Keys. У него есть атрибут [Flags], но он учитывается только для Alt, Control и Shift. Все остальные ключи имеют обычное значение.

private void showKeys(object sender, KeyEventArgs e)
{
    List<string> keys = new List<string>();

    if (e.Control == true)
    {
        keys.Add("CTRL");
    }

    if (e.Alt == true)
    {
        keys.Add("ALT");
    }

    if (e.Shift == true)
    {
        keys.Add("SHIFT");
    }

    switch (e.KeyCode)
    {
        case Keys.ControlKey:
        case Keys.Alt:
        case Keys.ShiftKey:
        case Keys.Menu:
            break;
        default:
            keys.Add(e.KeyCode.ToString()
                .Replace("Oem", string.Empty)
                );
            break;
    }

    e.Handled = true;

    textBox1.Text = string.Join(" + ", keys);
}
person user247702    schedule 13.02.2013
comment
Проблема в том, что я хочу напечатать удобную для пользователя строку, указывающую, какие клавиши были нажаты. Вы смотрели на пример в вопросе? Мне не нужно перечислять несколько ключей, так как я буду разрешать только модификаторы и еще один ключ. - person Lunyx; 13.02.2013
comment
Итак, у вас есть все необходимые данные. Вам все еще нужно сделать часть работы. Я отредактировал ответ, включив в него пример кода. В случае KeyDown и KeyUp свойство KeyCode будет содержать только одно значение, поэтому в зависимости от того, как вы обрабатываете событие, оно может потребовать некоторой модификации. - person user247702; 13.02.2013
comment
Могут быть некоторые крайние случаи, которые вам необходимо обработать, например, ключи Oem.... Просмотрите перечисление Keys, чтобы увидеть, есть ли какие-либо дополнительные случаи, которые вы хотите обработать. - person user247702; 13.02.2013
comment
Кажется, что-то не так. Вот что я получаю, когда нажимаю 5 (НЕ цифровую клавиатуру) i.imgur.com/qm2729X.png Я пытался нажимать обычные символы, но ни один из них на самом деле не переводил то, что нажимала клавиша в каком-либо из полей, поэтому я задал этот вопрос. - person Lunyx; 14.02.2013
comment
Я взглянул на Enum, и оказалось, что это немного странно. stackoverflow.com/questions/10162110 / объясняет это. Резюме: Alt, Control и Shift ведут себя как значения флажков, все остальные клавиши следует рассматривать как отдельные значения. D5 = 53 или 110101 — это ожидаемый результат, однако из-за атрибута [Flags] вы видите LButton = 1, MButton = 4, ShiftKey = 16, Space = 32 или 110101. i.imgur.com/x0c3bO5.png - person user247702; 14.02.2013
comment
Спасибо, что нашли объяснение этому. Позвольте мне изучить другие ключи, когда у меня будет время, и я свяжусь с вами. Проголосуйте пока. - person Lunyx; 14.02.2013
comment
Итак, я попытался напечатать значение, и оно отображается правильно. Я был немного сбит с толку значениями, показанными отладчиком. Я приму ваш ответ, так как он объяснил, почему я не видел фактического представления. - person Lunyx; 14.02.2013


Вы можете нажать клавишу ведьмы с помощью этого кода (для нажатия одной клавиши или нескольких клавиш установите для формы KeyPreview значение true )

    private void Form1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
    {
        label1.Text = null;
        label1.Text=e.Modifiers.ToString();
    }
person KF2    schedule 13.02.2013
comment
Я упомянул, что событие KeyEventArgs, а не PreviewKeyDownEventArgs. - person Lunyx; 13.02.2013

Для win-формы сначала необходимо установить свойство KeyPreview на true. Таким образом, нажатая клавиша должна быть обнаружена, даже если один из дочерних элементов формы имеет фокус, а сама форма его не имеет.

Затем переопределите один из следующих методов: OnKeyUp< /a>, OnKeyDown и OnKeyPress.

protected override void OnKeyUp(KeyEventArgs e)
{
  switch (e.KeyCode)
  {
      case Keys.F1:
         showHelpTopics();
         break;
  }
}

Если у вас нет описания некоторых ключей, просто выполните поиск msdn, и вы найдете его детали.

person Community    schedule 13.02.2013
comment
Я глобально обнаруживаю нажатия клавиш, поэтому я не думаю, что свойство KeyPreview имеет значение. Возможно, я должен был упомянуть об этом в вопросе. В любом случае я хочу иметь возможность обрабатывать все возможные ключи, поэтому было бы неэффективно делать что-то вроде оператора switch со всеми возможными сценариями. - person Lunyx; 13.02.2013