Skip to content

Instantly share code, notes, and snippets.

@emoacht
Last active December 6, 2022 20:23
Show Gist options
  • Save emoacht/eeea661d4587b7f3be43edd382fdd117 to your computer and use it in GitHub Desktop.
Save emoacht/eeea661d4587b7f3be43edd382fdd117 to your computer and use it in GitHub Desktop.
Test alternative PointToScreen and ScreenToPoint methods.
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
public static class WindowHelper
{
public static Point PointToScreen(Visual visual, Point point)
{
if (PresentationSource.FromVisual(visual) is HwndSource source)
{
var dpi = VisualTreeHelper.GetDpi(visual);
var buffer = new POINT
{
x = (int)(point.X * dpi.DpiScaleX),
y = (int)(point.Y * dpi.DpiScaleY)
};
if (ClientToScreen(source.Handle, ref buffer))
return buffer;
}
return default;
}
public static Point ScreenToPoint(Visual visual, Point point)
{
if (PresentationSource.FromVisual(visual) is HwndSource source)
{
POINT buffer = point;
if (ScreenToClient(source.Handle, ref buffer))
{
var dpi = VisualTreeHelper.GetDpi(visual);
return new Point
{
X = (int)(buffer.x / dpi.DpiScaleX),
Y = (int)(buffer.y / dpi.DpiScaleY)
};
}
}
return default;
}
public static Point GetCursorPoint()
{
return GetCursorPos(out POINT point) ? point : default;
}
#region Win32
[DllImport("User32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ClientToScreen(
IntPtr hWnd,
ref POINT lpPoint);
[DllImport("User32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ScreenToClient(
IntPtr hWnd,
ref POINT lpPoint);
[DllImport("User32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetCursorPos(
out POINT lpPoint);
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int x;
public int y;
public POINT(int x, int y) => (this.x, this.y) = (x, y);
public static implicit operator Point(POINT point) => new Point(point.x, point.y);
public static implicit operator POINT(Point point) => new POINT((int)point.X, (int)point.Y);
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment