C++ 键盘钩子 CTRL 键卡住

Posted

技术标签:

【中文标题】C++ 键盘钩子 CTRL 键卡住【英文标题】:C++ keyboard hook CTRL key gets stuck 【发布时间】:2020-05-07 06:20:40 【问题描述】:

我希望在我的 Windows 10 机器上重写 ctrl+cctrl+v 以添加一些额外的功能。

我能够正确复制和粘贴,并且在按下这些键后成功创建了一个键盘挂钩来执行我的代码,但是在我的程序运行时按 ctrl 后我遇到了问题运行时,ctrl 会持续动作,就好像它被按住一样。即使在我完全终止程序之后,ctrl 仍会继续执行,就好像它被按住一样,直到我完全退出计算机。我能做些什么来纠正这个问题?

谢谢!

编辑:经过一番折腾,我可以断定任何键都卡住了。 Shift 和大写锁定也会卡住。

#include <Windows.h>
#include <stdio.h>
#include <queue>

using namespace std;

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) 
    PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
    if (wParam == WM_KEYDOWN) 
        if (p->vkCode == 0x43 && GetKeyState(VK_CONTROL) & 0x8000)  // ctrl-c is pressed
            WM_COPY;
        
        else if (p->vkCode == 0x56 && GetKeyState(VK_CONTROL) & 0x8000)  // ctrl-v is pressed
            OpenClipboard(NULL);
            char* buffer;
            buffer = (char*)GetClipboardData(CF_TEXT);
            CloseClipboard();
            cout << buffer;
        
        return CallNextHookEx(NULL, nCode, wParam, lParam);
    


int main()

    HHOOK keyBoard = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, NULL);
    MSG msg;

    while (!GetMessage(&msg, NULL, NULL, NULL)) 
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    
    UnhookWindowsHookEx(keyBoard);

【问题讨论】:

你的编译器警告你,并不是你的钩子过程的所有控制路径都返回一个值。这些警告可以帮助您。不要忽视它们。 附带说明,您对GetClipboardData() 的使用完全错误。返回值是剪贴板拥有的可移动内存的HANDLE,你不能像你一样只是类型转换它,你必须使用GlobalLock()。而且无论哪种方式,调用CloseClipboard()后都无法访问数据,需要在关闭剪贴板之前复制数据。 【参考方案1】:

不要将return CallNextHookEx(NULL, nCode, wParam, lParam) 放入if (wParam == WM_KEYDOWN)

修改:

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) 
    PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
    if (wParam == WM_KEYDOWN) 
        if (p->vkCode == 0x43 && GetKeyState(VK_CONTROL) & 0x8000)  // ctrl-c is pressed
            WM_COPY;
        
        else if (p->vkCode == 0x56 && GetKeyState(VK_CONTROL) & 0x8000)  // ctrl-v is pressed
            OpenClipboard(NULL);
            char* buffer;
            buffer = (char*)GetClipboardData(CF_TEXT);
            CloseClipboard();
            cout << buffer;
        

    
    return CallNextHookEx(NULL, nCode, wParam, lParam);

【讨论】:

以上是关于C++ 键盘钩子 CTRL 键卡住的主要内容,如果未能解决你的问题,请参考以下文章

键盘钩子失灵

C++ 键盘钩子

linux下X上的系统范围键盘钩子

C++怎样简单实现全局钩子或者键盘监控

C++ 键盘钩子 - 参数 nCode 是啥意思?

使用低级键盘钩子更改键盘字符