【转】C#键盘钩子之局部钩子

用钩子(hook)实现C#的屏幕键盘效果 要实现一个屏幕键盘,需要监听所有键盘事件,无论窗体是否被激活。因此需要一个全局的钩子,也就是系统范围的钩子。什么是钩子(Hook)       钩子(Hook)是Windows提供的一种消息处理机制平台,是指在程序正常运行中接受信息之前预先启动的函数,用来检查和修改传给该程序的信息,(钩子)实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前, 阅读详情

这篇文章也是转载的,如果作者不希望被转载,请联系我删除,谢谢。

因为之前没看懂,所以特地转载了,留着自己再次学习使用。


最近碰巧要使用键盘钩子,于是在网上搜索了一番,发现大多数博客的文章都是雷同的,根本就没有讲清楚全局钩子和局部钩子的区别,于是特开一贴,讲全局钩子和局部钩子捋一捋。也供后面的人学习。 
   因为大部分应用都应该采用局部钩子,所以我这儿使用的是局部钩子,而全局钩子的例子网上到处都是。 
   大部分网上参考文章都只是展示了全局钩子的写法,而线程钩子的写法和介绍相对少一些,特别是关键语句上如果定义的不正确是没有任何效果的,在自己反复尝试后决定留下一个正确的版本分享出来 
    代码如下

 

sing System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace AssistToolSet.Util
{
    /// <summary>
    /// 键盘钩子类
    /// </summary>
    public class Hook
    {
        public delegate int HookProc(WH_CODE nCode, Int32 wParam, IntPtr lParam);
        public enum WH_CODE : int
        {
            WH_JOURNALRECORD = 0,
            WH_JOURNALPLAYBACK = 1,
            /// <summary>
            /// 进程钩子
            /// </summary>
            WH_KEYBOARD = 2,

            /// <summary>
            /// 底层键盘钩子 全局钩子就是用这个

            /// </summary>
            WH_KEYBOARD_LL = 13,
        }

        public enum HC_CODE : int
        {
            HC_ACTION = 0,
            HC_GETNEXT = 1,
            HC_SKIP = 2,
            HC_NOREMOVE = 3,
            HC_NOREM = 3,
            HC_SYSMODALON = 4,
            HC_SYSMODALOFF = 5
        }

        /// <summary>
        /// 安装钩子
        /// </summary>
        [DllImport("user32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr SetWindowsHookEx(WH_CODE idHook, HookProc lpfn, IntPtr pInstance, uint threadId);

        /// <summary>
        /// 卸载钩子
        /// </summary>
        [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(IntPtr pHookHandle);
        /// <summary>
        /// 传递钩子
        /// </summary>
        [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern int CallNextHookEx(IntPtr pHookHandle, WH_CODE nCodem, Int32 wParam, IntPtr lParam);

        /// <summary>
        /// 获取全部按键状态
        /// </summary>
        /// <param name="pbKeyState"></param>
        /// <returns>非0表示成功</returns>
        [DllImport("user32.dll")]
        public static extern int GetKeyboardState(byte[] pbKeyState);

        /// <summary>
        /// 获取程序集模块的句柄
        /// </summary>
        /// <param name="lpModuleName"></param>
        /// <returns></returns>
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr GetModuleHandle(string lpModuleName);

        /// <summary>
        /// 获取当前进程中的当前线程ID
        /// </summary>
        /// <returns></returns>
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern uint GetCurrentThreadId();

        #region 私有变量

        private byte[] mKeyState = new byte[256];
        private Keys mKeyData = Keys.None; //专门用于判断按键的状态

        /// <summary>
        /// 键盘钩子句柄
        /// </summary>
        private IntPtr mKetboardHook = IntPtr.Zero;

        /// <summary>
        /// 键盘钩子委托实例
        /// </summary>
        private HookProc mKeyboardHookProcedure;

        #endregion

        #region 键盘事件

        public event KeyEventHandler OnKeyDown;
        public event KeyEventHandler OnKeyUp;

        #endregion

        /// <summary>
        /// 构造函数
        /// </summary>
        public Hook()
        {
            GetKeyboardState(this.mKeyState);
        }

        ~Hook()
        {
            UnInstallHook();
        }

        /// <summary>
        /// 键盘钩子处理函数
        /// </summary>
        private int KeyboardHookProc(WH_CODE nCode, Int32 wParam, IntPtr lParam)
        {
        /*全局钩子应该这样设定
         KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
        */
            // 定义为线程钩子时,wParam的值是击打的按键,与Keys里的对应按键相同
            if ((nCode == (int)HC_CODE.HC_ACTION) && (this.OnKeyDown != null || this.OnKeyUp != null))
            {
                mKeyData = (Keys)wParam;
                KeyEventArgs keyEvent = new KeyEventArgs(mKeyData);
                //这里简单的通过lParam的值的正负情况与按键的状态相关联
                if (lParam.ToInt32() > 0 && this.OnKeyDown != null)
                {
                    this.OnKeyDown(this, keyEvent);
                }
                else if (lParam.ToInt32() < 0 && this.OnKeyUp != null)
                {
                    this.OnKeyUp(this, keyEvent);
                }
            }
            if (ShortcutManagement.s_bHotkeyUsed)
            {
                ShortcutManagement.s_bHotkeyUsed = false;
                return 1;
            }

            return CallNextHookEx(this.mKetboardHook, nCode, wParam, lParam);
        }
        /// <summary>
        /// 安装钩子
        /// </summary>
        /// <returns></returns>
        public bool InstallHook()
        {
            //线程钩子时一定要通过这个取得的值才是操作系统下真实的线程
            uint result = GetCurrentThreadId();

            if (this.mKetboardHook == IntPtr.Zero)
            {
                this.mKeyboardHookProcedure = new HookProc(this.KeyboardHookProc);
                //注册线程钩子时第三个参数是空
                this.mKetboardHook = SetWindowsHookEx(WH_CODE.WH_KEYBOARD, this.mKeyboardHookProcedure, IntPtr.Zero, result);
                /*
                如果是全局钩子应该这样使用
                this.mKetboardHook = SetWindowsHookEx(WH_CODE.WH_KEYBOARD_LL, mKeyboardHookProcedure,GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);
                */
                if (this.mKetboardHook == IntPtr.Zero)
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 卸载钩子
        /// </summary>
        /// <returns>true表示成功 </returns>
        public bool UnInstallHook()
        {
            bool result = true;
            if (this.mKetboardHook != IntPtr.Zero)
            {
                result = UnhookWindowsHookEx(this.mKetboardHook) && result;
                this.mKetboardHook = IntPtr.Zero;
            }
            return result;
        }
    }

}


--------------------- 
作者:PGEva 
来源:优快云 
原文:https://blog.youkuaiyun.com/programvae/article/details/80292076 

C# 实现系统级鼠标和键盘钩子函数Demo Windows Forms是.NET Framework中用于开发Windows桌面应用程序的图形用户界面(GUI)库。它是早期.NET平台应用程序的主要开发方式之一。通过Windows Forms,开发者能够快速创建丰富的交互式应用程序,其功能包括窗口创建、事件处理、控件管理等。事件在Windows应用程序中扮演着至关重要的角色,它们是应用程序与用户交互的桥梁。事件可以是由用户的动作(如鼠标点击或键盘按键)引起的,也可以是由系统消息(如定时器超时或窗口重绘)引起的。 阅读详情

相关推荐

C#实现键盘全局钩子屏蔽按键功能案例

C#(发音为“看#”或“西#”)是一种现代、面向对象的编程语言,由微软公司于2000年随.NET平台一同发布。它是由Anders Hejlsberg主导设计,他之前也是Turbo Pascal、Delphi和VisiCalc的首席架构师。C#语言的设计融合了C++的强大能力和Visual Basic的简单易用性,旨在为开发Windows应用程序提供一种高效、安全且类型安全的编程手段。在Windows操作系统中,钩子(Hook)是一种特殊的程序,它允许开发者介入系统消息的传递过程中。

weixin_29363791的博客 1075

c# 安装局部鼠标钩子 张宇轩

<br />#region 安装局部鼠标钩子 开始调用InstallHook() 并在load事件中加载 OnMouseActivity += new MouseEventHandler(hook_MainMouseMove);//添加鼠标钩子事件<br />        //安装钩子 <br />        [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]<br />        public stat

张宇轩的博客 1855

C#全局钩子实战:键盘监听与文件框内容获取技术

P/Invoke 是 .NET 提供的一种机制,允许托管代码调用非托管函数。这些非托管函数通常存在于Windows系统的DLL中,例如user32.dll和gdi32.dll等。对于全局钩子的实现,P/Invoke 是必不可少的桥梁,因为核心函数如和都是Windows API函数。P/Invoke 的作用包括:声明非托管函数的签名将C#中的数据类型映射为Windows API期望的数据类型控制调用约定(Calling Convention)

weixin_31749299的博客 953

深入分析C#键盘勾子(Hook)拦截器,屏蔽键盘活动的详解

这个列表的指针指向指定的,应用程 序定义的,被Hook子程调用的回调函数,也就是该钩子的各个处理子程。最近安装的钩子放在链的开始, 而最早安装的钩子放在最后,也就是后加入的先获得控制权。也就是说每个进程所拥有的相同的DLL的全局数据,它们的名称相同,但其值却并不一定是相同的,而且是互不干涉的。在钩子子程中调用得到控制权的钩子函数在完成对消息的处理后,如果想要该消息继续传递,那么它必须调用另外一个 SDK中的API函数CallNextHookEx来传递它,以执行钩子链表所指的下一个钩子子程。

weixin_42099527的博客 3826

Visual Studio 2010实现全局键盘鼠标钩子教程

在现代软件开发中,全局键盘鼠标钩子技术是构建各种应用程序的重要组成部分,它允许开发者捕获并处理系统级别的输入事件。本章节将为读者提供一个全局键盘鼠标钩子技术的概览,并讨论其工作原理以及在软件开发中的应用范围。钩子(Hook)技术是一种用于改变或增强操作系统、应用程序或软件库行为的技术。在Windows操作系统中,钩子是通过钩子链(Hook Chain)实现的,它允许系统或应用程序截获并处理其他进程的消息和事件。

weixin_36303305的博客 984

C#使用全局钩子(hook)

介绍C#开发中在使用钩子对键盘鼠标等事件进行监听时出现错误的解决方法

键盘HOOK解析

键盘HOOK也可以是全局的或者仅仅是监控某一个线程。但是这种钩子比较典型。所以拎出来专门写了一篇。与全局钩子(特指WH_GETMESSAGE类型的钩子,这里称其为全局是因为它监控的是系统消息队列并不是说键盘钩子不能全局监控)一样,都是截获消息,只是键盘HOOK类型专门用于键盘消息的监控。看一下其类型的描述: 可以看到这里键盘钩子类型有两种,一种是WH_KEYBOARD还有一种是WH_KEYB...

輚至消亡 3294

局部钩子程序实现的一个例子

局部钩子程序实现的一个例子 局部钩子程序实现的一个例子 局部钩子程序实现的一个例子

C#键盘钩子之局部钩子和全局钩子

最近碰巧要使用键盘钩子,于是在网上搜索了一番,发现大多数博客的文章都是雷同的,根本就没有讲清楚全局钩子和局部钩子的区别,于是特开一贴,讲全局钩子和局部钩子捋一捋。也供后面的人学习。 应为大部分应用都应该采用局部钩子,所以我这儿使用的是局部钩子,而全局钩子的例子网上到处都是。 代码如下 using System; using System.Collections.Generic;...

ProgramVAE的博客 5899

远距离长航时低成本泡沫垂直起降固定翼无人机技术详解

该技术通过采用泡沫材料制造无人机机体,并结合高效的垂直起降与固定翼飞行机制,实现了低成本、长航时、远距离的飞行能力。然而,需要注意的是,泡沫材料在强度和耐候性方面可能较传统金属材料有所不足,因此在设计和制造过程中需要采取额外的加固和防护措施。用于森林防火、水域监测、空气质量检测等场景,通过搭载相应的传感器和摄像设备,对大范围区域进行高效、精准的监测。- 增强智能化水平:集成更多先进的传感器、算法和人工智能技术,提升无人机的自主决策能力和作业效率。

专注多旋翼、复合翼无人机技术研究,从事低空经济行业。 1201

如何让Arduino IDE支持你手里的STM32 nucleo开发板

Arduino IDE开发环境在默认情况下不支持STM32 NUCLEO开发板,只有通过添加附加开发板管理包才能使用。目前为止,只有一部分板子支持使用Arduino IDE开发环境进行开发,分别是 Nucleo F207ZG, Nucleo F429ZI, Nucleo F030R8, Nucleo F091RC, Nucleo F103RB, Nucleo F303RE, Nucl...

mzw72188552的专栏 8971

drf--part2

drf--part2一、局部钩子和全局钩子1、局部钩子2、全局钩子3、常用字段和参数二、视图相关1、保存数据2、更新数据三、modelSerializer的使用四、响应状态码 一、局部钩子和全局钩子 接上篇: 1、局部钩子 在反序列化校验中,我们不仅可以通过validators来自定义校验函数,也可以使用钩子函数来进行校验,首先我们介绍局部钩子。 局部钩子用在单个属性的校验,具体写法如下: from rest_framework import serializers class StudentSerial

qq_39787513的博客 735

保姆级教程:在通达信V7.611上配置欧奈尔RPS曲线(附完整公式与每日更新流程)

本文提供通达信V7.611配置欧奈尔RPS曲线的保姆级教程,涵盖从环境准备、基础设置到核心公式配置的全流程。详细讲解如何创建股票池、编写EXTRS基础公式及RPS显示公式,并附每日更新流程与实战应用技巧,帮助投资者精准捕捉强势股。

weixin_30000735的博客 462

C#全局钩子和局部钩子记录

源自:https://blog.youkuaiyun.com/programvae/article/details/80292076 最近碰巧要使用键盘钩子,于是在网上搜索了一番,发现大多数博客的文章都是雷同的,根本就没有讲清楚全局钩子和局部钩子的区别,于是特开一贴,讲全局钩子和局部钩子捋一捋。也供后面的人学习。 因为大部分应用都应该采用局部钩子,所以我这儿使用的是局部钩子,而全局钩子的例子网上到处都...

weixin_30706691的博客 259

Macbook Pro上如何修改brew源

一、需求说明 我的macbook电脑安装了中科大的brew源码,发现安装gpg工具失败,其他工具可以正常安装,为了能将gpg安装成功,就找了找切换brew源的方案,记录如下。 二、切换至国内源 由于使用github默认源有可能存在路径远或者部分服务访问超时的原因,切换至国内源可以提速。 2.1 替换brew.git $ cd "$(brew --repo)" # 中国科大: $ git remote set-url origin https://mirrors.ustc.edu.cn/brew.git #

bufegar0的博客 1078

新能源车主必看:用高德API+充电站数据制作跨城出行充电规划工具(附完整代码)

本文为新能源车主提供了一份详细的跨城出行充电规划工具构建指南。通过整合高德地图API与充电站数据,手把手教你使用Python开发一个智能规划系统,可自动规划路线并推荐沿途充电站,有效缓解里程焦虑。文章包含完整代码、核心算法解析及可视化实现,帮助车主实现个性化、高效的出行规划。

tgb3456789的博客 899

C#通过键盘钩子获取数据

C#通过键盘钩子获取数据 前言 在做关于使用USB刷卡器、扫码枪等项目的开发时,有可能需要通过键盘钩子去获取刷卡器、扫码枪获取的数据,当然,如果设备是串口、或者非系统独占设备的USB,可以采用串口通信、HID设备读写去获取数据。 本文是记录了C#如何通过键盘钩子去获取刷卡器读取上来的数据。 一、项目背景 需要获取刷卡器读到的卡号,然后根据卡号从客户的WebService中获取数据。所以第一步工作是...

Flora1992的博客 3115

ONNX Runtime C# YOLO全链路压测:从300ms到22ms的15个底层优化技巧

摘要:本文分享了工业质检场景下C#调用YOLOv8s ONNX模型的性能优化实战经验。原始单帧推理耗时300ms无法满足产线需求,通过全链路分析定位瓶颈(预处理85ms、推理180ms、后处理30ms)。重点优化措施包括:使用OpenCVSharp CUDA加速预处理(85ms→12ms),开启ONNX Runtime ALL级别图优化,选用TensorRT执行提供程序(180ms→22ms),以及优化内存管理和线程调度。最终实现单帧总耗时22ms±2ms,GPU利用率提升至85%,完整满足产线120块板/

2601_94871597的博客 402

C#环境下的钩子详解(转)

1、 WINDOWS的消息机制 2、 HOOK介绍 3、 HOOK链 4、 HOOK钩子的作用范围 5、 HOOK类型 6、 回调函数 7、 HOOK钩子的安装与卸载 8、 HOOK实例演示 +++++++++++++++++++ WINDOWS的消息机制 +++++++++++++++++++ Windows系统是以消息处理为其控制机制,系统通过消息为窗口过程(w

【Stevenson】的专栏 2039

[Dify实战] 招投标标书智能生成:模板套用 + 风险校验

摘要:本文提出基于Dify构建AI标书生成工作流,解决传统标书撰写中内容重复(80%复用率)、人工修改效率低、风险检查易出错等痛点。方案包含三大核心模块:1)智能生成(基于模板自动填充项目信息);2)风险校验(AI自动检查废标风险点);3)多角色协作。通过拆分标书结构、设置详细Prompt、建立风险检查清单,实现从"人工撰写"到"参数化自动生成+AI审核"的转型,最终输出标准格式文档并支持企业系统集成。典型应用场景下,系统能自动生成技术方案并识别关键风险(如支付安全合

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 827

46、聚类算法在智能交通数据分析中的应用

本文探讨了聚类算法在智能交通数据分析中的应用,介绍了K-均值算法、K-中心点算法和基于模型的聚类算法的基本原理及特点,并结合实际交通数据讨论了其应用场景与挑战。通过聚类分析,能够从海量交通数据中发现隐藏模式,为交通管理和规划提供科学依据。文章还展示了具体的案例分析和实现流程,为未来智能交通系统的发展提供了参考。

zz67890的博客 133

钩子函数和键盘记录

<br />钩子必备函数<br /><br />要安装钩子,必须用SetWindowsHookEx函数,函数原型如下:<br /><br />HHOOK SetWindowsHookEx(int idHook,HOOKPROC lpfn,HINSTANCE hMod,DWORD dwThreadId);<br /><br />idhook参数指定钩子的类型,钩子的类型如下:<br /><br /> WH_CALLWNDPROC每当调用SendMessage函数时,函数将消息发送给目标窗口时首先调用钩子函

irainbow5的专栏 706

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

C#键盘钩子

http://www.pinvoke.net/default.aspx        HookProc hookProc = null;         IntPtr hookValue = IntPtr.Zero;         const int WM_CLICK = 0x00F5;         public Form1()         {

The_Eyes的博客 918

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

C#实现屏幕键盘(软键盘 ScreenKeyboard)

 要实现一个屏幕键盘,需要监听所有键盘事件,无论窗体是否被激活。因此需要一个全局的钩子,也就是系统范围的钩子。什么是钩子(Hook)   钩子(Hook)是Windows提供的一种消息处理机制平台,是指在程序正常运行中接受信息之前预先启动的函数,用来检查和修改传给该程序的信息,(钩子)实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目

郑长风 3185

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C# 实现屏幕键盘 (ScreenKeyboard)

要实现一个屏幕键盘,需要监听所有键盘事件,无论窗体是否被激活。因此需要一个全局的钩子,也就 是系统范围的钩子。 什么是钩子(Hook) 钩子(Hook)是Windows提供的一种消息处理机制平台,是指在程序正常运行中接受信息之前预先 启动的函数,用来检查和修改传给该程序的信息,(钩子)实际上是一个处理消息的程序段,通 过系统调用,把它挂入系统。每当特定的消息发...

weixin_33682719的博客 761
上一篇: [转]C# 键盘钩子,真正解决大小写/shift后字符获取问题
下一篇: winform组合键,以及在没有焦点情况下使用钩子
sunstar8921
博客等级 码龄9年 12粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值