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

ぃ、小莉子 提交于 2019-11-26 11:21:17

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()
{
    System.Drawing.Point 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()
{
    Win32Point w32Mouse = new Win32Point();
    GetCursorPos(ref w32Mouse);
    return new Point(w32Mouse.X, w32Mouse.Y);
}
erikH

Or in pure WPF use PointToScreen.

Sample helper method:

// Gets the absolute mouse position, relative to screen
Point GetMousePos(){
    return _window.PointToScreen(Mouse.GetPosition(_window))
}
Rachel

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;

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()
{
    System.Drawing.Point point = System.Windows.Forms.Control.MousePosition;
    return new System.Windows.Point(point.X, point.Y);
}
hemligaarne

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);
    }

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

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)

i add this for use with controls

   private void Control_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
 var mousepos = new List<double> { e.GetPosition(ControlName).X, e.GetPosition(ControlName).Y };

}

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!