using System; using System.Runtime.InteropServices; using Cute; using UnityEngine; public class WindowResize { public delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); public struct Rect { public int Left { get; set; } public int Top { get; set; } public int Right { get; set; } public int Bottom { get; set; } public int Width { get { return Right - Left; } set { Right = Left + value; } } public int Height { get { return Bottom - Top; } set { Bottom = Top + value; } } public Rect(int left, int top, int right, int bottom) { this = default(Rect); Left = left; Top = top; Right = right; Bottom = bottom; } } public struct WindowPos { public IntPtr hwnd; public IntPtr hwndafter; public int x; public int y; public int cx; public int cy; public uint flags; } private const int WINDOW_WIDTH_MIN = 128; private const int WINDOW_HEIGHT_MIN = 59; public const float ASPECT_RATIO_MAX = 2.1666667f; public const float ASPECT_RATIO_MIN = 1.333f; private static int _windowLastWidth; private static int _windowLastHeight; private static bool _lastFullscreen; private static int? _requestUiUpdateFrame; private static int _frameLastWidth; private static int _frameLastHeight; private const int WM_WINDOWPOSCHANGING = 70; private const int WM_SIZING = 532; private const int WMSZ_LEFT = 1; private const int WMSZ_TOP = 3; private const int WMSZ_TOPLEFT = 4; private const int WMSZ_TOPRIGHT = 5; private const int WMSZ_BOTTOMLEFT = 7; private const int SWP_NOSIZE = 1; private static WndProcDelegate _wndProc; private static IntPtr _oldwndProcPtr; private static bool _init; private IntPtr WndProcPtr(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { if (!Screen.fullScreen) { switch (msg) { case 532u: { Rect structure2 = (Rect)Marshal.PtrToStructure(lParam, typeof(Rect)); if (_windowLastWidth != structure2.Width || _windowLastHeight != structure2.Height) { (int, int) newWindowSize2 = GetNewWindowSize(hWnd, structure2.Width, structure2.Height); int item3 = newWindowSize2.Item1; int item4 = newWindowSize2.Item2; int num = (int)wParam; bool num2 = num == 7 || num == 1 || num == 4; bool flag = num == 3 || num == 4 || num == 5; if (num2) { structure2.Left = structure2.Right - item3; } else { structure2.Right = structure2.Left + item3; } if (flag) { structure2.Top = structure2.Bottom - item4; } else { structure2.Bottom = structure2.Top + item4; } Marshal.StructureToPtr(structure2, lParam, fDeleteOld: true); } break; } case 70u: { WindowPos structure = (WindowPos)Marshal.PtrToStructure(lParam, typeof(WindowPos)); if ((structure.flags & 1) == 0 && (_windowLastWidth != structure.cx || _windowLastHeight != structure.cy)) { (int, int) newWindowSize = GetNewWindowSize(hWnd, structure.cx, structure.cy); int item = newWindowSize.Item1; int item2 = newWindowSize.Item2; structure.cx = item; structure.cy = item2; Marshal.StructureToPtr(structure, lParam, fDeleteOld: true); } break; } } } return CallWindowProc(_oldwndProcPtr, hWnd, msg, wParam, lParam); } private (int, int) GetWindowFrameSize(IntPtr hWnd) { GetClientRect(hWnd, out var lpRect); if (lpRect.Right - lpRect.Left == 0 || lpRect.Bottom - lpRect.Top == 0) { return (_frameLastWidth, _frameLastHeight); } GetWindowRect(hWnd, out var lpRect2); int item = lpRect2.Right - lpRect2.Left - (lpRect.Right - lpRect.Left); int item2 = lpRect2.Bottom - lpRect2.Top - (lpRect.Bottom - lpRect.Top); return (item, item2); } private static (int, int) WindowToClientSize(int windowWidth, int windowHeight, int frameWidth, int frameHeight) { return (windowWidth - frameWidth, windowHeight - frameHeight); } private static (int, int) ClientToWindowSize(int clientWidth, int clientHeight, int frameWidth, int frameHeight) { return (clientWidth + frameWidth, clientHeight + frameHeight); } private (int, int) GetNewWindowSize(IntPtr hWnd, int width, int height) { (int, int) windowFrameSize = GetWindowFrameSize(hWnd); int item = windowFrameSize.Item1; int item2 = windowFrameSize.Item2; _frameLastWidth = item; _frameLastHeight = item2; (int, int) tuple = WindowToClientSize(width, height, item, item2); int item3 = tuple.Item1; int item4 = tuple.Item2; Vector3 fixedSize = getFixedSize(item3, item4); item3 = (int)fixedSize.x; item4 = (int)fixedSize.y; UpdateGame(fixedSize.z); _windowLastWidth = item3; _windowLastHeight = item4; return ClientToWindowSize(item3, item4, item, item2); } private void init() { if (!_init) { IntPtr activeWindow = GetActiveWindow(); _wndProc = WndProcPtr; IntPtr functionPointerForDelegate = Marshal.GetFunctionPointerForDelegate(_wndProc); IntPtr? intPtr = SetWindowLongPtr(activeWindow, -4, functionPointerForDelegate); if (intPtr.HasValue) { _oldwndProcPtr = intPtr.Value; _init = true; } } } public WindowResize() { init(); } private static Vector3 getFixedSize(int width, int height) { if (height < 59) { height = 59; } float num = (float)width / (float)height; if (num < 1.333f) { num = 1.333f; if (width < 128) { width = 128; } height = (int)((float)width / num); } else if (num > 2.1666667f) { num = 2.1666667f; width = (int)((float)height * num); } return new Vector3(width, height, num); } public static void SetResolution(int newWidth, int newHeight) { Vector3 fixedSize = getFixedSize(newWidth, newHeight); newWidth = (int)fixedSize.x; newHeight = (int)fixedSize.y; float z = fixedSize.z; if (Toolbox.QualityManager != null) { Toolbox.QualityManager.ChangeResolution(newWidth, newHeight, Screen.fullScreen); } UpdateGame(z); _windowLastWidth = Screen.width; _windowLastHeight = Screen.height; } private static void ResolutionChanged() { Vector3 fixedSize = getFixedSize(Screen.width, Screen.height); int num = (int)fixedSize.x; int num2 = (int)fixedSize.y; float z = fixedSize.z; if (Toolbox.QualityManager != null) { if (num != Screen.width || num2 != Screen.height) { Toolbox.QualityManager.ChangeResolution(num, num2, Screen.fullScreen); } else { Toolbox.QualityManager.UpdateFromUnity(); } } UpdateGame(z); _windowLastWidth = num; _windowLastHeight = num2; _lastFullscreen = Screen.fullScreen; } private static void UpdateGame(float ratio) { if (GameMgr.GetIns() != null) { GameMgr.GetIns().ChangeAspectRatio(ratio); } if (UIManager.GetInstance() != null && UIManager.GetInstance().GetCurrentScene() == UIManager.ViewScene.Battle && BattleManagerBase.GetIns() != null) { BattleManagerBase.GetIns().ChangeCameraFieldOfView(ratio); } _requestUiUpdateFrame = Time.frameCount; } private static void UpdateUI() { UILabel[] array = UnityEngine.Object.FindObjectsOfType(); for (int i = 0; i < array.Length; i++) { array[i].WrapOnResize(); array[i].UpdateNGUIText(); } UITable[] array2 = UnityEngine.Object.FindObjectsOfType(); for (int j = 0; j < array2.Length; j++) { array2[j].Reposition(); } AspectCameraPerspective[] array3 = UnityEngine.Object.FindObjectsOfType(); for (int k = 0; k < array3.Length; k++) { array3[k].UpdateFov(); } } public void Update() { init(); if (_requestUiUpdateFrame.HasValue && _requestUiUpdateFrame.Value < Time.frameCount) { UpdateUI(); _requestUiUpdateFrame = null; } if (Screen.fullScreen && (_windowLastWidth != Screen.width || _windowLastHeight != Screen.height)) { ResolutionChanged(); } } public void SetSavedResolutionSettings() { } [DllImport("user32.dll")] private static extern IntPtr GetActiveWindow(); [DllImport("user32.dll")] private static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll", EntryPoint = "SetWindowLong")] private static extern int SetWindowLong32(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")] private static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong); [DllImport("user32.dll")] private static extern bool GetWindowRect(IntPtr hwnd, out Rect lpRect); [DllImport("user32.dll")] private static extern bool GetClientRect(IntPtr hwnd, out Rect lpRect); public static IntPtr? SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong) { if (IntPtr.Size == 8) { return SetWindowLongPtr64(hWnd, nIndex, dwNewLong); } int num = SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32()); if (num == 0) { return null; } return new IntPtr(num); } }