2010-11-19 162 views
47

如何在屏幕上獲得當前的鼠標協調? 我知道只有Mouse.GetPosition()它得到mousePosition的元素,但我想得到協調而不使用元素。如何獲取WPF中的當前鼠標屏幕座標?

+0

鼠標座標相對於什麼?屏幕座標,相對於一個窗口? – 2010-11-19 16:19:10

+2

我的意思是在屏幕上的鼠標位置。 – 2010-11-19 18:10:35

回答

52

要在雷切爾的回答跟進。
這裏有兩種方法可以在WPF中獲得鼠標屏幕座標。

1.使用Windows窗體。一提到System.Windows.Forms的

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

2.使用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

雖然正確,但如果您採用原始的X和Y座標並使用它們設置窗口的位置,但如果您的DPI設置不是100% (96DPI)。 該問題的最後一個答案是否正確! – user195275 2017-08-21 21:15:17

+0

你的評論是完全正確的,這不應該被標記爲這個問題的正確答案! – Arash 2017-09-29 21:10:38

21

你想要相對於屏幕或應用程序的座標嗎?

如果它是在應用程序中只需使用:

Mouse.GetPosition(Application.Current.MainWindow); 

如果不是這樣,我相信你可以添加一個引用到System.Windows.Forms及用途:

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

它必須是System.Windows.Forms.Control.MousePosition – 2010-11-20 13:44:00

50

還是在純WPF使用PointToScreen

+2

這。很好,很乾淨。「 – 2012-08-30 19:21:27

+0

」將表示Visual的當前座標系的點轉換爲屏幕座標中的點。「。這與鼠標位置有什麼關係? – 2013-09-17 08:50:20

+13

Mouse.GetPosition返回一個Point,PointToScreen將該點轉換爲屏幕座標。 – erikH 2013-09-19 11:06:31

12

如果您在不同的分辨率,多臺顯示器等計算機上嘗試了很多這些答案,您可能會發現它們無法可靠地工作。這是因爲您需要使用變換來獲取相對於當前屏幕的鼠標位置,而不是由所有顯示器組成的整個查看區域。像這樣...(其中「this」是一個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

非常感謝!我遇到了高分辨率屏幕問題,而且這種轉換看起來非常有效。 – mdiehl13 2014-08-28 00:36:31

+0

@ mdiehl13不用擔心:)很高興你找到了我的轉換工作好嗎 – Alexandru 2014-08-28 01:49:19

+0

@ mdiehl13顯然,很多人只是測試基本情況。用於測試各種分辨率等。 :) – Alexandru 2014-08-28 13:42:57

1

這工作,而不必使用形式或導入任何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

您可以使用TimerDispatcher(WPF定時器模擬)和Windows「掛鉤」的組合,以捕獲從運作系統光標位置。

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

點是光struct。它只包含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; 
     } 
    } 

該解決方案還解決了參數閱讀過於頻繁或過於頻繁的問題,因此您可以自行調整。但請記住WPF方法超負荷,其中一個參數代表ticks而不是milliseconds

TimeSpan(50); //ticks