利用C#设置钩子函数,并封装成类。如果想要实现全局钩子的话,必须将实现的代码封装到类库里。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Diagnostics;
using System.Windows.Forms; namespace PublicHook
{
/// <summary>
///存放回调函数的委托
/// </summary>
public delegate int HOOKPROC(int nCode, IntPtr wParam, IntPtr lParam);
public enum HookType
{
WH_KEYBOARD = , //私有键盘钩子
WH_EKYBOARD_LL = , //全局键盘钩子
WH_MOUSE = , //私有鼠标钩子
WH_MOUSE_LL = //全局鼠标钩子
} public abstract class hook
{
//设置钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(HookType idHook, HOOKPROC lpfn, IntPtr hInstance, int threadId);
//取下钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
//获取当前线程一个唯一的线程标识符
[DllImport("kernel32")]
public static extern int GetCurrentThreadId();
//传递消息给下一个钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
//获取一个应用程序或动态链接库的模块句柄
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string name); /// <summary>
/// 钩子处理委托
/// </summary>
public HOOKPROC proc;
/// <summary>
/// 钩子类型
/// </summary>
public HookType type;
/// <summary>
/// 钩子的句柄
/// </summary>
public int hHook = ; public hook(HOOKPROC proc, HookType type)
{
this.proc = proc;
this.type = type;
}
//设置回调函数
public void SetProc(HOOKPROC proc)
{
this.proc = proc;
} public abstract int SetWindowsHookEx();
public virtual void UnhookWindowsHookEx()
{
bool retKeyboard = true;
//当前钩子句柄不为空,卸载钩子
if (hHook != )
{
retKeyboard = UnhookWindowsHookEx(hHook);
hHook = ;
}
if (!retKeyboard)
throw new Exception("UnhookWindowsHookEx failed.");
}
} public class PublicKBHook : hook
{
public PublicKBHook(HOOKPROC proc)
: base(proc, HookType.WH_EKYBOARD_LL)
{ } public override int SetWindowsHookEx()
{
if (hHook == )
hHook = SetWindowsHookEx(this.type, this.proc,
GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), );
return hHook;
} //Hook结构
[StructLayout(LayoutKind.Sequential)]
public class HookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
/// <summary>
///回调函数,屏蔽除了回车和tab之外的所有键盘消息
/// </summary>
public int MyKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if ( nCode >= )
{
HookStruct hookStruct = (HookStruct)Marshal.PtrToStructure((IntPtr)lParam, typeof(HookStruct));
//如果按下了回车,则将消息传给下一个钩子
if ((Keys)hookStruct.vkCode == Keys.Enter ||
(Keys)hookStruct.vkCode == Keys.Tab)
return CallNextHookEx(hHook, nCode, wParam, lParam);
//后门
if ((Keys)hookStruct.vkCode == Keys.F1)
UnhookWindowsHookEx( hHook );
} return ;
}
} public class PrivateKBHook : hook
{
public PrivateKBHook(HOOKPROC proc)
: base(proc, HookType.WH_KEYBOARD)
{ } public override int SetWindowsHookEx()
{
if (hHook == )
hHook = SetWindowsHookEx(this.type, this.proc, IntPtr.Zero, GetCurrentThreadId());
return hHook;
}
} public class PublicMouseHook : hook
{
public PublicMouseHook(HOOKPROC proc)
: base(proc, HookType.WH_MOUSE_LL)
{ } public override int SetWindowsHookEx()
{
if (hHook == )
hHook = SetWindowsHookEx(this.type, this.proc,
GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), );
return hHook;
} /// <summary>
/// 屏蔽除了鼠标移动之外的鼠标消息
/// </summary>
public int MyMouseProc(int nCode, IntPtr wParam, IntPtr lParam)
{
//当wParam = 0x0200 时,进行鼠标移动操作
//直接将消息传递给下一个钩子
if (wParam == (IntPtr)0x0200)
return CallNextHookEx(hHook, nCode, wParam, lParam); return ;
}
} public class PrivateMouseHook : hook
{
public PrivateMouseHook(HOOKPROC proc)
: base(proc, HookType.WH_MOUSE)
{ } public override int SetWindowsHookEx()
{
if (hHook == )
hHook = SetWindowsHookEx(this.type, this.proc, IntPtr.Zero, GetCurrentThreadId()); return hHook;
}
}
}

调用代码:

            //钩子句柄
int hKBHook = , hMouseHook = ;
//设置全局键盘钩子
PublicKBHook myKBHook = new PublicKBHook(null);
myKBHook.SetProc(myKBHook.MyKeyboardProc);
hKBHook = myKBHook.SetWindowsHookEx();

