C# 钩子函数使用
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# 钩子函数使用的更多相关文章
- Vue2.X的路由管理记录之 钩子函数(切割流水线)
$route可以在子组件任何地方调用,代表当前路由对象,这个属性是只读的,里面的属性是 immutable(不可变) 的,不过你可以 watch(监测变化) 它. 导航和钩子函数: 导航:路由正在发生 ...
- 【Mocha.js 101】钩子函数
前情提要 在上一篇文章<[Mocha.js 101]同步.异步与 Promise>中,我们学会了如何对同步方法.异步回调方法以及 Promise 进行测试. 在本篇文章中,我们将了解到 M ...
- wordpress钩子和钩子函数
ccc,看了很多博客,无法理解,还是自己来写吧. wordpress 在wordpress中有很多钩子,还有很多钩子函数,在什么地方用什么钩子,用什么钩子函数, 需要明白两个问题: 1:什么是钩子,钩 ...
- 使用PreTranslateMessage替代钩子函数处理键盘消息
2002年左右,我所在公司在开发基于H.323的VoIP电话系统(用了以色列一家公司的库,具体名字忘记了). 去电信科技研究院测试系统,同事发现处理键盘消息总有一些莫名其妙的问题,比如延迟或异常. 我 ...
- 10.PHP内核探索:Apache运行与钩子函数
Apache是目前世界上使用最为广泛的一种Web Server,它以跨平台.高效和稳定而闻名.按照去年官方统计的数据,Apache服务器的装机量占该市场60%以上的份额.尤其是在 X(Unix/Lin ...
- 对于数据包的截取,使用linux中的netfilter钩子函数
http://blog.csdn.net/wswifth/article/details/5115358 在师哥的代码(packet.c)中使用的是Linux2.4内核中的一个子系统:netfilte ...
- 黄聪:WordPress动作钩子函数add_action()、do_action()源码解析
WordPress常用两种钩子,过滤钩子和动作钩子.过滤钩子相关函数及源码分析在上篇文章中完成,本篇主要分析动作钩子源码. 然而,在了解了动作钩子的源码后你会发现,动作钩子核心代码竟然跟过滤钩子差不多 ...
- 利用钩子函数来捕捉键盘响应的windows应用程序
一:引言: 你也许一直对金山词霸的屏幕抓词的实现原理感到困惑,你也许希望将你的键盘,鼠标的活动适时的记录下来,甚至你想知道木马在windows操作系统是怎样进行木马dll的加载的…..其实这些都是用到 ...
- php 钩子函数原理 解析
目前对钩子的理解:<转载:http://www.cnblogs.com/del/archive/2008/02/25/1080825.html> 譬如我们用鼠标在某个窗口上双击了一次, 或 ...
- HOOK钩子 - 钩子函数说明
翻译参考自MaybeHelios的blog: http://blog.csdn.net/maybehelios/ 通过SetWindowsHookEx方法安装钩子,该函数指定处理拦截消息的钩子函数(回 ...
随机推荐
- PythonDay5Advance
PythonDay5Advance 函数和模块 main函数要有,用户自己选择要做的功能,根据选择调用不同的函数 用户注册的信息需要使用一个文件存储,登录需要判断用户是否存在,密码是否正确 注册的时候 ...
- mysql 自定义函数写法
1.业务场景 有时候我们希望通过sql语句解决一些复杂的问题,比如根据一个ID 查询组织的路径.这个时候我们可以使用函数来实现. 2.函数编写 CREATE FUNCTION getGroupById ...
- MySQL8设置root用户远程访问
查询当前root状态,默认root的host是localhost use mysql; select user,host from user; update root的host为% update us ...
- [Java]多个参数的非空判断,不要再使用多个if挨个判断了!(多参数非空判断技巧)
先上示例代码: if (StringUtils.isAnyBlank(form, to, subject, content)) { log.error("发送人,接收人,主题,内容均不可为空 ...
- 【微软】微软程序注册(zfile自建API)
Zfile支持设置自己的回调地址,怎么设置呢? 参考:https://docs.zfile.vip/advanced/onedrive-api/ 上面文档写的很清楚了,我提醒两点 1.进入 https ...
- 【Javaweb】在项目中添加MyBatis依赖等
pom.xml 仓库 如果你没有配置阿里云仓库镜像源,可以到这里来找 https://mvnrepository.com/ 如果你配置了阿里云仓库镜像源,可以来这里找 https://develope ...
- 【Java高级编程】Java多线程学习笔记
Java 多线程 目录 Java 多线程 1.多线程创建 方法1:通过 继承 thread 类 方法2:通过 实现 Runnable 接口 2.线程中的相关方法 (1)设置优先级 setPrlorty ...
- maven打包时跳过TEST的方式汇总
使用maven打包时如何跳过test,有以下几种方式 针对spring项目 <plugin> <groupId>org.apache.maven.plugins</gro ...
- Unity 3D简单使用C#脚本,脚本的执行顺序
Unity3D脚本间执行顺序 Unity3D中一个场景有时候需要多个脚本,可以挂在同一物体上执行,也可以挂在不同物体上执行 那么执行顺序是怎样的?我们来测试下 在上个项目基础上,再建一个Test2脚本 ...
- Qt/C++编写超精美自定义控件(历时9年更新迭代/超202个控件/祖传原创)
一.前言 无论是哪一门开发框架,如果涉及到UI这块,肯定需要用到自定义控件,越复杂功能越多的项目,自定义控件的数量就越多,最开始的时候可能每个自定义控件都针对特定的应用场景,甚至里面带了特定的场景的一 ...