c#钩子程序键盘事件监听(拦截系统组合键)WebBrowser浏览器控件

硅谷探秘者 3739 0 0

1.什么是钩子程序

        hook(钩子)是windows提供的一种消息处理机制平台,是指在程序正常运行中接受信息之前预先启动的函数,用来检查和修改传给该程序的信息,(钩子)实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出, 在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递(return)。

        运行下面的程序案例需注意,程序会全屏展示,并且拦截所有系统组合键(除ctrl+alt+del),在程序菜单栏可退出。

2.钩子程序的主要代码

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using static WindowsFormsApplication1.Win32Api;
namespace WindowsFormsApplication1
{
    /**
     * c#钩子程序 键盘监控(拦截系统组合键)
     * */
    public class Win32Api
    {
        #region 常数和结构
        public const int WM_KEYDOWN = 0x100;

        public const int WM_KEYUP = 0x101;

        public const int WM_SYSKEYDOWN = 0x104;

        public const int WM_SYSKEYUP = 0x105;

        public const int WH_KEYBOARD_LL = 13;

        [StructLayout(LayoutKind.Sequential)] //声明键盘钩子的封送结构类型 

        public class KeyboardHookStruct
        {
            public int vkCode; //表示一个在1到254间的虚似键盘码 
            public int scanCode; //表示硬件扫描码 
            public int flags;
            public int time;
            public int dwExtraInfo;
        }

        #endregion
        #region Api

        public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);

        //安装钩子的函数 
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

        //卸下钩子的函数 
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(int idHook);

        //下一个钩挂的函数 
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);

        [DllImport("user32")]
        public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState);

        [DllImport("user32")]
        public static extern int GetKeyboardState(byte[] pbKeyState);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr GetModuleHandle(string lpModuleName);

        #endregion
    }

    public class KeyboardHook
    {
        int hHook;

        Win32Api.HookProc KeyboardHookDelegate;

        public event KeyEventHandler OnKeyDownEvent;

        public event KeyEventHandler OnKeyUpEvent;

        public event KeyPressEventHandler OnKeyPressEvent;

        public KeyboardHook() { }

        /**
         * 设置钩子
         * */
        public void SetHook()
        {
            KeyboardHookDelegate = new Win32Api.HookProc(KeyboardHookProc);
            Process cProcess = Process.GetCurrentProcess();
            ProcessModule cModule = cProcess.MainModule;
            var mh = Win32Api.GetModuleHandle(cModule.ModuleName);
            hHook = Win32Api.SetWindowsHookEx(Win32Api.WH_KEYBOARD_LL, KeyboardHookDelegate, mh, 0);
        }

        /**
         * 卸载钩子
         * */
        public void UnHook()
        {
            Win32Api.UnhookWindowsHookEx(hHook);
        }

        /**
         * 拦截按键
         * nCode参数是钩子代码,钩子子程使用这个参数来确定任务,这个参数的值依赖于Hook类型。
         * wParam和lParam参数包含了消息信息,我们可以从中提取需要的信息。
         * */
        private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                KeyboardHookStruct kbh = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
                // 截获左win(开始菜单键)
                if (kbh.vkCode == 91)
                {
                    return 1;
                }
                // 截获右win
                if (kbh.vkCode == 92)
                {
                    return 1;
                }
                //截获Ctrl+Esc
                if (kbh.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control)
                {
                    return 1;
                }
                //截获alt+f4
                if (kbh.vkCode == (int)Keys.F4 && (int)Control.ModifierKeys == (int)Keys.Alt)
                {
                    return 1;
                }
                //截获alt+tab
                if (kbh.vkCode == (int)Keys.Tab && (int)Control.ModifierKeys == (int)Keys.Alt)
                {
                    return 1;
                }
                //截获Ctrl+Shift+Esc
                if (kbh.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Shift)
                {
                    return 1;
                }
                //截获alt+空格
                if (kbh.vkCode == (int)Keys.Space && (int)Control.ModifierKeys == (int)Keys.Alt)
                {
                    return 1;
                }
                //截获F1
                if (kbh.vkCode == 241)
                {
                    return 1;
                }
                //截获Ctrl+Alt+Delete
                if ((int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt + (int)Keys.Delete)      
                {
                    return 1;
                }
            }
            return Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam);
        }
    }
}

