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);
DeadJohnDoe
  • 103
  • 1
  • 1
  • 7
  • Why do you ignore error messages. Compiler complains? Read error messages reproduce them. – David Heffernan Sep 05 '14 at 21:34
  • 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?) – DeadJohnDoe Sep 05 '14 at 22:01
  • It's in System.Windows.Forms. As documented. – David Heffernan Sep 05 '14 at 22:02
  • 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?) – DeadJohnDoe Sep 05 '14 at 22:04
  • Well, that's because you won't reference winforms in a wpf app. Pinvoking SetCursorPos is a sound option. – David Heffernan Sep 05 '14 at 22:06
  • 1
    Anyway, websearch helps. Try these search terms: *c# set cursor position wpf* – David Heffernan Sep 05 '14 at 22:11
  • 2
    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. – Luke Dec 11 '20 at 09:26

1 Answers1

10

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.

B.K.
  • 9,982
  • 10
  • 73
  • 105
  • 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. – DeadJohnDoe Sep 05 '14 at 21:37
  • @DeadJohnDoe Glad it helped, just... expand on my sample. I would definitely not write it that way for production code. – B.K. Sep 05 '14 at 21:43
  • 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? – DeadJohnDoe Sep 05 '14 at 21:58
  • @DeadJohnDoe See my edit, so that I wouldn't have to type a lot here. – B.K. Sep 06 '14 at 00:07