CBT Hook只接收一些事件

时间:2013-12-03 18:46:30

标签: c++ winapi dll hook

我创建了一个DLL来使用CBT钩子挂钩一些事件。它似乎只适用于启动钩子的过程创建的窗口......

我的系统是Windows 7 x64,但x32上的行为也是一样。

这是代码(抱歉,但我不是C ++专家):

#include "windows.h"

extern "C"
{
    static LRESULT CALLBACK CbtProcCb(int nCode, WPARAM wParam, LPARAM lParam);
    HINSTANCE g_hDll       = NULL;
    HWND      g_hNotifyWin = NULL;
    DWORD     g_uNotifyMsg = NULL;
    HHOOK     g_hHook      = NULL;

    __declspec(dllexport) HHOOK SetCbtHook(HWND hWnd, LPCWSTR lStrMsg, DWORD threadId)
    {
        g_hNotifyWin = hWnd;
        g_uNotifyMsg = RegisterWindowMessage(lStrMsg);
        g_hHook      = SetWindowsHookEx(WH_CBT, (HOOKPROC)CbtProcCb, g_hDll, threadId);
        return g_hHook;
    }

    __declspec(dllexport) int UnsetCbtHook()
    {
        if ( !g_hHook )
            return 0;
        return UnhookWindowsHookEx(g_hHook);
    }
}

static LRESULT CALLBACK CbtProcCb(int nCode, WPARAM wParam, LPARAM lParam)
{
    SendNotifyMessage(g_hNotifyWin, g_uNotifyMsg, nCode, wParam); // Send nCode to check the received event
    return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    if ( fdwReason == DLL_PROCESS_ATTACH )
        g_hDll = hinstDLL;
    return true;
}

任何提示?

2 个答案:

答案 0 :(得分:3)

当Windows安装globals钩子时,实现钩子函数的DLL通常会加载到其他进程中。在这些进程中,g_hNotifyWing_uNotifyMsg全局变量为NULL。在发生SetCbtHook调用的过程中,全局变量不是NULL。

您必须有办法在任意过程中检索g_hNotifyWin和'g_uNotifyMsg'的正确值。

添加:

const char * g_pszClassName = "MyClassName";
const char * g_pszRegisteredMsg = "MyMessage";

到你的DLL,并用g_hNotifyWin窗口的类名替换“MyClassName”。查看EXE中的RegisterClass电话。更新“MyMessage”。

然后,使用以下CbtProcCb函数:

static LRESULT CALLBACK CbtProcCb(int nCode, WPARAM wParam, LPARAM lParam)
{
    if ( nCode >= 0 ) {
        if ( g_hNotifyWin == NULL ) g_hNotifyWin = FindWindow( g_pszClassName, NULL );
        if ( g_uNotifyMsg == 0) g_uNotifyMsg = RegisterWindowMessage(g_pszRegisteredMsg);
        if ( g_hNotifyWin && g_uNotifyMsg )
            SendNotifyMessage(g_hNotifyWin, g_uNotifyMsg, nCode, wParam); // Send nCode to check the received event
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam); // first arg useless see MSDN
}

修改 正如您在评论中指出的那样,g_uNotifyMsg的相同问题请参阅更新的功能。您可以在DllMain中设置这些变量。

CallNextHookEx的第一个参数可能为NULL。

答案 1 :(得分:1)

我猜你的ThreadId不是零,所以hook只分别附加到调用进程/线程。阅读文档:  http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx