كيف أحصل على إحداثيات شاشة الماوس الحالية في WPF؟
-
26-09-2019 - |
سؤال
كيف تحصل على تنسيق الماوس الحالي على الشاشة؟ أعرف فقط Mouse.GetPosition()
التي تحصل على مسيرة من العنصر ، لكنني أريد الحصول على التنسيق دون استخدام العنصر.
المحلول
لمتابعة إجابة راشيل.
فيما يلي طريقتان يمكنك الحصول على إحداثيات شاشة الماوس في WPF.
1. استخدام نماذج النوافذ. إضافة إشارة إلى 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);
}
نصائح أخرى
أو في استخدام WPF النقي PointToscreen.
نموذج طريقة المساعد:
// Gets the absolute mouse position, relative to screen
Point GetMousePos(){
return _window.PointToScreen(Mouse.GetPosition(_window))
}
هل تريد إحداثيات بالنسبة للشاشة أو التطبيق؟
إذا كان داخل التطبيق فقط استخدم:
Mouse.GetPosition(Application.Current.MainWindow);
إذا لم يكن الأمر كذلك ، أعتقد أنه يمكنك إضافة إشارة إلى System.Windows.Forms
والاستخدام:
System.Windows.Forms.Control.MousePosition;
إذا جربت الكثير من هذه الإجابات على قرارات مختلفة ، وأجهزة الكمبيوتر ذات الشاشات المتعددة ، وما إلى ذلك. قد تجد أنها لا تعمل بشكل موثوق. هذا لأنك تحتاج إلى استخدام تحويل للحصول على موضع الماوس بالنسبة للشاشة الحالية ، وليس منطقة المشاهدة بأكملها والتي تتكون من جميع شاشاتك. شيء من هذا القبيل ... (حيث "هذا" هو نافذة 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);
}
هذا يعمل دون الحاجة إلى استخدام النماذج أو استيراد أي DLLs:
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);
}
يمكنك استخدام مزيج من TimerDispatcher (WPF Timer Talog) و 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 Overload مع ARG واحد تمثل ticks
ليس milliseconds
.
TimeSpan(50); //ticks
إذا كنت تبحث عن بطانة واحدة ، فهذا جيد.
new Point(Mouse.GetPosition(mWindow).X + mWindow.Left, Mouse.GetPosition(mWindow).Y + mWindow.Top)
أضيف هذا للاستخدام مع عناصر التحكم
private void Control_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var mousepos = new List<double> { e.GetPosition(ControlName).X, e.GetPosition(ControlName).Y };
}
Mouse.GetPosition(mWindow)
يمنحك موضع الماوس بالنسبة للمعلمة التي تختارها.mWindow.PointToScreen()
تحويل الموضع إلى نقطة بالنسبة إلى الشاشة.
لذا mWindow.PointToScreen(Mouse.GetPosition(mWindow))
يمنحك موضع الماوس بالنسبة للشاشة ، على افتراض ذلك mWindow
هي نافذة (في الواقع ، أي فئة مشتقة من System.Windows.Media.Visual
سيكون لديك هذه الوظيفة) ، إذا كنت تستخدم هذا داخل فئة نافذة WPF ، this
يجب أن تعمل.