89 lines
3.0 KiB
C#
89 lines
3.0 KiB
C#
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;
|
||
}
|
||
} |