相信以前用过VB、Delphi,特别是VC的程序员应该对钩子程序都不陌生。在C#中我们同样可以使用钩子程序来实现特殊效果,比如当用户按下某个特殊键时提示,比如关闭应用程序前提示等。
当然使用方法相对VC来说要稍微复杂一点,有的地方还不太方便,下面的例子中实现两个基本功能:
1、按下Alt+F4时使窗口最小化
2、关闭应用程序前提示
不过目前只能捕获消息,不能屏蔽消息,我正在实验,也希望知道的高手能多多指教
一、加入winuser.h中的定义
因为钩子程序一般情况下都是在vc下使用的,在c#里面并没有对应的方法、结构等的定义,我们首先需要把winuser.h中的相关定义加入自己的类

 钩子类型的枚举
钩子类型的枚举
 public enum HookType : int
    public enum HookType : int

 
     {
{
 WH_JOURNALRECORD = 0,
        WH_JOURNALRECORD = 0,
 WH_JOURNALPLAYBACK = 1,
        WH_JOURNALPLAYBACK = 1,
 WH_KEYBOARD = 2,
        WH_KEYBOARD = 2,
 WH_GETMESSAGE = 3,
        WH_GETMESSAGE = 3,
 WH_CALLWNDPROC = 4,
        WH_CALLWNDPROC = 4,
 WH_CBT = 5,
        WH_CBT = 5,
 WH_SYSMSGFILTER = 6,
        WH_SYSMSGFILTER = 6,
 WH_MOUSE = 7,
        WH_MOUSE = 7,
 WH_HARDWARE = 8,
        WH_HARDWARE = 8,
 WH_DEBUG = 9,
        WH_DEBUG = 9,
 WH_SHELL = 10,
        WH_SHELL = 10,
 WH_FOREGROUNDIDLE = 11,
        WH_FOREGROUNDIDLE = 11,
 WH_CALLWNDPROCRET = 12,
        WH_CALLWNDPROCRET = 12,
 WH_KEYBOARD_LL = 13,
        WH_KEYBOARD_LL = 13,
 WH_MOUSE_LL = 14
        WH_MOUSE_LL = 14
 }
    }
具体的说明在msdn中都可以查到,主要的比如WH_KEYBOARD是监控按键事件,WH_CALLWNDPROC是在消息触发时执行

 虚键值的定义
虚键值的定义
 public enum VirtualKeys
    public enum VirtualKeys

 
     {
{
 VK_SHIFT = 0x10,
        VK_SHIFT = 0x10,
 VK_CONTROL = 0x11,
        VK_CONTROL = 0x11,
 VK_MENU = 0x12,    //ALT
        VK_MENU = 0x12,    //ALT
 VK_PAUSE = 0x13,
        VK_PAUSE = 0x13,
 VK_CAPITAL = 0x14
        VK_CAPITAL = 0x14
 }
    }
这个不用说明了,对应ALT、CTRL等键

 消息结构体
消息结构体
 public struct CWPSTRUCT
    public struct CWPSTRUCT

 
     {
{
 public IntPtr lparam;
        public IntPtr lparam;
 public IntPtr wparam;
        public IntPtr wparam;
 public int message;
        public int message;
 public IntPtr hwnd;
        public IntPtr hwnd;
 }
    }
这个是windows内部传递过来的消息的结构
二、加入自己定义的委托和事件参数

 钩子委托
钩子委托
 public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
    public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
 public delegate void HookEventHandler(object sender, HookEventArgs e);
    public delegate void HookEventHandler(object sender, HookEventArgs e);

HokkProc是
SetWindowsHookEx调用时的委托事件,HookEventHandler是自己的委托事件

 钩子事件参数
钩子事件参数
 public class HookEventArgs : EventArgs
    public class HookEventArgs : EventArgs

 
     {
{
 public int HookCode;
        public int HookCode;
 public IntPtr wParam;
        public IntPtr wParam;
 public IntPtr lParam;
        public IntPtr lParam;
 public Keys key;
        public Keys key;
 public bool bAltKey;
        public bool bAltKey;
 public bool bCtrlKey;
        public bool bCtrlKey;
 }
    }
