C#实现的鼠标钩子

C#实现鼠标钩子可以用来监视和控制鼠标事件,比如截取特定的鼠标事件、拦截在系统中发生的鼠标消息等。这里提供完整攻略,具体过程如下:

准备工作

在开始实现之前,需要准备以下工作:

  1. 安装Visual Studio,该IDE提供C#开发环境。选择安装.NET桌面开发工作负载,并安装所需的组件。
  2. 创建一个新的C#控制台应用程序项目。
  3. 添加一个引用System.Windows.Forms.dll,该DLL提供了Windows窗体应用程序程序集。可通过以下方法添加引用:右键单击项目->添加 引用->框架->选中System.Windows.Forms.dll->单击“确定”按钮。

实现过程

  1. 声明回调代理函数Delegate

首先,在命名空间顶部,先声明回调代理函数Delegate。
csharp
private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);

  1. 导入Windows API引用

为了访问Windows处理程序指针,需要导入以下Windows API引用:
```csharp
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
```

  1. 定义必要变量

C#实现鼠标钩子需要一些必要的变量,如HHOOK类型的变量、类型的枚举值以及系统级鼠标事件编码。这里定义以下两个变量:
csharp
private const int WH_MOUSE_LL = 14;
private static LowLevelMouseProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;

  1. 实现回调函数

实现回调函数HookCallback,该函数接收一个标准的鼠标消息结构体。
csharp
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
{
// 鼠标左键按下事件发生时
MessageBox.Show("Left button down");
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}

  1. 实现启动/停止鼠标钩子函数

这个方法用于启动或停止鼠标钩子。当你想要捕获鼠标事件时,使用StartHook函数,反之使用StopHook函数。
```csharp
private static void StartHook()
{
_hookID = SetHook(_proc);
}

private static void StopHook()
{
UnhookWindowsHookEx(_hookID);
}

// 辅助方法
private static IntPtr SetHook(LowLevelMouseProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
}
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
```

示例说明

接下来举两个示例说明如何使用C#实现鼠标钩子:

示例一

