2

Possible Duplicate:
C# moving the mouse around realistically

I am able to move the mouse as:

[DllImport("user32.dll")]
public static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);

// move relative from where the cursor is
public static void Move(int xDelta, int yDelta)
{

    mouse_event(0x0001, xDelta, yDelta, 0, 0);
}

anyways I would like to move the mouse smoothly so that the user can see it. I would like to animate it and take 1 second to move it to the new location. as a result I am looking for a method that will work as:

 public static void Move(int xDelta, int yDelta, int timeInMiliseconds)
 {
    // i will like to move the mouse to 
         (mouse.getCurentPos().x+xDelta, mouse.getCurentPos().y+yDelta) 
    // in timeInMiliseconds miliseconds

 }
Community
  • 1
  • 1
Tono Nam
  • 34,064
  • 78
  • 298
  • 470

1 Answers1

2

EDITED to support negative delta's.

That is the perfect combination of smooth and no extra calls to mouse_event.

public static void Move(int xDelta, int yDelta, int timeInMilliseconds, bool async = false)
{
    // No need to move the mouse at all.
    if (xDelta == 0 && yDelta == 0) return;

    // No need to move smoothly.
    if (timeInMilliseconds <= 0)
    {
        Move(xDelta, yDelta);
        return;
    }

    // Set direction factors and then make the delta's positive
    var xFactor = 1;
    var yFactor = 1;

    if (xDelta < 0)
    {
        xDelta *= (xFactor = -1);
    }

    if (yDelta < 0)
    {
        yDelta *= (yFactor = -1);
    }

    // Calculate the rates of a single x or y movement, in milliseconds
    // And avoid dividing by zero
    var xRate = xDelta == 0 ? -1 : (double)timeInMilliseconds / xDelta;
    var yRate = yDelta == 0 ? -1 : (double)timeInMilliseconds / yDelta;

    // Make a thread that will move the mouse in the x direction
    var xThread = new Thread(() =>
    {
        // No need to move in the x direction
        if (xDelta == 0) return;

        var sw = Stopwatch.StartNew();
        var c = 1;

        for (var i = 0; i < xDelta; i++)
        {
            // Wait for another "rate" amount of time to pass
            while (sw.ElapsedMilliseconds / xRate < c)
            {
            }

            c++;

            // Move by a single pixel (x)
            Move(xFactor, 0);
        }
    });

    // Make a thread that will move the mouse in the y direction
    var yThread = new Thread(() =>
    {
        // No need to move in the y direction
        if (yDelta == 0) return;

        var sw = Stopwatch.StartNew();
        var c = 1;

        for (var i = 0; i < yDelta; i++)
        {
            // Wait for another "rate" amount of time to pass
            while (sw.ElapsedMilliseconds / yRate < c)
            {
            }

            c++;

            // Move by a single pixel (y)
            Move(0, yFactor);
        }
    });

    // Activate the movers threads
    xThread.Start();
    yThread.Start();

    if (async)
    {
        return;
    }

    // Wait for both to end (remove this if you want it async)
    xThread.Join();
    yThread.Join();
}
SimpleVar
  • 14,044
  • 4
  • 38
  • 60
  • Thanks so much for the help. I would like for it to decelerate though. I guess I can do that maybe by decreasing the xRate and yRate. I will give it a try and accept your answer soon. – Tono Nam May 08 '12 at 00:24
  • It does not work when xDelta is negative... – Tono Nam May 08 '12 at 00:35
  • @TonoNam I also realized that. Edited to support negative delta's. – SimpleVar May 08 '12 at 00:43
  • @TonoNam If you want to decelerate, you should calculate starting rate and ending rate by some deceleration factor according to the current `xRate` - which would be the average rate for x. Then, start the actual x rate at `startXRate`, and increase rate by `(endXRate - startXRate) / xDelta)` each loop iteration (for example, after `c++`) – SimpleVar May 08 '12 at 00:47
  • ok I will try that. thanks again for the great help. this post is better than the other one hope you get more points lol – Tono Nam May 08 '12 at 00:49