首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 呼叫 Windows API 模擬滑鼠移動與點擊

     編輯:關於C語言

需求:程式控制滑鼠

自動化測試、示範腳本、巨集錄製回放。.NET 無內建 API,需 P/Invoke user32.dll。

核心 API

API用途簽名
SetCursorPos設定滑鼠絕對座標bool SetCursorPos(int X, int Y);
mouse_event模擬移動、點擊、滾輪(支援相對/絕對)void mouse_event(uint dwFlags, int dx, int dy, uint dwData, UIntPtr dwExtraInfo);

MouseEventFlag 列舉


[Flags]
public enum MouseEventFlag : uint
{
    Move = 0x0001,
    LeftDown = 0x0002,
    LeftUp = 0x0004,
    RightDown = 0x0008,
    RightUp = 0x0010,
    MiddleDown = 0x0020,
    MiddleUp = 0x0040,
    Wheel = 0x0800,
    Absolute = 0x8000, // dx/dy 為絕對座標 (0~65535 對應螢幕寬高)
    VirtualDesk = 0x4000 // 多螢幕虛擬桌面
}

封裝滑鼠操作類別


public static class MouseSimulator
{
    [DllImport("user32.dll")]
    private static extern bool SetCursorPos(int x, int y);

    [DllImport("user32.dll")]
    private static extern void mouse_event(uint dwFlags, int dx, int dy, uint dwData, UIntPtr dwExtraInfo);

    public static void MoveTo(int x, int y) => SetCursorPos(x, y);

    public static void LeftClick()
    {
        mouse_event((uint)(MouseEventFlag.LeftDown | MouseEventFlag.LeftUp), 0, 0, 0, UIntPtr.Zero);
    }

    public static void LeftDown() => mouse_event((uint)MouseEventFlag.LeftDown, 0, 0, 0, UIntPtr.Zero);
    public static void LeftUp() => mouse_event((uint)MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);

    public static void RightClick() => mouse_event((uint)(MouseEventFlag.RightDown | MouseEventFlag.RightUp), 0, 0, 0, UIntPtr.Zero);

    public static void Scroll(int delta) => mouse_event((uint)MouseEventFlag.Wheel, 0, 0, (uint)delta, UIntPtr.Zero);

    // 絕對座標移動 (0~65535)
    public static void MoveToAbsolute(int x, int y)
    {
        mouse_event((uint)(MouseEventFlag.Move | MouseEventFlag.Absolute), x, y, 0, UIntPtr.Zero);
    }
}

進階:尋找視窗並點擊「開始」按鈕示範


[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll")]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

[StructLayout(LayoutKind.Sequential)]
private struct RECT { public int Left, Top, Right, Bottom; }

public static void ClickStartButton()
{
    // 1. 找到任務列
    IntPtr taskbar = FindWindow("Shell_TrayWnd", null);
    // 2. 找到開始按鈕 (Windows 10/11 類別名可能不同,需用 Spy++ 確認)
    IntPtr startBtn = FindWindowEx(taskbar, IntPtr.Zero, "Button", null); // 簡化示範

    if (startBtn != IntPtr.Zero)
    {
        GetWindowRect(startBtn, out RECT rect);
        int centerX = (rect.Left + rect.Right) / 2;
        int centerY = (rect.Top + rect.Bottom) / 2;

        MoveTo(centerX, centerY);
        Thread.Sleep(100); // 視覺確認
        LeftClick();
    }
}

注意事項與最佳實務

  • 座標系統:SetCursorPos 使用螢幕絕對像素;mouse_event Absolute 使用 0~65535 正規化座標。
  • 執行緒睡眠:操作間加入 Thread.Sleep(50~200),避免過快導致目標應用程式來不及響應。
  • UIPI (User Interface Privilege Isolation):Vista+ 低完整性進程無法向高完整性視窗(如管理員權限程式)發送滑鼠訊息。模擬器需以相同或更高權限執行。
  • DPI 感知:高 DPI 環境下座標需對應縮放比例,建議設定應用程式為 DPI Aware (app.manifest)。
  • 測試框架:實務自動化測試請使用 Selenium、Playwright、FlaUI、WinAppDriver 等成熟框架,而非手寫 API 呼叫。

結語

P/Invoke user32.dll 模擬滑鼠是理解 Windows 訊息機制、座標系統與安全模型的好練習。生產級自動化請採用專業測試框架,獲得穩定、可維護、跨平台的解決方案。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved