【问题标题】:Running a C++ Event Loop WITHOUT using QT在不使用 QT 的情况下运行 C++ 事件循环
【发布时间】:2015-07-29 21:00:37
【问题描述】:

我一直在尝试用 C++ 开发一个后台 Windows 应用程序来捕获系统范围的击键和鼠标点击(不,我不是在编写击键记录器,只是击键速率!)。为此,我发现我需要使用 Windows Hooks,我遇到了this excellent video,它给了我一个基本的例子。不幸的是,它使用 QT 框架并且出于许可(和其他基于时间的)原因,我目前无法使用它。 我需要做的就是调整代码,使其不需要“return a.exec()”行(我相信这是事件循环的开始)。

对 youtube 视频的评论似乎有答案: “对于那些不使用QT的人,只需添加 而(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";
    }

   }
}

【问题讨论】:

  • WinAPI message loop 有点复杂。可能是问题出在它身上。
  • 你仍然在那里使用 QT 函数...
  • @Amartel 谢谢 - 会做一些进一步的阅读
  • @MarkJansen - 不确定您的评论是回复我最初的问题还是回复 Amartel 的评论。如果它是对我最初问题的回应——再读一遍——我输入的代码就是我需要改变的一个例子。这是我需要调整的工作代码示例。我不知道如何使它更清楚。
  • 我希望您至少尝试使用消息循环重写它,因此我感到困惑。

标签: c++ qt hook event-loop mouse-hook


【解决方案1】:

这是一个有效的示例。

#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,但现在他们似乎已经切换回低级挂钩。

【讨论】:

  • 感谢您的回复 Mark - 我会试试这个,但让我看不清的一件事是没有 main 函数,所以我不确定入口点在哪里。
  • 在那里,我将 test 重命名为 main。代码直接来自我的草稿应用程序。
  • 精湛的标记!这让我离开了地面。谢谢
  • P.S.对于使用上述 Mark 代码的任何其他人。包括这些头文件:#include #include #include
猜你喜欢
  • 1970-01-01
  • 2017-11-16
  • 1970-01-01
  • 1970-01-01
  • 2012-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多