C# WPF application .NET 4.5 Set Mouse Position [duplicate]
Asked Answered
F

1

7

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);
Fitted answered 5/9, 2014 at 21:26 Comment(7)
Why do you ignore error messages. Compiler complains? Read error messages reproduce them.Porism
Example: Error 1 'System.Windows.Input.Cursor' does not contain a definition for 'Current' and no extension method 'Current' accepting a first argument of type 'System.Windows.Input.Cursor' could be found (are you missing a using directive or an assembly reference?)Fitted
It's in System.Windows.Forms. As documented.Porism
My compiler does not recognize System.Windows.Forms Error 1 The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?)Fitted
Well, that's because you won't reference winforms in a wpf app. Pinvoking SetCursorPos is a sound option.Porism
Anyway, websearch helps. Try these search terms: c# set cursor position wpfPorism
I am here from the future to say that this Stackoverflow is now the top hit on Google for searching how to move the mouse in C# WPF. Thank you very much for the helpful comments saying to Google the answer instead of providing it.Nib
P
11

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.

Pori answered 5/9, 2014 at 21:32 Comment(5)
Thanks, this worked, I guess when I tried something similar to that from another answer they did not mention the required namespace. I am used to Java in Eclipse which has an auto-import feature for their libraries.Fitted
@Fitted Glad it helped, just... expand on my sample. I would definitely not write it that way for production code.Pori
So the cursor position that the above function uses is relevant to the computer's screen and not the program window? Is there a way to use the program window's coordinate system instead?Fitted
@Fitted See my edit, so that I wouldn't have to type a lot here.Pori
old thread but its important to warn new comers to make sure to add [return: MarshalAs(UnmanagedType.Bool)] underneath [DllImport("User32.dll")] , When using PInvoke to call native functions, it's important to ensure that the data types are marshaled correctly between managed and unmanaged code .Shuffleboard

© 2022 - 2024 — McMap. All rights reserved.