diff --git a/new/AutoItInterpreter/AutoItInterpreter.csproj b/new/AutoItInterpreter/AutoItInterpreter.csproj index aed0d9e..7265c71 100644 --- a/new/AutoItInterpreter/AutoItInterpreter.csproj +++ b/new/AutoItInterpreter/AutoItInterpreter.csproj @@ -1,9 +1,10 @@ Exe - net8.0 + net8.0-windows true preview + true enable @@ -14,7 +15,7 @@ Unknown6656.AutoIt3 false - true + false true false Auto diff --git a/new/AutoItInterpreter/Runtime/Interpreter.cs b/new/AutoItInterpreter/Runtime/Interpreter.cs index b3c716e..f54ba1e 100644 --- a/new/AutoItInterpreter/Runtime/Interpreter.cs +++ b/new/AutoItInterpreter/Runtime/Interpreter.cs @@ -85,11 +85,11 @@ public sealed class Interpreter /// public bool IsCOMAvailable => COMConnector is { }; - //public WinAPIConnector? Win32APIConnector { get; } + public WinAPIConnector? Win32APIConnector { get; } - //public GUIConnector GUIConnector { get; } + public GUIConnector GUIConnector { get; } - //public bool IsWin32APIAvailable => Win32APIConnector is { }; + public bool IsWin32APIAvailable => Win32APIConnector is { }; /// /// The interpreter's script scanner and caching unit. @@ -177,10 +177,10 @@ public Interpreter(CommandLineOptions opt, Telemetry telemetry, LanguageLoader l if (NativeInterop.OperatingSystem is OS.Windows) { COMConnector = new COMConnector(this); - //Win32APIConnector = new WinAPIConnector(this); + Win32APIConnector = new WinAPIConnector(this); } - //GUIConnector = new GUIConnector(this); + GUIConnector = new GUIConnector(this); Random = new BuiltinRandom(); ResetRandom(); @@ -213,9 +213,9 @@ public void Dispose() _threads.Dispose(); GlobalObjectStorage.Dispose(); - // GUIConnector.Dispose(); + GUIConnector.Dispose(); COMConnector?.Dispose(); - //Win32APIConnector?.Dispose(); + Win32APIConnector?.Dispose(); _instances.Remove(this); } diff --git a/new/AutoItInterpreter/Runtime/NativeInterop.cs b/new/AutoItInterpreter/Runtime/NativeInterop.cs index 8baf95f..67ade0d 100644 --- a/new/AutoItInterpreter/Runtime/NativeInterop.cs +++ b/new/AutoItInterpreter/Runtime/NativeInterop.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using System; +using System.Drawing; namespace Unknown6656.AutoIt3.Runtime.Native; @@ -113,6 +114,31 @@ public static class NativeInterop [DllImport(USER32_DLL, CharSet = CharSet.Auto)] public static extern nint SendMessage(nint hWnd, int Msg, nint wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam); + [DllImport("User32.Dll")] + public static extern long SetCursorPos(int x, int y); + + [DllImport("User32.Dll")] + public static extern bool ClientToScreen(IntPtr hWnd, ref POINT point); + + [DllImport("user32.dll", SetLastError = false)] + public static extern IntPtr GetDesktopWindow(); + + [DllImport(USER32_DLL)] + public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, UIntPtr dwExtraInfo); + + [StructLayout(LayoutKind.Sequential)] + public struct POINT + { + public int x; + public int y; + + public POINT(int X, int Y) + { + x = X; + y = Y; + } + } + #endregion #region SHELL32.DLL diff --git a/new/plugins/Plugin.Au3Framework.WindowsSpecific/WindowsSpecificFunctions.cs b/new/plugins/Plugin.Au3Framework.WindowsSpecific/WindowsSpecificFunctions.cs index 3e90040..1ef8990 100644 --- a/new/plugins/Plugin.Au3Framework.WindowsSpecific/WindowsSpecificFunctions.cs +++ b/new/plugins/Plugin.Au3Framework.WindowsSpecific/WindowsSpecificFunctions.cs @@ -1,6 +1,7 @@ using System.Windows.Forms; using System.IO; using System; +using System.Threading; using Unknown6656.Mathematics; using Unknown6656.Generics; @@ -8,6 +9,11 @@ using Unknown6656.AutoIt3.Extensibility; using Unknown6656.AutoIt3.Runtime.Native; using Unknown6656.AutoIt3.Runtime; +using System.Drawing; +using static Microsoft.FSharp.Core.ByRefKinds; +using Microsoft.FSharp.Core; +using System.Diagnostics.Eventing.Reader; +//using Plugin.Au3Framework.WindowsSpecific; [assembly: AutoIt3Plugin] @@ -29,6 +35,12 @@ public WindowsSpecificFunctions(Interpreter interpreter) RegisterFunction(nameof(GUICreate), 1, 8, GUICreate, Variant.Default, Variant.Default, -1, -1, -1, -1, Variant.Zero); + + RegisterFunction(nameof(MouseGetPos), 0, 1, MouseGetPos, OS.Windows); + RegisterFunction(nameof(MouseMove), 2, 3, MouseMove, OS.Windows); + RegisterFunction(nameof(MouseClick), 1, 5, MouseClick, OS.Windows); + RegisterFunction(nameof(MouseDown), 1, MouseDown, OS.Windows); + RegisterFunction(nameof(MouseUp), 1, MouseUp, OS.Windows); } private static FunctionReturnValue ClipGet(CallFrame frame, Variant[] args) @@ -212,6 +224,154 @@ private static FunctionReturnValue GUICreate(CallFrame frame, Variant[] args) //{ //} + // TODO relative coords + private static FunctionReturnValue MouseGetPos(CallFrame frame, Variant[] args) + { + Point pos = new Point(Cursor.Position.X, Cursor.Position.Y); + if (args[0].IsNull) + return Variant.FromArray(frame.Interpreter, pos.X, pos.Y); + else if (args[0] == 0) + return Variant.FromNumber(pos.X); + else if (args[0] == 1) + return Variant.FromNumber(pos.Y); + else + return FunctionReturnValue.Error(1); + } + + private static FunctionReturnValue MouseMove(CallFrame frame, Variant[] args) + { + // TODO if args.length is 3, move mouse at the given speed. Create thread? + if (args[0].Type is VariantType.Number && args[1].Type is VariantType.Number) + { + Cursor.Position = new Point((int)args[0].ToNumber(), (int)args[1].ToNumber()); + /* + NativeInterop.POINT p = new NativeInterop.POINT((int)args[0].ToNumber(), (int)args[1].ToNumber()); + IntPtr desktopWinHandle = NativeInterop.GetDesktopWindow(); + NativeInterop.ClientToScreen(desktopWinHandle, ref p); + NativeInterop.SetCursorPos(p.x, p.y); + */ + return FunctionReturnValue.Success(1); + } + return FunctionReturnValue.Error(1); + } + + private const UInt32 MOUSEEVENTF_MOVE = 0x0001; + private const UInt32 MOUSEEVENTF_LEFTDOWN = 0x0002; + private const UInt32 MOUSEEVENTF_LEFTUP = 0x0004; + private const UInt32 MOUSEEVENTF_MIDDLEDOWN = 0x0020; + private const UInt32 MOUSEEVENTF_MIDDLEUP = 0x0040; + private const UInt32 MOUSEEVENTF_RIGHTDOWN = 0x0008; + private const UInt32 MOUSEEVENTF_RIGHTUP = 0x0010; + private const UInt32 MOUSEEVENTF_ABSOLUTE = 0x8000; + + // TODO implement MouseClickDownDelay (Option) to set time between down and up + private static FunctionReturnValue MouseClick(CallFrame frame, Variant[] args) + { + // TODO if args.length is 5, specify speed? Of movement? + UInt32 button;// = MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP; + uint x; + uint y; + int repetitions; + + if (string.Equals(args[0].ToString(), "middle", StringComparison.InvariantCultureIgnoreCase)) + { + button = MOUSEEVENTF_MIDDLEDOWN | MOUSEEVENTF_MIDDLEUP; + } + else if (string.Equals(args[0].ToString(), "right", StringComparison.InvariantCultureIgnoreCase)) + { + button = MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP; + } + else if (string.Equals(args[0].ToString(), "left", StringComparison.InvariantCultureIgnoreCase)) + { + button = MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP; + } + else { + return FunctionReturnValue.Error(1); + } + + + if (args[1].IsNull) + x = (uint)Cursor.Position.X; + else + x = (uint)(args[1].ToNumber()); + + if (args[2].IsNull) + y = (uint)Cursor.Position.Y; + else + y = (uint)(args[2].ToNumber()); + + if (args[3].IsNull) + repetitions = 1; + else + repetitions = (int)(args[3].ToNumber()); + + Cursor.Position = new Point((int)x, (int)y); + for (int t = 0; t < repetitions; t++) + { + // MOUSEEVENTF_ABSOLUTE needs to do the 65560/screenwidth * x thing + // without, MOUSEEVENT_MOVE seems to do in pixels (relative) + NativeInterop.mouse_event(button, x, y, 0, 0); + Thread.Sleep(100); + } + return FunctionReturnValue.Success(1); + } + + private static FunctionReturnValue MouseDown(CallFrame frame, Variant[] args) + { + UInt32 button; + uint x = (uint)Cursor.Position.X; + uint y = (uint)Cursor.Position.Y; + + if (string.Equals(args[0].ToString(), "middle", StringComparison.InvariantCultureIgnoreCase)) + { + button = MOUSEEVENTF_MIDDLEDOWN; + } + else if (string.Equals(args[0].ToString(), "right", StringComparison.InvariantCultureIgnoreCase)) + { + button = MOUSEEVENTF_RIGHTDOWN; + } + else if (string.Equals(args[0].ToString(), "left", StringComparison.InvariantCultureIgnoreCase)) + { + button = MOUSEEVENTF_LEFTDOWN; + } + else + { + return FunctionReturnValue.Error(1); + } + + + NativeInterop.mouse_event(button, x, y, 0, 0); + return FunctionReturnValue.Success(1); + } + + private static FunctionReturnValue MouseUp(CallFrame frame, Variant[] args) + { + UInt32 button; + uint x = (uint)Cursor.Position.X; + uint y = (uint)Cursor.Position.Y; + + if (string.Equals(args[0].ToString(), "middle", StringComparison.InvariantCultureIgnoreCase)) + { + button = MOUSEEVENTF_MIDDLEUP; + } + else if (string.Equals(args[0].ToString(), "right", StringComparison.InvariantCultureIgnoreCase)) + { + button = MOUSEEVENTF_RIGHTUP; + } + else if (string.Equals(args[0].ToString(), "left", StringComparison.InvariantCultureIgnoreCase)) + { + button = MOUSEEVENTF_LEFTUP; + } + else + { + return FunctionReturnValue.Error(1); + } + + + NativeInterop.mouse_event(button, x, y, 0, 0); + return FunctionReturnValue.Success(1); + } + public sealed class WindowWrapper : IWin32Window {