Created
March 21, 2022 06:18
-
-
Save emoacht/dab1b7bb98d9b97b9afad47ad074b370 to your computer and use it in GitHub Desktop.
Get the direction of avilable space in the monitor where a specified window locates.
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; | |
public enum Direction { None, TopLeft, TopRight, BottomRight, BottomLeft } | |
public static class WindowHelper | |
{ | |
public static Direction GetAvailableDirection(IntPtr windowHandle) | |
{ | |
if (!GetWindowRect(windowHandle, out RECT buffer)) | |
return Direction.None; | |
System.Drawing.Rectangle windowRect = buffer; | |
IntPtr monitorHandle = MonitorFromWindow(windowHandle, MONITOR_DEFAULTTO.MONITOR_DEFAULTTONULL); | |
if (monitorHandle == IntPtr.Zero) | |
return Direction.None; | |
MONITORINFO info = new() { cbSize = (uint)Marshal.SizeOf<MONITORINFO>() }; | |
if (!GetMonitorInfo(monitorHandle, ref info)) | |
return Direction.None; | |
System.Drawing.Rectangle workingAreaRect = info.rcWork; | |
bool isWindowAlignedTop = (windowRect.Top - workingAreaRect.Top) < (workingAreaRect.Bottom - windowRect.Bottom); | |
bool isWindowAlignedLeft = (windowRect.Left - workingAreaRect.Left) < (workingAreaRect.Right - windowRect.Right); | |
return (isWindowAlignedTop, isWindowAlignedLeft) switch | |
{ | |
(true, true) => Direction.BottomRight, | |
(true, false) => Direction.BottomLeft, | |
(false, true) => Direction.TopRight, | |
(false, false) => Direction.TopLeft | |
}; | |
} | |
[DllImport("User32.dll", SetLastError = true)] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
private static extern bool GetWindowRect( | |
IntPtr hWnd, | |
out RECT lpRect); | |
[DllImport("User32.dll")] | |
private static extern IntPtr MonitorFromWindow( | |
IntPtr hwnd, | |
MONITOR_DEFAULTTO dwFlags); | |
private enum MONITOR_DEFAULTTO : uint | |
{ | |
MONITOR_DEFAULTTONULL = 0x00000000, | |
MONITOR_DEFAULTTOPRIMARY = 0x00000001, | |
MONITOR_DEFAULTTONEAREST = 0x00000002, | |
} | |
[DllImport("User32.dll", CharSet = CharSet.Unicode)] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
private static extern bool GetMonitorInfo( | |
IntPtr hMonitor, | |
ref MONITORINFO lpmi); | |
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] | |
private struct MONITORINFO | |
{ | |
public uint cbSize; | |
public RECT rcMonitor; | |
public RECT rcWork; | |
public uint dwFlags; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
private struct RECT | |
{ | |
public int left; | |
public int top; | |
public int right; | |
public int bottom; | |
public static implicit operator System.Drawing.Rectangle(RECT rect) | |
{ | |
return new System.Drawing.Rectangle( | |
rect.left, | |
rect.top, | |
rect.right - rect.left, | |
rect.bottom - rect.top); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment