Как различить левую и правую клавиши (CTRL и ALT)? - PullRequest
5 голосов
/ 15 апреля 2011

Я начал использовать сырые функции ввода Win32 для обнаружения всех клавиш на клавиатуре.Пока все работает отлично!Я могу различать цифры в верхнем ряду и цифры в клавиатуре справа.Я даже могу обнаружить между левой и правой клавишами переключения.Однако клавиши управления и Alt не возвращают уникальные коды сканирования.Клавиша control возвращает 29, а клавиша alt возвращает 56.

Популярным методом проверки состояний клавиш для этих клавиш является GetAsyncKeyState.Я протестировал эту функцию, используя VK_LCONTROL и VK_RCONTROL, и она работает, но это помогает мне только для захвата событий нажатия клавиш.Мне бы очень хотелось, чтобы у меня была возможность запечатлеть события, связанные с Key Up.Очевидно, что API каким-то образом знает, какая клавиша нажата;как получить эту информацию?

В настоящее время я извлекаю код сканирования из поля MakeCode структуры RAWKEYBOARD.Это дает мне информацию о каждом ключе (и его левом / правом выравнивании), кроме CTRL и ALT .Как бы я запечатлел события key up (и узнал, левое или правое)?Возможно ли использовать только структуру RAWKEYBOARD?Или я должен придумать какое-то решение?

Ответы [ 2 ]

6 голосов
/ 15 апреля 2011

Если вы хотите получить достаточно низкий уровень для обнаружения событий, связанных с повышением ключа, вам следует обработать события WM_KEYDOWN и WM_KEYUP:

Нажатие клавиши приводит к тому, что сообщение WM_KEYDOWN или WM_SYSKEYDOWN помещается в очередь сообщений потока, прикрепленную к окну с фокусом клавиатуры.Отпускание клавиши приводит к тому, что сообщение WM_KEYUP или WM_SYSKEYUP помещается в очередь.

Сообщения о нажатиях клавиш и нажатия клавиш обычно появляются парами, но если пользователь нажимает клавишу достаточно долго, чтобы запустить автоматическую клавиатуруфункция повтора, система генерирует несколько сообщений WM_KEYDOWN или WM_SYSKEYDOWN подряд.Затем он генерирует одно сообщение WM_KEYUP или WM_SYSKEYUP, когда пользователь отпускает клавишу.

Чтобы различать левую и правую версии клавиш Shift, Ctrl или Alt, необходимо использовать MapVirtualKey() функция или бит «расширенного ключа» в lParam, передаваемый с сообщением виртуального ключа.Следующая функция выполнит этот перевод для вас - просто передайте виртуальный ключевой код и lParam из сообщения, и вы получите соответствующие левые / правые виртуальные ключевые коды в зависимости от ситуации:

WPARAM MapLeftRightKeys( WPARAM vk, LPARAM lParam)
{
    WPARAM new_vk = vk;
    UINT scancode = (lParam & 0x00ff0000) >> 16;
    int extended  = (lParam & 0x01000000) != 0;

    switch (vk) {
    case VK_SHIFT:
        new_vk = MapVirtualKey(scancode, MAPVK_VSC_TO_VK_EX);
        break;
    case VK_CONTROL:
        new_vk = extended ? VK_RCONTROL : VK_LCONTROL;
        break;
    case VK_MENU:
        new_vk = extended ? VK_RMENU : VK_LMENU;
        break;
    default:
        // not a key we map from generic to left/right specialized
        //  just return it.
        new_vk = vk;
        break;    
    }

    return new_vk;
}

ЕслиВиртуальный код ключа, который передается, не тот, который отображается в левую / правую версию, исходный код ключа передается обратно без изменений.Таким образом, вы можете просто запустить параметры сообщения WM_KEYDOWN / WM_KEYUP / WM_SYSKEYDOWN / WM_SYSKEYUP через функцию всякий раз, когда вам нужно различить левый и правый варианты.

1 голос
/ 15 апреля 2011

GetAsyncKeyState В документации сказано, что:

... Если установлен старший значащий бит, ключ не работает ...

, что также означает, что, если MSB очищен, ключ активен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...