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方法安装钩子,该函数指定处理拦截消息的钩子函数(回 ...
随机推荐
- Vue.js 过渡 & 动画
1.前言 Vue动画/过渡的本质: 在通过v-if/v-show指令插入/移除/显示/隐藏某个标签元素时,在这个标签上包裹一个transition标签,Vue会为这个标签动态添加css类名,为这些类名 ...
- SFE人才需要具备哪些能力
SFE(销售队伍效力)人才在企业中扮演着至关重要的角色,他们需要具备一系列的能力来确保销售队伍的高效运作和业绩提升.关于SFE的角色和能力,可以从业务理解.数据洞察.向上管理以及效率提升等几个方面来通 ...
- Windows 触控笔
平板以及二合一平板均是触控屏,Laptop现在也有很多屏幕带触控 触控屏,都会配置触控笔配件,目前市场上一般是电容屏+电容笔的技术方案. 触控笔分为主动笔和被动笔,主动笔占绝大部分.主动笔是通过内部电 ...
- git commit之后,如何撤销commit
git reset --soft HEAD^ 仅仅是撤回commit操作,您写的代码仍然保留. HEAD^的意思是上一个版本,也可以写成HEAD~1 如果你进行了2次commit,想都撤回,可以使用H ...
- Visual Studio 2017 rc 资源文件 预处理 宏 无效
在属性c++下的预处理宏不会影响rc资源文件的,需要对rc资源文件单独设置. 右键rc资源文件,点击属性,在预处理器定义添加需要的宏
- Llama 3.2 900亿参数视觉多模态大模型本地部署及案例展示
Llama 3.2 900亿参数视觉多模态大模型本地部署及案例展示 本文将介绍如何在本地部署Llama 3.2 90B(900亿参数)视觉多模态大模型,并开发一些Use Case,展示其强大的视觉理解 ...
- k8s pod重启 deployment重启
1.15版本之后可通过kubectl rollout restart deployment -n 命令来实现滚动重启POD 该命令会先创建待用POD,待新POD运行成功后,再关闭原有POD.因此需要保 ...
- 基于Vue的前后段分离开发项目中<img :src />标签中引用vue的data属性中定义的图像地址失败的解决办法
问题描述: 基于Vue的前后段分离开发项目中<img :src />标签中引用vue的data属性中定义的图像地址失败,如下图所示: 解决办法: 修改后写法,加上require即可.如下 ...
- Matlab R2009b 版 license 到期问题
打开2009b Matlab,反复提示需要激活,是lisense到期了,到期时间2017年11月11日.解决方法: 将以下内容替换 Matlab 安装路径下 license/*.lic 文件中的所有内 ...
- 从新手到专家:如何设计一套亿级消息量的分布式IM系统
本文原作者Chank,原题"如何设计一个亿级消息量的 IM 系统",为了提升内容质量,本次有修订和改动. 1.写有前面 本文将在亿级消息量.分布式IM系统这个技术前提下,分析和总结 ...