2using System.Runtime.InteropServices;
4public static class MinimumWindowSize {
7 #if !UNITY_EDITOR && !UNITY_WEBGL
9 private const int DefaultValue = -1;
12 private const uint WM_GETMINMAXINFO = 0x0024;
15 private const int GWLP_WNDPROC = -4;
17 private static int width;
18 private static int height;
19 private static bool enabled;
22 private static HandleRef hMainWindow;
25 private static IntPtr unityWndProcHandler;
28 private static IntPtr customWndProcHandler;
31 private delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
34 private static WndProcDelegate procDelegate;
36 [StructLayout(LayoutKind.Sequential)]
37 private struct Minmaxinfo {
38 public Point ptReserved;
39 public Point ptMaxSize;
40 public Point ptMaxPosition;
41 public Point ptMinTrackSize;
42 public Point ptMaxTrackSize;
45 private struct Point {
52 public static void Set(
int minWidth,
int minHeight){
53 #if !UNITY_EDITOR && !UNITY_WEBGL
54 if (minWidth < 0 || minHeight < 0)
throw new ArgumentException(
"Any component of min size cannot be less than 0");
62 hMainWindow =
new HandleRef(
null, GetActiveWindow());
63 procDelegate = WndProc;
65 customWndProcHandler = Marshal.GetFunctionPointerForDelegate(procDelegate);
67 unityWndProcHandler = SetWindowLongPtr(hMainWindow, GWLP_WNDPROC, customWndProcHandler);
73 public static void Reset(){
74 #if !UNITY_EDITOR && !UNITY_WEBGL
77 SetWindowLongPtr(hMainWindow, GWLP_WNDPROC, unityWndProcHandler);
78 hMainWindow =
new HandleRef(
null, IntPtr.Zero);
79 unityWndProcHandler = IntPtr.Zero;
80 customWndProcHandler = IntPtr.Zero;
90 #if !UNITY_EDITOR && !UNITY_WEBGL
92 private static IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam){
94 if (msg != WM_GETMINMAXINFO)
return CallWindowProc(unityWndProcHandler, hWnd, msg, wParam, lParam);
97 var x = (Minmaxinfo) Marshal.PtrToStructure(lParam, typeof(Minmaxinfo));
98 x.ptMinTrackSize =
new Point{x = width, y = height};
99 Marshal.StructureToPtr(x, lParam,
false);
102 return DefWindowProc(hWnd, msg, wParam, lParam);
105 [DllImport(
"user32.dll")]
106 private static extern IntPtr GetActiveWindow();
108 [DllImport(
"user32.dll", EntryPoint =
"CallWindowProcA")]
109 private static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint wMsg, IntPtr wParam,
112 [DllImport(
"user32.dll", EntryPoint =
"DefWindowProcA")]
113 private static extern IntPtr DefWindowProc(IntPtr hWnd, uint wMsg, IntPtr wParam, IntPtr lParam);
115 private static IntPtr SetWindowLongPtr(HandleRef hWnd,
int nIndex, IntPtr dwNewLong){
116 if (IntPtr.Size == 8)
return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
117 return new IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32()));
120 [DllImport(
"user32.dll", EntryPoint =
"SetWindowLong")]
121 private static extern int SetWindowLong32(HandleRef hWnd,
int nIndex,
int dwNewLong);
123 [DllImport(
"user32.dll", EntryPoint =
"SetWindowLongPtr")]
124 private static extern IntPtr SetWindowLongPtr64(HandleRef hWnd,
int nIndex, IntPtr dwNewLong);