VSTO Office二次开发键盘鼠标钩子使用整理

简介:

VSTO Office二次开发键盘鼠标钩子使用整理

可能通过程序控制键盘的操作和控制鼠标的一些操作,网上提供比较多的也是比较好的就是通过钩子(Hook)的方式实现。
简单整理了一下,没有找到很好的程序示例,做了个简单的Hook测试。(对于Hook的原理和调用细则,这里不涉及了,只是简单的Hook小测试,感兴趣的查一下吧)
1.Win32API函数:(简单封装对于API函数的调用)

View Code

2.HookHelper.cs:(对于一些标识的定义,特别注意鼠标和键盘的标识参数)

View Code

3.Hook.cs:(简单对于键盘、鼠标的操作进行监控)

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace TestHook.MyHook
{
    public class Hook
    {
        #region 定义变量
        //定义鼠标钩子处理函数
        private Win32API.HookProc MouseHookProcedure = null;
        //定义键盘钩子处理函数
        private Win32API.HookProc KeyboardProcDelegate = null;

        //定义键盘钩子句柄
        private IntPtr khook;
        //定义鼠标钩子句柄
        private IntPtr hHook = IntPtr.Zero;

        //定义鼠标事件
        public event MouseEventHandler OnMouseActivity;
        #endregion

        /// <summary>
        /// 安装钩子
        /// </summary>
        public void InstallHook(HookHelper.HookType hookType)
        {
            if (hookType == HookHelper.HookType.KeyOperation)
            {
                if (khook == IntPtr.Zero)//键盘钩子
                {
                    uint id = Win32API.GetCurrentThreadId();
                    this.KeyboardProcDelegate = new Win32API.HookProc(this.KeyboardProc);
                    khook = Win32API.SetWindowsHookEx((IntPtr)HookHelper.WH_Codes.WH_KEYBOARD_LL, this.KeyboardProcDelegate, IntPtr.Zero, id);
                }
            }
            else
            {
                if (hHook == IntPtr.Zero)//鼠标钩子
                {
                    uint id = Win32API.GetCurrentThreadId();
                    this.MouseHookProcedure = new Win32API.HookProc(this.MouseHookProc);
                    //这里挂节钩子
                    hHook = Win32API.SetWindowsHookEx((IntPtr)HookHelper.WH_Codes.WH_MOUSE_LL, MouseHookProcedure, IntPtr.Zero, id);
                }
            }
        }

        /// <summary>
        /// 卸载鼠标钩子
        /// </summary>
        public void UnInstallHook(HookHelper.HookType hookType)
        {
            bool isSuccess = false;
            if (hookType == HookHelper.HookType.KeyOperation)//键盘钩子
            {
                if (khook != IntPtr.Zero)
                {
                    isSuccess = Win32API.UnhookWindowsHookEx(khook);
                    this.khook = IntPtr.Zero;
                }
            }
            else
            {
                if (this.hHook != IntPtr.Zero)//鼠标钩子
                {
                    isSuccess = Win32API.UnhookWindowsHookEx(hHook);
                    this.hHook = IntPtr.Zero;
                }
            }
            if (isSuccess)
            {
                MessageBox.Show("卸载成功!");
            }
            else
            {
                MessageBox.Show("卸载失败!");
            }
        }

        /// <summary>
        /// 鼠标钩子处理函数
        /// </summary>
        /// <param name="nCode"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        private int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode < (int)HookHelper.WH_Codes.HC_ACTION)
            {
                return Win32API.CallNextHookEx(hHook, nCode, wParam, lParam);
            }

            if (OnMouseActivity != null)
            {
                //Marshall the data from callback.
                HookHelper.MouseHookStruct mouseHookStruct = (HookHelper.MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(HookHelper.MouseHookStruct));
                MouseButtons button = MouseButtons.None;
                short mouseDelta = 0;
                switch ((int)wParam)
                {
                    case (int)HookHelper.WM_MOUSE.WM_LBUTTONDOWN:
                        //case WM_LBUTTONUP: 
                        //case WM_LBUTTONDBLCLK:
                        button = MouseButtons.Left;
                        break;
                    case (int)HookHelper.WM_MOUSE.WM_RBUTTONDOWN:
                        //case WM_RBUTTONUP: 
                        //case WM_RBUTTONDBLCLK: 
                        button = MouseButtons.Right;
                        break;
                    case (int)HookHelper.WM_MOUSE.WM_MOUSEWHEEL:
                        //button = MouseButtons.Middle;//滚动轮
                        //(value >> 16) & 0xffff; retrieves the high-order word from the given 32-bit value
                        mouseDelta = (short)((mouseHookStruct.MouseData >> 16) & 0xffff);
                        break;
                }

                int clickCount = 0;//点击数
                if (button != MouseButtons.None)
                {
                    if ((int)wParam == (int)HookHelper.WM_MOUSE.WM_LBUTTONDBLCLK || (int)wParam == (int)HookHelper.WM_MOUSE.WM_RBUTTONDBLCLK)
                    {
                        clickCount = 2;//双击
                    }
                    else
                    {
                        clickCount = 1;//单击
                    }
                }

                //鼠标事件传递数据
                MouseEventArgs e = new MouseEventArgs(button, clickCount, mouseHookStruct.Point.X, mouseHookStruct.Point.Y, mouseDelta);

                //重写事件
                OnMouseActivity(this, e);
            }

            return Win32API.CallNextHookEx(hHook, nCode, wParam, lParam);
        }

        /// <summary>
        /// 键盘钩子处理函数
        /// </summary>
        /// <param name="code"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        private int KeyboardProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            try
            {
                if (nCode < (int)HookHelper.WH_Codes.HC_ACTION)
                {
                    return Win32API.CallNextHookEx((IntPtr)khook, nCode, wParam, lParam);
                }

                HookHelper.KeyboardHookStruct keyHookStruct = (HookHelper.KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(HookHelper.KeyboardHookStruct));

                #region
                //if ((int)wParam == (int)Keys.C && ((int)lParam & (int)Keys.ControlKey) != 0 ||//Ctrl+C
                //    (int)wParam == (int)Keys.X && ((int)lParam & (int)Keys.ControlKey) != 0)//Ctrl+V
                //{
                //    MessageBox.Show("C||V");
                //}

                //if (lParam.ToInt32() > 0)//捕获键盘按下
                //{
                //    Keys keys = (Keys)wParam;
                //    MessageBox.Show("键盘按下");
                //}
                //if (lParam.ToInt32() < 0)//捕获键盘抬起
                //{
                //    MessageBox.Show("键盘抬起");
                //}
                /**************** 
                 //全局键盘钩子判断是否按下键 
                 wParam = = 0x100 // 键盘按下 
                 wParam = = 0x101 // 键盘抬起 
                ****************/
                //return 0;//如果返回1,则结束消息,消息截止,不再传递。如果返回0或调用CallNextHookEx函数,消息出这个钩子继续往下传递。
                #endregion

            }
            catch
            {

            }

            return Win32API.CallNextHookEx(khook, nCode, wParam, lParam);
        }
    }
}
复制代码

