4

我尝试在 c++ 中使用 Windows API,SetWindowsHookEx WH_KEYBOARD_LL但似乎没有从正确Shift的键(Shiftqwerty 键盘右侧的键,键下方的Enter键)获取事件。它确实适用于左键Shift。我该如何解决这个问题???

#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;
}

右移在警报中显示一个 blanco 字符串。然而,左移在警报中显示“SHIFT”字符串。有人知道吗???

PS:

如果我删除带有“ msg += ((st_hook.flags & LLKHF_EXTENDED) << 24);”的行 -> “RIGHT SHIFT”现在确实出现了,但是当按下“Windows 键”时出现了 undefined

4

2 回答 2

1

左移与右移显示在 的vkCode字段中KBDLLHOOKSTRUCT。您正在使用扫描码的键;右 Shift 键被命名为“Shift”,就像它在键盘上所说的那样。

显然,右移以扩展标志集结束,这导致 GetKeyNameText 在错误的表中查找。删除扩展标志最终会得到一个键名“右移”。

    msg += (st_hook.scanCode << 16);
    if (st_hook.scanCode != 0x3a)
    {
        msg += ((st_hook.flags & LLKHF_EXTENDED) << 24);
    }
    GetKeyNameText(msg, tmp, 0xFF);
于 2013-09-19T18:00:56.197 回答
1

此解决方案不依赖特定代码

if (st_hook.vkCode != VK_RSHIFT)
  msg += ((st_hook.flags & LLKHF_EXTENDED) << 24);
于 2015-03-02T06:17:21.207 回答