1
0
mirror of https://github.com/soarqin/DSP_Mods.git synced 2025-12-09 03:33:29 +08:00

optimized window repositioning

This commit is contained in:
2025-04-29 15:38:17 +08:00
parent 167f53e2df
commit 40e3206953
2 changed files with 39 additions and 79 deletions

View File

@@ -54,9 +54,6 @@ public static class WindowFunctions
_oldWndProc = WinApi.SetWindowLongPtr(gameWnd, WinApi.GWLP_WNDPROC, Marshal.GetFunctionPointerForDelegate(wndProc)); _oldWndProc = WinApi.SetWindowLongPtr(gameWnd, WinApi.GWLP_WNDPROC, Marshal.GetFunctionPointerForDelegate(wndProc));
} }
if (GamePatch.LoadLastWindowRectEnabled.Value)
GamePatch.LoadLastWindowRect.MoveWindowPosition(true);
ProcessPriority.SettingChanged += (_, _) => WinApi.SetPriorityClass(WinApi.GetCurrentProcess(), ProrityFlags[ProcessPriority.Value]); ProcessPriority.SettingChanged += (_, _) => WinApi.SetPriorityClass(WinApi.GetCurrentProcess(), ProrityFlags[ProcessPriority.Value]);
WinApi.SetPriorityClass(WinApi.GetCurrentProcess(), ProrityFlags[ProcessPriority.Value]); WinApi.SetPriorityClass(WinApi.GetCurrentProcess(), ProrityFlags[ProcessPriority.Value]);
ProcessAffinity.SettingChanged += (_, _) => UpdateAffinity(); ProcessAffinity.SettingChanged += (_, _) => UpdateAffinity();
@@ -104,43 +101,7 @@ public static class WindowFunctions
{ {
WinApi.SetWindowLongPtr(_gameWindowHandle, WinApi.GWLP_WNDPROC, _oldWndProc); WinApi.SetWindowLongPtr(_gameWindowHandle, WinApi.GWLP_WNDPROC, _oldWndProc);
} }
break; break;
case WinApi.WM_SYSCOMMAND:
switch ((long)wParam & 0xFFF0L)
{
case WinApi.SC_MOVE:
if (GamePatch.LoadLastWindowRectEnabled.Value && !GameMain.isRunning) return (IntPtr)1L;
break;
}
break;
case WinApi.WM_MOVING:
if (!GamePatch.LoadLastWindowRectEnabled.Value || GameMain.isRunning) break;
var rect = GamePatch.LastWindowRect.Value;
if (rect is { z: 0f, w: 0f }) break;
var x = Mathf.RoundToInt(rect.x);
var y = Mathf.RoundToInt(rect.y);
var rect2 = Marshal.PtrToStructure<WinApi.Rect>(lParam);
rect2.Left = x;
rect2.Top = y;
Marshal.StructureToPtr(rect2, lParam, false);
return (IntPtr)1L;
case WinApi.WM_SIZING:
if (!GamePatch.LoadLastWindowRectEnabled.Value || Screen.fullScreenMode is FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow || GameMain.isRunning) break;
rect = GamePatch.LastWindowRect.Value;
if (rect is { z: 0f, w: 0f }) break;
x = Mathf.RoundToInt(rect.x);
y = Mathf.RoundToInt(rect.y);
var w = Mathf.RoundToInt(rect.z);
var h = Mathf.RoundToInt(rect.w);
rect2 = Marshal.PtrToStructure<WinApi.Rect>(lParam);
rect2.Left = x;
rect2.Top = y;
rect2.Right = x + w;
rect2.Bottom = y + h;
Marshal.StructureToPtr(rect2, lParam, false);
return (IntPtr)1L;
} }
return WinApi.CallWindowProc(_oldWndProc, hWnd, uMsg, wParam, lParam); return WinApi.CallWindowProc(_oldWndProc, hWnd, uMsg, wParam, lParam);

View File

@@ -1,9 +1,10 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection.Emit; using System.Reflection.Emit;
using System.Threading;
using System.Xml; using System.Xml;
using BepInEx;
using BepInEx.Configuration; using BepInEx.Configuration;
using CommonAPI.Systems; using CommonAPI.Systems;
using HarmonyLib; using HarmonyLib;
@@ -232,11 +233,8 @@ public class GamePatch : PatchImpl<GamePatch>
public class LoadLastWindowRect : PatchImpl<LoadLastWindowRect> public class LoadLastWindowRect : PatchImpl<LoadLastWindowRect>
{ {
private static bool _loaded;
protected override void OnEnable() protected override void OnEnable()
{ {
GameLogic.OnDataLoaded += VFPreload_InvokeOnLoadWorkEnded_Postfix;
if (Screen.fullScreenMode is not (FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow)) if (Screen.fullScreenMode is not (FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow))
{ {
var rect = LastWindowRect.Value; var rect = LastWindowRect.Value;
@@ -275,58 +273,59 @@ public class GamePatch : PatchImpl<GamePatch>
protected override void OnDisable() protected override void OnDisable()
{ {
GameLogic.OnDataLoaded -= VFPreload_InvokeOnLoadWorkEnded_Postfix; //GameLogic.OnDataLoaded -= VFPreload_InvokeOnLoadWorkEnded_Postfix;
} }
public static void MoveWindowPosition(bool setResolution = false) public static IEnumerator SetWindowPosition(IntPtr wnd,int x, int y) {
{ yield return new WaitForEndOfFrame();
if (Screen.fullScreenMode is FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow || GameMain.isRunning) return; yield return new WaitForEndOfFrame();
var wnd = WindowFunctions.FindGameWindow();
if (wnd == IntPtr.Zero) return;
var rect = LastWindowRect.Value;
if (rect is { z: 0f, w: 0f }) return;
var x = Mathf.RoundToInt(rect.x);
var y = Mathf.RoundToInt(rect.y);
if (setResolution)
{
var w = Mathf.RoundToInt(rect.z);
var h = Mathf.RoundToInt(rect.w);
Screen.SetResolution(w, h, false);
}
WinApi.SetWindowPos(wnd, IntPtr.Zero, x, y, 0, 0, 0x0235); WinApi.SetWindowPos(wnd, IntPtr.Zero, x, y, 0, 0, 0x0235);
} }
[HarmonyPrefix] [HarmonyPrefix]
[HarmonyPatch(typeof(Screen), nameof(Screen.SetResolution), typeof(int), typeof(int), typeof(FullScreenMode), typeof(int))] [HarmonyPatch(typeof(Screen), nameof(Screen.SetResolution), typeof(int), typeof(int), typeof(FullScreenMode), typeof(int))]
private static void Screen_SetResolution_Prefix(ref int width, ref int height, FullScreenMode fullscreenMode) private static void Screen_SetResolution_Prefix(ref int width, ref int height, FullScreenMode fullscreenMode, ref Vector2Int __state)
{ {
if (fullscreenMode is FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow || GameMain.isRunning) return; if (fullscreenMode is FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow) return;
int x = 0, y = 0, w = 0, h = 0;
var rect = LastWindowRect.Value; var rect = LastWindowRect.Value;
if (rect is { z: 0f, w: 0f }) return; if (rect is not { z: 0f, w: 0f })
var w = Mathf.RoundToInt(rect.z); {
var h = Mathf.RoundToInt(rect.w); x = Mathf.RoundToInt(rect.x);
y = Mathf.RoundToInt(rect.y);
w = Mathf.RoundToInt(rect.z);
h = Mathf.RoundToInt(rect.w);
}
if (GameMain.isRunning)
{
__state = new Vector2Int(x, y);
return;
}
width = w; width = w;
height = h; height = h;
} }
private static void VFPreload_InvokeOnLoadWorkEnded_Postfix() [HarmonyPostfix]
[HarmonyPatch(typeof(Screen), nameof(Screen.SetResolution), typeof(int), typeof(int), typeof(FullScreenMode), typeof(int))]
private static void Screen_SetResolution_Postfix(FullScreenMode fullscreenMode, Vector2Int __state)
{ {
if (_loaded || Screen.fullScreenMode is FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow) return; if (fullscreenMode is FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow) return;
_loaded = true;
var wnd = WindowFunctions.FindGameWindow(); var wnd = WindowFunctions.FindGameWindow();
if (wnd == IntPtr.Zero) return; if (wnd == IntPtr.Zero) return;
var rect = LastWindowRect.Value; int x, y;
if (rect is { z: 0f, w: 0f }) return; if (GameMain.isRunning)
var x = Mathf.RoundToInt(rect.x); {
var y = Mathf.RoundToInt(rect.y); x = __state.x;
var w = Mathf.RoundToInt(rect.z); y = __state.y;
var h = Mathf.RoundToInt(rect.w); }
Screen.SetResolution(w, h, false); else
WinApi.SetWindowPos(wnd, IntPtr.Zero, x, y, 0, 0, 0x0235); {
if (EnableWindowResizeEnabled.Value) var rect = LastWindowRect.Value;
WinApi.SetWindowLong(wnd, WinApi.GWL_STYLE, if (rect is { z: 0f, w: 0f }) return;
WinApi.GetWindowLong(wnd, WinApi.GWL_STYLE) | WinApi.WS_THICKFRAME | WinApi.WS_MAXIMIZEBOX); x = Mathf.RoundToInt(rect.x);
y = Mathf.RoundToInt(rect.y);
}
ThreadingHelper.Instance.StartCoroutine(SetWindowPosition(wnd, x, y));
} }
private static GameOption _gameOption; private static GameOption _gameOption;