核心 API 簽名
[DllImport("user32.dll")] public static extern int ClipCursor(ref RECT lpRect);
[DllImport("user32.dll")] public static extern int GetWindowRect(IntPtr hwnd, ref RECT lpRect);
[DllImport("user32.dll")] public static extern int SwapMouseButton(int bSwap);
[DllImport("user32.dll")] public static extern int ShowCursor(int bShow); // 計數器機制
[DllImport("user32.dll")] public static extern int SetDoubleClickTime(int ms);
[DllImport("user32.dll")] public static extern int GetDoubleClickTime();
[StructLayout(LayoutKind.Sequential)]
public struct RECT { public int Left, Top, Right, Bottom; }
功能實作範例
1. 限制滑鼠在表單內移動
public void LockMouseToForm(Form form)
{
RECT rc = new RECT();
GetWindowRect(form.Handle, ref rc);
ClipCursor(ref rc);
}
public void UnlockMouse()
{
RECT rc = new RECT
{
Left = 0, Top = 0,
Right = Screen.PrimaryScreen.Bounds.Width,
Bottom = Screen.PrimaryScreen.Bounds.Height
};
ClipCursor(ref rc);
}
2. 左右鍵互換(適用左撇子模式)
// true = 互換,false = 還原
SwapMouseButton(1); // 左鍵變右鍵
SwapMouseButton(0); // 還原
3. 顯示/隱藏滑鼠游標
// ShowCursor 內部計數器:>=0 顯示,<0 隱藏
// 必須成對呼叫,否則計數器不歸零導致游標卡住
ShowCursor(0); // 隱藏(計數器 -1)
ShowCursor(1); // 顯示(計數器 +1)
// 更安全的包裝:
public void HideCursor() { while (ShowCursor(0) >= 0) ; }
public void ShowCursorSafe() { while (ShowCursor(1) < 0) ; }
4. 讀寫雙擊速度
public int GetDoubleClickSpeed() => GetDoubleClickTime(); // 預設通常 500ms
public void SetDoubleClickSpeed(int ms) => SetDoubleClickTime(ms);
⚠️ 重要注意事項
- 全域影響:以上 API 影響整個 Windows 會話,非僅限於你的應用程式。退出時務必還原(特別是
SwapMouseButton、ShowCursor)。
- 權限:
ClipCursor 在 UAC 高完整性層級下可能受限,建議應用程式以管理員身分執行或加入 app.manifest requireAdministrator。
- 多螢幕:解鎖時請使用
SystemInformation.VirtualScreen 取得所有螢幕合併範圍,而非 PrimaryScreen。
- 替代方案:若僅需在自家表單內限制滑鼠,考慮
Cursor.Clip = form.RectangleToScreen(form.ClientRectangle)(.NET 5+),純 managed 無 P/Invoke 風險。