是自己的委托事件中接受的事件参数
三、实现自己的钩子类
这一步是最重要的,要使用钩子,我们需要引用
user32.dll中的相应方法:
 [DllImport("user32.dll")]
        [DllImport("user32.dll")]
 static extern IntPtr SetWindowsHookEx(HookType hook, HookProc callback, IntPtr hMod, uint dwThreadId);
        static extern IntPtr SetWindowsHookEx(HookType hook, HookProc callback, IntPtr hMod, uint dwThreadId);

 [DllImport("user32.dll")]
        [DllImport("user32.dll")]
 static extern bool UnhookWindowsHookEx(IntPtr hhk);
        static extern bool UnhookWindowsHookEx(IntPtr hhk);

 [DllImport("user32.dll")]
        [DllImport("user32.dll")]
 static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
        static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

 [DllImport("user32.dll")]
        [DllImport("user32.dll")]
 static extern short GetKeyState(VirtualKeys nVirtKey);
        static extern short GetKeyState(VirtualKeys nVirtKey);

是注册一个钩子程序,
UnhookWindowsHookEx是释放钩子程序,
CallNextHookEx调用钩子的后续事件处理,
GetKeyState得到所按的虚键
然后就可以调用这些方法来实现钩子程序,比如注册一个钩子可以调用:
 m_hook = SetWindowsHookEx(m_hooktype, m_hookproc, IntPtr.Zero, (uint)AppDomain.GetCurrentThreadId());
            m_hook = SetWindowsHookEx(m_hooktype, m_hookproc, IntPtr.Zero, (uint)AppDomain.GetCurrentThreadId());

其中m_hooktype就是
HookType中定义的类型,m_hookproc就是实际的钩子处理程序:
 m_hookproc = new HookProc(KeyHookProcedure);
m_hookproc = new HookProc(KeyHookProcedure);
最关键的就是
KeyHookProcedure等钩子处理程序:
 protected int KeyHookProcedure(int code, IntPtr wParam, IntPtr lParam)
        protected int KeyHookProcedure(int code, IntPtr wParam, IntPtr lParam)

 
         {
{
 if (code != 0)
            if (code != 0)

 
             {
{
 return CallNextHookEx(m_hook, code, wParam, lParam);
                return CallNextHookEx(m_hook, code, wParam, lParam);
 }
            }

 if (HookInvoked != null)
            if (HookInvoked != null)

 
             {
{
 Keys key = (Keys)wParam.ToInt32();
                Keys key = (Keys)wParam.ToInt32();
 HookEventArgs eventArgs = new HookEventArgs();
                HookEventArgs eventArgs = new HookEventArgs();
 eventArgs.key = key;
                eventArgs.key = key;
 eventArgs.lParam = lParam;
                eventArgs.lParam = lParam;
 eventArgs.wParam = wParam;
                eventArgs.wParam = wParam;
 eventArgs.HookCode = code;
                eventArgs.HookCode = code;
 eventArgs.bAltKey = GetKeyState(VirtualKeys.VK_MENU) <= -127;
                eventArgs.bAltKey = GetKeyState(VirtualKeys.VK_MENU) <= -127;
 eventArgs.bCtrlKey = GetKeyState(VirtualKeys.VK_CONTROL) <= -127;
                eventArgs.bCtrlKey = GetKeyState(VirtualKeys.VK_CONTROL) <= -127;
 HookInvoked(this, eventArgs);
                HookInvoked(this, eventArgs);
 }
            }

 return CallNextHookEx(m_hook, code, wParam, lParam);
            return CallNextHookEx(m_hook, code, wParam, lParam);
 }
        }
在这个事件中可以取得消息的参数,特别是按键的值,然后通过HookInvoked委托调用事件实际的处理程序
四、在应用程序中调用钩子类
我们可以在自己的form中声明两个钩子对象
 private MyHook callProcHook = new MyHook(HookType.WH_CALLWNDPROC);
        private MyHook callProcHook = new MyHook(HookType.WH_CALLWNDPROC);
 private MyHook keyHook = new MyHook(HookType.WH_KEYBOARD);
        private MyHook keyHook = new MyHook(HookType.WH_KEYBOARD);

