доработана winUI реализация
This commit is contained in:
89
Lattice.UI.DragDrop.WinUI/Helpers/WinUIWindowHelper.cs
Normal file
89
Lattice.UI.DragDrop.WinUI/Helpers/WinUIWindowHelper.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using Lattice.Core.Geometry;
|
||||
using Microsoft.UI.Xaml;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
/// <summary>
|
||||
/// Вспомогательный класс для получения экранных координат в WinUI 3.
|
||||
/// Использует P/Invoke для доступа к нативным API Windows.
|
||||
/// </summary>
|
||||
internal static class WinUIWindowHelper
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POINT
|
||||
{
|
||||
public int X;
|
||||
public int Y;
|
||||
|
||||
public POINT(int x, int y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool ClientToScreen(IntPtr hWnd, ref POINT lpPoint);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr WindowFromPoint(POINT point);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
|
||||
|
||||
/// <summary>
|
||||
/// Преобразует координаты элемента в экранные координаты.
|
||||
/// </summary>
|
||||
public static Point ConvertToScreenCoordinates(FrameworkElement element, Point localPoint)
|
||||
{
|
||||
if (element == null || !element.IsLoaded)
|
||||
return localPoint;
|
||||
|
||||
try
|
||||
{
|
||||
var window = Window.Current;
|
||||
if (window == null)
|
||||
return localPoint;
|
||||
|
||||
// Получаем хэндл окна
|
||||
var hwnd = GetWindowHandle(window);
|
||||
if (hwnd == IntPtr.Zero)
|
||||
return localPoint;
|
||||
|
||||
// Преобразуем координаты элемента в координаты окна
|
||||
var transform = element.TransformToVisual(window.Content);
|
||||
var windowPoint = transform.TransformPoint(
|
||||
new Windows.Foundation.Point(localPoint.X, localPoint.Y));
|
||||
|
||||
// Преобразуем в POINT для P/Invoke
|
||||
var point = new POINT(
|
||||
(int)Math.Round(windowPoint.X),
|
||||
(int)Math.Round(windowPoint.Y));
|
||||
|
||||
// Преобразуем клиентские координаты в экранные
|
||||
if (ClientToScreen(hwnd, ref point))
|
||||
{
|
||||
return new Point(point.X, point.Y);
|
||||
}
|
||||
|
||||
return localPoint;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"Ошибка преобразования координат: {ex.Message}");
|
||||
return localPoint;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получает хэндл окна WinUI.
|
||||
/// </summary>
|
||||
private static IntPtr GetWindowHandle(Window window)
|
||||
{
|
||||
// В WinUI 3 можно использовать WinRT API для получения хэндла
|
||||
// или альтернативные методы в зависимости от контекста
|
||||
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(window);
|
||||
return hwnd;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user