I am trying to move mouse programatically between two coordinates. But I want to maintain the speed reliably on all fast or slow processing machines. I saw this link here. But it doesn't gurantee me the optimum, smooth, and visible speed of the cursor when simulating the move between two coordinates. I wonder if anyone knows a trick to determine the parameters like delay and steps optimum value for various machines Like my first idea was use for-loop for specific iteraton to determine the perfomance of the machine then grade the parameters based on how much time the for-loop took ...an idea? or Am i totally wrong on this? Thanks
3 Answers
You should make the motion a function of time. Starting with the answer at C# moving the mouse around realistically, and using the Stopwatch class to measure the elapsed time:
public void LinearSmoothMove(Point newPosition, TimeSpan duration)
{
Point start = GetCursorPosition();
// Find the vector between start and newPosition
double deltaX = newPosition.X - start.X;
double deltaY = newPosition.Y - start.Y;
// start a timer
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
double timeFraction = 0.0;
do
{
timeFraction = (double)stopwatch.Elapsed.Ticks / duration.Ticks;
if (timeFraction > 1.0)
timeFraction = 1.0;
PointF curPoint = new PointF(start.X + timeFraction * deltaX,
start.Y + timeFraction * deltaY);
SetCursorPosition(Point.Round(curPoint));
Thread.Sleep(20);
} while (timeFraction < 1.0);
}
-
this looks good but i couldn't grab on even slower speed with this algorithm. It just becomes instantaneous. i used different Timespan and delay values to measure it up. – Deku May 05 '11 at 21:27
-
@Deku - I saw you accepted the answer an hour or two after your comment. Did you figure out what was wrong? I didn't test this code; did it need any changes? – Justin May 06 '11 at 15:12
-
.. I gave it an Answer because it is a better solution. But didn't exactly answer my question for the above question.Here is the code to test it. – Deku May 06 '11 at 17:40
-
Where is iterPoint defined? – gonzobrains Mar 08 '13 at 03:14
-
@gonzobrains: It should have been `curPoint` throughout -- fixed. – Justin Mar 08 '13 at 12:20
-
does rounding off the PointF make this look unsmooth or cause inaccuracy in the mouse movement? – gonzobrains Mar 08 '13 at 19:24
-
@gonzobrains - I don't think it should, since the rounded value is only used for `SetCursorPosition`; the value of `curPoint` is unchanged after calling `Point.Round`. – Justin Mar 11 '13 at 11:48
I would recommend some physics. Speed is distance divided by time. If you want a consant mouse speed on every machine you have to get an accurate time.
Let's make an example:
You want to move the mouse from point 0/0 to 400/600 and the endpoint should always be reached after 3 seconds.
Therfore you have to save the start time and build a while loop wich will end at starttime + 3s. In the loop you calculate the X and Y coordinates from the elapsed and the total time.
X = 400 / 3s * ElapsedTime
Y = 600 / 3s * ElapsedTime
This will be machine independ. For a good result you should use a high accurate time like Stopwatch.

- 2,453
- 17
- 16
I tried this one but still not optimum. It still varies with the machine processing power.@Justin, use a different value for duration and sleep time. Let me know if you come up with a better solution after you tested it.Thanks!
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
namespace ConsoleApplication11
{
class Program
{
[DllImport("user32.dll")]
static extern bool SetCursorPos(int X, int Y);
public static void LinearSmoothMove(Point newPosition, TimeSpan duration)
{
Point start = Cursor.Position;
int sleep = 10;
//PointF iterPoint = start;
// Find the vector between start and newPosition
double deltaX = newPosition.X - start.X;
double deltaY = newPosition.Y - start.Y;
// start a timer
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
double timeFraction = 0.0;
do
{
timeFraction = (double)stopwatch.Elapsed.Ticks / duration.Ticks;
if (timeFraction > 1.0)
timeFraction = 1.0;
PointF curPoint = new PointF((float)(start.X + timeFraction * deltaX), (float)(start.Y + timeFraction * deltaY));
SetCursorPos(Point.Round(curPoint).X, Point.Round(curPoint).Y);
Thread.Sleep(sleep);
} while (timeFraction < 1.0);
}
static void Main(string[] args)
{
TimeSpan delayt = new TimeSpan(0, 0, 3);
LinearSmoothMove(new Point(20, 40), delayt);
Console.Read();
}
}
}

- 129
- 4
- 11