博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(转)vsto之鼠标事件的获取
阅读量:5210 次
发布时间:2019-06-14

本文共 16388 字,大约阅读时间需要 54 分钟。

 在做嵌入程序时,想要获取鼠标的一些事件,然后执行特定的逻辑。去网上找到了相关的有用的一些信息。现记录如下。

首先需要声明三个类 (Hook.cs    HookHelper.cs    Win32API.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        ///         /// 安装钩子        ///         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);                }            }        }        ///         /// 卸载鼠标钩子        ///         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("卸载失败!");            }        }        ///         /// 鼠标钩子处理函数        ///         ///         ///         ///         /// 
public bool btnUp = false; public bool btnMove = false; 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; int clickCount = 0;//点击数 bool move = false; switch ((int)wParam) { case (int)HookHelper.WM_MOUSE.WM_LBUTTONDOWN: //case WM_LBUTTONUP: //case WM_LBUTTONDBLCLK: button = MouseButtons.Left; btnUp = false; 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; case (int)HookHelper.WM_MOUSE.WM_LBUTTONDBLCLK: //鼠标双击 button = MouseButtons.Left; clickCount = 2; break; case (int)HookHelper.WM_MOUSE.WM_RBUTTONUP: btnUp = true; break; case (int)HookHelper.WM_MOUSE.WM_MOUSEMOVE: //鼠标移动 btnMove = true; btnUp = false; break; } //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); } /// /// 键盘钩子处理函数 /// /// /// /// ///
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); } }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Runtime.InteropServices;namespace TestHook.MyHook{    public class HookHelper    {        #region 枚举定义        ///         /// 操作类型        ///         public enum HookType        {            KeyOperation,//键盘操作            MouseOperation//鼠标操作        }        ///         /// 底层钩子标识        ///         public enum WH_Codes : int        {            //底层键盘钩子            WH_KEYBOARD_LL = 2,//2:监听键盘消息并且是线程钩子;13:全局鼠标钩子监听            //底层鼠标钩子            WH_MOUSE_LL = 7, //7:监听鼠标钩子;14:全局键盘钩子监听鼠标信息            //nCode为0            HC_ACTION = 0        }        ///         /// 鼠标按钮标识        ///         public enum WM_MOUSE : int        {            ///             /// 鼠标开始            ///             WM_MOUSEFIRST = 0x200,            ///             /// 鼠标移动            ///             WM_MOUSEMOVE = 0x200,            ///             /// 左键按下            ///             WM_LBUTTONDOWN = 0x201,            ///             /// 左键释放            ///             WM_LBUTTONUP = 0x202,            ///             /// 左键双击            ///             WM_LBUTTONDBLCLK = 0x203,            ///             /// 右键按下            ///             WM_RBUTTONDOWN = 0x204,            ///             /// 右键释放            ///             WM_RBUTTONUP = 0x205,            ///             /// 右键双击            ///             WM_RBUTTONDBLCLK = 0x206,            ///             /// 中键按下            ///             WM_MBUTTONDOWN = 0x207,            ///             /// 中键释放            ///             WM_MBUTTONUP = 0x208,            ///             /// 中键双击            ///             WM_MBUTTONDBLCLK = 0x209,            ///             /// 滚轮滚动            ///             /// 
WINNT4.0以上才支持此消息
WM_MOUSEWHEEL = 0x020A } /// /// 键盘按键标识 /// public enum WM_KEYBOARD : int { /// /// 非系统按键按下 /// WM_KEYDOWN = 0x100, /// /// 非系统按键释放 /// WM_KEYUP = 0x101, /// /// 系统按键按下 /// WM_SYSKEYDOWN = 0x104, /// /// 系统按键释放 /// WM_SYSKEYUP = 0x105 } /// /// SetWindowPos标志位枚举 /// ///
详细说明,请参见MSDN中关于SetWindowPos函数的描述
public enum SetWindowPosFlags : int { /// /// /// SWP_NOSIZE = 0x0001, /// /// /// SWP_NOMOVE = 0x0002, /// /// /// SWP_NOZORDER = 0x0004, /// /// /// SWP_NOREDRAW = 0x0008, /// /// /// SWP_NOACTIVATE = 0x0010, /// /// /// SWP_FRAMECHANGED = 0x0020, /// /// /// SWP_SHOWWINDOW = 0x0040, /// /// /// SWP_HIDEWINDOW = 0x0080, /// /// /// SWP_NOCOPYBITS = 0x0100, /// /// /// SWP_NOOWNERZORDER = 0x0200, /// /// /// SWP_NOSENDCHANGING = 0x0400, /// /// /// SWP_DRAWFRAME = 0x0020, /// /// /// SWP_NOREPOSITION = 0x0200, /// /// /// SWP_DEFERERASE = 0x2000, /// /// /// SWP_ASYNCWINDOWPOS = 0x4000 } #endregion 枚举定义 #region 结构定义 [StructLayout(LayoutKind.Sequential)] public struct POINT { public int X; public int Y; } /// /// 鼠标钩子事件结构定义 /// ///
详细说明请参考MSDN中关于 MSLLHOOKSTRUCT 的说明
[StructLayout(LayoutKind.Sequential)] public struct MouseHookStruct { /// /// Specifies a POINT structure that contains the x- and y-coordinates of the cursor, in screen coordinates. /// public POINT Point; public UInt32 MouseData; public UInt32 Flags; public UInt32 Time; public UInt32 ExtraInfo; } /// /// 键盘钩子事件结构定义 /// ///
详细说明请参考MSDN中关于 KBDLLHOOKSTRUCT 的说明
[StructLayout(LayoutKind.Sequential)] public struct KeyboardHookStruct { /// /// Specifies a virtual-key code. The code must be a value in the range 1 to 254. /// public UInt32 VKCode; /// /// Specifies a hardware scan code for the key. /// public UInt32 ScanCode; /// /// Specifies the extended-key flag, event-injected flag, context code, /// and transition-state flag. This member is specified as follows. /// An application can use the following values to test the keystroke flags. /// public UInt32 Flags; /// /// Specifies the time stamp for this message. /// public UInt32 Time; /// /// Specifies extra information associated with the message. /// public UInt32 ExtraInfo; } #endregion 结构定义 }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Runtime.InteropServices;namespace TestHook.MyHook{    class Win32API    {        #region DLL导入        ///         /// 用于设置窗口        ///         ///         ///         ///         ///         ///         ///         ///         /// 
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)] public static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags); /// /// 安装钩子 /// /// 钩子类型,鼠标\键盘\巨集等10几种 /// 挂钩的函数,用来处理拦截消息的函数,全局函数 /// 当前进程的句柄, /// 为NULL:当前进程创建的一个线程,子程位于当前进程; /// 为0(IntPtr.Zero):钩子子程与所有的线程关联,即为全局钩子 /// 设置要挂接的线程ID.为NULL则为全局钩子 ///
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)] public static extern IntPtr SetWindowsHookEx(IntPtr idHook, HookProc lpfn, IntPtr pInstance, uint threadId); /// /// 卸载钩子 /// /// ///
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)] public static extern bool UnhookWindowsHookEx(IntPtr pHookHandle); /// /// 传递钩子 /// 用于把拦截的消息继续传递下去,不然其他程序可能会得不到相应的消息 /// /// /// /// /// ///
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)] public static extern int CallNextHookEx(IntPtr pHookHandle, int nCode, IntPtr wParam, IntPtr lParam); /// /// 转换当前按键信息 /// /// /// /// /// /// ///
[DllImport("user32.dll")] public static extern int ToAscii(UInt32 uVirtKey, UInt32 uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, UInt32 fuState); /// /// 获取按键状态 /// /// ///
非0表示成功
[DllImport("user32.dll")] public static extern int GetKeyboardState(byte[] pbKeyState); [DllImport("user32.dll")] public static extern short GetKeyStates(int vKey); /// /// 获取当前线程Id /// ///
[DllImport("kernel32.dll")] public static extern uint GetCurrentThreadId(); /// /// 截屏位置 /// /// 目标设备的句柄 /// 目标对象的左上角的X坐标 /// 目标对象的左上角的Y坐标 /// 目标对象的矩形的宽度 /// 目标对象的矩形的高度 /// 源设备的句柄 /// 源对象的左上角的X坐标 /// 源对象的左上角的Y坐标 /// 光栅的操作值 ///
[DllImportAttribute("gdi32.dll")] private static extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, System.Int32 dwRop); /// /// /// /// 驱动名称 /// 设备名称 /// 无用,可以设定为"NULL" /// 任意的打印机数据 ///
[DllImportAttribute("gdi32.dll")] private static extern IntPtr CreateDC(string lpszDriver, string lpszDevice, string lpszOutput, IntPtr lpInitData); #endregion DLL导入 /// /// 钩子委托声明 /// /// /// /// ///
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam); }}

 

