1. 什么是钩子

hook(钩子)是windows提供的一种消息处理机制平台,是指在程序正常运行中接受信息之前预先启动的函数,用来检查和修改传给该程序的信息,(钩子)实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出, 在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递(return)。

2. 钩子函数的声明

C#是.NET Framework平台的相伴语言,用它本身的类库和编译器提供的方法是无法实现全局钩子的。但实际上对于非托管代码的调用在C#中是成立的,钩子函数存在于user32.dll中,使用DllImport属性可以引用非托管代码类库中的方法。

钩子函数的安装:

  //安装钩子
[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(int idHook, int nCode, IntPtr wParam, IntPtr lParam);

3.钩子函数的使用

首先声明一个委托:

        //委托+事件(把钩到的消息封装为事件,由调用者处理)

        public delegate void MouseMoveHandler(object sender, MouseEventArgs e);

        public event MouseMoveHandler MouseMoveEvent;

定义一个鼠标钩子类:

    public class MouseHook
{ private Point point; private Point Point
{ get { return point; } set
{
if (point != value)
{
point = value;
if (MouseMoveEvent != null)
{
var e = new MouseEventArgs(MouseButtons.None, 0, point.X, point.Y, 0);
MouseMoveEvent(this, e);
}
}
}
} private int hHook; public const int WH_MOUSE_LL = 14; public Win32Api.HookProc hProc; public MouseHook() { this.Point = new Point(); } public int SetHook()
{ hProc = new Win32Api.HookProc(MouseHookProc); hHook = Win32Api.SetWindowsHookEx(WH_MOUSE_LL, hProc, IntPtr.Zero, 0); return hHook; } public void UnHook()
{ Win32Api.UnhookWindowsHookEx(hHook); } private int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{ Win32Api.MouseHookStruct MyMouseHookStruct = (Win32Api.MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(Win32Api.MouseHookStruct)); if (nCode < 0)
{ return Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam); } else
{ this.Point = new Point(MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y); return Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam); } } //委托+事件(把钩到的消息封装为事件,由调用者处理) public delegate void MouseMoveHandler(object sender, MouseEventArgs e); public event MouseMoveHandler MouseMoveEvent; }

调用钩子:

   public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
MouseHook mh; private void Form1_Load(object sender, EventArgs e)
{ mh = new MouseHook(); mh.SetHook(); mh.MouseMoveEvent += mh_MouseMoveEvent; } void mh_MouseMoveEvent(object sender, MouseEventArgs e)
{ int x = e.Location.X; int y = e.Location.Y; label1.Text = string.Format("当前鼠标位置为:({0},{1})", x, y); } private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{ mh.UnHook();
}
}

Win32Api 导入类:

需要引入 using System.Runtime.InteropServices; 命名空间

public class Win32Api
{ [StructLayout(LayoutKind.Sequential)]
public class POINT
{
public int x; public int y; } [StructLayout(LayoutKind.Sequential)]
public class MouseHookStruct
{ public POINT pt; public int hwnd; public int wHitTestCode; public int dwExtraInfo; } public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam); //安装钩子
[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(int idHook, int nCode, IntPtr wParam, IntPtr lParam); }

运行结果:

鼠标在窗口移动的时候,显示鼠标当前的坐标位置(在整个显示屏幕中的坐标)。

