SendInput() для клавиатуры - только верхний регистр

Довольно забавно. Я только что спросил несколько минут назад здесь SendInput() для клавиатуры - только нижний регистр, как отправить буквы в верхнем регистре. Решение состояло в том, чтобы отправить сдвиг перед письмом. Но после включения шифта выключить не могу...

Я очень стараюсь с флагом KEYEVENTF_KEYUP следующим образом:

INPUT Input = { 0 };
Input.type       = INPUT_KEYBOARD;
Input.mi.dwFlags = KEYEVENTF_EXTENDEDKEY;
Input.ki.wVk   = VK_LSHIFT;
SendInput( 1, &Input, sizeof( INPUT ) );

Input.type       = INPUT_KEYBOARD;
Input.mi.dwFlags = KEYEVENTF_EXTENDEDKEY;
Input.ki.wVk   = 'A';
SendInput( 1, &Input, sizeof( INPUT ) );

Input.type       = INPUT_KEYBOARD;
Input.mi.dwFlags = KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY;
Input.ki.wVk   = VK_LSHIFT;
SendInput( 1, &Input, sizeof( INPUT ) );

Input.type       = INPUT_KEYBOARD;
Input.mi.dwFlags = KEYEVENTF_EXTENDEDKEY;
Input.ki.wVk   = 'A';
SendInput( 1, &Input, sizeof( INPUT ) );

но, похоже, это вообще не работает. Он всегда посылает АА.

Спасибо.


person tobi    schedule 11.07.2012    source источник
comment
Левая клавиша Shift не является KEYEVENTF_EXTENDEDKEY. Ни А.   -  person Hans Passant    schedule 11.07.2012
comment
Кроме того, вы отправляете вниз для A дважды.   -  person Raymond Chen    schedule 11.07.2012


Ответы (1)


Проблема была с

Input.mi.dwFlags

так должно быть

Input.ki.dwFlags

благодаря Родриго.

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

Из-за использования кодов сканирования мы должны сопоставить наш виртуальный код с кодом сканирования с помощью MapVirtualKey() со значением MAPVK_VK_TO_VSC, MSDN говорит:

uCode — это код виртуального ключа, который транслируется в скан-код. Если это код виртуальной клавиши, который не различает клавиши для левой и правой руки, возвращается скан-код для левой руки. Если перевода нет, функция возвращает 0.

а затем передать его в поле wScan структуры Input.ki, потому что, согласно MSDN, если мы используем коды сканирования, он игнорирует wVk и использует wScan, MSDN говорит:

Если указано, wScan идентифицирует ключ, а wVk игнорируется.

Поэтому код может выглядеть примерно так:

INPUT Event = { 0 };

const SHORT key = VkKeyScan('a');
const UINT mappedKey = MapVirtualKey( LOBYTE( key ), 0 );

// Press shift key
Event.type = INPUT_KEYBOARD;
Event.ki.dwFlags = KEYEVENTF_SCANCODE;
Event.ki.wScan = MapVirtualKey( VK_LSHIFT, 0 );
SendInput( 1, &Event, sizeof( Event ) );

// upper case 'A' (press down)
Event.type = INPUT_KEYBOARD;
Event.ki.dwFlags = KEYEVENTF_SCANCODE;
Event.ki.wScan = mappedKey;
SendInput( 1, &Event, sizeof( Event ) );

//  release 'A'
Event.type = INPUT_KEYBOARD;
Event.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
Event.ki.wScan = mappedKey;
SendInput( 1, &Event, sizeof( Event ) );

// Release shift key
Event.type = INPUT_KEYBOARD;
Event.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
Event.ki.wScan = MapVirtualKey( VK_LSHIFT, 0 );
SendInput( 1, &Event, sizeof( Event ) );

const SHORT key1 = VkKeyScan('a');
const UINT mappedKey1 = MapVirtualKey( LOBYTE( key1 ), 0 );

// lower case 'a' (press down)
Event.type = INPUT_KEYBOARD;
Event.ki.dwFlags = KEYEVENTF_SCANCODE;
Event.ki.wScan = mappedKey1;
SendInput( 1, &Event, sizeof( Event ) );

// release 'a'
Event.type = INPUT_KEYBOARD;
Event.ki.dwFlags = KEYEVENTF_SCANCODE;
Event.ki.wScan = mappedKey1;
SendInput( 1, &Event, sizeof( Event ) );

Если я что-то не так сказал, поправьте меня.

person tobi    schedule 11.07.2012
comment
Вы упустили весь смысл SendInput, а именно поместить массивы входных событий, которые не могут быть прерваны реальными входными событиями. - person David Heffernan; 06.09.2013
comment
Вы забыли поставить унарный OR KEYEVENTF_KEYUP при освобождении «a». @tobi, проверь мою правку - person xiriusly; 03.10.2013