热门标签 | 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;


推荐阅读
  • 本文探讨了在使用JavaMail发送电子邮件时,抄送功能未能正常工作的问题,并提供了详细的代码示例和解决方法。 ... [详细]
  • 本文介绍了如何通过C#语言调用动态链接库(DLL)中的函数来实现IC卡的基本操作,包括初始化设备、设置密码模式、获取设备状态等,并详细展示了将TextBox中的数据写入IC卡的具体实现方法。 ... [详细]
  • 本文探讨了如何通过Service Locator模式来简化和优化在B/S架构中的服务命名访问,特别是对于需要频繁访问的服务,如JNDI和XMLNS。该模式通过缓存机制减少了重复查找的成本,并提供了对多种服务的统一访问接口。 ... [详细]
  • 原文地址:https:blog.csdn.netqq_35361471articledetails84715491原文地址:https:blog.cs ... [详细]
  • 本文将深入探讨 Unreal Engine 4 (UE4) 中的距离场技术,包括其原理、实现细节以及在渲染中的应用。距离场技术在现代游戏引擎中用于提高光照和阴影的效果,尤其是在处理复杂几何形状时。文章将结合具体代码示例,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 本文详细介绍了 Java 中 org.w3c.dom.Node 类的 isEqualNode() 方法的功能、参数及返回值,并通过多个实际代码示例来展示其具体应用。此方法用于检测两个节点是否相等,而不仅仅是判断它们是否为同一个对象。 ... [详细]
  • 树莓派4B:安装基础操作系统指南
    本文将详细介绍如何为树莓派4B安装基础操作系统,包括所需材料、镜像下载、镜像烧录以及更换国内源等步骤。 ... [详细]
  • 本文详细介绍了如何在Android应用中实现重复报警功能。示例代码可在以下路径找到:https://developer.android.com/samples/RepeatingAlarm/index.html。首先,我们将从Manifest文件开始分析。 ... [详细]
  • 本文介绍了一种通过设置主题(Theme)来实现快速启动的Android引导页,并详细说明了如何避免因不同屏幕分辨率导致的图片拉伸问题。 ... [详细]
  • 本文记录了在Windows 8.1系统环境下,使用IIS 8.5和Visual Studio 2013部署Orchard 1.7.2过程中遇到的问题及解决方案,包括503服务不可用错误和web.config配置错误。 ... [详细]
  • 管理UINavigationController中的手势返回 - Managing Swipe Back Gestures in UINavigationController
    本文介绍了如何在一个简单的闪存卡片应用中实现平滑的手势返回功能,以增强用户体验。 ... [详细]
  • 使用Echarts for Weixin 小程序实现中国地图及区域点击事件
    本文介绍了如何使用Echarts for Weixin在微信小程序中构建中国地图,并实现区域点击事件。包括效果展示、条件准备和逻辑实现的具体步骤。 ... [详细]
  • 本文介绍了如何在 MapReduce 作业中使用 SequenceFileOutputFormat 生成 SequenceFile 文件,并详细解释了 SequenceFile 的结构和用途。 ... [详细]
  • 本打算教一步步实现koa-router,因为要解释的太多了,所以先简化成mini版本,从实现部分功能到阅读源码,希望能让你好理解一些。希望你之前有读过koa源码,没有的话,给你链接 ... [详细]
  • 本文介绍了如何使用 Gesture Detector 和 overridePendingTransition 方法来实现滑动界面和过渡动画。 ... [详细]
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社区 版权所有