首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CBT钩子只接收一些事件

CBT钩子只接收一些事件
EN

Stack Overflow用户
提问于 2013-12-03 18:46:30
回答 2查看 458关注 0票数 2

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

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

这是代码(对不起,我不是C++专家):

代码语言:javascript
复制
#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;
}

有什么暗示吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-03 21:24:52

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

您必须有一种方法在任意进程中检索g_hNotifyWin和'g_uNotifyMsg‘的正确值。

添加:

代码语言:javascript
复制
const char * g_pszClassName = "MyClassName";
const char * g_pszRegisteredMsg = "MyMessage";

并将"MyClassName“替换为g_hNotifyWin窗口的类名。请参阅EXE中的RegisterClass调用。更新也是"MyMessage“。

然后,使用以下CbtProcCb函数:

代码语言:javascript
复制
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。

票数 3
EN

Stack Overflow用户

发布于 2013-12-03 20:26:24

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20359189

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档