我写了个程序用了WH_CBT全局钩子,但是只能拦截到自己进程的消息,并且当鼠标指针移出我的窗口之外,钩子就失效了。
帮忙看看哪里写错了,我实在是瞅不出来了
回调函数是放在dll里的
Hook.cpp内容如下:#include "Hook.h"#pragma data_seg("MySeg")
HHOOK g_hCbtHook = NULL;
HWND g_hReceiveWnd = NULL;
#pragma data_seg()
#pragma  comment(linker,"/section:MySeg,RWS")// 设置接受消息的窗口
void SetReceiveWnd(HWND hWnd)
{
    g_hReceiveWnd=hWnd;
}
// 窗口切换钩子回调
static LRESULT CALLBACK CbtHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    ::SendMessage(g_hReceiveWnd, WM_MY_MESSAGE, (WPARAM)nCode, lParam);
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}
// 开关窗口切换钩子
bool HookCbt(bool bHook)
{
    if(bHook)
    {
        g_hCbtHook = ::SetWindowsHookEx(WH_CBT, CbtHookProc, GetModuleHandle(NULL), 0);
        return g_hCbtHook ? true : false;
    }
    else
    {
        g_hCbtHook ? UnhookWindowsHookEx(g_hCbtHook) : NULL;
        g_hCbtHook = NULL;
        return true;
    }
}Hook.h内容如下:#pragma once#include "windows.h"#define WM_MY_MESSAGE WM_USER + 1// 设置接受消息的窗口
void SetReceiveWnd(HWND hWnd);
// 窗口切换钩子回调
static LRESULT CALLBACK CbtHookProc(int nCode, WPARAM wParam, LPARAM lParam);
// 开关窗口切换钩子
bool HookCbt(bool bHook);Hook.def内容如下:LIBRARY "Hook"EXPORTS
SetReceiveWnd @2
HookCbt @3

解决方案 »

  1.   

    if(g_hReceiveWnd)
    ::SendMessage(g_hReceiveWnd, WM_MY_MESSAGE, (WPARAM)nCode, lParam);
    else
    MessageBox(NULL, "no recv window", "t", 0);
    return CallNextHookEx(g_hCbtHook, nCode, wParam, lParam);
      

  2.   

    试了下还是不行。
    MSDN上说这个参数在2003系统上是忽略的。
    我刚才有测试了下。如果我鼠标指针不移出窗口而是用ALT+TABLE切换窗口时,是能收到消息的。
    也就是说这个是个全局钩子,只不过在鼠标指针移出窗口的时候,钩子失效了。
    但是,我用ALT+TABLE切换到任何一个其他程序都会导致那个程序崩溃.提示内存无法访问
      

  3.   

    你要hook的是什么消息啊,wh_cbt真的适合你么?
      

  4.   

    那用cbt是没错,但是你鼠标移出程序窗口你想收到什么呢?只有当你去激活另一窗口时hook才会被触发啊
      

  5.   

    CBT钩子拦截的消息包括你的鼠标在某个窗口上移动。
    激活窗口只是我要拦截的那种。
    问题是怎么就导致程序崩溃呢
      

  6.   

    CBT钩子拦截的消息包括你的鼠标在某个窗口上移动。 
    ----------
    你在哪查到这个的?程序会崩溃的话得看你hook里怎么写的了.
      

  7.   

    代码已经贴出来了。
    CBTProc Function
    The system calls this function before activating, creating, destroying, minimizing, maximizing, moving, or sizing a window; before completing a system command; before removing a mouse or keyboard event from the system message queue; before setting the keyboard focus; or before synchronizing with the system message queue. 
      

  8.   

    同样只这段代码,换成WH_KEYBOARD_LL就可以正常运行
    无奈了
      

  9.   

    感觉上没处理好WM_MY_MESSAGE消息。这么多的消息。。会不会没处理好?
      

  10.   

    刚才我把SendMessage那行注释掉也没用。
    切换窗口时还是崩溃,而且现在发现好像只能做WH_KEYBOARD_LL WH_MOUSE_LL这两个钩子
    刚才试了下WH_CALLWNDPROCRET也不行
      

  11.   

    before removing a mouse or keyboard event from the system message queue;
    -------------------
    system message queue not thread's message queue.
      

  12.   

    更恶心的是这个全局WH_CBT钩子
    那怕回调过程里只有一句
    CallNextHookEx
    也照样会导致大量其他程序崩溃
      

  13.   

    帅哥,仔细看看帖子问题在于这种全局钩子根本无法执行钩子的回调dll被挂到了每个进程上当一个进程的消息被拦截后,也就是说那个回调dll要在该进程上执行,然后就导致该进程崩溃
      

  14.   

    I found the problem.It's SetWindowsHookEx(WH_CBT, CbtHookProc, GetModuleHandle(NULL), 0);
    The third parameter cause the problem.If I save the handle of the dll in the function DllMain by a shared global variable, the problem is solved.I also found that the Handle we get from the DllMain and GetModuleHandle is not the same.