From 22e2fa2ac266d8f94883e69d27e16d3660afd229 Mon Sep 17 00:00:00 2001 From: Mihai Ciuraru Date: Wed, 9 Nov 2022 02:42:09 +0200 Subject: [PATCH] Convert to single-threaded --- ElegantRecorder/AutomationEngine.cs | 3 +- ElegantRecorder/ElegantRecorder.cs | 142 ++++++++++++++-------------- ElegantRecorder/WinAPI.cs | 29 ------ 3 files changed, 74 insertions(+), 100 deletions(-) diff --git a/ElegantRecorder/AutomationEngine.cs b/ElegantRecorder/AutomationEngine.cs index 4a46ee8..1d5ddaf 100644 --- a/ElegantRecorder/AutomationEngine.cs +++ b/ElegantRecorder/AutomationEngine.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Threading; -using static System.Windows.Forms.VisualStyles.VisualStyleElement; namespace ElegantRecorder { @@ -95,7 +94,7 @@ public virtual bool ReplayKeypressAction(UIAction action, ref string status) public virtual bool ReplayClipboardAction(UIAction action, ref string status) { - App.WinAPI.SetClipboardText(action.TextData); + System.Windows.Clipboard.SetText(action.TextData); return true; } diff --git a/ElegantRecorder/ElegantRecorder.cs b/ElegantRecorder/ElegantRecorder.cs index df3c6f1..b852089 100644 --- a/ElegantRecorder/ElegantRecorder.cs +++ b/ElegantRecorder/ElegantRecorder.cs @@ -3,10 +3,8 @@ using System.Diagnostics; using System.IO; using System.Text.Json; -using System.Threading; using System.Windows.Forms; using ElegantRecorder.Properties; -using System.Threading.Tasks; namespace ElegantRecorder { @@ -187,9 +185,8 @@ private void PreRecordClipboard() } } - public /*async*/ void RecordMouse(MouseHookStruct currentMouseHookStruct, MouseHookStruct prevMouseHookStruct) + public void RecordMouse(MouseHookStruct currentMouseHookStruct, MouseHookStruct prevMouseHookStruct) { - //await System.Threading.Tasks.Task.Run(() => RecordMouseWorker()); RecordMouseWorker(currentMouseHookStruct, prevMouseHookStruct); SetStatus(status); @@ -276,9 +273,6 @@ public void Record() WinAPI.InstallHooks(); } - CancellationTokenSource tokenSource = new CancellationTokenSource(); - CancellationToken token; - // Use MouseDown istead of Click event to avoid situations where other UI events happen between mouse down and up, due to the automation private void buttonStop_MouseDown(object sender, MouseEventArgs e) { @@ -289,12 +283,9 @@ public void Stop(bool paused) { WinAPI.UninstallHooks(); - stopwatch.Reset(); + replayInterrupted = true; - if (tokenSource != null) - { - tokenSource.Cancel(); - } + stopwatch.Reset(); ClearStatus(); @@ -326,7 +317,7 @@ public void Stop(bool paused) } } - private async void buttonReplay_Click(object sender, EventArgs e) + private void buttonReplay_Click(object sender, EventArgs e) { if (replaying) return; @@ -334,87 +325,100 @@ private async void buttonReplay_Click(object sender, EventArgs e) ResetButtons(); replaying = true; - buttonReplay.Image = Resources.play_edit; + replayInterrupted = false; - tokenSource.Dispose(); - tokenSource = new CancellationTokenSource(); - token = tokenSource.Token; + buttonReplay.Image = Resources.play_edit; ClearStatus(); - var task = Task.Run(ReplayWorker, token); - - try - { - await task; - } - catch (Exception) { } + Replay(); SetStatus(status); } private int currentActionIndex = 0; + private Timer replayTimer = null; + private Recording ReplayRec = null; + private bool replayInterrupted = false; - void ReplayWorker() + void Replay() { - var rec = new Recording(this, CurrentRecordingName); - rec.Load(); + ReplayRec = new Recording(this, CurrentRecordingName); + ReplayRec.Load(); - UIAction[] steps = rec.UIActions; - - if (currentActionIndex >= steps.Length - 1) + if (currentActionIndex >= ReplayRec.UIActions.Length - 1) currentActionIndex = 0; - for (int i = currentActionIndex; i < steps.Length; i++) + if (ReplayRec.UIActions.Length > 0) { - var action = steps[i]; + replayTimer = new Timer(); + replayTimer.Tick += ReplayTimer_Tick; + PlayAction(); + } + } - currentActionIndex = i; + private void PlayAction() + { + if (replayInterrupted) + { + replayTimer.Stop(); + SetStatus("Replay interrupted"); + return; + } - if (action.elapsed != null) - { - Thread.Sleep((int)ElegantOptions.GetPlaybackSpeedDuration(rec.PlaybackSpeed, (double)action.elapsed)); - } + var action = ReplayRec.UIActions[currentActionIndex]; - try - { - token.ThrowIfCancellationRequested(); - } - catch (OperationCanceledException) - { - status = "Replay interrupted"; - return; - } + if (action.EventType == "click") + { + AutomationEngine.ReplayClickAction(action, ref status); + } + else if (action.EventType == "mousemove") + { + AutomationEngine.ReplayMouseMoveAction(action, ref status); + } + else if (action.EventType == "mousewheel") + { + AutomationEngine.ReplayMouseWheelAction(action, ref status); + } + else if (action.EventType == "keypress") + { + AutomationEngine.ReplayKeypressAction(action, ref status); + } + else if (action.EventType == "clipboard") + { + AutomationEngine.ReplayClipboardAction(action, ref status); + } + else if (action.EventType == "mousepath") + { + AutomationEngine.ReplayMousePathAction(action, ReplayRec.PlaybackSpeed, ref status); + } - if (action.EventType == "click") - { - AutomationEngine.ReplayClickAction(action, ref status); - } - else if (action.EventType == "mousemove") - { - AutomationEngine.ReplayMouseMoveAction(action, ref status); - } - else if (action.EventType == "mousewheel") - { - AutomationEngine.ReplayMouseWheelAction(action, ref status); - } - else if (action.EventType == "keypress") - { - AutomationEngine.ReplayKeypressAction(action, ref status); - } - else if (action.EventType == "clipboard") + if (currentActionIndex < ReplayRec.UIActions.Length - 1) + { + currentActionIndex++; + + if (ReplayRec.UIActions[currentActionIndex].elapsed != null && ReplayRec.UIActions[currentActionIndex].elapsed != 0) { - AutomationEngine.ReplayClipboardAction(action, ref status); + replayTimer.Interval = (int)ElegantOptions.GetPlaybackSpeedDuration(ReplayRec.PlaybackSpeed, (double)ReplayRec.UIActions[currentActionIndex].elapsed); + replayTimer.Start(); } - else if (action.EventType == "mousepath") + else { - AutomationEngine.ReplayMousePathAction(action, rec.PlaybackSpeed, ref status); + PlayAction(); } } + else + { + replayTimer.Stop(); + SetStatus("Replay finished"); + ResetButtons(); + } + } - status = "Replay finished"; - - ResetButtons(); + private void ReplayTimer_Tick(object? sender, EventArgs e) + { + replayTimer.Stop(); + PlayAction(); } private void buttonSettings_Click(object sender, EventArgs e) diff --git a/ElegantRecorder/WinAPI.cs b/ElegantRecorder/WinAPI.cs index adeb113..b43410a 100644 --- a/ElegantRecorder/WinAPI.cs +++ b/ElegantRecorder/WinAPI.cs @@ -104,8 +104,6 @@ public WinAPI(ElegantRecorder App) private const int WM_CLIPBOARDUPDATE = 0x031D; - private const int CF_UNICODETEXT = 13; - [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelHookProc lpfn, IntPtr hMod, uint dwThreadId); @@ -154,18 +152,6 @@ public WinAPI(ElegantRecorder App) [return: MarshalAs(UnmanagedType.Bool)] static extern bool RemoveClipboardFormatListener(IntPtr hwnd); - [DllImport("user32.dll", SetLastError = true)] - static extern bool OpenClipboard(IntPtr hWndNewOwner); - - [DllImport("user32.dll", SetLastError = true)] - static extern bool CloseClipboard(); - - [DllImport("user32.dll")] - static extern bool EmptyClipboard(); - - [DllImport("user32.dll")] - static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem); - [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool RegisterHotKey(IntPtr hWnd, int id, KeyModifiers fsModifiers, Keys vk); @@ -176,7 +162,6 @@ public WinAPI(ElegantRecorder App) private LowLevelHookProc mouseDelegate = null; private LowLevelHookProc keyboardDelegate = null; - public MouseHookStruct CurrentMouseHookStruct; public MouseHookStruct PrevMouseHookStruct; public KeyboardHookStruct KeyboardHookStruct; @@ -382,20 +367,6 @@ public bool ProcessClipboardMessage(int message, ref string clipboardText) return false; } - public void SetClipboardText(string text) - { - //string nullTerminatedStr = text + "\0"; - - //byte[] strBytes = Encoding.Unicode.GetBytes(nullTerminatedStr); - //IntPtr hglobal = Marshal.AllocHGlobal(strBytes.Length); - //Marshal.Copy(strBytes, 0, hglobal, strBytes.Length); - //OpenClipboard(IntPtr.Zero); - //EmptyClipboard(); - //SetClipboardData(CF_UNICODETEXT, hglobal); - //CloseClipboard(); - //Marshal.FreeHGlobal(hglobal); - } - public static void GetModifiers(Keys keydata, out Keys key, out KeyModifiers modifers) { key = keydata;