作者:熊熊粉丝6888 | 来源:互联网 | 2023-08-26 20:58
我写了个程序用了WH_CBT全局钩子,但是只能拦截到自己进程的消息,并且当鼠标指针移出我的窗口之外,钩子就失效了。帮忙看看哪里写错了,我实在是瞅不出来了。。。回调函数是放在dll里的Hook.c
我写了个程序用了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
17 个解决方案
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);
你要hook的是什么消息啊,wh_cbt真的适合你么?
我想写个程序监视另外某个程序的窗口是否处于活动状态。
那用cbt是没错,但是你鼠标移出程序窗口你想收到什么呢?只有当你去激活另一窗口时hook才会被触发啊
CBT钩子拦截的消息包括你的鼠标在某个窗口上移动。
激活窗口只是我要拦截的那种。
问题是怎么就导致程序崩溃呢
CBT钩子拦截的消息包括你的鼠标在某个窗口上移动。
----------
你在哪查到这个的?
程序会崩溃的话得看你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就可以正常运行
无奈了
感觉上没处理好WM_MY_MESSAGE消息。这么多的消息。。会不会没处理好?
before removing a mouse or keyboard event from the system message queue;
-------------------
system message queue not thread's message queue.
反正是我在窗口内移动鼠标时能拦截到消息的。
出了窗口就不行了。
更恶心的是这个全局WH_CBT钩子
那怕回调过程里只有一句
CallNextHookEx
也照样会导致大量其他程序崩溃
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.