2010-11-19 12 views
47

Come ottenere la coordinazione del mouse corrente sullo schermo? Conosco solo Mouse.GetPosition() che ottiene mousePosition di elemento, ma voglio ottenere il coordinamento senza usare l'elemento.Come posso ottenere le coordinate dello schermo del mouse in WPF?

+0

Coordinate del mouse relative a cosa? Coordinate dello schermo, relative ad una finestra? –

+2

I indica la posizione del mouse sullo schermo. –

risposta

52

dare seguito alla risposta di Rachel.
Ecco due modi in cui è possibile ottenere le Coordinate dello schermo del mouse in WPF.

1.Utilizzo di Windows Form. Aggiungere un riferimento a System.Windows.Forms

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

2.Tramite 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); 
} 
+1

Se corretto, se si prendono le coordinate X e Y non elaborate e si imposta la posizione di una finestra che le utilizza, non funzionerà correttamente se le impostazioni DPI non sono al 100% (96 dpi). L'ultima risposta alla domanda è corretta! – user195275

+0

Il tuo commento è completamente vero e questo non dovrebbe essere contrassegnato come la risposta corretta di questa domanda! – Arash

21

Vuoi le coordinate relative allo schermo o all'applicazione?

Se è all'interno dell'applicazione basta usare:

Mouse.GetPosition(Application.Current.MainWindow); 

In caso contrario, io credo che si possa aggiungere un riferimento a System.Windows.Forms ed impiego:

System.Windows.Forms.Control.MousePosition; 
+0

Deve essere System.Windows.Forms.Control.MousePosition –

50

O in puro WPF usare PointToScreen.

+2

Questo. Bello e pulito. –

+0

"Converte un punto che rappresenta il sistema di coordinate corrente del Visual in un punto nelle coordinate dello schermo.". Che cosa ha a che fare con la posizione del mouse? –

+13

Mouse.GetPosition restituisce un punto e PointToScreen converte il punto nella coordinata dello schermo. – erikH

12

Se si provano molte di queste risposte su risoluzioni diverse, computer con più monitor, ecc. Si potrebbe scoprire che non funzionano in modo affidabile. Questo perché è necessario utilizzare una trasformazione per ottenere la posizione del mouse relativa alla schermata corrente, non l'intera area di visualizzazione che consiste di tutti i monitor. Qualcosa del genere ... (dove "questa" è una finestra WPF).

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

Grazie! Stavo avendo problemi con gli schermi ad alta risoluzione e la trasformazione sembra funzionare meravigliosamente. – mdiehl13

+0

@ mdiehl13 Nessun problema :) felice di aver trovato le mie trasformazioni funzionanti okay – Alexandru

+0

@ mdiehl13 Chiaramente, molte persone testano solo il caso base. +1 per testare risoluzioni diverse e simili. :) – Alexandru

1

Questo funziona senza dover utilizzare moduli o importare qualsiasi DLL:

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

È possibile utilizzare combinazione di TimerDispatcher (WPF timer analogico) e "ganci" di Windows per la cattura di posizione del cursore dal sistema operativo.

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

Punto è una luce struct. Contiene solo i campi X, Y.

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

Questa soluzione è anche risolvendo il problema con la lettura dei parametri troppo spesso o troppo poco frequenti in modo da poter regolare da soli. Ma ricorda il sovraccarico del metodo WPF con un arg che rappresenta ticks non milliseconds.

TimeSpan(50); //ticks 
Problemi correlati