我有这段代码,它为低级事件设置键盘钩子(Hook),然后显示一个消息框。
HHOOK keyboardHook = SetWindowsHookEx (WH_KEYBOARD_LL, HookKey, hInstance, 0);
MessageBox(NULL, L"Click to exit", L"hook test", NULL);
UnhookWindowsHookEx(keyboardHook);
如何在不创建前景窗口的情况下运行应用程序的主循环,以及如何设置 hInstance
来捕获全局事件?
最佳答案
答案都在the MSDN docs page for SetWindowsHookEx上.要试验示例应用程序,请创建一个新解决方案,添加两个项目,一个控制台应用程序和一个 DLL。每个项目只需要一个文件。 DLL 将包含 Hook ,控制台应用程序安装 Hook 。
钩子(Hook)的代码必须存在于 DLL 中,MSDN 文档非常清楚地指出:“如果 dwThreadId 参数为零或指定由不同进程创建的线程的标识符,则lpfn 参数必须指向 DLL 中的 Hook 过程。”实际上, Hook 显然必须位于 DLL 中,否则 shell 如何在另一个应用程序的消息循环中运行代码? DLL 使用其 HINSTANCE 安装 Hook 以识别函数指针所在的位置。
主应用程序运行启动 Hook 并发送消息,再次遵循 MSDN 文档中的说明:“... Hook 应用程序必须继续发送消息,否则它可能会阻止 64 位进程的正常运行”
请注意,这是非常小众的应用程序——您几乎不需要像这样注入(inject) DLL。请,请三思而后行。对于许多应用程序,没有必要捕获低级事件,尽管抑制“开始”菜单的沉浸式应用程序是一个合理的用例。但更重要的是,您很少需要捕获发送到其他应用程序的输入。在使用此代码之前检查您是否确实需要这样做。例如,只需将输入 Hook 到您自己的应用程序窗口,即可录制宏。
main.cpp
#include <windows.h>
#include <tchar.h>
__declspec(dllimport) void (__stdcall runHook)(BOOL startOrStop);
__declspec(dllimport) LRESULT (CALLBACK hookProc)(int code, WPARAM wParam, LPARAM lParam);
int _tmain(int argc, _TCHAR* argv[])
{
runHook(true);
MSG Msg;
while(GetMessage(&Msg, NULL, 0, 0) > 0 && Msg.message != WM_QUIT) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
runHook(false);
return 0;
}
动态链接库
#include <assert.h>
#include <windows.h>
static HINSTANCE dllInst = 0;
static HHOOK hookSelf = 0;
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
dllInst = (HINSTANCE)dllInst;
return TRUE;
}
__declspec(dllexport) LRESULT (CALLBACK hookProc)(int code, WPARAM wParam, LPARAM lParam)
{
if (code >= 0) {
UINT msgType = wParam;
KBDLLHOOKSTRUCT* msgInfo = (KBDLLHOOKSTRUCT*)lParam;
// The msgInfo contains the VK_CODE and flags.
}
return hookSelf ? CallNextHookEx(hookSelf, code, wParam, lParam) : 0;
}
__declspec(dllexport) void (__stdcall runHook)(BOOL startOrStop)
{
assert((bool)hookSelf != (bool)startOrStop);
if (startOrStop)
hookSelf = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, dllInst, 0);
else {
UnhookWindowsHookEx(hookSelf);
hookSelf = 0;
}
}
关于c - 如何使用 SetWindowsHookEx 过滤低级按键事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17502485/