Winapi - расширенные коды сканирования клавиатуры
Если бы я хотел смоделировать нажатие клавиши, используя расширенный код сканирования, например 0xE0 0x1D (для правого CTRL), как бы я смоделировал такое нажатие клавиши в C? Я пробовал звонить SendInput
с двумя INPUT
структурирует, но только левая клавиша CTRL была "нажата". То же самое происходит в случае других клавиш, которые имеют "двойник" (Shift и Alt).
Во-вторых, как вызвать событие keyup для "расширенного" ключа?
2 ответа
KEYBDINPUT
структура имеет KEYEVENTF_EXTENDEDKEY
флаг для обработки 0xE0
Байт для вас:
Если указан, коду сканирования предшествует байт префикса со значением 0xE0 (224).
Попробуйте что-то вроде этого:
INPUT inputs[2];
ZeroMemory(inputs, sizeof(inputs));
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wScan = 0x1D;
inputs[0].ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_EXTENDEDKEY;
CopyMemory(&inputs[1], &inputs[0], sizeof(INPUT));
inputs[1].ki.dwFlags |= KEYEVENTF_KEYUP;
SendInput(2, inputs, sizeof(INPUT));
Однако я бы предложил использовать виртуальный ключ вместо кода сканирования:
INPUT inputs[2];
ZeroMemory(inputs, sizeof(inputs));
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = VK_CONTROL;
inputs[0].ki.dwFlags = KEYEVENTF_EXTENDEDKEY;
CopyMemory(&inputs[1], &inputs[0], sizeof(INPUT));
inputs[1].ki.dwFlags |= KEYEVENTF_KEYUP;
SendInput(2, inputs, sizeof(INPUT));
Но, если вам абсолютно необходим код сканирования, по крайней мере, посмотрите на MapVirtualKey()
преобразовать виртуальный ключ в код сканирования:
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wScan = MapVirtualKey(VK_RCONTROL, MAPVK_VK_TO_VSC);
inputs[0].ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_EXTENDEDKEY;
Вы не указали, следует ли отправлять ключи тому же приложению или другому приложению. Используя SendInput, мы не можем указать куда идут ключи. Мы должны как-то убедиться, что окно активно и что фокус установлен правильно. Обратите внимание, что SendInput отправит сообщение WM_KEYDOWN или WM_KEYUP. У вас больше гибкости, если вы используете SendMesage напрямую для отправки сообщений WM_KEYDOWN и WM_KEYUP. Вы указываете дескриптор окна для отправки. Дескриптор окна предназначен для текстового поля или элемента управления, который принимает текст, а не окна, в котором находится текстовое поле или другой элемент управления.
Это как определить точные параметры для использования в SendMessage. Обратите внимание, что SendInput создаст SendMessage.
В Visual Studio щелкните меню "Сервис". Вы увидите "Spy++" и "Spy++ x64". Я не уверен, когда нам нужно одно или другое, но если одно не работает, попробуйте другое. В Spy ++ в меню "Сообщения" выберите "Параметры журнала...". В правом верхнем углу нажмите на инструмент поиска и перетащите в окно. После того, как вы отпустите кнопку мыши, щелкните вкладку "Сообщения". Затем нажмите "Очистить все", затем установите флажок "Клавиатура". Обратите внимание, что в меню "Сообщения" также есть команды для запуска и остановки регистрации, но я думаю, что она включена по умолчанию. Перейдите к выбранному окну и введите ключи, которые вы хотите попробовать. Затем посмотрите на сообщения, зарегистрированные в Spy++. Вы увидите все сообщения, которые были отправлены в / из окна. Я обычно прекращаю запись в журнал, как только у меня есть все, что мне нужно, поскольку, в зависимости от сообщений, выбранных для ведения журнала, может быть слишком много сообщений, зарегистрированных для полезности. Если вы регистрируете только сообщения клавиатуры, вы не будете регистрировать слишком много сообщений.
Для меня поле Extended - 1 для правого Ctrl и 0 для левого Ctrl.