【发布时间】:2015-04-19 18:46:54
【问题描述】:
我正在尝试创建一个全局键盘挂钩,用于读取我正在创建的热键程序的击键,但遇到了一些问题。首先是每当我激活我的钩子时,键盘就会变得迟钝。屏幕上出现的每个字符之间几乎有整整一秒的延迟。第二个问题是我在 DLL 回调函数中编写的任何代码都不会被执行。
这是我的代码:
DLL cpp 文件
#include<Windows.h>
#include "keyDLL.h"
using namespace std;
LRESULT CALLBACK HookProcedure(int code, WPARAM wParam, LPARAM lParam)
{
return CallNextHookEx(0, code, wParam, lParam);
}
DLL 头文件
#include "windows.h"
extern "C" __declspec(dllexport) LRESULT CALLBACK HookProcedure(int code, WPARAM wParam, LPARAM lParam);
挂钩 CPP 文件
#include<Windows.h>
#include<iostream>
using namespace std;
HHOOK WINAPI SetWindowsHookEx(_In_ int idHook, _In_ HOOKPROC lpfn, _In_ HINSTANCE hMod, _In_ DWORD dwThreadId
static HINSTANCE dllHandle;
HOOKPROC address;
static HHOOK keyboard_hook;
int main()
{
dllHandle = LoadLibrary(TEXT("keyDLL.dll"));
address = (HOOKPROC)GetProcAddress(dllHandle, "HookProcedure");
cout << address << endl << dllHandle << endl;
keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL, address, dllHandle, 0);
system("pause");
}
这个版本的代码只是一个超级简单的缩减版,只设置了键盘挂钩。我删除了所有其他代码,试图找出导致问题的原因。根据我对钩子的理解(显然不是那么多),这段代码应该钩住键盘,但对击键没有任何作用。我不明白为什么它会减慢我的键盘速度。我使用 dumpbin 来确保 DLL 导出函数上没有名称修改。我正在运行 Windows 8 64 位,我的 DLL 和我的 exe 文件都编译为 64 位。当我计算出地址和 dllHandle 变量时,我得到了内存地址,所以我知道至少部分代码正在工作。任何帮助将不胜感激,谢谢。
【问题讨论】:
-
WH_KEYBOARD_LL 挂钩需要消息循环,而不是 DLL。这是“缓慢”的,因为如果您的程序不调用 GetMessage(),Windows 将无法调用消息挂钩函数。
-
@Hans Passant 那么如果我只使用 WH_KEYBOARD 而不是 WH_KEYBOARD_LL 会更好吗?或者这对全局钩子不起作用?我并不完全清楚两者之间的所有差异
-
低级钩子需要一个消息循环。做一个。
-
您应该切换到Raw Input API,而不是使用
WH_KEYBOARD_LL。它更安全、更高效。甚至LowLevelKeyboardProcdocumentation 也这么说:“在大多数情况下,应用程序需要使用低级挂钩,它应该监视原始输入。这是因为原始输入可以异步监视针对其他线程的鼠标和键盘消息比低级钩子更有效。".