利用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. Spring配置文件解析--依赖注入

    1.构造器注入基于构造器的DI通过调用带参数的构造器来实现,每个参数代表着一个依赖.此外,还可通过给stattic工厂方法传参数来构造bean.构造器参数解析根据参数类型进行匹配,如果bean的构造器 ...

  2. C++的vector学习abc

    开始学习和使用vector了,用到之后再去学似乎神迹的感觉啊,就像跑一下就能给个糖吃哈哈 百度上的六种初始化的方法就不再说了,那些方法都很对. 如果没有值初始化,系统会自行初始化,目前我遇到的是用脚标 ...

  3. 数据库索引<二> 补充前篇 (上一篇抽风了,这个补上)

    在前一个创建索引中已经大概说了三部分的影响,基本应该注意哪一些.写完上一篇后我感觉有很多地方没有写清楚,所以这篇就是更深入一些的理解索引到底是怎么和数据表关联,怎么快速查询的. 先看一下下面的图,图是 ...

  4. js首字母大写--单个单词的处理方式

    var operate2='OR'; for (var j = 0, len = operate1.length; j< len; j++) { //获得unicode码 var ch2 = o ...

  5. linux copy

    cp -ri 131115-6/* /web/www/attachment/  把13这个文件夹下面所有的文件和文件夹复制到 /web/www/attachment cp -a  a  /web/ww ...

  6. PHP+mysql常用类库

    <?php /** * @title: Ekcms mysql类库 * @version: 1.0 * @author: perry <perry@1kyou.com> * @pub ...

  7. Group by的使用方法

    sql中如果要分组查询,一般都会使用到group by语句,如何熟练使用group by语句呢,我分以下几点进行总结. Group by与聚合函数 Group by与Having 需要注意的地方 Gr ...

  8. MySql避免全表扫描【转】

    原文地址:http://blog.163.com/ksm19870304@126/blog/static/37455233201251901943705/ 对查询进行优化,应尽量避免全表扫描,首先应考 ...

  9. js基础之arguments、css

    arguments就是一个包含传入的参数的数组对象 栗子一: function sum(){ var result=0; for(var i=0;i<arguments.length;i++){ ...

  10. 浅谈C++源码的过国内杀软的免杀

    以下只是简单的思路和定位.也许有人秒过,但是不要笑话我写的笨方法.定位永远是过期不了的. 其实这里废话一下 , 本人并不是大牛 ,今天跟大家分享下 .所以写出这篇文章.(大牛飘过) 只是个人实战的经验 ...