using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text; namespace WindowsFormsApplication1
{
/// <summary>
/// 键盘Hook管理类 /// </summary>
public class KeyboardHookLib
{
private const int WH_KEYBOARD_LL = ; //键盘 //键盘处理事件委托.
private delegate int HookHandle(int nCode, int wParam, IntPtr lParam); //客户端键盘处理事件
public delegate void ProcessKeyHandle(HookStruct param, out bool handle); //接收SetWindowsHookEx返回值
private static int _hHookValue = ; //勾子程序处理事件
private HookHandle _KeyBoardHookProcedure; //Hook结构
[StructLayout(LayoutKind.Sequential)]
public class HookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
} //设置钩子
[DllImport("user32.dll")]
private static extern int SetWindowsHookEx(int idHook, HookHandle lpfn, IntPtr hInstance, int threadId); //取消钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern bool UnhookWindowsHookEx(int idHook); //调用下一个钩子
[DllImport("user32.dll")]
private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam); //获取当前线程ID
[DllImport("kernel32.dll")]
private static extern int GetCurrentThreadId(); //Gets the main module for the associated process.
[DllImport("kernel32.dll")]
private static extern IntPtr GetModuleHandle(string name); private IntPtr _hookWindowPtr = IntPtr.Zero; //构造器
public KeyboardHookLib() { } //外部调用的键盘处理事件
private static ProcessKeyHandle _clientMethod = null; /// <summary>
/// 安装勾子
/// </summary>
/// <param name="hookProcess">外部调用的键盘处理事件</param>
public void InstallHook(ProcessKeyHandle clientMethod)
{
_clientMethod = clientMethod; // 安装键盘钩子
if (_hHookValue == )
{
_KeyBoardHookProcedure = new HookHandle(GetHookProc); _hookWindowPtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName); _hHookValue = SetWindowsHookEx(
WH_KEYBOARD_LL,
_KeyBoardHookProcedure,
_hookWindowPtr,
); //如果设置钩子失败.
if (_hHookValue == ) UninstallHook();
}
} //取消钩子事件
public void UninstallHook()
{
if (_hHookValue != )
{
bool ret = UnhookWindowsHookEx(_hHookValue);
if (ret) _hHookValue = ;
}
} //钩子事件内部调用,调用_clientMethod方法转发到客户端应用。
private static int GetHookProc(int nCode, int wParam, IntPtr lParam)
{
if (nCode >= )
{
//转换结构
HookStruct hookStruct = (HookStruct)Marshal.PtrToStructure(lParam, typeof(HookStruct)); if (_clientMethod != null)
{
bool handle = false;
//调用客户提供的事件处理程序。
_clientMethod(hookStruct, out handle);
if (handle) return ; //1:表示拦截键盘,return 退出
}
}
return CallNextHookEx(_hHookValue, nCode, wParam, lParam);
} }
}

钩子类使用:

   //钩子管理类
