SendInput() не "отправляет" правильные смещенные символы?
void WriteChar(char c)
{
INPUT input = {0};
input.type = INPUT_KEYBOARD;
input.ki.wVk= VkKeyScanEx(c, GetKeyboardLayout(0) ) ;
SendInput(1,&input, sizeof(INPUT));
}
VkKeyScanEx возвращает разные коды клавиш для "/" и "?" (Один и тот же ключ), однако, если вы попытаетесь использовать этот метод для написания сообщения, содержащего "?", Он будет писать только "/". Я не знаю, что происходит. То же самое происходит с ';' а также ':'.
Я частично не понимаю коды клавиш и коды сканирования. Большинство символов имеют виртуальный код клавиши, однако я не могу найти что-то похожее для вопросительных знаков. Они должны существовать, но их нет в списке?
2 ответа
Коды сканирования - это необработанные идентификаторы клавиш, возвращаемые с клавиатуры. Таким образом, клавиатура из 101 клавиши (в теории) будет иметь 101 уникальный код сканирования, который она может вернуть. (см. сноску 1)
Коды виртуальных клавиш - это отдельный набор кодов, которые представляют собой клавишу на идеализированной клавиатуре. Независимо от того, где на реальной клавиатуре находится клавиша TAB и какой код сканирования используется для нее, код виртуальной клавиши всегда равен VK_TAB. windows.h
определяет коды VK_xxx для непечатаемых виртуальных ключей, для печатаемых код виртуального ключа совпадает со значением ASCII.
Но виртуальные коды клавиш все еще являются кодами клавиш. "A" и "a" имеют одинаковый код виртуальной клавиши, поэтому, если вы хотите отправить "A", вам нужно отправить VK_SHIFT вниз, затем "a" вниз, затем "a" вверх, затем VK_SHIFT вверх.
VkKeyScanEx()
преобразует символ в клавишу сканирования и состояние сдвига. См. приведенную ниже цитату с этой страницы. http://msdn.microsoft.com/en-us/library/ms646332(VS.85).aspx
Если функция завершается успешно, младший байт возвращаемого значения содержит код виртуальной клавиши, а старший бит содержит состояние сдвига, которое может быть комбинацией следующих битов флага.
Таким образом, вы не можете просто получить возврат из VkKeyScanEx(), вам нужно проверить, не помечен ли он клавишей Shift. и отправить клавишу Shift отдельным нажатием клавиши
SHORT vk = VkKeyScanEx(c, ...);
if (vk & 0x100) // check upper byte for shift flag
{
// send a shift key down
}
if (vk & 0x200) // check for ctrl flag
{
// send a ctrl key down
}
input.ki.wVk = vk & 0xFF;
// send keyup for each of the keydown
Вы также должны отправить ключ для каждого нажатия.
Примечания:
1 Это только теоретически, на практике стандартные клавиатуры ПК эмулируют старую клавиатуру IBM, которую вы даже больше не можете получить, поэтому некоторые клавиши могут возвращать 2 разных кода сканирования на основе другой клавиши, в то время как другие в других случаях две клавиши могут возвращать тот же код сканирования.
Попробуйте сделать это так. Если вы делаете это с помощью KEYEVENTF_UNICODE
Платформа хоста должна быть как минимум Windows 2000 или XP.
INPUT input[ 2 ];
input[ 0 ].type = INPUT_KEYBOARD;
input[ 0 ].ki.wVk = 0;
input[ 0 ].ki.wScan = c;
input[ 0 ].ki.dwFlags = KEYEVENTF_UNICODE;
input[ 0 ].ki.time = 0;
input[ 0 ].ki.dwExtraInfo = GetMessageExtraInfo();
input[ 1 ].type = INPUT_KEYBOARD;
input[ 1 ].ki.wVk = 0;
input[ 1 ].ki.wScan = c;
input[ 1 ].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
input[ 1 ].ki.time = 0;
input[ 1 ].ki.dwExtraInfo = GetMessageExtraInfo();
SendInput( ( UINT )2, input, sizeof( *input ) );
Судя по тому, что вы неправильно заполнили структуру ввода и не инициализировали некоторые обязательные элементы, я предполагаю, что вы не видели документации для этого. Смотрите SendInput, INPUT и KEYBDINPUT.