如果不好理解,将键盘、鼠标操作分离为两个文件分别封装:KeyHook.cs和MouseHook.cs
KeyHook.cs文件:

View Code

MouseHook.cs文件:

View Code

4.对于Hook文件的调用,使用一个WinForm窗体做的测试,鼠标监控按钮、键盘监控按钮、停止监控按钮,一个RichTextBox显示监控日志,一个Label显示鼠标坐标监控:

复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using TestHook.MyHook;

namespace TestHook
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private Hook hook = new Hook();//总钩子控制
        private KeyHook keyHook = new KeyHook();//键盘钩子        
        private MouseHook  mouseHook = new MouseHook();//鼠标钩子        

        private void Form1_Load(object sender, EventArgs e)
        {
            hook.OnMouseActivity += new MouseEventHandler(hook_OnMouseActivity);
            mouseHook.OnMouseActivity += new MouseEventHandler(mouseHook_OnMouseActivity);
            keyHook.OnKeyDown += new KeyEventHandler(keyHook_OnKeyDown);
        }

        void keyHook_OnKeyDown(object sender, KeyEventArgs e)
        {
            WriteLog("KeyDown     - " + e.KeyData.ToString());
        }

        void hook_OnMouseActivity(object sender, MouseEventArgs e)
        {
            this.lblMousePosition.Text = string.Format("X:{0} Y={1} Wheel={2}", e.X, e.Y, e.Delta);
            if (e.Clicks > 0)
            {
                WriteLog("MouseButton   -" + e.Button.ToString());
            }
        }
       
        private void btnMouseHook_Click(object sender, EventArgs e)
        {           
            //mouseHook.InstallHook();
            hook.InstallHook(HookHelper.HookType.MouseOperation);
        }

        private void btnKeyHook_Click(object sender, EventArgs e)
        {            
            keyHook.InstallHook();
            //hook.InstallHook(HookHelper.HookType.KeyOperation);
        }

        private void btnUnIntallHook_Click(object sender, EventArgs e)
        {
            //mouseHook.UnInstallHook();
            //keyHook.UnInstallHook();

            hook.UnInstallHook(HookHelper.HookType.KeyOperation);//卸载键盘钩子
            hook.UnInstallHook(HookHelper.HookType.MouseOperation);//卸载鼠标钩子
        }

        private void WriteLog(string message)
        {
            if (string.IsNullOrWhiteSpace(this.richMessage.Text))
            {
                this.richMessage.Text = "监控鼠标和键盘操作记录:" + Environment.NewLine;
            }
            this.richMessage.AppendText(message + Environment.NewLine);
            this.richMessage.SelectionStart = this.richMessage.Text.Length;
        }

        void mouseHook_OnMouseActivity(object sender, MouseEventArgs e)
        {
            this.lblMousePosition.Text = string.Format("X:{0} Y={1} Wheel={2}",e.X,e.Y,e.Delta);
            if (e.Clicks > 0)
            {
                WriteLog("MouseButton   -"+e.Button.ToString());
            }
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            hook.UnInstallHook(HookHelper.HookType.KeyOperation);//卸载键盘钩子
            hook.UnInstallHook(HookHelper.HookType.MouseOperation);//卸载鼠标钩子
        }
    }
}
复制代码

