钩子其实就是调用一下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 { .... }
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=714599
|