c++ - CBT Hook 仅接收一些事件

标签 c++ winapi dll hook

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

我的系统是 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;
}

有什么提示吗?

最佳答案

当Windows安装全局钩子(Hook)时,实现钩子(Hook)函数的DLL往往会被其他进程加载。在这些进程中,g_hNotifyWing_uNotifyMsg 全局变量为 NULL。该全局变量仅在发生 SetCbtHook 调用的进程上下文中不为 NULL。

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

添加:

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

到您的 DLL,并将“MyClassName”替换为 g_hNotifyWin 窗口的类名。请参阅 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。

关于c++ - CBT Hook 仅接收一些事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20359189/

相关文章:

dll - 转储 Windows DLL 版本的命令行工具?

c++ - 在 C++ 98 中优化 vector 过滤

c - 如何以编程方式扩展卷

c - DllMain 中没有中断的开关/大小写

c# - 从 PowerShell 调用 WNetAddConnection2

c++ - 如何读取注册表的键值并使用 MessageBox() 将其打印到屏幕上

c++ - 在 MFC 应用程序中创建和使用 Dll

c++ - 表达式必须具有整数或枚举类型

c++ - 使用 sscanf 读取数字怎么会崩溃?

c++ - GTK 和 CSS : Rounded buttons