3.窗体类主要代码:

using System;
using System.Windows.Forms;
/**
 * 命名空间,类似于java中的import
 * */
namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

4.窗体样式主要代码:

using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
    partial class Form1
    {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码

        /// <summary>
        /// 设计器支持所需的方法 - 不要修改
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.menuStrip1 = new System.Windows.Forms.MenuStrip();
            this.菜单ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.退出程序ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.考试须知ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.webBrowser1 = new System.Windows.Forms.WebBrowser();
            this.menuStrip1.SuspendLayout();
            this.SuspendLayout();
            // 
            // menuStrip1
            // 
            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.菜单ToolStripMenuItem,
            this.考试须知ToolStripMenuItem});
            this.menuStrip1.Location = new System.Drawing.Point(0, 0);
            this.menuStrip1.Name = "menuStrip1";
            this.menuStrip1.Size = new System.Drawing.Size(893, 25);
            this.menuStrip1.TabIndex = 0;
            this.menuStrip1.Text = "menuStrip1";
            // 
            // 菜单ToolStripMenuItem
            // 
            this.菜单ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.退出程序ToolStripMenuItem});
            this.菜单ToolStripMenuItem.Name = "菜单ToolStripMenuItem";
            this.菜单ToolStripMenuItem.Size = new System.Drawing.Size(44, 21);
            this.菜单ToolStripMenuItem.Text = "菜单";
            // 
            // 退出程序ToolStripMenuItem
            // 
            this.退出程序ToolStripMenuItem.Name = "退出程序ToolStripMenuItem";
            this.退出程序ToolStripMenuItem.Size = new System.Drawing.Size(124, 22);
            this.退出程序ToolStripMenuItem.Text = "退出程序";
            this.退出程序ToolStripMenuItem.Click += new System.EventHandler(this.退出程序ToolStripMenuItem_Click);
            // 
            // 考试须知ToolStripMenuItem
            // 
            this.考试须知ToolStripMenuItem.Name = "考试须知ToolStripMenuItem";
            this.考试须知ToolStripMenuItem.Size = new System.Drawing.Size(68, 21);
            this.考试须知ToolStripMenuItem.Text = "考试须知";
            this.考试须知ToolStripMenuItem.Click += new System.EventHandler(this.考试须知ToolStripMenuItem_Click);
            // 
            // webBrowser1 属性设置
            // 
            this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.webBrowser1.Location = new System.Drawing.Point(0, 25);
            this.webBrowser1.MinimumSize = new System.Drawing.Size(20, 20);
            this.webBrowser1.Name = "webBrowser1";
            this.webBrowser1.Size = new System.Drawing.Size(893, 286);
            this.webBrowser1.TabIndex = 1;

            /**
             * 设置 WebBrowser 容器默认请求的ip地址
             * */
            this.webBrowser1.Navigate("http://www.baidu.com");

            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(893, 311);
            this.Controls.Add(this.webBrowser1);
            this.Controls.Add(this.menuStrip1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            this.MainMenuStrip = this.menuStrip1;
            this.Name = "Form1";
            this.ShowInTaskbar = false;
            this.Text = "Form1";
            this.TopMost = true;
            this.WindowState = System.Windows.Forms.FormWindowState.Maximized;//窗体最大化
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
            this.Load += new System.EventHandler(this.Form1_Load);
            this.menuStrip1.ResumeLayout(false);
            this.menuStrip1.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion
        /**
         * 定义菜单
         * */
        private MenuStrip menuStrip1;
        /**
         * 定义菜单按钮
         * */
        private ToolStripMenuItem 菜单ToolStripMenuItem;
        private ToolStripMenuItem 退出程序ToolStripMenuItem;
        private ToolStripMenuItem 考试须知ToolStripMenuItem;

        /**
         * 定义WebBrowser容器
         * */
        private WebBrowser webBrowser1;
    }
}

