C# WPF application .NET 4.5 Set Mouse Position

DeadJohnDoe picture DeadJohnDoe · Sep 5, 2014 · Viewed 18.1k times · Source

First time asking a question here, the solutions I found on here do not seem to work for some reason. My app needs to set the mouse position when the window becomes active, I have the function set up but cannot get cursor properties to work. I can't use Cursor.Position or anything really for some reason. I had hoped to visit the chat rooms to find a solution but apparently I cannot speak until I have 20 reputation.

So here I am asking how to change the cursor position with something like

this.Cursor.SetPosition(x, y);

Thanks for the help.

Edit: Tried this already as a test from here:

private void MoveCursor()
{
   // Set the Current cursor, move the cursor's Position, 
   // and set its clipping rectangle to the form.  

   this.Cursor = new Cursor(Cursor.Current.Handle);
   Cursor.Position = new Point(Cursor.Position.X - 50, Cursor.Position.Y - 50);
   Cursor.Clip = new Rectangle(this.Location, this.Size);
}

but the compiler complains about Current, Position, Clip, Location, Size

Final solution:

using System.Runtime.InteropServices;

...

[DllImport("User32.dll")]
private static extern bool SetCursorPos(int X, int Y);

...

Point relativePoint = MouseCaptureButton.TransformToAncestor(this)
                           .Transform(new Point(0, 0));
Point pt = new Point(relativePoint.X + MouseCaptureButton.ActualWidth / 2,
                     relativePoint.Y + MouseCaptureButton.ActualHeight / 2);
Point windowCenterPoint = pt;//new Point(125, 80);
Point centerPointRelativeToSCreen = this.PointToScreen(windowCenterPoint);
SetCursorPos((int)centerPointRelativeToSCreen.X, (int)centerPointRelativeToSCreen.Y);

Answer

B.K. picture B.K. · Sep 5, 2014

You can use InteropServices to accomplish this fairly easily:

// Quick and dirty sample...
public partial class MainWindow : Window
{
    [DllImport("User32.dll")]
    private static extern bool SetCursorPos(int X, int Y);

    public MainWindow()
    {
        InitializeComponent();
        SetCursorPos(100, 100);
    }
}

Just make sure you include System.Runtime.InteropServices namespace. There are also a lot of other ways, such as the one pointed out in the duplicate link above. Use what's best for you.

EDIT:

Per request in the comment, here's one way to make it an application window coordinate system, rather than a global one:

public partial class MainWindow : Window
{
    [DllImport("User32.dll")]
    private static extern bool SetCursorPos(int X, int Y);

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        SetCursor(200, 200);
    }

    private static void SetCursor(int x, int y)
    {
        // Left boundary
        var xL = (int)App.Current.MainWindow.Left;
        // Top boundary
        var yT = (int)App.Current.MainWindow.Top;

        SetCursorPos(x + xL, y + yT);
    }
}

I don't think you would do this... but just make sure that you don't try to get Window coordinates during the initialization phase (in the constructor). Wait until it's loaded, similarly to how I've done above; otherwise, you may get NaN for some of the values.

If you want to restrict it to the confinements of the window, an easy way would be to add System.Windows.Forms to your references and use the code provided in the duplicate link. However, if you want to use my method (all about personal preference... I use what I like... and I like PInvoke), you may check the x and y positions in SetCursor(..) prior to passing them to SetCursorPos(..), similarly to this:

private static void SetCursor(int x, int y)
{
    // Left boundary
    var xL = (int)App.Current.MainWindow.Left;
    // Right boundary
    var xR = xL + (int)App.Current.MainWindow.Width;
    // Top boundary
    var yT = (int)App.Current.MainWindow.Top;
    // Bottom boundary
    var yB = yT + (int)App.Current.MainWindow.Height;

    x += xL;
    y += yT;

    if (x < xL)
    {
        x = xL;
    }
    else if (x > xR)
    {
        x = xR;
    }

    if (y < yT)
    {
        y = yT;
    }
    else if (y > yB)
    {
        y = yB;
    }

    SetCursorPos(x, y);
}

Note that you may want to account for the border if you application uses Windows look and feel.