доработана winUI реализация

This commit is contained in:
2026-01-25 06:29:37 +03:00
parent 0e050b452a
commit a902474345
8 changed files with 1594 additions and 452 deletions

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