|
@@ -0,0 +1,101 @@
|
|
|
+using System;
|
|
|
+using System.Runtime.InteropServices;
|
|
|
+
|
|
|
+namespace PixiEditor.Helpers
|
|
|
+{
|
|
|
+ static class WindowSizeHelper
|
|
|
+ {
|
|
|
+ public static IntPtr SetMaxSizeHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
|
|
+ {
|
|
|
+ // All windows messages (msg) can be found here
|
|
|
+ // https://docs.microsoft.com/de-de/windows/win32/winmsg/window-notifications
|
|
|
+ if (msg == WM_GETMINMAXINFO)
|
|
|
+ {
|
|
|
+ // We need to tell the system what our size should be when maximized. Otherwise it will
|
|
|
+ // cover the whole screen, including the task bar.
|
|
|
+ MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
|
|
|
+
|
|
|
+ // Adjust the maximized size and position to fit the work area of the correct monitor
|
|
|
+ IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
|
|
|
+
|
|
|
+ if (monitor != IntPtr.Zero)
|
|
|
+ {
|
|
|
+ MONITORINFO monitorInfo = default;
|
|
|
+ monitorInfo.cbSize = Marshal.SizeOf(typeof(MONITORINFO));
|
|
|
+ GetMonitorInfo(monitor, ref monitorInfo);
|
|
|
+ RECT rcWorkArea = monitorInfo.rcWork;
|
|
|
+ RECT rcMonitorArea = monitorInfo.rcMonitor;
|
|
|
+ mmi.ptMaxPosition.X = Math.Abs(rcWorkArea.Left - rcMonitorArea.Left);
|
|
|
+ mmi.ptMaxPosition.Y = Math.Abs(rcWorkArea.Top - rcMonitorArea.Top);
|
|
|
+ mmi.ptMaxSize.X = Math.Abs(rcWorkArea.Right - rcWorkArea.Left);
|
|
|
+ mmi.ptMaxSize.Y = Math.Abs(rcWorkArea.Bottom - rcWorkArea.Top);
|
|
|
+ }
|
|
|
+
|
|
|
+ Marshal.StructureToPtr(mmi, lParam, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ return IntPtr.Zero;
|
|
|
+ }
|
|
|
+
|
|
|
+ private const int WM_GETMINMAXINFO = 0x0024;
|
|
|
+
|
|
|
+ private const uint MONITOR_DEFAULTTONEAREST = 0x00000002;
|
|
|
+
|
|
|
+ [DllImport("user32.dll")]
|
|
|
+ private static extern IntPtr MonitorFromWindow(IntPtr handle, uint flags);
|
|
|
+
|
|
|
+ [DllImport("user32.dll")]
|
|
|
+ private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
|
|
|
+
|
|
|
+ [Serializable]
|
|
|
+ [StructLayout(LayoutKind.Sequential)]
|
|
|
+ private struct RECT
|
|
|
+ {
|
|
|
+ public int Left;
|
|
|
+ public int Top;
|
|
|
+ public int Right;
|
|
|
+ public int Bottom;
|
|
|
+
|
|
|
+ public RECT(int left, int top, int right, int bottom)
|
|
|
+ {
|
|
|
+ this.Left = left;
|
|
|
+ this.Top = top;
|
|
|
+ this.Right = right;
|
|
|
+ this.Bottom = bottom;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ [StructLayout(LayoutKind.Sequential)]
|
|
|
+ private struct MONITORINFO
|
|
|
+ {
|
|
|
+ public int cbSize;
|
|
|
+ public RECT rcMonitor;
|
|
|
+ public RECT rcWork;
|
|
|
+ public uint dwFlags;
|
|
|
+ }
|
|
|
+
|
|
|
+ [Serializable]
|
|
|
+ [StructLayout(LayoutKind.Sequential)]
|
|
|
+ private struct POINT
|
|
|
+ {
|
|
|
+ public int X;
|
|
|
+ public int Y;
|
|
|
+
|
|
|
+ public POINT(int x, int y)
|
|
|
+ {
|
|
|
+ this.X = x;
|
|
|
+ this.Y = y;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ [StructLayout(LayoutKind.Sequential)]
|
|
|
+ private struct MINMAXINFO
|
|
|
+ {
|
|
|
+ public POINT ptReserved;
|
|
|
+ public POINT ptMaxSize;
|
|
|
+ public POINT ptMaxPosition;
|
|
|
+ public POINT ptMinTrackSize;
|
|
|
+ public POINT ptMaxTrackSize;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|