代码整理,模拟数据:来自蓝天旭日的《C#钩子实现简单鼠标键盘的监控和屏蔽 》文章,其示例来自GermanyGeorge Mamaladze的开源代码:
http://www.codeproject.com/KB/cs/globalhook.aspx

本文转自SanMaoSpace博客园博客,原文链接:http://www.cnblogs.com/SanMaoSpace/archive/2013/02/27/2935852.html,如需转载请自行联系原作者


相关文章
|
2月前
|
安全
猿大师办公助手在线编辑微软Office/金山wps网页组件COM加载项启用说明
猿大师办公助手是一款独特的在线编辑Office插件,不同于其他厂商的弹窗模式,它真正实现了网页内嵌本机Office。其COM加载项可在Office主菜单栏增加PageHi子菜单,提供文件保存、打印等功能,并能控制文档操作权限。安装后,默认自动启动COM加载项,但需注意可能被禁用或拦截,必要时需手动启用。对于WPS和微软Office,均有详细的启用步骤。
54 3
猿大师办公助手在线编辑微软Office/金山wps网页组件COM加载项启用说明
|
3月前
|
人工智能 自然语言处理 安全
微软会将ChatGPT整合纳入Office套件吗?
微软会将ChatGPT整合纳入Office套件吗?
|
6月前
|
Web App开发 JavaScript 前端开发
2024年纯前端VUE在线编辑微软Office/金山WPS的Word/Excel文档
现在,随着数字化进程渗透到到各行各业,数据安全已经成为了数字化革命中的重要组成部分,而在线Office成在OA、ERP、文档系统中得到了广泛的应用,为我国的信息化事业也做出了巨大贡献。随着操作系统、浏览器及Office软件的不断升级和更新换代,加上国家对信息化、数字化系统要求的不断提升,一些厂家的WebOffice控件产品不断被淘汰出局,而现存的几个产品也存在以下几个问题:
707 12
2024年纯前端VUE在线编辑微软Office/金山WPS的Word/Excel文档
|
6月前
微软Office 2019
微软办公软件套件Microsoft Office 2019 专业增强版2024年4月批量许可版更新推送!Office2019正式版2018年10月份推出,主要为多人跨平台办公与团队协作打造。Office2019整合对过去三年在Office365里所有功能,包括对Word、Excel、PowerPoint、Outlook、Project、Visio、Access、Publisher的更新。
152 2