Высокоуровневый глобальный клавиатурный хук для C # и WPF для считывания с клавиатуры сканером клиновых карт
-
22-09-2019 - |
Вопрос
Единственный клавиатурный хук, поддерживаемый для управляемого кода .NET, - это низкоуровневый клавиатурный хук (WH_KEYBOARD_LL).
Видишь Использование глобального подключения клавиатуры (WH_KEYBOARD_LL) в WPF / C#
В данный момент в моем приложении работает приведенный выше код, так что, когда вы проводите пальцем по своей карте, вы получаете список всех нажатий клавиш.Проблема заключается в том, что при вводе символов-разделителей, таких как "%" и ";", он отправит мне Alt + Numpad +?Ключевые объекты WPF, соответствующие этим символам.
Мой вопрос:Есть ли какой-нибудь способ сделать это поведение более высокоуровневым, то есть захватить строку, сгенерированную из всех команд клавиатуры?
Ваше здоровье!
Решение
Не уверен, что происходит, но получить символ типа % из хука клавиатуры очень нетривиально.Хук уведомляет вас только о виртуальных ключах.Но % - это клавиша ввода, создаваемая нажатием 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(object sender, KeyEventArgs e) { if (!StartState){ if (e.KeyCode == Keys.D5) StartState = true; sbInput.Append((char)e.KeyValue); }else{ if (e.KeyCode == Keys.OemSemicolon){ StartState = false; // sbInput will contain the data from the scanner, // copy it somewhere else and reset sbInput // sbInput.Remove(0, sbInput.Length); } sbInput.Append((char)e.KeyValue); } e.Handled = true; }
Надеюсь, это поможет, С наилучшими пожеланиями, Том.