Last active
December 6, 2022 20:23
-
-
Save emoacht/eeea661d4587b7f3be43edd382fdd117 to your computer and use it in GitHub Desktop.
Test alternative PointToScreen and ScreenToPoint methods.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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