2017-01-11 33 views
1

Я искал, как обнаружить комбинации клавиш в C#.Обнаружить, если комбинация нажатых клавиш - это модификатор и модификатор.

В связи с этим я использую событие KeyDown формы с KeyPreview = true.

Мне нужно проверить, есть ли у e.Modifiers модификатор, а e.KeyCode - это нечто иное, чем модификатор.

Лучше всего было бы действительно открытое заявление, как:

if(Keys.Modifiers.Contains(e.Modifiers) && !Keys.Modifiers.Contains(e.KeyCode)){} 

К сожалению, это не работает.

Это тоже не работает, все это происходит со всеми ключами-модификаторами.

if ((e.Modifiers == Keys.Alt || e.Modifiers == Keys.Control || e.Modifiers == Keys.Shift) 
    && (e.KeyCode != Keys.Alt && e.KeyCode != Keys.Control && e.KeyCode != Keys.Shift)) 

Это почти работает, но нет Keys.AltKey становится истинным, когда ALT нажата.

if ((e.Modifiers == Keys.Alt || e.Modifiers == Keys.Control || e.Modifiers == Keys.Shift) 
    && (e.KeyCode != Keys.Alt && e.KeyCode != Keys.ControlKey && e.KeyCode != Keys.ShiftKey)) 

Как я мог добиться этого? Должно быть возможно, что e.KeyCode может быть чем-то вроде модификатора.

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

После правильной постановки инструкции, как наилучшим образом сохранить комбинацию в переменной и проверить ее при повторном вводе? Я думал о чем-то вроде сохранения каждого введенного ключа (когда он является модификатором, а другой нет) в List<Keys> и проверяет его через foreach, который return false;, когда один ключ введенной комбинации отсутствует в списке.

Все должно быть максимально динамичным.

Как это можно расширить, чтобы проверить любую комбинацию? Как Ctrl + F + Shift + C или Ctrl + F + H

Спасибо!

Майкл

ответ

0

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

[DllImport("user32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
static extern bool GetKeyboardState(byte [] lpKeyState); 

var array = new byte[256]; 
GetKeyboardState(array); 

После того, как у вас есть массив, вы можете сканировать все ключи в то же время без каких-либо больше/вызовов S O, которые должны создать гораздо меньше накладные расходы.

Например, вы можете увидеть, сколько клавиш нажаты с чем-то вроде

int countKeys = array.Count(a => a & 0x80); 

Если вы просто хотите проверить, если левая клавиша Alt нажата, вы можете использовать

bool leftAlt = (array[(byte)Key.LeftAlt] & 0x80); 
0

Я думаю, вам, возможно, придется делать то, что Джон Ву предлагает или, по крайней мере, на каком-то низком уровне, так как вам нужно будет запомнить последнюю нажатую клавишу.Если вы используете «несколько» ключей CHARACTER ... НЕ модификаторов, вам нужно будет запомнить, какая была последняя комбинация клавиш. Например: Ctrl + F + Shift + C ... прежде чем вы сможете найти символ «C», вам нужно будет запомнить часть Ctrl + F + Shift.

Каждый раз, когда вы используете несколько клавиш «Символ», вы должны помнить первый ключ (ы) в последовательности. Я не уверен, что использование этого большого количества ключей для достижения чего-то было бы удобным для пользователя. Однако одно из возможных решений, которое пришло от @Vivelin на How to get a combination of keys in c#, похоже, делает трюк. Это выглядит грязным и имеет только два разных условия.

Используя ваш пример, предположим, что мы ищем комбинацию Ctrl + F + Shift + C Код в основном устанавливает логическое значение в true, когда первая часть комбинации встречается Ctrl + F + Shift, затем она завершается. Когда будет нажата следующая клавиша, и комбинация будет Ctrl + Shift + C, тогда вы узнаете эту комбинацию Ctrl + F + Shift + C. Это похоже на другие программы, в которых вы удерживаете контрольный ключ (ы), затем нажмите один символ, а другой символ не обязательно в одно и то же время. В приведенном ниже коде я использовал отключенное текстовое поле для вывода, когда комбинация запущена. Надеюсь, это поможет.

private bool keyCombo1 = false; 
private bool keyCombo2 = false; 

private void textBox1_KeyDown(object sender, KeyEventArgs e) { 
    if (e.Control) { 
    if (e.Shift) { 
     if (e.KeyCode == Keys.F) { 
     keyCombo1 = true; 
     } 
     else { 
     if (e.KeyCode == Keys.C && keyCombo1) { 
      textBox2.AppendText("Key Combo 1 hit" + Environment.NewLine); 
     } 
     else { 
      keyCombo1 = false; 
     } 
     } 
    } 
    else { 
     // control only no-shift 
     if (e.KeyCode == Keys.F) { 
     keyCombo2 = true; 
     } 
     else { 
     if (e.KeyCode == Keys.H && keyCombo2) { 
      textBox2.AppendText("Key Combo 2 hit" + Environment.NewLine); 
     } 
     else { 
      keyCombo2 = false; 
     } 
     } 
    } 
    } 
    else { 
    // no control key pressed 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^