钩子其实就是调用一下api而已:
1、安装钩子:
setwindowshookex
函数原形:hhook setwindowshookex(
int idhook, // 钩子类型,
hookproc lpfn, // 钩子函数地址
instance hmod, // 钩子所在的实例的句柄,
dword dwthreadid // 钩子所监视的线程的线程号
)
hmod: 对于线程序钩子,参数传null;
对于系统钩子:参数为钩子dll的句柄
dwthreadid:对于全局钩子,该参数为null。
钩子类型用wh_callwndproc=4(发送到窗口的消息。由sendmessage触发)
返回:成功:返回setwindowshookex返回所安装的钩子句柄;
失败:null;
2、回调,你要截获消息就在这里进行:
lresult winapi myhookproc(
int ncode , // 指定是否需要处理该消息
wparam wparam, // 包含该消息的附加消息
lparam lparam // 包含该消息的附加消息
)
3、调用下一个钩子
lresult callnexthookex(
hhook hhk, // 是您自己的钩子函数的句柄。用该句柄可以遍历钩子链
int ncode, // 把传入的参数简单传给callnexthookex即可
wparam wparam, // 把传入的参数简单传给callnexthookex即可
lparam lparam // 把传入的参数简单传给callnexthookex即可
);
4、用完后记得卸载钩子哦,要不然你的系统会变得奇慢无比!
bool unhookwindowshookex(
hhook hhk // 要卸载的钩子句柄。
)
把上面这些api用c#封装一下,就可以直接用了!
给个线程钩子的例子吧(两个form都在同一个线程中运行):
using system.runtime.interopservices;
public class form1 : system.windows.forms.form
{
...
//定义委托(钩子函数,用于回调)
public delegate int hookproc(int code, intptr wparam, ref cwpstruct cwp);
//安装钩子的函数
[dllimport("user32.dll",charset = charset.auto)]
public static extern intptr setwindowshookex(int type, hookproc hook, intptr instance, int threadid);
//调用下一个钩子的函数
[dllimport("user32.dll",charset = charset.auto)]
public static extern int callnexthookex(intptr hookhandle, int code, intptr wparam, ref cwpstruct cwp);
//卸载钩子
[dllimport("user32.dll",charset = charset.auto)]
public static extern bool unhookwindowshookex(intptr hookhandle);
//获取窗体线程id
dllimport("user32.dll",charset = charset.auto)]
public static extern int getwindowthreadprocessid(intptr hwnd, int id);
private hookproc hookproc;
private intptr hookhandle = intptr.zero;
public form1()
{
....
//挂接钩子处理方法
this.hookproc = new hookproc(myhookproc);
}
//开始拦截
private bool starthook()
{
form2 f=new form2();
f.show();//加上这个
//安装钩子,拦截系统向form2发出的消息
this.hookhandle = setwindowshookex(4, hookproc, intptr.zero ,getwindowthreadprocessid(f.handle,0));
return (this.hookhandle != 0);
}
//停止拦截
private bool stophook()
{
return unhookwindowshookex(this.hookhandle);
}
//钩子处理函数,在这里拦截消息并做处理
private int myhookproc(int code, intptr wparam, ref cwpstruct cwp)
{
switch(code)
{
case 0:
switch(cwp.message)
{
case 0x0000f://wm_paint,拦截wm_paint消息
//do something
break;
}
break;
}
return callnexthookex(hookhandle,code,wparam, ref cwp);
}
[structlayout(layoutkind.sequential)]
public struct cwpstruct
{
public intptr lparam;
public intptr wparam;
public int message;
public intptr hwnd;
}
}
public class form2 : system.windows.forms.form
{
....
}
新闻热点
疑难解答