C# 中通过 Win32 API 模拟鼠标点击与移动的实现

沈亦白
沈亦白
发布时间:2026-10-13| 5人浏览过
原创

在开发需要模拟用户交互的自动化程序时,直接使用 Win32 底层 API 比传统的高级封装更具灵活性。本文将解析如何在 C# 中通过导入 User32.dll 中的 SendMessage、SetCursorPos 和 WindowFromPoint 等函数,精确控制鼠标的移动、单击(左/右/中键)及双击操作,解决静默模拟或目标窗口消息投递的需求。

核心原理:消息机制与坐标处理

模拟鼠标点击的本质是向特定窗口句柄发送 WM 系列消息。一个完整的“鼠标左键单击”事件包含两个步骤:先发送左键按下消息 (WM_LBUTTONDOWN),再发送左键抬起消息 (WM_LBUTTONUP)。如果只发送按下而不抬起,目标窗口会认为鼠标一直处于按下状态,导致选中文本无法取消或拖拽错位等问题。

为了实现精准控制,我们需要处理两个关键问题:

  1. 坐标系统转换:API 通常需要屏幕绝对坐标,但有时需要相对当前光标位置移动;或者需要将屏幕坐标转换为窗口客户区坐标,以确保消息被正确的子控件接收。
  2. 目标窗口识别:通过坐标获取目标所在的窗口句柄,确保消息投递到正确的界面元素。

第 1 步:定义常量与 API 接口

首先需要在 C# 项目中引入 System.Runtime.InteropServices,并定义所需的 Win32 常量及外部函数声明。以下代码包含了键盘/鼠标动作标志位以及核心 API 入口。

[DllImport("user32.dll", SetLastError = true)]
public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, int lParam);

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr WindowFromPoint(int xPoint, int yPoint);

[DllImport("user32.dll", SetLastError = true)]
public static extern int SetCursorPos(int x, int y);

[DllImport("user32.dll", SetLastError = true)]
public static extern bool ScreenToClient(IntPtr hWnd, ref Point lppt);

// 鼠标消息常数
public const int WM_LBUTTONDOWN = 0x0201;
public const int WM_LBUTTONUP = 0x0202;
public const int WM_RBUTTONDOWN = 0x0204;
public const int WM_RBUTTONUP = 0x0205;
public const int WM_MBUTTONDOWN = 0x0207;
public const int WM_MBUTTONUP = 0x0208;

// 鼠标事件标志
public const int MOUSEEVENTF_MOVE = 0x0001;
public const int MOUSEEVENTF_LEFTDOWN = 0x0002;
public const int MOUSEEVENTF_LEFTUP = 0x0004;
public const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
public const int MOUSEEVENTF_RIGHTUP = 0x0010;
public const int MOUSEEVENTF_ABSOLUTE = 0x8000;

第 2 步:实现辅助函数用于坐标调整

原始的 mouse_event 函数已弃用且行为不可控。我们通过自定义包装器来接管坐标计算。以下函数负责将相对或绝对坐标转换为实际屏幕坐标,并定位目标窗口。

static void edit_position(int dwFlags, int dx, int dy, ref int x, ref int y)
{
    // 获取当前光标位置作为基准
    Point pos = MousePosition; 
    if ((dwFlags | MOUSEEVENTF_ABSOLUTE) == dwFlags)
    {
        // 绝对坐标模式:直接设置光标位置
        SetCursorPos(dx, dy); 
    }
    else
    {
        // 相对移动模式:基于当前位置叠加偏移量
        x = x + pos.X;
        y = y + pos.Y;
        SetCursorPos(x, y); 
    }
}

此外,还需要将屏幕坐标转换为窗口客户区坐标,以便精确瞄准窗口内的特定控件:

static bool screen_to_client(IntPtr hwnd, ref int x, ref int y)
{
    Point lpptPos = new Point(x, y);
    if ((bool)ScreenToClient(hwnd, ref lpptPos))
    {
        x = lpptPos.X;
        y = lpptPos.Y;
        return true;
    }
    return false;
}

第 3 步:构建模拟点击的核心逻辑

核心模拟函数 send_message 负责将鼠标按键状态映射为具体的 Window Message。为了支持双击或组合键,我们还提供了一个简单的整数合并工具 MakeDWord,用于组装 lParam 参数(低位存放 X 坐标,高位存放 Y 坐标)。

// 合并高低字为一个 Int32 (lParam)
static int MakeDWord(int low, int high)
{
    // 简单起见,此处使用位移运算逻辑,实际需处理无符号转换
    return low | (high << 16);
}

static void send_message(IntPtr hWnd, int dwFlags, int cButtons, int x, int y)
{
    // 根据 Flags 发送对应的按下和抬起消息
    if ((dwFlags & MOUSEEVENTF_LEFTDOWN) != 0)
        SendMessage(hWnd, WM_LBUTTONDOWN, cButtons, MakeDWord(x, y));
    if ((dwFlags & MOUSEEVENTF_LEFTUP) != 0)
        SendMessage(hWnd, WM_LBUTTONUP, cButtons, MakeDWord(x, y));
        
    if ((dwFlags & MOUSEEVENTF_RIGHTDOWN) != 0)
        SendMessage(hWnd, WM_RBUTTONDOWN, cButtons, MakeDWord(x, y));
    if ((dwFlags & MOUSEEVENTF_RIGHTUP) != 0)
        SendMessage(hWnd, WM_RBUTTONUP, cButtons, MakeDWord(x, y));
        
    // 中键类似... (略)
}

常见场景使用示例

基于上述基础组件,我们可以实现各种常见的鼠标操作:

1. 静默右键单击

适用于需要在后台执行上下文菜单操作而不触发视觉光标跳动的场景。注意必须同时发送 DOWN 和 UP,否则右键长按状态会残留。

// 在当前光标位置发送右键点击
int currentX = Cursor.Position.X;
int currentY = Cursor.Position.Y;
IntPtr targetHwnd = WindowFromPoint(currentX, currentY);
send_message(targetHwnd, MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, 0, currentX, currentY); 

2. 相对移动鼠标

相对于当前光标位置移动指定像素。例如向右移 100 像素,向下移 50 像素。

edit_position(MOUSEEVENTF_MOVE, 100, 50, ref currentX, ref currentY);

3. 绝对坐标移动到屏幕某点

直接将光标移动到屏幕坐标 (500, 300)。

SetCursorPos(500, 300);

通过以上模块化设计,你可以更清晰地掌控鼠标事件的时序与坐标细节,避免直接依赖已废弃的高层函数所带来的兼容性问题。

以上就是 C# 利用 Win32 API 模拟鼠标操作的详细内容,更多关于 C# 自动化控制的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。