using System.Runtime.InteropServices; namespace CursorLang.Core.Interop; /// /// Win32 API for the popup window: styles, positioning near the cursor /// and the scale of the monitor the cursor is on. /// internal static class PopupWindowNative { [StructLayout(LayoutKind.Sequential)] internal struct Point { public int X; public int Y; } [DllImport("user32.dll")] private static extern bool GetCursorPos(out Point lpPoint); [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); [DllImport("user32.dll")] private static extern IntPtr MonitorFromPoint(Point pt, uint dwFlags); [DllImport("shcore.dll")] private static extern int GetDpiForMonitor(IntPtr hMonitor, int dpiType, out uint dpiX, out uint dpiY); [DllImport("user32.dll")] private static extern IntPtr MonitorFromWindow(IntPtr hWnd, uint dwFlags); [DllImport("user32.dll")] private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MonitorInfo lpmi); [StructLayout(LayoutKind.Sequential)] internal struct Rect { public int Left; public int Top; public int Right; public int Bottom; } [StructLayout(LayoutKind.Sequential)] private struct MonitorInfo { public int cbSize; public Rect rcMonitor; public Rect rcWork; public uint dwFlags; } private const uint SWP_NOSIZE = 0x0001; private const uint SWP_NOZORDER = 0x0004; private const uint SWP_NOACTIVATE = 0x0010; private const uint MONITOR_DEFAULTTONEAREST = 2; private const int MDT_EFFECTIVE_DPI = 0; internal static Point GetCursorPosition() { GetCursorPos(out Point cursor); return cursor; } /// /// Moves the window to a screen point without changing its size or z-order. /// The coordinates are physical pixels: monitors have different scaling, while /// Window.Left/Top are converted using the DPI of the monitor the window is on /// right now, which misses the target on a neighbouring monitor. /// internal static void MoveTo(IntPtr hWnd, int x, int y) { SetWindowPos(hWnd, IntPtr.Zero, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } /// The scale of the monitor the point is on (1.0 at 96 DPI). internal static double GetScaleAt(Point point) => GetScaleOf(MonitorFromPoint(point, MONITOR_DEFAULTTONEAREST)); /// /// The work area of the monitor holding the active window — without the taskbar — /// and its scale. That is the monitor the user is working on right now. /// internal static (Rect WorkArea, double Scale) GetActiveMonitorWorkArea() { IntPtr monitor = MonitorFromWindow(GetForegroundWindow(), MONITOR_DEFAULTTONEAREST); var info = new MonitorInfo { cbSize = Marshal.SizeOf() }; if (!GetMonitorInfo(monitor, ref info)) { return (new Rect(), 1.0); } return (info.rcWork, GetScaleOf(monitor)); } private static double GetScaleOf(IntPtr monitor) { if (GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, out uint dpiX, out _) < 0) { return 1.0; } return dpiX / 96.0; } }