How to get mouse position related to desktop in WPF? How to get mouse position related to desktop in WPF? wpf wpf

How to get mouse position related to desktop in WPF?


Getting the Screen Coordinates:

[DllImport("user32.dll")][return: MarshalAs(UnmanagedType.Bool)]static extern bool GetCursorPos(out POINT lpPoint);[StructLayout(LayoutKind.Sequential)]public struct POINT{    public int X;    public int Y;    public POINT(int x, int y)    {        this.X = x;        this.Y = y;    }}private void WritePoint(object sender, RoutedEventArgs e){    POINT p;    if (GetCursorPos(out p))    {        System.Console.WriteLine(Convert.ToString(p.X) + ";" + Convert.ToString(p.Y));    }}

Converting Pixels to WPF Units:

[DllImport("User32.dll")]static extern IntPtr GetDC(IntPtr hwnd);[DllImport("gdi32.dll")]static extern int GetDeviceCaps(IntPtr hdc, int nIndex);[DllImport("user32.dll")]static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);private Point ConvertPixelsToUnits(int x, int y){    // get the system DPI    IntPtr dDC = GetDC(IntPtr.Zero); // Get desktop DC    int dpi = GetDeviceCaps(dDC, 88);    bool rv = ReleaseDC(IntPtr.Zero, dDC);    // WPF's physical unit size is calculated by taking the     // "Device-Independant Unit Size" (always 1/96)    // and scaling it by the system DPI    double physicalUnitSize = (1d / 96d) * (double)dpi;    Point wpfUnits = new Point(physicalUnitSize * (double)x,        physicalUnitSize * (double)y);    return wpfUnits;          }

Putting both together:

private void WriteMouseCoordinatesInWPFUnits(){    POINT p;    if (GetCursorPos(out p))    {        Point wpfPoint = ConvertPixelsToUnits(p.X, p.Y);        System.Console.WriteLine(Convert.ToString(wpfPoint.X) + ";" + Convert.ToString(wpfPoint.Y));    }}


Two options:

Use System.Windows.Forms.Control.MousePosition, or p/invoke

[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]public static extern bool GetCursorPos([In, Out] NativeMethods.POINT pt);

The first option already does the p/invoke for you. I'm not entirely sure it requires you have some UI splashed up, but I don't think so. Yes, its winforms and not wpf, but it really doesn't have anything to do with where its located at.

If you want to skip any dependencies on system.windows.forms.dll then check out more information about the second on pinvoke.net.


I stumbled over that thread while looking for a solution for the same problem. In the meantime, I found PointToScreen, which does not require any P/Invoke. The method is available on any Visual starting .NET 3.0 (and thus UIElement, Control, etc.) and an implementation would look like this:

protected void OnMouseLeave(object Sender, MouseEventArgs e) {    var relativePosition = e.GetPosition(this);    var screenPosition = this.PointToScreen(relativePosition);}