5.窗体事件的主要代码:

using System;
using System.Diagnostics;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
    /**
     * 窗体类
     * */
    public partial class Form1 : Form
    {
        public Form1()
        {
            /**
             * 容器初始化
             * */
            InitializeComponent();
        }
        /**
         * 定义钩子对象
         * */
        KeyboardHook kh;

        /**
         * 窗体加载时启动 winfrom 钩子
         **/
        private void Form1_Load(object sender, EventArgs e)
        {
            kh = new KeyboardHook();
            kh.SetHook();
        }
        
        /**
         * 键盘事件监听
         * */
        void kh_OnKeyDownEvent(object sender, KeyEventArgs e)
        {
            
        }

        /**
         * 窗体关闭
         * */
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            kh.UnHook();
        }

        /**
         * 退出程序
         * */
        private void 退出程序ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Process.GetCurrentProcess().Kill();
        }

        private void 考试须知ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("考生请注意:作弊者,格杀勿论,不留余地~");
        }
    }
}



评论区
请写下您的评论...
暂无评论...
猜你喜欢
weblog 2029 vue,修饰符和按修饰符!DOCTYPEhtmlhtml head metacharset="UTF-8" title/title scriptsrc="js
前端(h5) 2340 web前端html页面添加$(document).keydown(function(event){if(event.keyCode==13){document.getElementById
setUpVpn 14538 谷歌vpn插翻墙将下载的文拖到谷歌的扩展窗口中,即可安装
rabbitmq,springboot 1688 客户端应用。 为了消费,应用需要声明一个队列,并绑定到一个指定的交换去消费消息。 插在默认的虚拟主机上声明了一个topic类型的exchange(交换
weblog 1589 layuitable表格单选以及选中数据获取表格设置table.render({ elem:'#test' ,url:'[[@{/smmc/artificial}]]'+'?xsId
weblog 1097 linuxvivim编辑查找指定内容(关字)在命令行模式下按'/',然后输入你要查找的关字,回车即可此时你可以按n向下查找,或按N向上查找
插件 谷歌 1666 谷歌访问接口返回json格式字符串时比较混乱,如下图安装此插后的格式如下图点击右上方按钮下载安装方法打开拓展,如下将插拖到这个界面,点击同意安装插,安装完成后如上图。
official 767 《计算机成原理》运算的基本成如下运算的基本的基本的基本成完成一条指令的步骤完成一条指令的步骤计算机的工作过描述起来非常复杂,不太好描述,我也是图贴在了这里(原视
归档
2018-11  12 2018-12  33 2019-01  28 2019-02  28 2019-03  32 2019-04  27 2019-05  33 2019-06  6 2019-07  12 2019-08  12 2019-09  21 2019-10  8 2019-11  15 2019-12  25 2020-01  9 2020-02  5 2020-03  16 2020-04  4 2020-06  1 2020-07  7 2020-08  13 2020-09  9 2020-10  5 2020-12  3 2021-01  1 2021-02  5 2021-03  7 2021-04  4 2021-05  4 2021-06  1 2021-07  7 2021-08  2 2021-09  8 2021-10  9 2021-11  16 2021-12  14 2022-01  7 2022-05  1 2022-08  3 2022-09  2 2022-10  2 2022-12  5 2023-01  3 2023-02  1 2023-03  4 2023-04  2 2023-06  3 2023-07  4 2023-08  1 2023-10  1 2024-02  1 2024-03  1 2024-04  1
标签
算法基础 linux 前端 c++ 数据结构 框架 数据库 计算机基础 储备知识 java基础 ASM 其他 深入理解java虚拟机 nginx git 消息中间件 搜索 maven redis docker dubbo vue 导入导出 软件使用 idea插件 协议 无聊的知识 jenkins springboot mqtt协议 keepalived minio mysql ensp 网络基础 xxl-job rabbitmq haproxy srs 音视频 webrtc javascript
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。