C ++ ToUnicodeEx () не распознает клавишу Shift, если у меня нет messgaebox () - PullRequest
0 голосов
/ 28 января 2012

У меня возникли некоторые проблемы с написанием хуков клавиатуры на C ++.

Я могу читать нажатия клавиш, но я пытаюсь использовать ToUnicodeEx () для преобразования нажатий клавиш при нажатии клавиши Shift.В коде, который у меня есть, у меня есть

i = ToUnicodeEx(keyboard.vkCode, keyboard.scanCode, (PBYTE)&keyState, (LPWSTR)&keybuff, sizeof(keybuff) / 16, 0,keyboardlayout);
MessageBox(MainnhWnd,keybuff, L"message", MB_OK | MB_ICONEXCLAMATION);

с этой строкой 'MessageBox', когда я нажимаю Shift + 2, я получаю два всплывающих окна с сообщениями, первое пустое для клавиши Shift, второе показываетхарактер.Это ожидаемо.

Но если я удаляю это окно сообщения, функция ToUnicodeEx () преобразует нажатие клавиши, как если бы клавиша Shift не использовалась.Я могу увидеть это, либо установив точку останова со счетчиком обращений, либо выведя символ в поле редактирования в окнах моей программы.

Также, когда я включаю строку MsgBox и использую CapLock, мои буквы изменяются соответственноно после того, как я удалил строку msgbox, она использует только состояние блокировки заглавных букв во время запуска моей программы (при запуске программы заглавные буквы включаются, все буквы заглавные, наоборот, заглавные буквы при запуске программы все буквы маленькие ,,даже если я изменю состояние блокировки крышки)

Кто-нибудь знает, почему мой хук просто запоминает состояние клавиатуры при запуске, если я не включаю msgbox?

Мой хук установлен так:

theHook = SetWindowsHookEx ( WH_KEYBOARD_LL, (HOOKPROC) KeyEvent, exe, 0);

и моя функция обратного вызова:

DLLEXPORT LRESULT CALLBACK KeyEvent(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode>=0) {
    int i = 0;
    KBDLLHOOKSTRUCT keyboard;
    WCHAR keybuff[256]= {0};

    if ((wParam == WM_KEYDOWN)|| (wParam == WM_SYSKEYDOWN)||(wParam == WM_SYSKEYUP)) {
        keyboard = *((KBDLLHOOKSTRUCT*)lParam);
        if (keyboard.vkCode == VK_RETURN) {
            i += wsprintf (((LPWSTR)keybuff + i),L"[Return]\r\n");
        }
        else {
            HKL keyboardlayout = GetKeyboardLayout(0);
            GetKeyboardState((PBYTE)&keyState);
            i = ToUnicodeEx(keyboard.vkCode, keyboard.scanCode, (PBYTE)&keyState, (LPWSTR)&keybuff, sizeof(keybuff) / 16, 0,keyboardlayout);

            MessageBox(MainnhWnd,keybuff, L"message", MB_OK | MB_ICONEXCLAMATION);
        }
        if (keybuff>0) {
            addToEditBox(keybuff);
        }
    }
}
return CallNextHookEx(theHook, nCode, wParam, lParam);
}

1 Ответ

2 голосов
/ 28 января 2012

Согласно документации функция ToUnicodeEx , вы должны предоставить указатель на 256-байтовый массив, который содержит текущее состояние клавиатуры (const BYTE *lpKeyState). Каждый элемент (байт) в массиве содержит состояние одного ключа. Если бит старшего разряда байта установлен, клавиша нажата.

Перед вызовом ToUnicodeEx вы должны установить этот массив следующим образом (псевдокод):

enum Keys
{
    ShiftKey    = 16, // shift
    ControlKey  = 17, // ctrl
    Menu        = 18, // alt
    Capital     = 20, // caps lock
};

BYTE keyState[256]= {0};

if (Control key down)
    keyState[Keys::ControlKey] = 0x80;

if (Shift key down)
    keyState[Keys::ShiftKey] = 0x80;

if (Alt key down)
    keyState[Keys::Menu] = 0x80;

if (Caps lock ON)
    keyState[Keys::Capital] = 0x01;

А когда установлен массив keyState, вы можете вызвать:

ToUnicodeEx(keyboard.vkCode, keyboard.scanCode, (PBYTE)&keyState, (LPWSTR)&keybuff, sizeof(keybuff) / 16, 0,keyboardlayout);

Я работал с ToUnicodeEx функцией так же, как это, и она работала нормально.
Надеюсь, это поможет вам;)

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