带有 WH_KEYBOARD 的 SetWindowsHookEx 卡在循环/队列中

Posted

技术标签:

【中文标题】带有 WH_KEYBOARD 的 SetWindowsHookEx 卡在循环/队列中【英文标题】:SetWindowsHookEx with WH_KEYBOARD stuck in a loop/queue 【发布时间】:2014-10-04 18:51:34 【问题描述】:

我正在尝试使用 dll 注入挂钩记事本。在运行 exe 并挂接记事本(形成我可以成功告诉的内容)并按下一些键后,似乎发生的事情是按键卡在循环或队列中(记事本没有响应)。 exe 解开挂钩后,记事本会做出响应,并且所有按下的键都会出现在文本字段中。

exe

#include <iostream>
#include <fstream>
#include <windows.h>
#include <stdio.h>

HHOOK       hHook     = NULL;
HWND        handle    = NULL;
HMODULE     dll       = NULL;
HOOKPROC    address   = NULL;
DWORD       thread_id = 0;

using namespace std;

int main()

    handle=FindWindow(NULL,L"Untitled - Notepad");
    if(handle==NULL)
        cout<<"Window not found"<<endl;
        getchar();
        return 0;
    

    thread_id=GetWindowThreadProcessId(handle,NULL);
    if(thread_id==0)
        cout<<"ID not found"<<endl;
        getchar();
        return 0;
    

    dll = LoadLibrary(TEXT("X:\\qt\\hook\\debug\\hook.dll"));
    if(dll==NULL)
        cout<<"hook.dll not found"<<endl;
        getchar();
        return 0;
    

    address=(HOOKPROC)GetProcAddress(dll,"CallWndProc@12");
    if(address==NULL)
        cout<<"Address not found"<<endl;
        getchar();
        return 0;
    

    hHook=SetWindowsHookEx(WH_KEYBOARD,address,dll,thread_id);
    if(hHook==NULL)
        cout<<"hook was not set"<<endl;
        return 0;
    

    cout<<"Program successfully hooked"<<endl;
    cout<<"Press enter to unhook the function and stop the program"<<endl;
    getchar();
    UnhookWindowsHookEx(hHook);

    return 0;

dll

#include "hook.h"
#include <windows.h>
#include <iostream>
#include <fstream>

using namespace std;

extern "C"
    __declspec(dllexport) LRESULT CALLBACK CallWndProc(int nCode,WPARAM wParam,LPARAM lParam)

        if(nCode<0)
           return CallNextHookEx(NULL,nCode,wParam,lParam);
        

        ofstream file;
        file.open("X:\\qt\\klog\\debug\\function.txt");
        file<<"Function keyboard_hook called\n";
        file.close();
        return CallNextHookEx(NULL,nCode,wParam,lParam);
    


BOOL APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)

    switch(Reason) 
    case DLL_PROCESS_ATTACH: break;
    case DLL_PROCESS_DETACH: break;
    case DLL_THREAD_ATTACH:  break;
    case DLL_THREAD_DETACH:  break;
    

    return TRUE;

【问题讨论】:

来自KeyboardProc callback function页面:This hook may be called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook. Therefore, the thread that installed the hook must have a message loop. 谢谢@500 不知道我是怎么错过的。 【参考方案1】:

在 SetWindowsHookEx 和 UnhookWindowsHookEx 之间添加消息循环修复了它

while(GetMessage(&Msg, NULL, 0, 0) > 0)

    TranslateMessage(&Msg);
    DispatchMessage(&Msg);

【讨论】:

以上是关于带有 WH_KEYBOARD 的 SetWindowsHookEx 卡在循环/队列中的主要内容,如果未能解决你的问题,请参考以下文章

SetWindowsHookEx c#

MFC -- 键盘全局HOOK

delphi 键盘全局钩子

Delphi的子类化控件消息, 消息子类化

Keyboard Hook API函数 参数说明

Win32/MFC 从客户端矩形获取窗口矩形