运行 不使用 QT 的 C++ 事件循环
Running a C++ Event Loop WITHOUT using QT
我一直在尝试用 c++ 开发后台 Windows 应用程序来捕获系统范围内的击键和鼠标点击(不,我不是在编写击键记录器,只是击键率!)。为此,我发现我需要使用 Windows Hooks,我遇到了 this excellent video 这给了我一个基本的例子。不幸的是,它使用 QT 框架,并且出于许可(和其他基于时间的)原因,我目前无法使用它。
我需要做的就是调整代码,使其不需要 "return a.exec()" 行(我相信这是事件循环的开始)。
youtube 视频的评论似乎给出了答案:
“对于那些不使用QT的人,只需添加
while(GetMessage(NULL, NULL, 0, 0));
而不是 a.exec(),QT 循环。它应该工作正常
但无法使此解决方案起作用。非常感谢您帮助让下面的代码在不依赖于 QT 框架的情况下作为事件循环执行。
#include <QtCore/QCoreApplication>
#inlcude <QDebug>
#include <iostream>
#include <Windows.h>
HHOOK hHook = NULL;
using namespace std;
LRESULT CALLBACK MyLowLevelKeyBoardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
qDebug() << "A Key was pressed";
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv); //need to remove this QT dependency
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, MyLowLevelKeyBoardProc, NULL, 0);
if (hHook==NULL){
qDebug() << "Hook Failed";
}
return a.exec(); //need to remove this QT dependency
}
这是使用消息循环重写并删除 QT 引用的尝试(仅显示 main()):
int main(int argc, char *argv[])
{
MSG msg = NULL;
while (GetMessage(msg, NULL, NULL, NULL)){
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, MyLowLevelKeyBoardProc, NULL, 0);
if (hHook==NULL){
qDebug() << "Hook Failed";
}
}
}
这是一个有效的示例。
#include <Windows.h>
#include <stdlib.h>
#include <iostream>
HHOOK g_hHook = NULL;
DWORD g_HookThread;
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
PKBDLLHOOKSTRUCT hookstruct = reinterpret_cast<PKBDLLHOOKSTRUCT>(lParam);
std::cout << hookstruct->vkCode << std::endl;
if( wParam == WM_KEYUP ) {
if( hookstruct->vkCode == VK_ESCAPE ) {
PostThreadMessage( g_HookThread, WM_QUIT, NULL, NULL );
}
}
return CallNextHookEx( g_hHook, nCode, wParam, lParam );
}
int main()
{
g_HookThread = GetCurrentThreadId();
g_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, 0, 0);
MSG msg;
while( GetMessage(&msg, NULL, NULL, NULL) ) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnhookWindowsHookEx(g_hHook);
return 0;
}
编辑:
我最初评论 whatpulse 切换到 directinput,但现在他们似乎已经切换回低级钩子。
我一直在尝试用 c++ 开发后台 Windows 应用程序来捕获系统范围内的击键和鼠标点击(不,我不是在编写击键记录器,只是击键率!)。为此,我发现我需要使用 Windows Hooks,我遇到了 this excellent video 这给了我一个基本的例子。不幸的是,它使用 QT 框架,并且出于许可(和其他基于时间的)原因,我目前无法使用它。 我需要做的就是调整代码,使其不需要 "return a.exec()" 行(我相信这是事件循环的开始)。
youtube 视频的评论似乎给出了答案: “对于那些不使用QT的人,只需添加 while(GetMessage(NULL, NULL, 0, 0)); 而不是 a.exec(),QT 循环。它应该工作正常
但无法使此解决方案起作用。非常感谢您帮助让下面的代码在不依赖于 QT 框架的情况下作为事件循环执行。
#include <QtCore/QCoreApplication>
#inlcude <QDebug>
#include <iostream>
#include <Windows.h>
HHOOK hHook = NULL;
using namespace std;
LRESULT CALLBACK MyLowLevelKeyBoardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
qDebug() << "A Key was pressed";
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv); //need to remove this QT dependency
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, MyLowLevelKeyBoardProc, NULL, 0);
if (hHook==NULL){
qDebug() << "Hook Failed";
}
return a.exec(); //need to remove this QT dependency
}
这是使用消息循环重写并删除 QT 引用的尝试(仅显示 main()):
int main(int argc, char *argv[])
{
MSG msg = NULL;
while (GetMessage(msg, NULL, NULL, NULL)){
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, MyLowLevelKeyBoardProc, NULL, 0);
if (hHook==NULL){
qDebug() << "Hook Failed";
}
}
}
这是一个有效的示例。
#include <Windows.h>
#include <stdlib.h>
#include <iostream>
HHOOK g_hHook = NULL;
DWORD g_HookThread;
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
PKBDLLHOOKSTRUCT hookstruct = reinterpret_cast<PKBDLLHOOKSTRUCT>(lParam);
std::cout << hookstruct->vkCode << std::endl;
if( wParam == WM_KEYUP ) {
if( hookstruct->vkCode == VK_ESCAPE ) {
PostThreadMessage( g_HookThread, WM_QUIT, NULL, NULL );
}
}
return CallNextHookEx( g_hHook, nCode, wParam, lParam );
}
int main()
{
g_HookThread = GetCurrentThreadId();
g_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, 0, 0);
MSG msg;
while( GetMessage(&msg, NULL, NULL, NULL) ) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnhookWindowsHookEx(g_hHook);
return 0;
}
编辑: 我最初评论 whatpulse 切换到 directinput,但现在他们似乎已经切换回低级钩子。