在此示例中,我们将捕获鼠标左键单击事件,并向用户显示消息框。

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace MouseHookDemo
{
    class Program
    {
        private const int WH_MOUSE_LL = 14;
        private static LowLevelMouseProc _proc = HookCallback;
        private static IntPtr _hookID = IntPtr.Zero;

        private static IntPtr SetHook(LowLevelMouseProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
        private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
            {
                // 鼠标左键按下事件发生时
                MessageBox.Show("Left button down");
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        private static IntPtr GetModuleHandle(string lpModuleName)
        {
            IntPtr hModule = GetModuleHandleW(lpModuleName);
            if (hModule == IntPtr.Zero)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
            return hModule;
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandleW(string lpModuleName);

        static void Main(string[] args)
        {
            _hookID = SetHook(_proc);
            Application.Run();
            UnhookWindowsHookEx(_hookID);
        }
    }

    internal enum MouseMessages
    {
        WM_LBUTTONDOWN = 0x0201,
        WM_LBUTTONUP = 0x0202,
        WM_MOUSEMOVE = 0x0200,
        WM_MOUSEWHEEL = 0x020A,
        WM_RBUTTONDOWN = 0x0204,
        WM_RBUTTONUP = 0x0205
    }
}

示例二

在此示例中,我们将记录鼠标移动输入事件的坐标,并将其显示在控制台上。

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace MouseHookDemo
{
    class Program
    {
        private const int WH_MOUSE_LL = 14;
        private static LowLevelMouseProc _proc = HookCallback;
        private static IntPtr _hookID = IntPtr.Zero;

        private static IntPtr SetHook(LowLevelMouseProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
        private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && MouseMessages.WM_MOUSEMOVE == (MouseMessages)wParam)
            {
                // 鼠标移动事件发生时
                MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
                Console.WriteLine($"X:{hookStruct.pt.x}; Y:{hookStruct.pt.y}");
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        private static IntPtr GetModuleHandle(string lpModuleName)
        {
            IntPtr hModule = GetModuleHandleW(lpModuleName);
            if (hModule == IntPtr.Zero)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
            return hModule;
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandleW(string lpModuleName);

        static void Main(string[] args)
        {
            _hookID = SetHook(_proc);
            Console.WriteLine("Mouse move input events are being monitored.");
            Console.ReadLine();
            UnhookWindowsHookEx(_hookID);
        }
    }

    internal enum MouseMessages
    {
        WM_LBUTTONDOWN = 0x0201,
        WM_LBUTTONUP = 0x0202,
        WM_MOUSEMOVE = 0x0200,
        WM_MOUSEWHEEL = 0x020A,
        WM_RBUTTONDOWN = 0x0204,
        WM_RBUTTONUP = 0x0205
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct POINT
    {
        public int x;
        public int y;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct MSLLHOOKSTRUCT
    {
        public POINT pt;
        public uint mouseData;
        public uint flags;
        public uint time;
        public IntPtr dwExtraInfo;
    }
}

以上为C#实现鼠标钩子的攻略以及2个示例说明。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#实现的鼠标钩子 - Python技术站

(0)
上一篇 2023年6月1日
下一篇 2023年6月1日

相关文章

  • C#根据身份证号码判断出生日期和性别

    C# 根据身份证号码判断出生日期和性别 步骤1:获取身份证号码的输入 在 C# 中,我们可以通过 Console.ReadLine() 方法获取用户输入的身份证号码。示例代码如下: Console.WriteLine("请输入身份证号码:"); string idCard = Console.ReadLine(); 步骤2:校验身份证号码…

    C# 2023年6月1日
    00
  • ASP.NET Core应用JWT进行用户认证及Token的刷新方案

    下面我将为您详细讲解如何使用 ASP.NET Core 应用 JWT 进行用户认证及 Token 的刷新方案。 什么是 JWT? JWT (JSON Web Token) 是一个开放标准 (RFC 7519),用于在网络上传输声明 (Claims),通常用于身份认证。JWT 由三部分组成:头部 (Header)、载荷 (Payload) 和签名 (Signa…

    C# 2023年6月3日
    00
  • ASP.NET Core使用功能开关控制路由访问操作

    ASP.NET Core使用功能开关控制路由访问操作 在ASP.NET Core应用程序中,我们可以使用功能开关来控制路由访问操作。功能开关是一种机制,可以在应用程序中启用或禁用特定的功能。在本文中,我们将介绍如何使用功能开关来控制路由访问操作,并提供一些示例来说明如何使用它们。 安装Microsoft.FeatureManagement.AspNetCor…

    C# 2023年5月17日
    00
  • 在C#中使用OpenCV(使用OpenCVSharp)的实现

    在C#中使用OpenCV实现图像处理功能,可以使用OpenCVSharp库。以下是使用OpenCVSharp的攻略: 步骤一:安装OpenCVSharp库 首先在你的项目中安装OpenCVSharp库。可以通过NuGet安装方式,或者在其官网下载dll文件或源代码手动添加到项目中。 步骤二:引用命名空间 在所需要使用OpenCVSharp库的类文件中,引用命…

    C# 2023年6月1日
    00
  • vs2015浮点数计算怎么提高数据精度?

    想要提高VS2015中浮点数计算的数据精度,可以尝试以下几种方法: 1.使用高精度浮点数库 在C++标准库中,对于浮点数计算,可使用<boost/multiprecision>库中的高精度浮点数类型cpp_dec_float类进行计算。该类使用了基于任意精度算法的十进制算术来进行精度计算。下面是一个示例: #include <boost/m…

    C# 2023年6月6日
    00
  • c#判断字符是否为中文的三种方法分享(正则表达式判断)

    当我们需要实现c#中判断一个字符是否为中文时,可以运用以下三种方法进行判断: 1. Unicode码判断法 Unicode码代表着一个全球通用的编码标准,它为每个字符分配了一个唯一的标识。 中文的Unicode编码范围为 4E00 ~ 9FFF,因此可以通过以下代码实现中文判断: public static bool IsChinese(char c) { …

    C# 2023年6月8日
    00
  • C#框架winform实现简单点餐系统

    下面是详细讲解“C#框架winform实现简单点餐系统”的完整攻略。 1. 准备工作 在正式开始开发点餐系统之前,需要准备好相关的工具和资源,以下是准备工作的具体步骤: 1.1 安装Visual Studio Visual Studio是Windows平台下的一款集成开发环境,它支持多种编程语言,其中包括C#。因此,我们需要安装Visual Studio来进…

    C# 2023年6月3日
    00
  • C# DataTable中Compute方法用法集锦(数值/字符串/运算符/表等操作)

    C# DataTable中Compute方法用法集锦 DataTable的Compute方法提供了一种简便的方式,允许在DataTable中进行多种类型的计算。本文主要介绍该方法的用法集锦,包括数值计算、字符串操作、运算符、表操作以及自定义函数等方面的操作。 数值计算 Compute方法可以对包含数值的DataTable进行计算。以下面的表格为例,介绍相关的…

    C# 2023年5月15日
    00
合作推广
合作推广
分享本页
返回顶部