private KeyboardHookLib _keyBoardHook = null; //安装钩子
private void button5_Click(object sender, EventArgs e)
{
_keyBoardHook = new KeyboardHookLib();
_keyBoardHook.InstallHook(this.KeyPress); } //取消钩子
private void button6_Click(object sender, EventArgs e)
{
if (_keyBoardHook != null) _keyBoardHook.UninstallHook();
} public void KeyPress(KeyboardHookLib.HookStruct hookStruct, out bool handle)
{
handle = false; //预设不拦截任何键 if (hookStruct.vkCode == ) // 截获左win(开始菜单键)
{
handle = true;
} if (hookStruct.vkCode == )// 截获右win
{
handle = true;
} //截获Ctrl+Esc
if (hookStruct.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control)
{
handle = true;
} //截获alt+f4
if (hookStruct.vkCode == (int)Keys.F4 && (int)Control.ModifierKeys == (int)Keys.Alt)
{
handle = true;
} //截获alt+tab
if (hookStruct.vkCode == (int)Keys.Tab && (int)Control.ModifierKeys == (int)Keys.Alt)
{
handle = true;
} //截获F1
if (hookStruct.vkCode == (int)Keys.F1)
{
handle = true;
} //截获Ctrl+Alt+Delete
if ((int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt + (int)Keys.Delete)
{
handle = true;
} //如果键A~Z
if (hookStruct.vkCode >= (int)Keys.A && hookStruct.vkCode <= (int)Keys.Z)
{
//挡掉G键,想要挡掉哪些键就把下面的G换成那个要挡掉的键,同理可以挡多个
if (hookStruct.vkCode == (int)Keys.G)
hookStruct.vkCode = (int)Keys.None; //设键为0 handle = true;
} Keys key = (Keys)hookStruct.vkCode;
label1.Text = "你按下:" + (key == Keys.None ? "None" : key.ToString());
}

c# 钩子类的更多相关文章

  1. C# 键盘钩子类

    键盘钩子类代码如下 class globalKeyboardHook { #region Constant, Structure and Delegate Definitions /// <su ...

  2. C# 封装一个钩子类

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

  3. CApiHook__Api钩子类

    见过网上有很多ApiHook的类,但是都不尽入人意,要么就是写的不够好不够完善,要么就是跑不起来. 用别人写的代码总是有种不安心,所以自己就花了一晚上写了CApiHook类.已经尽量确保自己写的类是非 ...

  4. 基于TP框架的ThinkCMF,控制器display方法源码分析

    昨天在写代码的时候,看见写了无数次的模版渲染方法:$this->display(),突然很想弄清楚它是如何实现的. 今天不忙,就分析了一下. class TestController exten ...

  5. dbcp基本配置和重连配置 -- mysql 8小时自动断开连接的问题

    1. 引入dbcp (选择1.4) Java代码   com.alibaba.external jakarta.commons.dbcp 1.4 2. dbcp的基本配置 相关配置说明: initia ...

  6. windows 勾子简介

    近段时间因朋友催促让试着写一个监控系统,主要是用来管理孩子使用电脑,帮助孩子合理使用电脑.在网上查询了相关内容发现没有这方面的资料,所以只有自已来试试,要用到钩子来对windows应用程序进行监控,也 ...

  7. 解读dbcp自动重连那些事---转载

    http://agapple.iteye.com/blog/791943 可以后另一篇做对比:http://agapple.iteye.com/blog/772507 同样的内容,不同的描述方式,不一 ...

  8. Windows消息拦截技术的应用

    Windows消息拦截技术的应用 民航合肥空管中心 周毅 一.前 言 众所周知,Windows程式的运行是依靠发生的事件来驱动.换句话说,程式不断等待一个消息的发生,然后对这个消息的类型进行判断,再做 ...

  9. Windows消息拦截技术的应用(作者博客里有许多相关文章)

    民航合肥空管中心 周毅 一.前 言 众所周知,Windows程式的运行是依靠发生的事件来驱动.换句话说,程式不断等待一个消息的发生,然后对这个消息的类型进行判断,再做适当的处理.处理完此次消息后又回到 ...

随机推荐

  1. Vue.js学习笔记(代码)

    ##v-cloak   v-text   v-html    v-bind    v-on的使用 <!DOCTYPE html> <html> <head> < ...

  2. C# EntityFramework Code First 迁移 降级 回退到空数据库

    C# EntityFramework  Code First 迁移 降级 回退到空数据库 1.包管理器控制台-迁移 在包管理器控制台中运行 Enable-Migrations Add-Migratio ...

  3. 【svn】本地文件夹同步到SVN

    本地代码上传至SVN 起因: 我在开发项目代码时往往在本地开发很久,在基本功能完成时才上传svn,添加版本控制. 做法: 右键 TortoiseSVN - Repo browser 在希望项目存储的根 ...

  4. 【算法】CRF(条件随机场)

    CRF(条件随机场) 基本概念 场是什么 场就是一个联合概率分布.比如有3个变量,y1,y2,y3, 取值范围是{0,1}.联合概率分布就是{P(y2=0|y1=0,y3=0), P(y3=0|y1= ...

  5. HttpClient不必每次新建实例而RestSharp推荐新建实例的原因

    https://stackoverflow.com/questions/49588205/should-restclient-be-singleton-or-new-for-every-request ...

  6. java PageHelper 分页插件出现 Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Duplicate column name 'Id' 错误

    情景: Mapper.xml定义连表查询,如果sql的字段名中有sql关键字,会导致PageHelper插件出现 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntax ...

  7. 【lamba】java 8的新特性

    看到lamba表达式用起来还不错,找了几篇文章学习下: 所以结合之前两个反编译的结果可以看到,lamdba表达式运行整体思路大致如下: 1. lamdba表达式被编译生成当前类的一个私有静态方法 2. ...

  8. kafka可视化客户端工具(Kafka Tool)的基本使用(转)

    转载地址:https://www.cnblogs.com/frankdeng/p/9452982.html 1.下载 下载地址:http://www.kafkatool.com/download.ht ...

  9. Spring,Spring MVC及Spring Boot区别

    什么是Spring?它解决了什么问题? 我们说到Spring,一般指代的是Spring Framework,它是一个开源的应用程序框架,提供了一个简易的开发方式,通过这种开发方式,将避免那些可能致使代 ...

  10. UOJ#103. 【APIO2014】Palindromes PAM模板题

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ103.html 前言 我终于会PAM啦 感谢CLY大佬手把手教我PAM 题解 建个 PAM. 统计一下每一个节点的 Rig ...