利用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. 张艾迪(创始人):世界级天才女孩Eidyzhang

    让整个世界与我们一同解读世界第一天才:Eidyzhang 她改变了整个世界.她的故事也激励了整个世界的不论亚洲.欧洲.非洲.南美州.北美洲.南极洲 天才Eidyzhang的故事激励了整个世界不论黑人. ...

  2. DataProcessing

    clear load X4058 [m,n]=size(X528); Mean=zeros(1,n); Dev=zeros(1,n); for i=1:n Xi=X528(1:end-1,i); Xi ...

  3. C# 通过URL获取图片并显示在PictureBox上的方法

    , ); System.Net.WebRequest webreq = System.Net.WebRequest.Create(url); System.Net.WebResponse webres ...

  4. 高度30px,宽度自适应,点线在文字中间

    <style>  .div{ position: relative; width: 100%; height: 30px; background: #ffff00}        .div ...

  5. 数据库与SQL语言

    数据库(DB) :长期储存在计算机中.有组织.可共享的数据的集合. 特点:(1)数据按一定的数据模型组织.描述和储存:(2)较小的冗余度:(3)数据独立性较高:(4)易扩展:(5)可共享(不同用户可按 ...

  6. 克隆机器后eth1变为eth0问题

    1. 清空该文件 2.进入网络配置文件把HADDR 和UUID注释掉,并重启 3.成功修改eth0 4. 4.可以结合这篇帖子来看   http://www.cnblogs.com/zydev/p/4 ...

  7. Linux 下一个很棒的命令行工具

    导读 Taskwarrior 是 Ubuntu/Linux 下一个简单而直接的基于命令行的 TODO 工具.这个开源软件是我曾用过的最简单的基于命令行的工具之一.Taskwarrior 可以帮助你更好 ...

  8. LA 5059 - Playing With Stones

    博弈 SG  由于每个a太大,没有办法递推,但是可以找规律 a为偶数  SG(a)=a/2 a为奇数  SG(a)=SG(a/2) 代码: #include <iostream> #inc ...

  9. HDU 1698 Just a Hook

    题意:初始1-n 值为1,有Q操作,每次可以把一段[l,r] 整段每个值变成 x,问最后的[1,n]总和. 线段树成段更新(基础题) #include<cstdio> #include&l ...

  10. ROS语音识别

    一.语音识别包 1.安装         安装很简单,直接使用ubuntu命令即可,首先安装依赖库: $ sudo apt-get install gstreamer0.10-pocketsphinx ...