Wie erhalte ich die aktuellen Mausbildschirmkoordinaten in WPF?

74

Wie erhalte ich die aktuelle Mauskoordination auf dem Bildschirm? Ich weiß nur, Mouse.GetPosition()welche mousePosition des Elements erhalten, aber ich möchte die Koordination ohne Verwendung des Elements erhalten.

Prinz des Diebes
quelle
Mauskoordinaten relativ zu was? Bildschirmkoordinaten relativ zu einem Fenster?
Fredrik Hedblad
3
Ich meine Mausposition auf dem Bildschirm.
Prince OfThief
System.Windows.Forms.Cursor.Position
Vinsa

Antworten:

77

Um Rachels Antwort zu verfolgen.
Hier sind zwei Möglichkeiten, wie Sie Mausbildschirmkoordinaten in WPF erhalten können.

1.Verwenden von Windows Forms. Fügen Sie einen Verweis auf System.Windows.Forms hinzu

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

2.Verwenden von 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);
}
Fredrik Hedblad
quelle
3
Wenn Sie die rohen X- und Y-Koordinaten verwenden und die Position eines Fensters mithilfe dieser Koordinaten festlegen, funktioniert dies zwar nicht richtig, wenn Ihre DPI-Einstellungen alles andere als 100% (96 dpi) betragen. Die letzte Antwort auf die Frage hat es richtig!
user195275
Ihr Kommentar ist völlig richtig und sollte nicht als die richtige Antwort auf diese Frage markiert werden!
Arash
81

Oder verwenden Sie in reinem WPF PointToScreen .

Beispiel für eine Hilfsmethode:

// Gets the absolute mouse position, relative to screen
Point GetMousePos() => _window.PointToScreen(Mouse.GetPosition(_window));
erikH
quelle
"Konvertiert einen Punkt, der das aktuelle Koordinatensystem des Visuals darstellt, in einen Punkt in Bildschirmkoordinaten." Was hat das mit der Mausposition zu tun?
Jonas Elfström
16
Mouse.GetPosition gibt einen Punkt zurück und PointToScreen konvertiert den Punkt in die Bildschirmkoordinate.
ErikH
Hallo @erikH, Könnten Sie den Link aktualisieren? Es ist kaputt
Patrick D'Souza
Danke Patrick. Jetzt ist es wieder ok. (msdn hat etwas geändert ...)
erikH
Dies funktioniert nur, wenn sich die Maus im Fenster befindet
AustinWBryan
27

Möchten Sie Koordinaten relativ zum Bildschirm oder zur Anwendung?

Wenn es in der Anwendung enthalten ist, verwenden Sie einfach:

Mouse.GetPosition(Application.Current.MainWindow);

Wenn nicht, können Sie meiner Meinung nach einen Verweis hinzufügen System.Windows.Formsund verwenden:

System.Windows.Forms.Control.MousePosition;
Rachel
quelle
1
Es muss System.Windows.Forms.Control.MousePosition
Prince OfThief
error CS0234: The type or namespace name 'Control' does not exist in the namespace 'System.Windows.Forms' (are you missing an assembly reference?)
Jonathan Tuzman
21

Wenn Sie viele dieser Antworten auf verschiedenen Auflösungen, Computern mit mehreren Monitoren usw. ausprobieren, stellen Sie möglicherweise fest, dass sie nicht zuverlässig funktionieren. Dies liegt daran, dass Sie eine Transformation verwenden müssen, um die Mausposition relativ zum aktuellen Bildschirm zu ermitteln, nicht den gesamten Anzeigebereich, der aus all Ihren Monitoren besteht. So etwas in der Art ... (wobei "dies" ein WPF-Fenster ist).

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);
}
Alexandru
quelle
1
Vielen Dank! Ich hatte Probleme mit hochauflösenden Bildschirmen und die Transformation scheint wunderbar zu funktionieren.
mdiehl13
@ mdiehl13 Keine Sorge :) Ich bin froh, dass du festgestellt hast, dass meine Transformationen in Ordnung sind
Alexandru
1
@ mdiehl13 Es ist klar, dass viele Leute nur den Basisfall testen. +1 zum Testen verschiedener Auflösungen und dergleichen. :)
Alexandru
4

Dies funktioniert, ohne Formulare verwenden oder DLLs importieren zu müssen:

   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);
    }
Hemligaarne
quelle
2

Sie können eine Kombination aus TimerDispatcher (WPF Timer analog) und Windows "Hooks" verwenden, um die Cursorposition vom Betriebssystem zu erfassen.

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

Punkt ist ein Licht struct. Es enthält nur X-, Y-Felder.

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

Diese Lösung löst das Problem auch durch zu häufiges oder zu seltenes Lesen von Parametern, sodass Sie es selbst anpassen können. Denken Sie jedoch an die Überladung der WPF-Methode mit einem Argument, das ticksnicht darstellt milliseconds.

TimeSpan(50); //ticks
Max Bender
quelle
2

Wenn Sie nach einem 1-Liner suchen, ist dies gut.

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

Das + mWindow.Leftund + mWindow.Topstellt sicher, dass die Position an der richtigen Stelle ist, auch wenn der Benutzer das Fenster herumzieht.

Jesse Grunert
quelle
0

Mouse.GetPosition(mWindow)gibt Ihnen die Mausposition relativ zum Parameter Ihrer Wahl. mWindow.PointToScreen()Konvertieren Sie die Position in einen Punkt relativ zum Bildschirm.

So mWindow.PointToScreen(Mouse.GetPosition(mWindow))haben Sie die Mausposition relativ zum Bildschirm, unter der Annahme , dass mWindowein Fenster (eigentlich aus jeder Klasse abgeleitet System.Windows.Media.Visualwird diese Funktion haben), wenn Sie diese verwenden innerhalb einer WPF - Fensterklasse, thisfunktionieren sollte.

Fire1nRain
quelle