【问题标题】:How do I get the current mouse screen coordinates in WPF?如何在 WPF 中获取当前鼠标屏幕坐标?
【发布时间】:2010-11-19 15:57:42
【问题描述】:

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

【问题讨论】:

  • 鼠标坐标相对于什么?屏幕坐标,相对于窗口?
  • 我的意思是鼠标在屏幕上的位置。
  • System.Windows.Forms.Cursor.Position

标签: wpf mouse-coordinates


【解决方案1】:

或者在纯 WPF 中使用PointToScreen

示例辅助方法:

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

【讨论】:

  • "将表示当前视觉坐标系的点转换为屏幕坐标中的点。"。这和鼠标位置有什么关系?
  • Mouse.GetPosition 返回一个Point,PointToScreen将该点转换为屏幕坐标。
  • 你好@erikH,你能更新链接吗?坏了
  • 谢谢帕特里克。现在又好了。 (msdn 改变了一些东西...)
【解决方案2】:

跟进瑞秋的回答。
以下是在 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);
}

【讨论】:

  • 虽然正确,但如果您采用原始 X 和 Y 坐标并使用它们设置窗口的位置,如果您的 DPI 设置不是 100% (96dpi),它将无法正常工作。问题的最后一个答案是正确的!
  • 您的评论完全正确,不应将其标记为该问题的正确答案!
【解决方案3】:

您想要相对于屏幕或应用程序的坐标吗?

如果它在应用程序中,只需使用:

Mouse.GetPosition(Application.Current.MainWindow);

如果没有,我相信你可以添加对System.Windows.Forms的引用并使用:

System.Windows.Forms.Control.MousePosition;

【讨论】:

  • 一定是 System.Windows.Forms.Control.MousePosition
  • error CS0234: The type or namespace name 'Control' does not exist in the namespace 'System.Windows.Forms' (are you missing an assembly reference?)
【解决方案4】:

如果您在不同的分辨率、具有多台显示器的计算机等上尝试了很多这些答案,您可能会发现它们无法可靠地工作。这是因为您需要使用转换来获取鼠标相对于当前屏幕的位置,而不是由所有显示器组成的整个查看区域。像这样的东西......(其中“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);
}

【讨论】:

  • 非常感谢!我在使用高分辨率屏幕时遇到了问题,而且转换似乎效果很好。
  • @mdiehl13 不用担心 :) 很高兴你发现我的转换可以正常工作
  • @mdiehl13 显然,很多人只测试基本情况。 +1 用于测试不同的分辨率等。 :)
【解决方案5】:

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

【讨论】:

    【解决方案6】:

    您可以结合使用 TimerDispatcher(WPF 计时器模拟)和 Windows“Hooks”从操作系统中捕获光标位置。

        [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
    

    【讨论】:

      【解决方案7】:

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

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

      + mWindow.Left+ mWindow.Top 确保即使在用户拖动窗口时位置在正确的位置。

      【讨论】:

        【解决方案8】:

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

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

        【讨论】:

          【解决方案9】:

          我想用这个代码

          Point PointA;
          private void Button_PreviewMouseUp(object sender, MouseButtonEventArgs e) {
              PointA = e.MouseDevice.GetPosition(sender as UIElement);
          }
          
          private void Button_Click(object sender, RoutedEventArgs e) {
              // use PointA Here
          }
          

          【讨论】:

            猜你喜欢
            • 2010-09-09
            • 1970-01-01
            • 1970-01-01
            • 2022-06-20
            • 2022-07-07
            • 2016-03-19
            • 1970-01-01
            • 2021-10-22
            • 2015-08-01
            相关资源
            最近更新 更多