在文本框中写入鼠标的绝对位置

3

我有以下问题:

我有一个带有两个文本框的窗口。当我在一个文本框中单击,然后单击任何其他位置(甚至是窗口外部),鼠标单击的位置应该写入文本框。

我找到了MouseKeyHook库,在其中一个演示中展示了如何在Windows表单中更新鼠标位置。但我还没有成功将代码应用到我的问题上。我甚至不知道在哪里应该编写在演示中找到的代码。

到目前为止,我想到的是:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace LineClicker
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void StarttextBox_GotFocus(object sender, RoutedEventArgs e)
        {
            Mouse.Capture(StarttextBox);
            StarttextBox.Text = string.Format(" x {0} , y {1}", PointToScreen(Mouse.GetPosition(this)).X, PointToScreen(Mouse.GetPosition(this)).Y);
        }
    }
}

这是一个文本框的代码。当我点击它时,会显示x和y坐标。它们不是绝对值,我认为这是由于GetPosition方法中的参数this导致的。我应该选择什么替代this
另一件事是位置不总是更新。当我将鼠标移动到桌面右下角,然后通过按Tab键激活文本框时,位置不会得到更新。
在这里需要执行哪些步骤?

如果您想获取鼠标相对于屏幕的绝对位置,并在您离开 WPF 窗口时更新它,那么您将需要使用 MouseHook(使用 Win32 API 调用来获取位置)和一个计时器,在 TextBlock 中获取位置并显示它。 - Lupu Silviu
2个回答

3
我使用 Cursor.Position 实现了这个结果:

表示光标在屏幕坐标中位置的Point

示例

using System.Windows;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void textBox_GotFocus(object sender, RoutedEventArgs e)
        {
            var postion = System.Windows.Forms.Cursor.Position;
            textBox.Text = string.Format($"{postion.X}, {postion.Y}");
        }
    }
}

你可以从Microsoft参考源代码中看到,Cursor.Position被定义为:
public static Point Position {
    get {
        NativeMethods.POINT p = new NativeMethods.POINT();
        UnsafeNativeMethods.GetCursorPos(p);
        return new Point(p.x, p.y);
    }
    set {
        IntSecurity.AdjustCursorPosition.Demand();
        UnsafeNativeMethods.SetCursorPos(value.X, value.Y);
    }
}

所以就像 yan yankelevich的答案 中所说,它仍然使用 SetCursorPos,但这样调用会更加容易。
除此之外,它很可能只取决于您是否愿意包含对 System.Windows.Forms 的引用。

当我尝试这样做时,“System.Windows.Forms”会被用红色下划线标出,并且会出现一个错误,指出CS0234 C#中“Forms”类型或命名空间在命名空间“System.Windows”中不存在(您是否缺少程序集引用?) - David P
@DavidP 你需要将 System.Windows.Forms 添加为引用,方法是在菜单栏中选择 项目 -> 添加引用,然后从列表中选择它(它会在程序集 -> 框架下)。 - Bassie
它起作用了,谢谢! 这个解决方案看起来比yan yankalevich的更简单。你的答案和他的有什么优缺点吗? - David P
1
这个网站真是太神奇了。 - David P

2

首先,您需要获取绝对鼠标位置(而不是相对于窗口或控件的位置)。为此,您需要以下选项之一(来自此处:https://dev59.com/S2855IYBdhLWcg3wpmDw#4232281):

  • By adding a reference to System.Windows.Forms in your project ( go in References in your solution explorer -> Right Click -> Add a Reference -> Assemblys-> Framework -> Tick the box near System.Windows.Forms). Then add this static funtcion in some class (let's call it MouseHelper.cs) :

    public static Point GetMousePositionWindowsForms()
    {
        System.Drawing.Point point = Control.MousePosition;
        return new Point(point.X, point.Y);
    }
    
  • By pasting this code in your MainWindow.xaml.cs:

        [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);
        }
    
无论你选择哪种方式,你都需要在OnFocusChanged中调用其中一个函数,方法如下:
 private void StarttextBox_GotFocus(object sender, RoutedEventArgs e)
        {
            Mouse.Capture(StarttextBox);
            Point mouseCoord = MouseHelper.GetMousePositionWindowsForms();
            // Or if you choose the other way :
            //Point mouseCoord = GetMousePosition();
            StarttextBox.Text = string.Format(" x {0} , y {1}", mouseCoord.X, mouseCoord .Y);
        }

这样坐标应该是正确的。 对于您坐标没有在正确时间显示的问题,我认为您所关注的解决方案并不是您正在寻找的。 您应该尝试实现类似于这样的东西:https://dev59.com/Z3I95IYBdhLWcg3w_zMN#2064009 并在每次调用TheMouseMoved事件时更改文本框值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接