我正在编写一个 Windows C++ 应用程序,目前遇到了 GetMessage 的问题,下面是我的简单程序,它拦截所有程序的键盘输入。
LRESULT WINAPI keyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
printf("Hey!\n");
return 1;
//return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int main(int argc, char *argv[])
{
HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)(keyboardProc), NULL, 0);
MSG message;
memset(&message, 0, sizeof(MSG));
GetMessage(&message, NULL, 0, 0);
UnhookWindowsHookEx(hook);
return 0;
}
问题是 GetMessage 永远不会返回。我无法使用 PeekMessage,因为要使用 PeekMessage,我需要在消息循环中添加一个 Sleep 函数,这会显着减慢挂钩速度(使用 Sleep(1),您可以在扫描条形码时注意到很多滞后),但如果没有 Sleep(1 ),循环会消耗大量的CPU。
既然键盘事件不会导致GetMessage提前返回,那么如何才能让GetMessage提前返回呢? (例如,也许从另一个线程发布 WM_USER / WM_QUIT 消息?我尝试了不同的选项但无济于事,并且文档非常混乱)我对此很陌生,因此非常感谢显示以下内容的代码示例:
GetMessage
仅在消息发送到您的应用程序时返回,而不是在触发钩子时返回。
您需要首先决定何时退出,然后将
WM_QUIT
发送到您的主线程,或者任何安装了钩子的线程,以下代码会在用户按下 x
时执行此操作。
#include <iostream>
#include <Windows.h>
HHOOK g_hookHandle = nullptr;
LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION)
{
KBDLLHOOKSTRUCT* pKeyboardData = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
DWORD vkCode = pKeyboardData->vkCode;
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)
{
if (vkCode == 'X') // quit when button is X
{
std::cout << "Exiting the program." << std::endl;
PostThreadMessage(GetCurrentThreadId(), WM_QUIT, 0 ,0); // post WM_QUIT to end app
}
}
}
return CallNextHookEx(g_hookHandle, nCode, wParam, lParam);
}
int main()
{
g_hookHandle = SetWindowsHookExA(WH_KEYBOARD_LL, KeyboardHookProc, nullptr, 0);
MSG message;
GetMessage(&message, nullptr, 0, 0);
UnhookWindowsHookEx(g_hookHandle);
return 0;
}
如果您想从另一个线程发布此消息,您