代码之家  ›  专栏  ›  技术社区  ›  Tommy

不使用QT运行C++事件循环

  •  1
  • Tommy  · 技术社区  · 9 年前

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

    youtube视频上的一条评论似乎给出了答案: “对于不使用QT的用户,只需添加 而(GetMessage(NULL,NULL,0,0)); 而不是.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";
        }
    
       }
    }
    
    1 回复  |  直到 9 年前
        1
  •  1
  •   Mark Jansen    9 年前

    这是一个有效的示例。

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