C# 钩子函数使用的更多相关文章

  1. Vue2.X的路由管理记录之 钩子函数(切割流水线)

    $route可以在子组件任何地方调用,代表当前路由对象,这个属性是只读的,里面的属性是 immutable(不可变) 的,不过你可以 watch(监测变化) 它. 导航和钩子函数: 导航:路由正在发生 ...

  2. 【Mocha.js 101】钩子函数

    前情提要 在上一篇文章<[Mocha.js 101]同步.异步与 Promise>中,我们学会了如何对同步方法.异步回调方法以及 Promise 进行测试. 在本篇文章中,我们将了解到 M ...

  3. wordpress钩子和钩子函数

    ccc,看了很多博客,无法理解,还是自己来写吧. wordpress 在wordpress中有很多钩子,还有很多钩子函数,在什么地方用什么钩子,用什么钩子函数, 需要明白两个问题: 1:什么是钩子,钩 ...

  4. 使用PreTranslateMessage替代钩子函数处理键盘消息

    2002年左右,我所在公司在开发基于H.323的VoIP电话系统(用了以色列一家公司的库,具体名字忘记了). 去电信科技研究院测试系统,同事发现处理键盘消息总有一些莫名其妙的问题,比如延迟或异常. 我 ...

  5. 10.PHP内核探索:Apache运行与钩子函数

    Apache是目前世界上使用最为广泛的一种Web Server,它以跨平台.高效和稳定而闻名.按照去年官方统计的数据,Apache服务器的装机量占该市场60%以上的份额.尤其是在 X(Unix/Lin ...

  6. 对于数据包的截取,使用linux中的netfilter钩子函数

    http://blog.csdn.net/wswifth/article/details/5115358 在师哥的代码(packet.c)中使用的是Linux2.4内核中的一个子系统:netfilte ...

  7. 黄聪:WordPress动作钩子函数add_action()、do_action()源码解析

    WordPress常用两种钩子,过滤钩子和动作钩子.过滤钩子相关函数及源码分析在上篇文章中完成,本篇主要分析动作钩子源码. 然而,在了解了动作钩子的源码后你会发现,动作钩子核心代码竟然跟过滤钩子差不多 ...

  8. 利用钩子函数来捕捉键盘响应的windows应用程序

    一:引言: 你也许一直对金山词霸的屏幕抓词的实现原理感到困惑,你也许希望将你的键盘,鼠标的活动适时的记录下来,甚至你想知道木马在windows操作系统是怎样进行木马dll的加载的…..其实这些都是用到 ...

  9. php 钩子函数原理 解析

    目前对钩子的理解:<转载:http://www.cnblogs.com/del/archive/2008/02/25/1080825.html> 譬如我们用鼠标在某个窗口上双击了一次, 或 ...

  10. HOOK钩子 - 钩子函数说明

    翻译参考自MaybeHelios的blog: http://blog.csdn.net/maybehelios/ 通过SetWindowsHookEx方法安装钩子,该函数指定处理拦截消息的钩子函数(回 ...

随机推荐

  1. uniapp h5 和 小程序互相传值

    小程序端 <template> <div> <web-view :webview-styles="webviewStyles" :src=" ...

  2. WPF下,控件未响应鼠标属性触发器

    WPF下,控件未响应鼠标属性触发器 记一次自定义控件调试 问题现象 问题分析 解决方式 记一次自定义控件调试 使用WPF写了个自定义控件,其中有个Button按钮,重写了样式模板 <Button ...

  3. 论文解读《The Philosopher’s Stone: Trojaning Plugins of Large Language Models》

    发表时间:2025 期刊会议:Network and Distributed System Security (NDSS) Symposium 论文单位:Shanghai Jiao Tong Univ ...

  4. 不错的AI项目集合

    最近收集了一些不错的AI项目. AutoGPT:AutoGPT 的愿景是让每个人都可以使用和构建无障碍 AI.我们的使命是提供工具,以便您可以专注于重要的事情. Stable Diffusion we ...

  5. 履机乘变,轻舟便楫:源启分布式PaaS深度赋能企业级技术平台建设

    导语 源启分布式PaaS平台围绕应用视角为用户提供应用运行的全生命周期管控能力,提供注册中心.服务路由.网关.服务治理等中间件技术支持,实现应用之间的联通,解决客户多厂商产品不兼容.产品组合不可选择. ...

  6. 【WEB前端】【报错解决】This request has been blocked; the content must be served over HTTPS.

    问题描述 部署WEB项目后,开启了强制HTTPS,产生如下错误: Mixed Content: The page at 'https://ask.mllt.vip/index.php/data1.ht ...

  7. 【转载】Spring Cloud Gateway-路由谓词工厂详解(Route Predicate Factories)

    http://www.imooc.com/article/290804 TIPS 本文基于Spring Cloud Greenwich SR2编写,兼容Spring Cloud Finchley及更高 ...

  8. vue3 封装axios

    1添加一个新的 http.js文件 封装axios 引入axios //引入Axios import axios from 'axios' 定义一个根地址 //视你自己的接口地址而定 var root ...

  9. 基于Netty,从零开发IM(三):编码实践篇(群聊功能)

    本文由作者"大白菜"分享,有较多修订和改动.注意:本系列是给IM初学者的文章,IM老油条们还望海涵,勿喷! 1.引言 接上两篇<IM系统设计篇>.<编码实践篇(单 ...

  10. 万字长文:手把手教你实现一套高效的IM长连接自适应心跳保活机制

    本文作者"Carson",现就职于腾讯公司,原题"高效保活长连接:手把手教你实现自适应的心跳保活机制",有较多修订和改动. 1.引言 当要实现IM即时通讯聊天. ...