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. uni-app 蓝牙扫码适配

    1.前言 蓝牙设备扫码的效率要高于手机摄像头 App需要进行对蓝牙扫码枪进行适配才能正常使用蓝牙设备枪,并兼容之前的摄像头扫码 适配的关键在于:扫码枪进行扫码时,需要对其进行事件监听,并拿到条码的值 ...

  2. 正也科技S2P 数字化推动医药信息传播多元化

    在当今数字化迅猛发展的时代浪潮中,医药信息传播正经历着深刻而广泛的变革.这种变革犹如一场波澜壮阔的革命,席卷了医药领域的每一个角落,对医药行业的发展产生了深远且不可忽视的影响. 一.传播渠道的多元化拓 ...

  3. S2P销讯通-SFE人才对企业管理层至关重要

    SFE这一概念,最初由外资企业引入,如今已逐渐被内资企业所采纳并融入其组织结构中,不少企业正积极构建这一部门. 1 我们观察到,近两年企业内对于SFE部门所需的人才需求急剧上升.这一部门,在外资企业中 ...

  4. 渗透测试-前端验签绕过之SHA256

    本文是高级前端加解密与验签实战的第1篇文章,本系列文章实验靶场为Yakit里自带的Vulinbox靶场,本文讲述的是绕过SHA256签名来爆破登录. 绕过 通过查看源代码可以看到key为 123412 ...

  5. Redis应用—4.在库存里的应用

    大纲 1.库存模块设计 2.库存缓存分片和渐进式同步方案 3.基于缓存分片的下单库存扣减方案 4.商品库存设置流程与异步落库的实现 6.库存入库时"缓存分片写入 + 渐进式写入 + 写入失败 ...

  6. 【Amadeus原创】SQL Server查询某数据库所有表名行数和空间占用率

    ` select object_name(id) tablename, 8reserved/1024 reserved, rtrim(8dpages)+'kb' used, 8(reserved-dp ...

  7. .NET 6 探索 Minimal API 系列

    今天看到来自 https://www.dotnetdeveloper.cn/ 的一个 .NET 6 Minimal API 系列,感觉质量不错,特别收录在这里. .Net 6探索 (1) Minima ...

  8. nexus如何上传自己的依赖包

    一.创建第三方包仓库创建第三方jar包的仓库选用hosted 取名为nexus-3rd 然后再public组中加入nexus-3rd,交给public管理 二.创建用户仓库创建完成以后可以创建一个管理 ...

  9. [转]Bundle Adjustment简述

    原文链接:https://optsolution.github.io/archives/58892.html或https://blog.csdn.net/optsolution/article/det ...

  10. Android Studio4.1.2中,修改了gradle后,如何在不关闭AS IDE的情况下使gradle进行sync

    Android Studio4.1.2中,修改了gradle后,如何在不关闭AS IDE的情况下使gradle进行sync: 方法1: 修改了gradle后,上面自然就弹出了一个提示框 你点击上面的S ...