简体   繁体   中英

SetWindowsHookEx WH_KEYBOARD_LL not responding on right shift

I try to use the Windows API in c++ and SetWindowsHookEx WH_KEYBOARD_LL does not seem to get events from the right Shift key (the Shift key at the right side of a qwerty keyboard, below the Enter key). It does work with the left Shift key. How do I troubleshoot this problem???

#include "stdafx.h"
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
#include <windows.h>
#include <string> 
#include <shlobj.h>
#include <Shlwapi.h>
#include <stdio.h>
#include <aclapi.h>
#include <tchar.h>
#include <iostream>
#include <fstream>
#include <future>
#include <stdlib.h>
#include <random>
#include <ctime>
#include <time.h>       
#include <Lmcons.h>



HHOOK   kbdhook;    /* Keyboard hook handle */
bool    running;    /* Used in main loop */


__declspec(dllexport) LRESULT CALLBACK handlekeys(int code, WPARAM wp, LPARAM lp)
{
        static bool capslock = false;
        static bool shift = false;
        char tmp[0xFF] = {0};
        std::string str;
        DWORD msg = 1;
        KBDLLHOOKSTRUCT st_hook = *((KBDLLHOOKSTRUCT*)lp);



        msg += (st_hook.scanCode << 16);
        msg += ((st_hook.flags & LLKHF_EXTENDED) << 24);
        GetKeyNameText(msg, tmp, 0xFF);
        str = std::string(tmp);


    if (code == HC_ACTION && (wp == WM_SYSKEYDOWN || wp == WM_KEYDOWN )) {
        MessageBox(NULL,str.c_str(),NULL,MB_OK);
}
return CallNextHookEx(kbdhook, code, wp, lp);
}

LRESULT CALLBACK windowprocedure(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
    switch (msg) {
        case WM_CLOSE: case WM_DESTROY:
            running = false;
            break;
        default:
            /* Call default message handler */
            return DefWindowProc(hwnd, msg, wp, lp);
    }

    return 0;
}

int WINAPI WinMain(HINSTANCE thisinstance, HINSTANCE previnstance,
        LPSTR cmdline, int ncmdshow)
{


    HWND        hwnd;
    HWND        fgwindow = GetForegroundWindow(); 
    MSG     msg;
    WNDCLASSEX  windowclass;
    HINSTANCE   modulehandle;

    modulehandle = GetModuleHandle(NULL);
    kbdhook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)handlekeys, modulehandle, NULL);
    running = true;






    while (running) {

        if (!GetMessage(&msg, NULL, 0, 0))
            running = false; 
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

Right shift shows a blanco string in the alert. Left shift however shows a "SHIFT" string in the alert. Anyone a clue???

PS:

If I remove the line with " msg += ((st_hook.flags & LLKHF_EXTENDED) << 24);" -> "RIGHT SHIFT" does show up now, but undefined shows up, when pressing the "Windows key"

Left vs. right shift shows up in the vkCode field of KBDLLHOOKSTRUCT . You're using the key name of the scancode; the right shift key is named 'Shift', just like it says on the keyboard.

Apparently, right shift ends up with the extended flag set, which causes GetKeyNameText to look in the wrong table. Removing the extended flag ends up with a key name of "right shift".

    msg += (st_hook.scanCode << 16);
    if (st_hook.scanCode != 0x3a)
    {
        msg += ((st_hook.flags & LLKHF_EXTENDED) << 24);
    }
    GetKeyNameText(msg, tmp, 0xFF);

This solution does not rely on a specific code

if (st_hook.vkCode != VK_RSHIFT)
  msg += ((st_hook.flags & LLKHF_EXTENDED) << 24);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM