如何在WPF中获取当前的鼠标屏幕坐标?


74

如何在屏幕上获得当前的鼠标协调?我只知道Mouse.GetPosition()哪个会获得element的mousePosition,但我想在不使用element的情况下获得协调。


鼠标坐标相对于什么?屏幕坐标,相对于窗口?
Fredrik Hedblad 2010年

3
我的意思是鼠标在屏幕上的位置。
Thief OfThief

System.Windows.Forms.Cursor.Position

Answers:


78

跟进瑞秋的回答。
您可以通过两种方式在WPF中获取鼠标屏幕坐标。

1.使用Windows窗体。添加对System.Windows.Forms的引用

public static Point GetMousePositionWindowsForms()
{
    var 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()
{
    var w32Mouse = new Win32Point();
    GetCursorPos(ref w32Mouse);

    return new Point(w32Mouse.X, w32Mouse.Y);
}

3
正确无误,但如果您使用原始X和Y坐标并使用它们设置窗口的位置,则DPI设置不是100%(96dpi)时,它将无法正常工作。问题的最后答案是正确的!
user195275

您的评论完全正确,不应将其标记为该问题的正确答案!
Arash

81

或者在纯WPF中使用PointToScreen

样本助手方法:

// Gets the absolute mouse position, relative to screen
Point GetMousePos() => _window.PointToScreen(Mouse.GetPosition(_window));

“将代表Visual的当前坐标系的Point转换为屏幕坐标中的Point。” 这与鼠标位置有什么关系?
JonasElfström2013年

16
Mouse.GetPosition返回一个Point,PointToScreen将其转换为屏幕坐标。
erikH 2013年

您好@erikH,您可以更新链接吗?它被打破了
Patrick D'Souza

谢谢帕特里克。现在可以了。(msdn更改了某些内容...)
erikH,2015年

27

是否要相对于屏幕或应用程序的坐标?

如果在应用程序中,则使用:

Mouse.GetPosition(Application.Current.MainWindow);

如果没有,我相信您可以添加参考System.Windows.Forms并使用:

System.Windows.Forms.Control.MousePosition;

1
它必须是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?)
乔纳森·图兹曼

21

如果您在不同的分辨率,带有多台显示器的计算机等上尝试了很多这些答案,则可能会发现它们无法可靠地运行。这是因为您需要使用变换来获得鼠标相对于当前屏幕的位置,而不是相对于包含所有监视器的整个查看区域。诸如此类...(其中“ this”是WPF窗口)。

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

1
万分感谢!我在使用高分辨率屏幕时遇到了问题,并且转换效果很好。
mdiehl13 2014年

@ mdiehl13不用担心:)很高兴您发现我的转换工作正常
Alexandru

1
@ mdiehl13显然,很多人只测试基本情况。+1用于围绕不同分辨率等进行测试。:)
Alexandru

4

无需使用表单或导入任何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);
    }

2

您可以结合使用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方法重载的一个arg表示ticks不是的问题milliseconds

TimeSpan(50); //ticks

2

如果您正在寻找1班轮,这做得很好。

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

+ mWindow.Left+ mWindow.Top确保的位置是即使在用户周围拖动窗口的正确的地方。


0

Mouse.GetPosition(mWindow) 为您提供相对于您选择的参数的鼠标位置。 mWindow.PointToScreen()将位置转换为相对于屏幕的点。

因此,如果您在WPF窗口类中使用此窗口mWindow.PointToScreen(Mouse.GetPosition(mWindow)),则假定您mWindow是一个窗口(实际上,派生自该类的任何类System.Windows.Media.Visual都将具有此功能),从而为您提供相对于屏幕的鼠标位置this

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.