2015-11-04 4 views
1

фона:VkKeyScan возвращается тем же код без модификаторов для акцентного и безударного письма

Я имитируя нажатия клавиша с помощью неуправляемой функции SendInput (https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310(v=vs.85).aspx). Есть 3 способа вызова этой функции:

  1. Уточняйте клавиатуры скан
  2. указать символ Юникода
  3. Укажите виртуальный код клавиши

Все работы, но, чтобы иметь возможность моделировать ярлыки такие как CTRL + PI, хотят использовать код виртуального ключа. В настоящее время у меня есть ручное сопоставление символа с кодом виртуального ключа, но это не очень хороший подход, поскольку он не чувствителен к раскладке клавиатуры операционной системы пользователя. Например, на английской (Великобритании) клавиатуре "." символ может быть сопоставлен с VirtualKeyCode.OEM_PERIOD, но если раскладка клавиатуры ОС - французская, то «.» это VirtualKeyCode.OEM_PERIOD + SHIFT.

Чтобы сделать мой код более надежным, я хочу вызвать метод VkKeyScan (https://msdn.microsoft.com/en-us/library/windows/desktop/ms646329(v=vs.85).aspx), передающий символ, чтобы получить код виртуального ключа (плюс shift/ctrl/alt). Этот подход, теоретически, заботится обо всем.

Проблема:

Декларация:

[DllImport("user32.dll", CharSet = CharSet.Unicode)] 
static extern short VkKeyScan(char ch); 

Использование:

var vkKeyScanResult = PInvoke.VkKeyScan(character); 
var vk = vkKeyScanResult & 0xff; 
var shift = (vkKeyScanResult >> 8 & 1) == 1; 
var ctrl = (vkKeyScanResult >> 8 & 2) == 1; 
var alt = (vkKeyScanResult >> 8 & 4) == 1; 

if (vk != -1) 
{ 
    Log.InfoFormat("'{0}' => virtual key code {1}{2}{3}{4}", 
     character, vk, shift ? "+shift" : null, ctrl ? "+ctrl" : null, alt ? "+alt" : null); 
} 

С макетом OS клавиатуры английского (UK) Я вижу следующие результаты:

  • 'е' => код виртуальной клавиши 69
  • 'E' = код ключа> виртуальная 69 + сдвиг
  • 'é' => код виртуальной клавиши 69

нотабене 69 - 0x45 в HEX, что соответствует клавише «E» в списках кодов виртуальных ключей, таких как http://www.kbdedit.com/manual/low_level_vk_list.html

Как можно «e» и «é» производить один и тот же код виртуального ключа? «é» на английской (британской) клавиатуре выводится нажатием «e» + ctrl + alt или «e» + altgr.

Теории:

  1. Мой код не так, и я не извлекая Ctrl и альт биты правильно.
  2. VkScanKey не работает так, как я ожидаю, и не способен возвращать такие вещи, как «é» как «e» + ctrl + alt (хотя документация MSDN предполагает, что она может).
  3. Что-то еще.
+0

Это несовершенная функция, только модификаторы, которые он поддерживает являются Shift, Ctrl и Alt. Не AltGr. Или, что бы ни случилось, с IME. –

+1

Я немного читал об ограничениях, но AltGr, похоже, поддерживается как Shift + Ctrl. Из статьи MSDN «Для раскладок клавиатуры, которые используют правую клавишу ALT в качестве клавиши сдвига (например, французский раскладку клавиатуры), состояние сдвига представлено значением 6, поскольку правый ключ ALT преобразован внутренне в CTRL + ALT. " – Julius

ответ

1

Похоже, что теория 1 - что я не извлекал биты модификатора правильно.Этот код работает:

var vkKeyScan = PInvoke.VkKeyScan(character); 
var vkCode = vkKeyScan & 0xff; 
var shift = (vkKeyScan & 0x100) > 0; 
var ctrl = (vkKeyScan & 0x200) > 0; 
var alt = (vkKeyScan & 0x400) > 0; 

Так что проблема была или что-то делать с упорядочением оператора (т.е. &, возможно, принимает приоритет над >> (бит сдвига)), хотя я не думаю, что так Я попробовал скобки вокруг сдвига бит, ИЛИ сам сдвиг работал не так, как ожидалось.

Вот совершить рабочий код, если вы заинтересованы: https://github.com/JuliusSweetland/OptiKey/commit/0e61c52371638c61e0ef05834cd31a363181ea0d

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