2010-11-19 168 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