我写了个程序用了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
帮忙看看哪里写错了,我实在是瞅不出来了
回调函数是放在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
::SendMessage(g_hReceiveWnd, WM_MY_MESSAGE, (WPARAM)nCode, lParam);
else
MessageBox(NULL, "no recv window", "t", 0);
return CallNextHookEx(g_hCbtHook, nCode, wParam, lParam);
MSDN上说这个参数在2003系统上是忽略的。
我刚才有测试了下。如果我鼠标指针不移出窗口而是用ALT+TABLE切换窗口时,是能收到消息的。
也就是说这个是个全局钩子,只不过在鼠标指针移出窗口的时候,钩子失效了。
但是,我用ALT+TABLE切换到任何一个其他程序都会导致那个程序崩溃.提示内存无法访问
激活窗口只是我要拦截的那种。
问题是怎么就导致程序崩溃呢
----------
你在哪查到这个的?程序会崩溃的话得看你hook里怎么写的了.
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.
无奈了
切换窗口时还是崩溃,而且现在发现好像只能做WH_KEYBOARD_LL WH_MOUSE_LL这两个钩子
刚才试了下WH_CALLWNDPROCRET也不行
-------------------
system message queue not thread's message queue.
那怕回调过程里只有一句
CallNextHookEx
也照样会导致大量其他程序崩溃
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.