Высокоуровневая глобальная клавиатурная зацепка для C# и WPF для чтения клавиатурных сканеров

Единственный перехват клавиатуры, поддерживаемый для управляемого кода.NET, - перехват клавиатуры низкого уровня (WH_KEYBOARD_LL).

См. Использование глобальной клавиатуры (WH_KEYBOARD_LL) в WPF / C#

В данный момент у меня в приложении работает приведенный выше код, поэтому, когда вы проводите по карте, вы получите список всех нажатий клавиш. Проблема заключается в наборе символов-разделителей, таких как "%" и ";" это отправит мне Alt+Numpad+? WPF Ключевые объекты, соответствующие этим символам.

Мой вопрос: есть ли какой-нибудь способ сделать это более высокоуровневым, то есть захватить строку, сгенерированную всеми командами клавиатуры?

Ура!

2 ответа

Решение

Не уверен, что происходит, но вытащить символ, такой как%, из клавишной ловушки очень нетривиально. Хук только уведомляет вас о виртуальных ключах. Но% - это клавиша для ввода, которая создается нажатием Shift + 5 на моей клавиатуре (раскладка в США). Обычно Windows создает эти символы, обрабатывая сообщения WM_KEYDOWN/UP, генерируя сообщение WM_CHAR для клавиши ввода. Это не происходит в вашем случае. Низкоуровневая функция Windows, которая делает это, ToUnicodeEx().

Я полагаю, если вы проводите карту, есть ли где-то в форме wpf, например, текстовое поле? Затем я был бы склонен добавить событие, возможно, обработчик события KeyUp, (сканер карты клина клавиатуры отправляет сигнал об окончании обработки, такой как ENTER, чтобы указать, что считывание прошло успешно, да?), В обработчике событий KeyUp, создайте строку, используя StringBuilder, и когда сигнал об окончании обработки, такой как ENTER, перехватывается, вы можете удалить "%" и ";" из экземпляра StringBuilder и делайте все, что вам нужно с ним делать.

Возможно, было бы проще использовать систему состояний, когда обработчик событий KeyUp получает "%", а затем перейти в другое состояние, где конечное ожидаемое состояние будет ";"

static bool StartState = false;
StringBuilder sbInput = new StringBuilder ();
private void textBox1_KeyUp (отправитель объекта, KeyEventArgs e)
{
   if (!StartState){
    if (e.KeyCode == Keys.D5) StartState = true;
    sbInput.Append((символ)e.KeyValue);
   } Еще {
    if (e.KeyCode == Keys.OemSemicolon){
       StartState = false;
       // sbInput будет содержать данные со сканера,
       // копируем его куда-то еще и сбрасываем sbInput
       // sbInput.Remove(0, sbInput.Length); 
    }
    sbInput.Append((символ)e.KeyValue);
   }
   e.Handled = true;
}

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

Другие вопросы по тегам