卸载钩子:

//撤销钩子
myKBHook.UnhookWindowsHookEx();

C# 封装一个钩子类的更多相关文章

  1. 网络游戏开发-服务器(01)Asp.Net Core中的websocket,并封装一个简单的中间件

    先拉开MSDN的文档,大致读一遍 (https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/websockets) WebSocket 是一 ...

  2. JS实现继承,封装一个extends方法

    父类 function Person(name,age){ this.name = name; this.age = age; } Person.prototype = { eat:function( ...

  3. 自己封装一个Log模块

    Unity自己有log系统,为什么要自己封装一个 1.不好用,只能在pc上记录log文件,移动平台是没有的 2.在开发时期的log,不想在正式版里面出现.没有一个统一的开关来控制是不是要显示log,要 ...

  4. PHP封装一个通用好用的文件上传处理类

    封装一个文件上传类完成基本功能如下: 1.可上传多个或单个文件 2.上传成功返回一个或多个文件名 3.上传失败则返回每个失败文件的错误信息 上传类中的基本功能: 1.构造参数,用户可以自定义配置参数, ...

  5. Swift - 简单封装一个工具类模板

    创建模板类(封装一个类) 例1:新建一个名字叫做 Product 的类 Product.swift File 的内容 class Product { var name: String var desc ...

  6. 使用xib封装一个自定义view的步骤

    使用xib封装一个自定义view的步骤 1> 新建一个继承UIView的自定义view,假设类名叫做(MJAppView) 2> 新建一个MJAppView.xib文件来描述MJAppVi ...

  7. yii2封装一个类控制div宽度,高度

    1.首先,封装一个类,放在文件夹vendor下,命名为articls.php. <?phpclass Articles{ //测试    function add()    {        r ...

  8. C 封装一个简单二叉树基库

    引文 今天分享一个喜欢佩服的伟人,应该算人类文明极大突破者.收藏过一张纸币类型如下 那我们继续科普一段关于他的简介 '高斯有些孤傲,但令人惊奇的是,他春风得意地度过了中产阶级的一生,而  没有遭受到冷 ...

  9. IOS中封装一个View的思路

    一.封装一个View的思路 1.将View内部的业务逻辑(显示内容)封装到View中 2.一般情况下,View的位置应该由父控件来决定,也就是位置不应该固定死在View内部 3.至于View的宽高,根 ...

随机推荐

  1. CSS 声明( Declarations )

    CSS 声明1可以为空,或者由 CSS 特性( property ),后加一个冒号 ":",跟着是一个特性的值构成.中间可以有空格将它们隔开. 可用以下方式表达: property ...

  2. asp.net 奇淫技巧

    VS2013自动注释插件 分享一个Visual Studio的背景插件,让堆码更富情趣 工欲善其事必先利其器系列之:更换Visual Studio代码风格. 为Visual Studio更换皮肤和背景 ...

  3. C#运算除法和求整

    在C#与法中,“/”除后所得的值的类型,跟他的除数和被除数的类型有关.如:                        int a=4;                        int b=5 ...

  4. influxdb和boltDB简介——底层本质类似LMDB,MVCC+B+树

    influxdb influxdb是最新的一个时间序列数据库,最新一两年才产生,但已经拥有极高的人气.influxdb 是用Go写的,0.9版本的influxdb对于之前会有很大的改变,后端存储有Le ...

  5. 我的R代码备份

    1 #f1=scan(file="f1.txt");  2 #f2=scan(file="f2.txt");  3 f=scan(file="5.2_ ...

  6. (转)onTouchEvent方法的使用

      (转)onTouchEvent方法的使用 手机屏幕事件的处理方法onTouchEvent.该方法在View类中的定义,并且所有的View子类全部重写了该方法,应用程序可以通过该方法处理手机屏幕的触 ...

  7. LinearLayout练习

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  8. Hibernate 通过 Session 操纵对象

    Session 概述 •Session 接口是 Hibernate 向应用程序提供的操纵数据库的最主要的接口, 它提供了基本的保存, 更新, 删除和加载 Java 对象的方法. •Session 具有 ...

  9. UINavigationController 子控制器管理原理

    UINavigationController 显示在导航控制器上的控制器 永远是栈顶控制器 后进先出  先进后出原则 /** * 程序获得焦点才能获取触摸事件 * */- (void)applicat ...

  10. 蓝桥杯 BASIC_17 矩阵乘法 (矩阵快速幂)

    问题描述 给定一个N阶矩阵A,输出A的M次幂(M是非负整数) 例如: A = 1 2 3 4 A的2次幂 7 10 15 22 输入格式 第一行是一个正整数N.M(1<=N<=30, 0& ...