具有WH_KEYBOARD_LL和keybd_event的全局键盘挂钩(Windows) [英] Global keyboard hook with WH_KEYBOARD_LL and keybd_event (windows)

查看:260
本文介绍了具有WH_KEYBOARD_LL和keybd_event的全局键盘挂钩(Windows)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个简单的全局键盘挂钩程序来重定向一些键.例如,执行该程序时,我按键盘上的"a",该程序可以禁用它并模拟"b"单击.我不需要图形用户界面,只需一个控制台就足够了(让它继续运行)

I am trying to write a simple global keyboard hook program to redirect some keys. For example, when the program is executed, I press 'a' on the keyboard, the program can disable it and simulate a 'b' click. I do not need a graphic ui, just a console is enough (keep it running)

我的计划是使用全局挂钩捕获按键输入,然后使用keybd_event模拟键盘.但是我有一些问题.

My plan is to use global hook to catch the key input, and then use keybd_event to simulate the keyboard. But I have some problems.

第一个问题是程序可以正确地阻止"A",但是如果我一次按下键盘上的"A",则回调函数中的printf以及keybd_event将被执行两次.因此,如果我打开一个txt文件,则单击一次"A",有两个"B"输入.为什么呢?

The first problem is that the program can correctly block 'A' but if I hit 'A' on the keyboard once, the printf in the callback function is executed twice, as well as the keybd_event. So if i open a txt file, i click 'A' once, there are two 'B's input. why is that?

第二个问题是,为什么使用WH_KEYBOARD_LL的钩子可以在没有dll的情况下在其他进程上工作?我以为在写这个例子之前,我们必须使用dll来做一个全局钩子.

The second question is that why the hook using of WH_KEYBOARD_LL can work on other process without a dll? I thought that we had to use a dll to make a global hook until I wrote this example...

#include "stdafx.h"
#include <Windows.h>
#define _WIN32_WINNT 0x050

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    BOOL fEatKeystroke = FALSE;

    if (nCode == HC_ACTION)
    {
        switch (wParam)
        {
        case WM_KEYDOWN:
        case WM_SYSKEYDOWN:
        case WM_KEYUP:
        case WM_SYSKEYUP:
            PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
            if (fEatKeystroke = (p->vkCode == 0x41)) {     //redirect a to b
            printf("Hello a\n");
            keybd_event('B', 0, 0, 0);
            keybd_event('B', 0, KEYEVENTF_KEYUP, 0);
            break;
            }
            break;
        }
    }
    return(fEatKeystroke ? 1 : CallNextHookEx(NULL, nCode, wParam, lParam));
}

int main()
{
    // Install the low-level keyboard & mouse hooks
    HHOOK hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, 0, 0);

    // Keep this app running until we're told to stop
    MSG msg;
    while (!GetMessage(&msg, NULL, NULL, NULL)) {    //this while loop keeps the hook
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    UnhookWindowsHookEx(hhkLowLevelKybd);

    return(0);
}

非常感谢!

推荐答案

第一个很简单.您可以通过一个按键来获得,而通过另一个按键来获得. :)

First one is easy. You get one for key down and another for key up. :)

为什么不使用DLL就可以工作-这是因为它是一个全局钩子.与特定于线程的线程不同,它是在您自己的进程中执行的,而不是在发生键盘事件的进程中执行的.这是通过将消息发送到已安装钩子的线程来完成的-这就是为什么您需要在此处进行消息循环的原因.没有它,您的钩子将无法运行,因为将没有人可以监听传入的消息.

As for the why it can work without a DLL - that's because it is a global hook. Unlike thread-specific ones it is executed in your own process, not in the process where keyboard event happened. It is done via message sending to the thread which has installed the hook - that's precisely why you need message loop here. Without it your hook can't be ran as there would be no one to listen for incoming messages.

DLL是特定于线程的挂钩所必需的,因为它们是在另一个进程的上下文中调用的.为此,您的DLL应该被注入到该进程中.情况并非如此.

The DLL is required for thread-specific hooks because they're called in the context of another process. For this to work, your DLL should be injected into that process. It is just not the case here.

这篇关于具有WH_KEYBOARD_LL和keybd_event的全局键盘挂钩(Windows)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