然后在初始化时注册钩子:
 private void Form1_Load(object sender, EventArgs e)
        private void Form1_Load(object sender, EventArgs e)

 
         {
{
 keyHook.HookInvoked += new HookEventHandler(keyHook_HookInvoked);
            keyHook.HookInvoked += new HookEventHandler(keyHook_HookInvoked);
 keyHook.Install();
            keyHook.Install();

 callProcHook.HookInvoked += new HookEventHandler(callProcHook_HookInvoked);
            callProcHook.HookInvoked += new HookEventHandler(callProcHook_HookInvoked);
 callProcHook.Install();
            callProcHook.Install();
 }
        }
然后就是实际的钩子事件:
 private void keyHook_HookInvoked(object sender, HookEventArgs e)
        private void keyHook_HookInvoked(object sender, HookEventArgs e)

 
         {
{
 if (e.key == Keys.F4 && e.bAltKey) //Alt + F4
            if (e.key == Keys.F4 && e.bAltKey) //Alt + F4

 
             {
{
 this.WindowState = FormWindowState.Minimized;
                this.WindowState = FormWindowState.Minimized;
 }
            }
 }
        }

 private void callProcHook_HookInvoked(object sender, HookEventArgs e)
        private void callProcHook_HookInvoked(object sender, HookEventArgs e)

 
         {
{
 unsafe
            unsafe

 
             {
{
 CWPSTRUCT* message = (CWPSTRUCT*)e.lParam;
                CWPSTRUCT* message = (CWPSTRUCT*)e.lParam;
 if (message != null)
                if (message != null)

 
                 {
{
 if (message->message == WM_CLOSE)
                    if (message->message == WM_CLOSE)

 
                     {
{
 (sender as MyHook).CallNextProc = false;
                        (sender as MyHook).CallNextProc = false;
 MessageBox.Show("程序即将关闭!");
                        MessageBox.Show("程序即将关闭!");
 }
                    }
 }
                }
 }
            }
 }
        }这样我们就可以通过钩子实现一些相对底层的应用。
代码说的有点乱,我就把最主要的代码直接列在下面供大家参考:

 例子代码
例子代码
  1 using System;
using System;
  2 using System.Collections.Generic;
using System.Collections.Generic;
  3 using System.ComponentModel;
using System.ComponentModel;
  4 using System.Data;
using System.Data;
  5 using System.Drawing;
using System.Drawing;
  6 using System.Text;
using System.Text;
  7 using System.Windows.Forms;
using System.Windows.Forms;
  8 using System.Runtime.InteropServices;
using System.Runtime.InteropServices;
  9
 10 namespace HookTest
