You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
259 lines
7.2 KiB
259 lines
7.2 KiB
1 year ago
|
// This script can be used to control the system mouse - position of the mouse cursor and clicks
|
||
|
// Author: Akhmad Makhsadov
|
||
|
//
|
||
|
|
||
|
using UnityEngine;
|
||
|
using System.Collections;
|
||
|
using System.Runtime.InteropServices;
|
||
|
using System;
|
||
|
|
||
|
public class MouseControl
|
||
|
{
|
||
|
// Import function mouse_event() from WinApi
|
||
|
[DllImport("User32.dll")]
|
||
|
private static extern void mouse_event(MouseFlags dwFlags, int dx, int dy, int dwData, System.UIntPtr dwExtraInfo);
|
||
|
|
||
|
// Flags needed to specify the mouse action
|
||
|
[System.Flags]
|
||
|
private enum MouseFlags
|
||
|
{
|
||
|
Move = 0x0001,
|
||
|
LeftDown = 0x0002,
|
||
|
LeftUp = 0x0004,
|
||
|
RightDown = 0x0008,
|
||
|
RightUp = 0x0010,
|
||
|
Absolute = 0x8000,
|
||
|
}
|
||
|
|
||
|
// public static int MouseXSpeedCoef = 45000; // Cursor rate in Х direction
|
||
|
// public static int MouseYSpeedCoef = 45000; // Cursor rate in Y direction
|
||
|
|
||
|
[StructLayout(LayoutKind.Sequential)]
|
||
|
public struct RECT
|
||
|
{
|
||
|
public int Left; // x position of upper-left corner
|
||
|
public int Top; // y position of upper-left corner
|
||
|
public int Right; // x position of lower-right corner
|
||
|
public int Bottom; // y position of lower-right corner
|
||
|
}
|
||
|
|
||
|
[DllImport("user32.dll")]
|
||
|
//[return: MarshalAs(UnmanagedType.Bool)]
|
||
|
static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
|
||
|
|
||
|
[DllImport("user32.dll")]
|
||
|
static extern IntPtr GetActiveWindow();
|
||
|
|
||
|
enum GetWindow_Cmd : uint
|
||
|
{
|
||
|
GW_HWNDFIRST = 0,
|
||
|
GW_HWNDLAST = 1,
|
||
|
GW_HWNDNEXT = 2,
|
||
|
GW_HWNDPREV = 3,
|
||
|
GW_OWNER = 4,
|
||
|
GW_CHILD = 5,
|
||
|
GW_ENABLEDPOPUP = 6
|
||
|
}
|
||
|
|
||
|
[DllImport("user32.dll", SetLastError = true)]
|
||
|
static extern IntPtr GetWindow(IntPtr hWnd, GetWindow_Cmd uCmd);
|
||
|
|
||
|
const int MONITOR_DEFAULTTONULL = 0;
|
||
|
const int MONITOR_DEFAULTTOPRIMARY = 1;
|
||
|
const int MONITOR_DEFAULTTONEAREST = 2;
|
||
|
|
||
|
[DllImport("user32.dll")]
|
||
|
static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags);
|
||
|
|
||
|
[StructLayout(LayoutKind.Sequential)]
|
||
|
private struct MONITORINFO
|
||
|
{
|
||
|
public int cbSize;
|
||
|
public RECT rcMonitor;
|
||
|
public RECT rcWork;
|
||
|
public uint dwFlags;
|
||
|
}
|
||
|
|
||
|
[DllImport("user32.dll")]
|
||
|
static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
|
||
|
|
||
|
|
||
|
// private static int windowX = 0;
|
||
|
// private static int windowY = 0;
|
||
|
// private static int winSizeX = 0;
|
||
|
// private static int winSizeY = 0;
|
||
|
|
||
|
private static Vector2 monitorSize = Vector2.zero;
|
||
|
private static MONITORINFO monitorInfo = new MONITORINFO();
|
||
|
private static bool winRectPrinted = false;
|
||
|
|
||
|
|
||
|
// Public function to move the mouse cursor to the specified position
|
||
|
public static void MouseMove(Vector3 screenCoordinates, UnityEngine.UI.Text debugText)
|
||
|
{
|
||
|
int windowX = 0;
|
||
|
int windowY = 0;
|
||
|
int winSizeX = 0;
|
||
|
int winSizeY = 0;
|
||
|
|
||
|
bool isConvertToFullScreen = Screen.fullScreen;
|
||
|
|
||
|
IntPtr hWnd = GetActiveWindow();
|
||
|
hWnd = GetClosestWindow(hWnd, Screen.width, Screen.height);
|
||
|
|
||
|
if (hWnd != IntPtr.Zero)
|
||
|
{
|
||
|
RECT winRect;
|
||
|
|
||
|
if (GetWindowRect(hWnd, out winRect))
|
||
|
{
|
||
|
winSizeX = winRect.Right - winRect.Left;
|
||
|
winSizeY = winRect.Bottom - winRect.Top;
|
||
|
|
||
|
windowX = winRect.Left + (winSizeX - (int)Screen.width) / 2;
|
||
|
|
||
|
if (!isConvertToFullScreen)
|
||
|
{
|
||
|
windowY = winRect.Top + (winSizeY - (int)Screen.height + 36) / 2;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
windowY = winRect.Top + (winSizeY - (int)Screen.height) / 2;
|
||
|
}
|
||
|
|
||
|
// get display resolution
|
||
|
if (monitorSize == Vector2.zero)
|
||
|
{
|
||
|
monitorInfo.cbSize = Marshal.SizeOf (monitorInfo);
|
||
|
|
||
|
IntPtr hMonitoŕ = MonitorFromWindow (hWnd, MONITOR_DEFAULTTONEAREST);
|
||
|
if (!GetMonitorInfo (hMonitoŕ, ref monitorInfo))
|
||
|
{
|
||
|
monitorInfo.rcMonitor.Left = monitorInfo.rcMonitor.Top = 0;
|
||
|
monitorInfo.rcMonitor.Right = Screen.currentResolution.width - 1;
|
||
|
monitorInfo.rcMonitor.Bottom = Screen.currentResolution.height - 1;
|
||
|
|
||
|
monitorInfo.rcWork.Left = monitorInfo.rcWork.Top = 0;
|
||
|
monitorInfo.rcWork.Right = Screen.currentResolution.width - 1;
|
||
|
monitorInfo.rcWork.Bottom = Screen.currentResolution.height - 1;
|
||
|
}
|
||
|
|
||
|
monitorSize.x = monitorInfo.rcMonitor.Right - monitorInfo.rcMonitor.Left + 1;
|
||
|
monitorSize.y = monitorInfo.rcMonitor.Bottom - monitorInfo.rcMonitor.Top + 1;
|
||
|
}
|
||
|
|
||
|
if (!winRectPrinted)
|
||
|
{
|
||
|
Debug.Log (string.Format ("monSize: ({0}, {1})", monitorSize.x, monitorSize.y));
|
||
|
Debug.Log (string.Format ("scrSize: ({0}, {1})", Screen.width, Screen.height));
|
||
|
Debug.Log (string.Format ("winRect: ({0}, {1}, {2}, {3})", winRect.Left, winRect.Top, winRect.Right, winRect.Bottom));
|
||
|
Debug.Log (string.Format ("winPos: ({0}, {1})", windowX, windowY));
|
||
|
winRectPrinted = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (monitorSize == Vector2.zero)
|
||
|
{
|
||
|
monitorSize.x = Screen.currentResolution.width;
|
||
|
monitorSize.y = Screen.currentResolution.height;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int mouseX = 0;
|
||
|
int mouseY = 0;
|
||
|
|
||
|
if(!isConvertToFullScreen)
|
||
|
{
|
||
|
float screenX = windowX + screenCoordinates.x * Screen.width;
|
||
|
float screenY = windowY + (1f - screenCoordinates.y) * Screen.height;
|
||
|
|
||
|
float screenRelX = screenX / monitorSize.x;
|
||
|
float screenRelY = screenY / monitorSize.y;
|
||
|
|
||
|
// if(debugText)
|
||
|
// {
|
||
|
// if(!debugText.text.Contains("ScrPos"))
|
||
|
// {
|
||
|
// string sDebug = string.Format("\nScrPos: ({0:F0}, {1:F0})", screenX, screenY);
|
||
|
// debugText.text += sDebug;
|
||
|
// //Debug.Log (sDebug);
|
||
|
// }
|
||
|
// }
|
||
|
|
||
|
mouseX = (int)(screenRelX * 65535);
|
||
|
mouseY = (int)(screenRelY * 65535);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
mouseX = (int)(screenCoordinates.x * 65535);
|
||
|
mouseY = (int)((1f - screenCoordinates.y) * 65535);
|
||
|
}
|
||
|
|
||
|
mouse_event(MouseFlags.Absolute | MouseFlags.Move, mouseX, mouseY, 0, System.UIntPtr.Zero);
|
||
|
}
|
||
|
|
||
|
// find the closest matching child window to the screen size
|
||
|
private static IntPtr GetClosestWindow(IntPtr hWndMain, int scrWidth, int scrHeight)
|
||
|
{
|
||
|
if(hWndMain == IntPtr.Zero)
|
||
|
return hWndMain;
|
||
|
|
||
|
IntPtr hWnd = hWndMain;
|
||
|
RECT winRect;
|
||
|
|
||
|
if(GetWindowRect(hWndMain, out winRect))
|
||
|
{
|
||
|
int winSizeX = winRect.Right - winRect.Left;
|
||
|
int winSizeY = winRect.Bottom - winRect.Top;
|
||
|
int winDiff = Math.Abs(winSizeX - scrWidth) + Math.Abs(winSizeY - scrHeight);
|
||
|
|
||
|
IntPtr hWndChild = GetWindow(hWndMain, GetWindow_Cmd.GW_CHILD);
|
||
|
int winDiffMin = winDiff;
|
||
|
|
||
|
while(hWndChild != IntPtr.Zero)
|
||
|
{
|
||
|
if(GetWindowRect(hWndChild, out winRect))
|
||
|
{
|
||
|
winSizeX = winRect.Right - winRect.Left;
|
||
|
winSizeY = winRect.Bottom - winRect.Top;
|
||
|
winDiff = Math.Abs(winSizeX - scrWidth) + Math.Abs(winSizeY - scrHeight - 36);
|
||
|
|
||
|
if(scrWidth <= winSizeX && scrHeight <= winSizeY && winDiff <= winDiffMin)
|
||
|
{
|
||
|
hWnd = hWndChild;
|
||
|
winDiffMin = winDiff;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
hWndChild = GetWindow(hWndChild, GetWindow_Cmd.GW_HWNDNEXT);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hWnd;
|
||
|
}
|
||
|
|
||
|
// Public function to emulate a mouse button click (left button)
|
||
|
public static void MouseClick()
|
||
|
{
|
||
|
mouse_event(MouseFlags.LeftDown, 0, 0, 0, System.UIntPtr.Zero);
|
||
|
mouse_event(MouseFlags.LeftUp, 0, 0, 0, System.UIntPtr.Zero);
|
||
|
}
|
||
|
|
||
|
// Public function to emulate a mouse drag event (left button)
|
||
|
public static void MouseDrag()
|
||
|
{
|
||
|
mouse_event(MouseFlags.LeftDown, 0, 0, 0, System.UIntPtr.Zero);
|
||
|
}
|
||
|
|
||
|
// Public function to emulate a mouse release event (left button)
|
||
|
public static void MouseRelease()
|
||
|
{
|
||
|
mouse_event(MouseFlags.LeftUp, 0, 0, 0, System.UIntPtr.Zero);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|