热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#钩子内部消息拦截

钩子其实就是调用一下API而已:1、安装钩子:SetWindowsHookEx函数原形:HHOOKSetWindowsHookEx(int

钩子其实就是调用一下API而已:

 

1、安装钩子:

  SetWindowsHookEx

    函数原形:HHOOK SetWindowsHookEx(

                       int       idHook,    // 钩子类型,

                       HOOKPROC  lpfn,      // 钩子函数地址

                       INSTANCE  hMod,      // 钩子所在的实例的句柄,

                       DWORD     dwThreadId // 钩子所监视的线程的线程号

                      )

    hMod: 对于线程序钩子,参数传NULL;

    对于系统钩子:参数为钩子DLL的句柄

  dwThreadId:对于全局钩子,该参数为NULL

    钩子类型用WH_CALLWNDPROC=4(发送到窗口的消息。由SendMessage触发)

    返回:成功:返回SetWindowsHookEx返回所安装的钩子句柄;

          失败:NULL;

 

2、回调,你要截获消息就在这里进行:

LRESULT WINAPI MyHookProc(

          int     nCode ,     // 指定是否需要处理该消息

          WPARAM  wParam,     // 包含该消息的附加消息

          LPARAM  lParam      // 包含该消息的附加消息

                        )

 

3、调用下一个钩子

LRESULT CallNextHookEx(

          HHOOK   hhk,      // 是您自己的钩子函数的句柄。用该句柄可以遍历钩子链

          int     nCode,    // 把传入的参数简单传给CallNextHookEx即可

          WPARAM  wParam,   // 把传入的参数简单传给CallNextHookEx即可

          LPARAM  lParam    // 把传入的参数简单传给CallNextHookEx即可

                      );

 

4、用完后记得卸载钩子哦,要不然你的系统会变得奇慢无比!

BOOL UnhookWindowsHookEx(

         HHOOK      hhk       // 要卸载的钩子句柄。

                      )

 

把上面这些APIC#封装一下,就可以直接用了!

给个线程钩子的例子吧(两个Form都在同一个线程中运行):

 

using System.Runtime.InteropServices;

 

public class Form1 : System.Windows.Forms.Form

{

    ...

    //定义委托(钩子函数,用于回调)

    public delegate int HookProc(int code, IntPtr wparam, ref CWPSTRUCT cwp);

 

    //安装钩子的函数

    [DllImport("User32.dll",CharSet = CharSet.Auto)]

    public static extern IntPtr SetWindowsHookEx(int type, HookProc hook, IntPtr instance, int threadID);

    //调用下一个钩子的函数

    [DllImport("User32.dll",CharSet = CharSet.Auto)]

    public static extern int CallNextHookEx(IntPtr hookHandle, int code, IntPtr wparam, ref CWPSTRUCT cwp);

    //卸载钩子

    [DllImport("User32.dll",CharSet = CharSet.Auto)]

    public static extern bool UnhookWindowsHookEx(IntPtr hookHandle);

    //获取窗体线程ID

    DllImport("User32.dll",CharSet = CharSet.Auto)]

    public static extern int GetWindowThreadProcessId(IntPtr hwnd, int ID);

 

    private HookProc hookProc;

    private IntPtr hookHandle = IntPtr.Zero;

 

    public Form1()

    {

        ....

        //挂接钩子处理方法

        this.hookProc = new HookProc(myhookproc);

    }

 

    //开始拦截

private bool StartHook()

    {

        Form2 f=new Form2();

        f.Show();//加上这个

        //安装钩子,拦截系统向Form2发出的消息

        this.hookHandle = SetWindowsHookEx(4, hookProc, IntPtr.Zero ,GetWindowThreadProcessId(f.Handle,0));

        return (this.hookHandle != 0);

    }

 

 

    //停止拦截

    private bool StopHook()

    {

        return UnhookWindowsHookEx(this.hookHandle);

    }

 

    //钩子处理函数,在这里拦截消息并做处理

    private int myhookproc(int code, IntPtr wparam, ref CWPSTRUCT cwp)

    {

        switch(code)

        {

    case 0:

    switch(cwp.message)

    {

        case 0x0000F://WM_PAINT,拦截WM_PAINT消息

                //do something

        break;

    }

            break;

        }

        return CallNextHookEx(hookHandle,code,wparam, ref cwp);

    }

   

    [StructLayout(LayoutKind.Sequential)]

    public struct CWPSTRUCT

    {

 public IntPtr lparam;

 public IntPtr wparam;

 public int message;

 public IntPtr hwnd;

    }

}

 

public class Form2 : System.Windows.Forms.Form

{

    ....

}

 

 

钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。

 

关于Hook的详细介绍,在微软的MSDN中有,http://www.microsoft.com/china/community/program/originalarticles/techdoc/hook.mspx

下面是我在C#中来应用Hook:

 

实现效果:

 

当用户在TextBox中输入 b 的时候,TextBox 始终显示 a

 

实现过程:

 

1、新建一个C#WindowsApplication

 

2、在Form1中,添加下面一些变量:  

 

        internal enum HookType //枚举,钩子的类型

 

        {

 

            //MsgFilter     = -1,

 

            //JournalRecord    = 0,

 

            //JournalPlayback  = 1,

 

            Keyboard         = 2,

 

            //GetMessage       = 3,

 

            //CallWndProc      = 4,

 

            //CBT              = 5,

 

            //SysMsgFilter     = 6,

 

            //Mouse            = 7,

 

            //Hardware         = 8,

 

            //Debug            = 9,

 

            //Shell           = 10,

 

            //ForegroundIdle  = 11,

 

            //CallWndProcRet  = 12,

 

            //KeyboardLL        = 13,

 

            //MouseLL           = 14,

 

        };

 

        IntPtr _nextHookPtr; //记录Hook编号

 

 

3、在Form1中引入必须的API  

 

        [DllImport("kernel32.dll")]

        static extern int GetCurrentThreadId(); //取得当前线程编号的API

 

        [DllImport("User32.dll")]

 

        internal extern static void UnhookWindowsHookEx(IntPtr handle); //取消HookAPI

 

        [DllImport("User32.dll")]

 

        internal extern static IntPtr SetWindowsHookEx(int idHook, [MarshalAs(UnmanagedType.FunctionPtr)] HookProc lpfn, IntPtr         hinstance, int threadID);  //设置HookAPI

 

        [DllImport("User32.dll")]

 

        internal extern static IntPtr CallNextHookEx(IntPtr handle, int code, IntPtr wparam, IntPtr lparam); //取得下一个HookAPI

 

4、声明一个实现的委托

 

        internal delegate IntPtr HookProc(int code, IntPtr wparam, IntPtr lparam);

 

5、添加自己的Hook处理过程 

 

        IntPtr MyHookProc(int code, IntPtr wparam, IntPtr lparam)

 

        {  

 

            if( code <0 ) return CallNextHookEx(_nextHookPtr,code, wparam, lparam); //返回&#xff0c;让后面的程序处理该消息           

 

             if( wparam.ToInt32() &#61;&#61; 98 || wparam.ToInt32() &#61;&#61; 66 ) //如果用户输入的是 b

 

            {

 

                this.textBox1.Text &#61; "a";

 

                 return   (IntPtr) 1; //直接返回了&#xff0c;该消息就处理结束了

 

            }

 

            else

 

            {

 

                return IntPtr.Zero; //返回&#xff0c;让后面的程序处理该消息

 

            }

 

        }

 

 6、添加加入Hook链和从Hook链中取消的函数

 

        public void SetHook()

 

        {

 

            if( _nextHookPtr !&#61; IntPtr.Zero ) //已经勾过了

 

              return;

 

            HookProc myhookProc &#61; new HookProc(MyHookProc); //声明一个自己的Hook实现函数的委托对象

 

            _nextHookPtr &#61; SetWindowsHookEx((int)HookType.Keyboard, myhookProc , IntPtr.Zero ,  GetCurrentThreadId()); //加到Hook链中

 

        }

 

        public void UnHook()

 

        {

 

            if( _nextHookPtr !&#61; IntPtr.Zero )

 

            {

 

                UnhookWindowsHookEx(_nextHookPtr); //Hook链中取消

 

                _nextHookPtr &#61; IntPtr.Zero;

 

            }

 

        }

 

 7、在Form1Load事件中添加 SetHook() &#xff0c; Form1closing 事件中添加 UnHook()

 

        private void Form1_Load(object sender, System.EventArgs e)

 

        {

 

            SetHook();

 

        }

 

        private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)

 

        {

 

            UnHook();

 

        }

 

 

 

8、运行

   

    输入 b , 发现 textbox 里面显示的是 a 了&#xff01;


推荐阅读
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 本文介绍了lintcode(12)题目的要求和解题思路,以及给出了相应的代码实现。题目要求在给定的字符串source中找到包括所有目标字符串字母的最短子串,并且时间复杂度为O(n)。解题思路是使用滑动窗口的方法,通过维护一个unordered_map来记录目标字符串中每个字符的出现次数,并使用双指针来寻找最小子串。代码实现部分给出了具体的实现代码。 ... [详细]
author-avatar
全球不懂我_934
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有