имитировать перемещение курсора мыши в С# между двумя координатами

Я пытаюсь программно перемещать мышь между двумя координатами. Но я хочу надежно поддерживать скорость на всех быстрых или медленных машинах. Я видел эту ссылку здесь. Но это не гарантирует мне оптимальную, плавную и видимую скорость движения курсора при моделировании перемещения между двумя координатами. Интересно, знает ли кто-нибудь трюк для определения таких параметров, как задержка и оптимальное значение шагов для различных машин? Моя первая идея заключалась в том, чтобы использовать цикл for для конкретной итерации, чтобы определить производительность машины, а затем оценить параметры в зависимости от того, сколько времени for -петля взяла ...идею? или я совершенно не прав в этом? Спасибо


person Deku    schedule 05.05.2011    source источник


Ответы (3)


Вы должны сделать движение функцией времени. Начиная с ответа на C# реалистично перемещает мышь, и используя класс Stopwatch для измерения прошедшего времени:

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);
}
person Justin    schedule 05.05.2011
comment
это выглядит хорошо, но я не мог ухватиться за еще более медленную скорость с этим алгоритмом. Это просто становится мгновенным. я использовал разные значения Timespan и задержки, чтобы измерить его. - person Deku; 06.05.2011
comment
@Deku - я видел, что ты принял ответ через час или два после своего комментария. Вы поняли, что было не так? Я не тестировал этот код; нужны ли были какие-то изменения? - person Justin; 06.05.2011
comment
.. Я дал ответ, потому что это лучшее решение. Но точно не ответил на мой вопрос по вышеуказанному вопросу. Вот код для его проверки. - person Deku; 06.05.2011
comment
Где определяется iterPoint? - person gonzobrains; 08.03.2013
comment
@gonzobrains: Это должно было быть curPoint повсюду - исправлено. - person Justin; 08.03.2013
comment
округление PointF делает это негладким или вызывает неточность в движении мыши? - person gonzobrains; 08.03.2013
comment
@gonzobrains - я не думаю, что так должно быть, поскольку округленное значение используется только для SetCursorPosition; значение curPoint не меняется после вызова Point.Round. - person Justin; 11.03.2013

Я бы порекомендовал немного физики. Скорость это расстояние делённое на время. Если вам нужна постоянная скорость мыши на каждой машине, вы должны получить точное время.

Сделаем пример:

Вы хотите переместить мышь из точки 0/0 в точку 400/600, и конечная точка всегда должна быть достигнута через 3 секунды.

Поэтому вам нужно сохранить время начала и построить цикл while, который завершится во время начала + 3 с. В цикле вы вычисляете координаты X и Y по прошедшему и общему времени.

X = 400 / 3s * ElapsedTime
Y = 600 / 3s * ElapsedTime

Это будет независимо от машины. Для хорошего результата вы должны использовать высокоточное время, например Секундомер.

person Matthias Alleweldt    schedule 05.05.2011

Я попробовал этот, но все еще не оптимален. Это все еще зависит от вычислительной мощности машины. @ Джастин, используйте другое значение для продолжительности и времени ожидания. Дайте мне знать, если вы найдете лучшее решение после того, как протестировали его. Спасибо!

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();
        }       
    }
}
person Deku    schedule 06.05.2011