namespace HookTest
 11

 {
{
 12 public partial class Form1 : Form
    public partial class Form1 : Form
 13
 
     {
{
 14
 消息定义(WinUser.h中定义)#region 消息定义(WinUser.h中定义)
        消息定义(WinUser.h中定义)#region 消息定义(WinUser.h中定义)
 15 private const int WM_PAINT = 0x000F;
        private const int WM_PAINT = 0x000F;
 16 private const int WM_CLOSE = 0x0010;
        private const int WM_CLOSE = 0x0010;
 17 private const int WM_QUIT = 0x0012;
        private const int WM_QUIT = 0x0012;
 18 private const int WM_DESTROY = 0x0002;
        private const int WM_DESTROY = 0x0002;
 19 #endregion
        #endregion
 20
 21 private MyHook callProcHook = new MyHook(HookType.WH_CALLWNDPROC);
        private MyHook callProcHook = new MyHook(HookType.WH_CALLWNDPROC);
 22 private MyHook keyHook = new MyHook(HookType.WH_KEYBOARD);
        private MyHook keyHook = new MyHook(HookType.WH_KEYBOARD);
 23
 24 public Form1()
        public Form1()
 25
 
         {
{
 26 InitializeComponent();
            InitializeComponent();
 27 }
        }
 28
 29 private void Form1_Load(object sender, EventArgs e)
        private void Form1_Load(object sender, EventArgs e)
 30
 
         {
{
 31 keyHook.HookInvoked += new HookEventHandler(keyHook_HookInvoked);
            keyHook.HookInvoked += new HookEventHandler(keyHook_HookInvoked);
 32 keyHook.Install();
            keyHook.Install();
 33
 34 callProcHook.HookInvoked += new HookEventHandler(callProcHook_HookInvoked);
            callProcHook.HookInvoked += new HookEventHandler(callProcHook_HookInvoked);
 35 callProcHook.Install();
            callProcHook.Install();
 36 }
        }
 37
 38 private void keyHook_HookInvoked(object sender, HookEventArgs e)
        private void keyHook_HookInvoked(object sender, HookEventArgs e)
 39
 
         {
{
 40 if (e.key == Keys.F4 && e.bAltKey) //Alt + F4
            if (e.key == Keys.F4 && e.bAltKey) //Alt + F4
 41
 
             {
{
 42 this.WindowState = FormWindowState.Minimized;
                this.WindowState = FormWindowState.Minimized;
 43 }
            }
 44 }
        }
 45
 46 private void callProcHook_HookInvoked(object sender, HookEventArgs e)
        private void callProcHook_HookInvoked(object sender, HookEventArgs e)
 47
 
         {
{
 48 unsafe
            unsafe
 49
 
             {
{
 50 CWPSTRUCT* message = (CWPSTRUCT*)e.lParam;
                CWPSTRUCT* message = (CWPSTRUCT*)e.lParam;
 51 if (message != null)
                if (message != null)
 52
 
                 {
{
 53 if (message->message == WM_CLOSE)
                    if (message->message == WM_CLOSE)
 54
 
                     {
{
 55 (sender as MyHook).CallNextProc = false;
                        (sender as MyHook).CallNextProc = false;
 56 MessageBox.Show("程序即将关闭!");
                        MessageBox.Show("程序即将关闭!");
 57 }
                    }
 58 }
                }
 59 }
            }
 60 }
        }
 61
 62 }
    }
 63
 64
 消息结构体(参照WinUser.h中定义)#region 消息结构体(参照WinUser.h中定义)
    消息结构体(参照WinUser.h中定义)#region 消息结构体(参照WinUser.h中定义)
 65 public struct CWPSTRUCT
    public struct CWPSTRUCT
 66
 
     {
{
 67 public IntPtr lparam;
        public IntPtr lparam;
 68 public IntPtr wparam;
        public IntPtr wparam;
 69 public int message;
        public int message;
 70 public IntPtr hwnd;
        public IntPtr hwnd;
 71 }
    }
 72 #endregion
    #endregion
 73
 74
 钩子类型的枚举#region 钩子类型的枚举
    钩子类型的枚举#region 钩子类型的枚举
 75 public enum HookType : int
    public enum HookType : int
 76
 
     {
{
 77 WH_JOURNALRECORD = 0,
        WH_JOURNALRECORD = 0,
 78 WH_JOURNALPLAYBACK = 1,
        WH_JOURNALPLAYBACK = 1,
 79 WH_KEYBOARD = 2,
        WH_KEYBOARD = 2,
 80 WH_GETMESSAGE = 3,
        WH_GETMESSAGE = 3,
 81 WH_CALLWNDPROC = 4,
        WH_CALLWNDPROC = 4,
 82 WH_CBT = 5,
        WH_CBT = 5,
 83 WH_SYSMSGFILTER = 6,
        WH_SYSMSGFILTER = 6,
 84 WH_MOUSE = 7,
        WH_MOUSE = 7,
 85 WH_HARDWARE = 8,
        WH_HARDWARE = 8,
 86 WH_DEBUG = 9,
        WH_DEBUG = 9,
 87 WH_SHELL = 10,
        WH_SHELL = 10,
 88 WH_FOREGROUNDIDLE = 11,
        WH_FOREGROUNDIDLE = 11,
 89 WH_CALLWNDPROCRET = 12,
        WH_CALLWNDPROCRET = 12,
 90 WH_KEYBOARD_LL = 13,
        WH_KEYBOARD_LL = 13,
 91 WH_MOUSE_LL = 14
        WH_MOUSE_LL = 14
 92 }
    }
 93 #endregion
    #endregion
 94
 95
 虚键值的定义(参照WinUser.h中定义)#region 虚键值的定义(参照WinUser.h中定义)
    虚键值的定义(参照WinUser.h中定义)#region 虚键值的定义(参照WinUser.h中定义)
 96 public enum VirtualKeys
    public enum VirtualKeys
 97
 
     {
{
 98 VK_SHIFT = 0x10,
        VK_SHIFT = 0x10,
 99 VK_CONTROL = 0x11,
        VK_CONTROL = 0x11,
100 VK_MENU = 0x12,    //ALT
        VK_MENU = 0x12,    //ALT
101 VK_PAUSE = 0x13,
        VK_PAUSE = 0x13,
102 VK_CAPITAL = 0x14
        VK_CAPITAL = 0x14
103 }
    }
104 #endregion
    #endregion
105
106
 钩子委托#region 钩子委托
    钩子委托#region 钩子委托
107 public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
    public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
108 public delegate void HookEventHandler(object sender, HookEventArgs e);
    public delegate void HookEventHandler(object sender, HookEventArgs e);
109 #endregion
    #endregion
110
111
 钩子事件参数#region 钩子事件参数
    钩子事件参数#region 钩子事件参数
112 public class HookEventArgs : EventArgs
    public class HookEventArgs : EventArgs
113
 
     {
{
114 public int HookCode;
        public int HookCode;
115 public IntPtr wParam;
        public IntPtr wParam;
116 public IntPtr lParam;
        public IntPtr lParam;
117 public Keys key;
        public Keys key;
118 public bool bAltKey;
        public bool bAltKey;
119 public bool bCtrlKey;
        public bool bCtrlKey;
120 }
    }
121 #endregion
    #endregion
122
123
 钩子类#region 钩子类
    钩子类#region 钩子类
124 public class MyHook
    public class MyHook
125
 
     {
{
126
 调用Windows API#region 调用Windows API
        调用Windows API#region 调用Windows API
127 [DllImport("user32.dll")]
        [DllImport("user32.dll")]
128 static extern IntPtr SetWindowsHookEx(HookType hook, HookProc callback, IntPtr hMod, uint dwThreadId);
        static extern IntPtr SetWindowsHookEx(HookType hook, HookProc callback, IntPtr hMod, uint dwThreadId);
129
130 [DllImport("user32.dll")]
        [DllImport("user32.dll")]
131 static extern bool UnhookWindowsHookEx(IntPtr hhk);
        static extern bool UnhookWindowsHookEx(IntPtr hhk);
132
133 [DllImport("user32.dll")]
        [DllImport("user32.dll")]
134 static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
        static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
135
136 [DllImport("user32.dll")]
        [DllImport("user32.dll")]
137 static extern short GetKeyState(VirtualKeys nVirtKey);
        static extern short GetKeyState(VirtualKeys nVirtKey);
138 #endregion
        #endregion
139
140
 局部变量#region 局部变量
        局部变量#region 局部变量
141 private IntPtr m_hook;
        private IntPtr m_hook;
142 private HookType m_hooktype;
        private HookType m_hooktype;
143 private HookProc m_hookproc;
        private HookProc m_hookproc;
144
145 private bool _bCallNext;
        private bool _bCallNext;
146
147 public bool CallNextProc
        public bool CallNextProc
148
 
         {
{
149
 get
            get  { return _bCallNext; }
{ return _bCallNext; }
150
 set
            set  { _bCallNext = value; }
{ _bCallNext = value; }
151 }
        }
152 
    
153 #endregion
        #endregion
154
155 public event HookEventHandler HookInvoked;
        public event HookEventHandler HookInvoked;
156
157 public void Install()
        public void Install()
158
 
         {
{
159 m_hook = SetWindowsHookEx(m_hooktype, m_hookproc, IntPtr.Zero, (uint)AppDomain.GetCurrentThreadId());
            m_hook = SetWindowsHookEx(m_hooktype, m_hookproc, IntPtr.Zero, (uint)AppDomain.GetCurrentThreadId());
160 }
        }
161
162 public void Uninstall()
        public void Uninstall()
163
 
         {
{
164 if (m_hook != IntPtr.Zero)
            if (m_hook != IntPtr.Zero)
165
 
             {
{
166 UnhookWindowsHookEx(m_hook);
                UnhookWindowsHookEx(m_hook);
167 }
            }
168 }
        }
169
170 public MyHook(HookType HookType)
        public MyHook(HookType HookType)
171
 
         {
{
172 m_hooktype = HookType;
            m_hooktype = HookType;
173 if (m_hooktype == HookType.WH_KEYBOARD)
            if (m_hooktype == HookType.WH_KEYBOARD)
174
 
             {
{
175 m_hookproc = new HookProc(KeyHookProcedure);
                m_hookproc = new HookProc(KeyHookProcedure);
176 }
            }
177 else if (m_hooktype == HookType.WH_CALLWNDPROC)
            else if (m_hooktype == HookType.WH_CALLWNDPROC)
178
 
             {
{
179 m_hookproc = new HookProc(CallProcHookProcedure);
                m_hookproc = new HookProc(CallProcHookProcedure);
180 }
            }
181 }
        }
182
183 protected int KeyHookProcedure(int code, IntPtr wParam, IntPtr lParam)
        protected int KeyHookProcedure(int code, IntPtr wParam, IntPtr lParam)
184
 
         {
{
185 if (code != 0)
            if (code != 0)
186
 
             {
{
187 return CallNextHookEx(m_hook, code, wParam, lParam);
                return CallNextHookEx(m_hook, code, wParam, lParam);
188 }
            }
189
190 if (HookInvoked != null)
            if (HookInvoked != null)
191
 
             {
{
192 Keys key = (Keys)wParam.ToInt32();
                Keys key = (Keys)wParam.ToInt32();
193 HookEventArgs eventArgs = new HookEventArgs();
                HookEventArgs eventArgs = new HookEventArgs();
194 eventArgs.key = key;
                eventArgs.key = key;
195 eventArgs.lParam = lParam;
                eventArgs.lParam = lParam;
196 eventArgs.wParam = wParam;
                eventArgs.wParam = wParam;
197 eventArgs.HookCode = code;
                eventArgs.HookCode = code;
198 eventArgs.bAltKey = GetKeyState(VirtualKeys.VK_MENU) <= -127;
                eventArgs.bAltKey = GetKeyState(VirtualKeys.VK_MENU) <= -127;
199 eventArgs.bCtrlKey = GetKeyState(VirtualKeys.VK_CONTROL) <= -127;
                eventArgs.bCtrlKey = GetKeyState(VirtualKeys.VK_CONTROL) <= -127;
200 HookInvoked(this, eventArgs);
                HookInvoked(this, eventArgs);
201 }
            }
202
203 return CallNextHookEx(m_hook, code, wParam, lParam);
            return CallNextHookEx(m_hook, code, wParam, lParam);
204 }
        }
205
206 protected int CallProcHookProcedure(int code, IntPtr wParam, IntPtr lParam)
        protected int CallProcHookProcedure(int code, IntPtr wParam, IntPtr lParam)
207
 
         {
{
208 try
            try
209
 
             {
{
210 CallNextProc = true;
                CallNextProc = true;
211 if (HookInvoked != null)
                if (HookInvoked != null)
212
 
                 {
{
213 HookEventArgs eventArgs = new HookEventArgs();
                    HookEventArgs eventArgs = new HookEventArgs();
214 eventArgs.lParam = lParam;
                    eventArgs.lParam = lParam;
215 eventArgs.wParam = wParam;
                    eventArgs.wParam = wParam;
216 eventArgs.HookCode = code;
                    eventArgs.HookCode = code;
217 HookInvoked(this, eventArgs);
                    HookInvoked(this, eventArgs);
218 }
                }
219
220 if (CallNextProc)
                if (CallNextProc)
221
 
                 {
{
222 return CallNextHookEx(m_hook, code, wParam, lParam);
                    return CallNextHookEx(m_hook, code, wParam, lParam);
223 }
                }
224 else
                else
225
 
                 {
{
226 //return 1;
                    //return 1;
227 return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
                    return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
228 }
                }
229 }
            }
230 catch (Exception ex)
            catch (Exception ex)
231
 
             {
{
232 MessageBox.Show(ex.Message);
                MessageBox.Show(ex.Message);
233 return 0;
                return 0;
234 }
            }
235 }
        }
236 }
    }
237 #endregion
    #endregion
238 }
}
以上的钩子只对当前应用程序起作用,如果想控制其他的所有程序,需要使用全局钩子。原则上全局钩子在C#中是不支持的,在http://www.codeproject.com/csharp/globalhook.asp 中的代码可以参照来实现全局钩子