SetWindowsHookEx没有调用我的回调?

时间:2012-12-13 16:52:27

标签: c++ winapi hook keyboard-hook

好吧,我尝试了不同的解决方案来处理我的问题,但它无法正常工作。

我调用SetWindowsHookExA然后当我按下一个键时,不会显示消息框。怎么办?

这是我的代码(这是一个由程序加载的另一个DLL加载的DLL):

#include <Windows.h>

HINSTANCE gl_hThisInstance = NULL;
HHOOK hHook = NULL;

LRESULT CALLBACK KeyHit(int code,WPARAM wParam,LPARAM lParam);

BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
         gl_hThisInstance = (HINSTANCE)hModule;
         hHook = SetWindowsHookExA(
            WH_KEYBOARD,
            KeyHit,
            //(HWND)gl_hThisInstance//not working
            0,//not working
            //(DWORD)gl_hThisInstance//not working
            //GetCurrentThreadId()//even not working with this
            0//not working
            );
        break;
    }
    return TRUE;
}

LRESULT CALLBACK KeyHit(int code,WPARAM wParam,LPARAM lParam)
{
    MessageBox(0,"PRESSED","PRESSED",0);
    return CallNextHookEx(hHook,code,wParam,lParam);
}

1 个答案:

答案 0 :(得分:1)

我之前遇到了问题。不是真正的问题,但我做的方式不应该。 首先,您应该从DLL中SetHookRemoveHook输出2个函数。 SetHook函数会从那里调用SetWindowsHookEx()。如果您尝试从DLL的线程或SetWindowsHookEx()内调用DLLMain,则该函数不会返回任何错误,但永远不会调用回调函数。我有时会想出来。

发布在这里是我的工作代码来捕捉WH_GETMESSAGE,你可以从这里引用。

这是我从DLL中导出的SetHook()函数。

bool __declspec(dllexport) __stdcall SetHook(DWORD myWnd)
{
    mySavedHook = SetWindowsHookEx(WH_GETMESSAGE,
        GetMsgProc,
        infoContainer.DllHModule,
        myWnd);

    int errorID = GetLastError();
    if (errorID != 0)
    {
        MessageBoxA(NULL, "Failed to implement hook", "Failed", 0);
        MessageBoxA(NULL, to_string(errorID).c_str(), "Error ID", 0);
        return false;
    }
    else
    {
        return true;
    }
}

infoContainer.DllHModule:DLL的实例,它是DllMain()的第一个参数。 myWnd:是我的主机ID(不是进程ID) - 从GetWindowThreadProcessId(window_handle, NULL)获取。要实现全局钩子,请将0用作myWnd

这是我的回调函数。

LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode >= 0)
    {
        LPMSG msg = (LPMSG)lParam;
        if (msg->message == WM_CALLFUNCTION)
        {
            MessageBoxA(NULL, "Receive WM_CALLFUNTION", "Good news", 0);
        }

    }
    //Doesn't matter, just call this function and return it.
    return CallNextHookEx(_hook, nCode, wParam, lParam);
}

回调函数必须具有CALLBACK关键字才能生效。

从外部应用程序中,从DLL调用SetHook()并使用线程ID作为其参数。