2

我想制作一个可以捕获键盘事件的程序,即使它在任何时候都不活动。钩子太复杂了,我必须做的所有事情才能使它工作(制作一个 DLL,读取它,等等),所以我决定继续使用热键。

但现在我有一个问题。注册热键会禁用键盘上的键,因此我只能将键发送到程序,而不能在任何其他程序(例如记事本)上键入。

这是我的代码:

#include <iostream>
#include <windows.h>
using namespace std;

int main(int argc, char* argv[]) {
    RegisterHotKey(NULL, 1, NULL, 0x41); //Register A
    MSG msg = {0};

    while (GetMessageA(&msg, NULL, 0, 0) != 0) {
        if (msg.message == WM_HOTKEY) {
            cout << "A"; //Print A if I pressed it
        }
    }

    UnregisterHotKey(NULL, 1);
    return 0;
}

// and now I can't type A's

这个问题有什么简单的解决方案吗?谢谢

4

1 回答 1

4

我会让您的程序模拟一个与您实际执行的按键相同的按键。这意味着:

  1. 你按'A'。
  2. 该程序捕获'A'。
  3. 该程序模拟按键。

这很简单。唯一的问题是你的程序也会捕捉到模拟的按键。为避免这种情况,您可以执行以下操作:

  1. 你按'A'。
  2. 该程序捕获'A'。
  3. 程序取消注册热键。
  4. 该程序模拟按键。
  5. (该程序不会(!)捕获“A”。)
  6. 程序再次注册热键。

这就是整个循环。

现在,要模拟按键,您需要添加一些额外的代码。看看这个:

#include <iostream>
#include <windows.h>
using namespace std;

int main(int argc, char* argv[]) {
    RegisterHotKey(NULL, 1, 0, 0x41);            //Register A; Third argument should also be "0" instead of "NULL", so it is not seen as pointer argument
    MSG msg = {0};
    INPUT ip;
    ip.type = INPUT_KEYBOARD;
    ip.ki.wScan = 0;
    ip.ki.time = 0;
    ip.ki.dwExtraInfo = 0;
    ip.ki.wVk = 0x41;                            //The key to be pressed is A.

    while (GetMessage(&msg, NULL, 0, 0) != 0) {
        if (msg.message == WM_HOTKEY) {
            UnregisterHotKey(NULL, 1);           //Prevents the loop from caring about the following
            ip.ki.dwFlags = 0;                   //Prepares key down
            SendInput(1, &ip, sizeof(INPUT));    //Key down
            ip.ki.dwFlags = KEYEVENTF_KEYUP;     //Prepares key up
            SendInput(1, &ip, sizeof(INPUT));    //Key up
            cout << "A";                         //Print A if I pressed it
            RegisterHotKey(NULL, 1, 0, 0x41);    //you know...
        }
    }

    UnregisterHotKey(NULL, 1);
    return 0;
}

我试过了,它工作正常,我猜。希望我能帮上忙;)

于 2013-08-14T00:05:19.163 回答