然后最后如果需要用的话就在 某个函数里调用,方法如下

private Hook hook = new Hook();//总钩子控制void go(){   hook.InstallHook(HookHelper.HookType.MouseOperation);   hook.OnMouseActivity += new MouseEventHandler(hook_OnMouseActivity);}  void hook_OnMouseActivity(object sender, MouseEventArgs e){   //你的逻辑。    //通过e.XX 来获取鼠标的事件的相关信息(左右键,按下抬起,坐标等)   }

 

//因为翻了很多博客,所以那些是从哪里copy下来的我也不知道出处了。所以就只能在标题写个转载了。

 

转载于:https://www.cnblogs.com/winshuo/p/9857536.html

你可能感兴趣的文章
gulp下单页面应用打包
查看>>
python应用:爬虫实例(静态网页)
查看>>
012 webpack中的router
查看>>
用Monitor简单3步监控中间件ActiveMQ
查看>>
ANDROID_MARS学习笔记_S01原始版_018_SERVICE之Parcel
查看>>
迅为iTOP-4418开发板兼容八核6818开发板介绍
查看>>
com.fasterxml.jackson.databind.JsonMappingException
查看>>
【UVa 540】Team Queue
查看>>
Advanced Architecture for ASP.NET Core Web API
查看>>
排序算法(二)
查看>>
4.4 多线程进阶篇<下>(NSOperation)
查看>>
如何更改Android的默认虚拟机地址(Android virtual driver路径设置)
查看>>
Python内置函数(36)——iter
查看>>
事件双向绑定原理
查看>>
HTML标签_1
查看>>
[Angular] @ViewChildren and QueryLists (ngAfterViewInit)
查看>>
jsp组成元素
查看>>
排序算法(转)
查看>>
windows自带的可生成各种数据库连接字符串工具打开方法
查看>>
Linux查看系统开机时间(转)
查看>>