我用spy++发现了WM_USER+2002这样的一条消息,我想用全局钩子截获,可以做到吗?
如果可以,其他的程序中也定义了这个消息该怎么办?谢谢!
如果可以,其他的程序中也定义了这个消息该怎么办?谢谢!
解决方案 »
- 在多文档或单文档程序中,如何只改变VIEW的大小,而不改变框架的大小
- HOOK send函数之后,如何从捕获到的数据中得到目标IP和端口?
- 大家给点意见,我很着急的!!!!!!!!!!!!
- 看过《深入浅出MFC〉〉的前辈请进!
- (x1,y1),(x2,y2).......(xn,yn),对这些n组数据进行拟合的算法
- 哪里有VC6。0下载啊
- 我要在我的程序中加入一段代码,用来分析用户输入的SQL where语句的语法是否正确,以及column name是否在表中存在,我应该如何入手,现在
- 如何给单文档视图加滚动条?
- 原来DOS也不是他自己做的。
- sock数据类型,知道的进来
- 跪求代码,那位大哥能帮帮小弟啊,急啊
- 如何用spy++得到qq的消息呢?谢谢!
文章摘要:
钩子(Hook),是Windows消息处理机制的一个平台(point),应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。本文将简单介绍钩子的原理和如何使用钩子。
--------------------------------------------------------------------------------
正文: 钩子使用指南 钩子的概念
钩子机制允许应用程序截获处理window消息或特定事件。与DOS中断截获处理机制有类似之处。钩子(Hook),是Windows消息处理机制的一个平台(point),应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。每一个hook都有一个与之相关联的指针列表,称之为钩子链表,该链表中的指针指向这个钩子的各个处理子程。一个钩子处理一种类型的消息。当钩子所监视的消息出现时,Windows调用链表中的第一个钩子子程。某些类型的钩子只能在系统范围内设置处理子程,其余类型的钩子还可以在特定的线程中设置(用SetWindowsHookEx设置)。对于某一特定类型的钩子(它处理某一类型的消息),线程钩子子程被先调用,接着是系统钩子子程。钩子子程是一个应用程序定义的回调函数(callback function),不能定义成某个类的成员函数,只能定义为普通的C函数。例如:
LRESULT CALLBACK HookProc(int nCode ,WPARAM wParam,LPARAM lParam)钩子的设置
可以使用API函数SetWindowsHookEx()把一个应用程序定义的钩子子程安装到钩子链表中。所安装的钩子子程用以监视系统或某一特定类型的事件,这些事件可以是与某一特定线程关联的,也可以是系统中所有线程的事件。
HHOOK SetWindowsHookEx(
int idHook, // 钩子的类型,即它处理的消息类型
HOOKPROC lpfn, // 钩子子程的地址指针。如果dwThreadId参数为0
或是一个由别的进程创建的线程的标识,lpfn必
须指向DLL中的钩子子程。除此以外,lpfn可以
指向当前进程的一段钩子子程代码。
HINSTANCE hMod, // 应用程序实例的句柄。标识包含lpfn所指的子程
的DLL。如果dwThreadId 标识当前进程创建的一
个线程,而且子程代码位于当前进程,hMod必须
为NULL。
DWORD dwThreadId // 与安装的钩子子程相关联的线程的标识符,
如果为0,钩子子程与所有的线程关联。
);
函数成功则返回钩子子程的句柄,失败返回NULL。
以上所说的钩子子程与线程相关联是指在一钩子链表中发给该线程的消息同时发送给钩子子程,且被钩子子程先处理。
虽然这并不是强制的,但一般推荐在钩子子程中调用CallNextHookEx()函数以执行钩子链表所指的下一个钩子子程。否则安装了别的钩子的应用程序就会收不到钩子通知,从而产生错误的结果。除非确实需要禁止向别的应用程序发通知,否则应调用CallNextHookEx()。程序终止之前,必须调用UnhookWindowsHookEx()函数释放钩子关联的系统资源。钩子的实例
//找到要截获其消息的窗口的句柄
HWND hWnd=::FindWindow(
"#32770",//LPCTSTR lpClassName,
NULL //LPCTSTR lpWindowName
);
if(hWnd) //如果窗口句柄非零,则设置钩子,
HHOOK oldkeyhook=SetWindowsHookEx(
WH_KEYBOARD, //截获键盘消息的钩子类型
(HOOKPROC)KeyBoardProc, //钩子子程地址
//包含钩子子程的动态链接库的地址
GetModuleHandle("hookdll.dll"),
//得到创建该窗口的线程的标识
GetWindowThreadProcessId(hWnd,NULL)); 释放钩子函数的资源:
UnhookWindowsHookEx(oldkeyhook);钩子消息处理函数:
建议在动态链接库中实现钩子消息处理函数,这样比较不容易犯错误。
下面是钩子消息处理函数的例子:
LRESULT CALLBACK KeyBoardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
//当接收到的消息为WM_KEYUPSH时,存储字符到文件log.sys中
if(lParam&0x80000000)
{
char code=(char)wParam;
CFile
file("c:\\log.sys",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite);
file.SeekToEnd();
file.Write(&code,1);
file.Close();
}
//调用CallNextHookEx()函数,并返回该函数的返回值。
return CallNextHookEx(oldkeyhook, nCode, wParam, lParam);
}作者会员名:lijin
我认为不应该会有影响,代码编译、运行时,消息处理应该有些附加的信息(如进程ID)来区分消息。
--------------------------------------------------------------------------------
请问钩子函数的消息处理如何区分WM_USER消息来自哪一个线程呢?
盼望有人能指点一二。