钩子程序很高深的话题,对我我这个在C#里面混得人的确不容易理解,我这里就对钩子胡乱说一番,不过也觉得有的东西有点道理
一,定义一个全局的hook的静态变量一般是int类型,然后在你的要执行的代码之前先 Hook_Start();通俗的讲就是先安装一下
二, 然后执行其他无关系的代码,例如执行鼠标的事件添加事件处理程序。系统执行这些后,把控制权交给系统,这个系统是谁呢!一般来说说是main,采用框架的就难说了!总是是有系统层面的。
this.visWindow.MouseDown += new EWindow_MouseDownEventHandler(MyMouseDown); this.visWindow.MouseMove += new EWindow_MouseMoveEventHandler(MyMouseMove); this.visWindow.MouseUp += new EWindow_MouseUpEventHandler(MyMouseUp);
三,这样定义委托,为什么定义委托呢,钩子是win32下的,说白了,钩子有点函数c语言中回调的意思,回调可以理解成函数指针,特定钩子特定功能我觉得是,我这里的钩子是键盘按键的钩子作用
作用我认为就是这样
事件-----》注册过事件的程序------------》事件的钩子,钩子上的程序
因为有回调的类似的功能,所以,事件的钩子程序先执行,然后才是正常的事件绑定的程序执行。当然真正的程序没有那么简单。
钩子是win32里面的东西。为了实现钩子上执行的程序执行完全之后,能够回到注册过的程序,用什么好呢! 用普通的程序段肯定不行,为什么啊 ?
因为普通的程序执行都是顺序执行的!不能实现回调的目标,有人说可以实现这个功能
void docallback(fuctionArgs LastFun){ bool isok= doing();//执行其他事 if(isok) { LastFun();//执行从哪个地方传递过来的那个方法 } }
好了问题就在这里FuntiionArgs是一个方法的指针,这个方法必须能直接作为方法调用。我想啊想啊!C#语言中能作为方法调用的有委托和事件,事件委托本质上一样,我就不讲事件了
对了用委托实现,传递过来的win32的程序,然后把win32中的程序先保存指针,相当于委托,doing完成后,这个很关键。然后用保存的win32指针,委托再执行回去当初传递过来点额指针。
大体意思是这个意思。但是单纯的回调也没有什么意思,你想啊! 我调用你,你再调用我,岂不是没完没了了吗?呵呵
其实系统采用是真实的消息队列,消息队列就是一串,状态命令,比如说,鼠标点了什么,键盘按下什么。我们把这些状态和我们处理程序连接在一起,就实现了事件处理程序。如果我们
不用钩子,能找到处理的,你的程序默认会处理,不能处理就丢弃了。还一种情况,就是你能处理,但是你希望他按照你的条件处理,比如说,你想在鼠标单击事件的时候,执行一个
特别的程序,不管什么未来是什么程序。例如在QQ输入密码的时候,QQ不可能让你知道源代码吧,执行你的一段程序,嘿嘿盗号啊1小子! 说了那么多
就是并不是我们想我们每次转换之后,重复回去执行,我们要的是过滤功能,这里是回去取出下一个消息队列在下面的程序中比较理想。
等等在想想,不对啊! 我们主要的任务是,对事件过滤,对事件进行可耻的移花接木啊 !!
消息就想不断下车的乘客一样,你要做的就是找到你感兴趣的人(专门找mm呵呵),总体说来对于事件还是理解的不太好! 希望下一步重新写一下这篇博客
废话不说了 上代码!
//委托
2 public delegate int HookProc(int nCode, int wParam, IntPtr lParam);
3 static int hHook = 0;
4 public const int WH_KEYBOARD_LL = 13;
5
6 //LowLevel键盘截获,如果是WH_KEYBOARD=2,并不能对系统键盘截取,截取之前获得键盘。
7 HookProc KeyBoardHookProcedure;
8
9 //键盘Hook结构函数
10 [StructLayout(LayoutKind.Sequential)]
11 public class KeyBoardHookStruct
12 {
13 public int vkCode;
14 public int scanCode;
15 public int flags;
16 public int time;
17 public int dwExtraInfo;
18 }
19 //设置钩子
20 [DllImport("user32.dll")]
21 public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
22 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
23 //抽掉钩子
24 public static extern bool UnhookWindowsHookEx(int idHook);
25 [DllImport("user32.dll")]
26 //调用下一个钩子
27 public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);
28
29 [DllImport("kernel32.dll")]
30 public static extern int GetCurrentThreadId();
31
32 [DllImport("kernel32.dll")]
33 public static extern IntPtr GetModuleHandle(string name);
34
35 public void Hook_Start()
36 {
37 // 安装键盘钩子
38 if (hHook == 0)
39 {
40 KeyBoardHookProcedure = new HookProc(KeyBoardHookProc);
41
42 hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyBoardHookProcedure, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
43
44 //如果设置钩子失败.
45 if (hHook == 0)
46 {
47 Hook_Clear();
48 }
49 }
50 }
51
52 //取消钩子事件
53 public void Hook_Clear()
54 {
55 bool retKeyboard = true;
56 if (hHook != 0)
57 {
58 retKeyboard = UnhookWindowsHookEx(hHook);
59 hHook = 0;
60 }
61 //如果去掉钩子失败.
62 if (!retKeyboard) throw new Exception("UnhookWindowsHookEx failed.");
63 }
64
65 //这里可以添加自己想要的信息处理
66 public static int KeyBoardHookProc(int nCode, int wParam, IntPtr lParam)
67 {
68 //if (SystemInfor.IsActiveWindow("Portal") == true)
69 //{
70 // // return 0;
71 //}
72 if (nCode >= 0)
73 {
74 KeyBoardHookStruct kbh = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct));
75 if (kbh.vkCode == (int)Keys.Delete)//截获Delete
76 {
77 return 1;
78 }
79 if (kbh.vkCode == (int)Keys.X && (int)Control.ModifierKeys == (int)Keys.Control)
80 {
81 return 1;
82 }
83 if (kbh.vkCode == (int)Keys.A && (int)Control.ModifierKeys == (int)Keys.Control)
84 {
85 return 1;
86 }
87 }
88 return CallNextHookEx(hHook, nCode, wParam, lParam);
89 }
此外:钩子先的挂上后执行,后挂的先执行。