鼠标钩子(鼠标钩子程序[通俗易懂])

发布时间:2025-12-10 19:29:44 浏览次数:27

鼠标钩子程序[通俗易懂]-鼠标钩子能不能检测出来

鼠标钩子程序[通俗易懂]终于把我这个鼠标钩子程序实现了,刚开始我把句柄赋值赋错了,也就是SetWindowsHookEx(intidHook,HookProclpfn,IntPtrhInstance,intthreadId)的第三个参数,现在找好了,程序运行一切正常。钩子(Hook),是windows消息处理

  终于把我这个鼠标钩子程序实现了,刚开始我把句柄赋值赋错了,也就是SetWindowsHookEx(int idHook, HookProc lpfn,IntPtr hInstance, int threadId)的第三个参数,现在找好了,程序运行一切正常。

  钩子(Hook),是windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理windows消息或特定事件。   钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。

  我这里实现了一个简单的鼠标钩子程序,用于监视鼠标,把获取的鼠标坐标显示在wpf应用窗口。

  第一步:声明API函数

        [DllImport("kernel32.dll")]        public static extern IntPtr GetModuleHandle(string name);        //安装钩子        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);        //卸载钩子        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]        public static extern bool UnhookWindowsHookEx(int idHook);        //调用下一个钩子        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]        public static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

希望我今天分享的这篇文章可以帮到您。

  使用钩子,需要使用WindowsAPI函数,所以要先声明这些API函数。声明一下API函数,以后就可以直接调用了。

  第二步:声明、定义

        public delegate int HookProc(int nCode, int wParam, IntPtr lParam);       public HookProc MyProcedure;        //获取模块句柄        IntPtr intp = GetModuleHandle(null);        //定义钩子句柄        public static int hHook = 0;        //定义钩子类型        public const int WH_MOUSE_LL = 14;

  钩子必须使用标准的钩子子程,钩子子程就是一段方法,就是处理上面提到的把获取的鼠标坐标显示在wpf应用窗口操作。

  钩子子程必须按照HookProc(int nCode, int wParam, IntPtr lParam)这种结构定义,三个参数会得到关于消息的数据。

  GetModuleHandle获取一个应用程序或动态链接库的模块句柄,参数null将返回自身应用程序句柄。

  当使用SetWindowsHookEx函数安装钩子成功后会返回钩子子程的句柄,hHook变量记录返回的句柄,如果hHook不为0则说明钩子安装成功。

  WH_MOUSE_LL参数用于截获整个系统的鼠标事件。

  第三步:安装钩子、卸载钩子、写钩子子程

        private void button1_Click(object sender, RoutedEventArgs e)        {         if(hHook==0)           {               IntPtr intp = GetModuleHandle("user32.dll");               MyProcedure = new HookProc(this.MouseHookProc);               //这里挂节钩子               hHook = SetWindowsHookEx(WH_MOUSE_LL, MyProcedure, intp, 0);               if (hHook == 0)               {                   MessageBox.Show("SetWindowsHookEx Failed");                   return;               }               button1.Content = "卸载钩子";           }           else           {               bool ret = UnhookWindowsHookEx(hHook);               if(ret == false )               {                   MessageBox.Show("UnhookWindowsHookEx Failed");                   return;               }               hHook = 0;               button1.Content = "安装钩子";           }        }        public int MouseHookProc(int nCode, int wParam, IntPtr lParam)        {            POINT MyPOINT = (POINT)Marshal.PtrToStructure(lParam, typeof(POINT));            if (nCode < 0)            {                return CallNextHookEx((IntPtr)hHook, nCode, (IntPtr)wParam, lParam);            }            else            {                String strCaption = "x = " + MyPOINT.x.ToString("d") + "  y = " + MyPOINT.y.ToString("d");                text1.Text = strCaption;                return CallNextHookEx((IntPtr)hHook, nCode, (IntPtr)wParam, lParam);            }       }    }    [StructLayout(LayoutKind.Sequential)]    public class POINT    {        public int x;        public int y;    }

  SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId)函数将钩子加入到钩子链表中,说明一下四个参数:

  idHook钩子类型,即确定钩子监听何种消息。

  lpfn钩子子程的地址指针。如果threadId参数为0 或是一个由别的进程创建的线程的标识,lpfn必须指向dll中的钩子子程。 除此以外,lpfn可以指向当前进程的一段钩子子程代码。钩子函数的入口地址,当钩子钩到任何消息后便调用这个函数。

  hInstance应用程序实例的句柄。

  趣味验证:

  这个程序可以显示鼠标在任何位置的坐标,拖动鼠标时,程序会实时刷新显示鼠标的坐标。鲁大师测试我的电脑分辨率是1280×800,现在我们来验证下,运行我上面的程序,鼠标指向电脑屏幕左上角和右下角,分别显示如图:

  代码清单:


 public partial class MainWindow : Window { [DllImport("kernel32.dll")] public static extern IntPtr GetModuleHandle(string name); //安装钩子 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); //卸载钩子 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern bool UnhookWindowsHookEx(int idHook); //调用下一个钩子 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); public delegate int HookProc(int nCode, int wParam, IntPtr lParam); public HookProc MyProcedure; //获取模块句柄 IntPtr intp = GetModuleHandle(null); //定义钩子句柄 public static int hHook = 0; //定义钩子类型 public const int WH_MOUSE_LL = 14; public MainWindow() { InitializeComponent(); } private void button1_Click(object sender, RoutedEventArgs e) { if(hHook==0) { MyProcedure = new HookProc(this.MouseHookProc); //这里挂节钩子 hHook = SetWindowsHookEx(WH_MOUSE_LL, MyProcedure, intp, 0); if (hHook == 0) { MessageBox.Show("SetWindowsHookEx Failed"); return; } button1.Content = "卸载钩子"; } else { bool ret = UnhookWindowsHookEx(hHook); if(ret == false ) { MessageBox.Show("UnhookWindowsHookEx Failed"); return; } hHook = 0; button1.Content = "安装钩子"; } } public int MouseHookProc(int nCode, int wParam, IntPtr lParam) { POINT MyPOINT = (POINT)Marshal.PtrToStructure(lParam, typeof(POINT)); if (nCode < 0) { return CallNextHookEx((IntPtr)hHook, nCode, (IntPtr)wParam, lParam); } else { String strCaption = "x = " + MyPOINT.x.ToString("d") + " y = " + MyPOINT.y.ToString("d"); text1.Text = strCaption; return CallNextHookEx((IntPtr)hHook, nCode, (IntPtr)wParam, lParam); } } } [StructLayout(LayoutKind.Sequential)] public class POINT { public int x; public int y; }

View Code

2013-06-02

需要做网站?需要网络推广?欢迎咨询客户经理 13272073477