Prince OfThief
Prince OfThief

Reputation: 6423

How do I get the current mouse screen coordinates in WPF?

How to get current mouse coordination on the screen? I know only Mouse.GetPosition() which get mousePosition of element, but I want to get the coordination without using element.

Upvotes: 85

Views: 170691

Answers (10)

Paolo Guccini
Paolo Guccini

Reputation: 57

To get the mouse absolute coordinates (tested on dual 4K screens) in pure WPF for the current window instance ('this')

System.Windows.Point  MousePos  =  this.PointToScreen( System.Windows.Input.Mouse.GetPosition(this));

Upvotes: 0

hossein sedighian
hossein sedighian

Reputation: 2063

I wanna use this code

Point PointA;
private void Button_PreviewMouseUp(object sender, MouseButtonEventArgs e) {
    PointA = e.MouseDevice.GetPosition(sender as UIElement);
}

private void Button_Click(object sender, RoutedEventArgs e) {
    // use PointA Here
}

Upvotes: 0

Alexandru
Alexandru

Reputation: 12922

If you try a lot of these answers out on different resolutions, computers with multiple monitors, etc. you may find that they don't work reliably. This is because you need to use a transform to get the mouse position relative to the current screen, not the entire viewing area which consists of all your monitors. Something like this...(where "this" is a WPF window).

var transform = PresentationSource.FromVisual(this).CompositionTarget.TransformFromDevice;
var mouse = transform.Transform(GetMousePosition());

public System.Windows.Point GetMousePosition()
{
    var point = Forms.Control.MousePosition;
    return new Point(point.X, point.Y);
}

Upvotes: 28

Fredrik Hedblad
Fredrik Hedblad

Reputation: 84674

To follow up on Rachel's answer.
Here's two ways in which you can get Mouse Screen Coordinates in WPF.

1.Using Windows Forms. Add a reference to System.Windows.Forms

public static Point GetMousePositionWindowsForms()
{
    var point = Control.MousePosition;
    return new Point(point.X, point.Y);
}

2.Using Win32

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetCursorPos(ref Win32Point pt);

[StructLayout(LayoutKind.Sequential)]
internal struct Win32Point
{
    public Int32 X;
    public Int32 Y;
};
public static Point GetMousePosition()
{
    var w32Mouse = new Win32Point();
    GetCursorPos(ref w32Mouse);

    return new Point(w32Mouse.X, w32Mouse.Y);
}

Upvotes: 86

erikH
erikH

Reputation: 2346

Or in pure WPF use PointToScreen.

Sample helper method:

// Gets the absolute mouse position, relative to screen
Point GetMousePos() => _window.PointToScreen(Mouse.GetPosition(_window));

Upvotes: 96

Jesse Grunert
Jesse Grunert

Reputation: 31

If you're looking for a 1 liner, this does well.

new Point(Mouse.GetPosition(mWindow).X + mWindow.Left, Mouse.GetPosition(mWindow).Y + mWindow.Top)

The + mWindow.Left and + mWindow.Top makes sure the position is in the right place even when the user drags the window around.

Upvotes: 3

Fire1nRain
Fire1nRain

Reputation: 11

Mouse.GetPosition(mWindow) gives you the mouse position relative to the parameter of your choice. mWindow.PointToScreen() convert the position to a point relative to the screen.

So mWindow.PointToScreen(Mouse.GetPosition(mWindow)) gives you the mouse position relative to the screen, assuming that mWindow is a window(actually, any class derived from System.Windows.Media.Visual will have this function), if you are using this inside a WPF window class, this should work.

Upvotes: 1

Max Bender
Max Bender

Reputation: 392

You may use combination of TimerDispatcher (WPF Timer analog) and Windows "Hooks" to catch cursor position from operational system.

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool GetCursorPos(out POINT pPoint);

Point is a light struct. It contains only X, Y fields.

    public MainWindow()
    {
        InitializeComponent();

        DispatcherTimer dt = new System.Windows.Threading.DispatcherTimer();
        dt.Tick += new EventHandler(timer_tick);
        dt.Interval = new TimeSpan(0,0,0,0, 50);
        dt.Start();
    }

    private void timer_tick(object sender, EventArgs e)
    {
        POINT pnt;
        GetCursorPos(out pnt);
        current_x_box.Text = (pnt.X).ToString();
        current_y_box.Text = (pnt.Y).ToString();
    }

    public struct POINT
    {
        public int X;
        public int Y;

        public POINT(int x, int y)
        {
            this.X = x;
            this.Y = y;
        }
    }

This solution is also resolving the problem with too often or too infrequent parameter reading so you can adjust it by yourself. But remember about WPF method overload with one arg which is representing ticks not milliseconds.

TimeSpan(50); //ticks

Upvotes: 5

hemligaarne
hemligaarne

Reputation: 114

This works without having to use forms or import any DLLs:

   using System.Windows;
   using System.Windows.Input;

    /// <summary>
    /// Gets the current mouse position on screen
    /// </summary>
    private Point GetMousePosition()
    {
        // Position of the mouse relative to the window
        var position = Mouse.GetPosition(Window);

        // Add the window position
        return new Point(position.X + Window.Left, position.Y + Window.Top);
    }

Upvotes: 8

Rachel
Rachel

Reputation: 132618

Do you want coordinates relative to the screen or the application?

If it's within the application just use:

Mouse.GetPosition(Application.Current.MainWindow);

If not, I believe you can add a reference to System.Windows.Forms and use:

System.Windows.Forms.Control.MousePosition;

Upvotes: 35

Related Questions