2016-11-03 12 views
3

У меня есть следующая проблема:Запись абсолютной позиции мыши в TextBox

У меня есть окно с двумя текстовыми полями. Когда я нажимаю в текстовом поле, а затем нажимаю в другом месте (даже вне окна), позиция щелчка мыши должна быть записана в текстовое поле.

Я нашел библиотеку MouseKeyHook, в которой демонстрация показывает, как позиция мыши обновляется в форме окна. Но мне еще не удалось применить код к моей проблеме. Я даже не знаю, где я должен написать код, найденный в демо.

То, что я придумал до сих пор является следующее:

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

Это код для одного TextBox. Когда я нажимаю на него, отображаются координаты x и y. Они не являются абсолютными, я думаю, что это связано с параметром this в методе GetPosition. Что мне нужно выбрать вместо this?

Другое дело, что позиция не обновляется всегда. Когда я перемещаю мышь в нижний правый угол моего рабочего стола, а затем активирую текстовое поле, вставляя его в нее, позиция не обновляется.

Каковы шаги для этого?

+0

Если вы хотите получить абсолютное положение мыши относительно экрана и обновить ее, даже если вы находитесь за пределами WPF Window, вам придется использовать MouseHook (использует вызовы API Win32 для получения позиции) , и таймер, который получает позицию и отображает ее в TextBlock. –

ответ

3

мне удалось добиться этого результата с помощью Cursor.Position:

точка который представляет позицию курсора в координатах экрана.

Пример

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

Вы можете видеть из the Microsoft reference source, что 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's answer, он по-прежнему использует SetCursorPos, но таким образом, легче л.

Помимо этого, возможно, это зависит от того, можете ли вы включить ссылку на System.Windows.Forms.

+0

Когда я пытаюсь это сделать, «System.Windows.Forms» подчеркивается красным цветом и появляется сообщение об ошибке CS0234 C# Тип или имя пространства имен «Формы» не существует в пространстве имен «System.Windows» (вам не хватает сборки ссылка?) –

+0

@DavidP Вам нужно будет добавить 'System.Windows.Forms' в качестве ссылки, перейдя' Project' -> 'Добавить ссылку', а затем выберите ее из списка (она будет находиться под Assmblies -> Framework) – Bassie

+0

Это сработало, спасибо! Это решение выглядит проще, чем у yan yankalevich. Есть ли какие-либо преимущества/недостатки между вашим ответом и его? –

2

Для начала вам необходимо получить абсолютную позицию мыши (не относительно вашего окна или элементов управления). Для этого необходимо один из этих вариантов (отсюда: https://stackoverflow.com/a/4232281/4664754):

  • Добавив ссылку на System.Windows.Forms в проекте (перейти в References в вашем обозревателе решений -> Щелкните правой кнопкой мыши -> Добавить ссылку -> Assemblys-> Framework -> Отметьте поле возле System.Windows.Forms). Затем добавьте этот статический funtcion в некотором классе (назовем его MouseHelper.cs):

    public static Point GetMousePositionWindowsForms() 
    { 
        System.Drawing.Point point = Control.MousePosition; 
        return new Point(point.X, point.Y); 
    } 
    
  • Вставив этот код в 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://stackoverflow.com/a/2064009/4664754 и изменить ваши Textboxes значения каждый раз, когда событие TheMouseMoved называется