AquaDX/AquaMai/AquaMai.Mods/GameSystem/Window.cs

108 lines
3.2 KiB
C#
Raw Normal View History

2024-09-27 21:50:27 +08:00
using System;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using AquaMai.Config.Attributes;
2024-09-27 21:50:27 +08:00
using UnityEngine;
namespace AquaMai.Mods.GameSystem;
2024-09-27 21:50:27 +08:00
[ConfigSection(
en: "Windowed Mode / Window Settings.",
zh: "窗口化/窗口设置")]
public class Window
2024-09-27 21:50:27 +08:00
{
[ConfigEntry(
en: "Window the game.",
zh: "窗口化游戏")]
private static readonly bool windowed = false;
[ConfigEntry(
en: """
Window width (and height) for windowed mode, rendering resolution for fullscreen mode.
If set to 0, windowed mode will remember the user-set size, fullscreen mode will use the current display resolution.
""",
zh: """
0使
""")]
private static readonly int width = 0;
[ConfigEntry(
en: "Height, as above.",
zh: "高度,同上")]
private static readonly int height = 0;
2024-09-27 21:50:27 +08:00
private const int GWL_STYLE = -16;
2024-10-01 15:50:00 +08:00
private const int WS_WHATEVER = 0x14CF0000;
2024-09-27 21:50:27 +08:00
private static IntPtr hwnd = IntPtr.Zero;
public static void OnBeforePatch()
2024-09-27 21:50:27 +08:00
{
if (windowed)
2024-09-27 21:50:27 +08:00
{
var alreadyWindowed = Screen.fullScreenMode == FullScreenMode.Windowed;
if (width == 0 || height == 0)
2024-09-27 21:50:27 +08:00
{
Screen.fullScreenMode = FullScreenMode.Windowed;
}
else
{
alreadyWindowed = false;
Screen.SetResolution(width, height, FullScreenMode.Windowed);
2024-09-27 21:50:27 +08:00
}
hwnd = GetWindowHandle();
2024-10-01 15:50:00 +08:00
if (alreadyWindowed)
2024-09-27 21:50:27 +08:00
{
SetResizeable();
}
else
{
Task.Run(async () =>
{
await Task.Delay(3000);
// Screen.SetResolution has delay
SetResizeable();
});
}
}
else
{
var width = Window.width == 0 ? Display.main.systemWidth : Window.width;
var height = Window.height == 0 ? Display.main.systemHeight : Window.height;
2024-09-27 21:50:27 +08:00
Screen.SetResolution(width, height, FullScreenMode.FullScreenWindow);
}
}
public static void SetResizeable()
{
if (hwnd == IntPtr.Zero) return;
SetWindowLongPtr(hwnd, GWL_STYLE, WS_WHATEVER);
}
private delegate bool EnumThreadDelegate(IntPtr hwnd, IntPtr lParam);
[DllImport("user32.dll")]
static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
[DllImport("Kernel32.dll")]
static extern int GetCurrentThreadId();
static IntPtr GetWindowHandle()
{
IntPtr returnHwnd = IntPtr.Zero;
var threadId = GetCurrentThreadId();
EnumThreadWindows(threadId,
(hWnd, lParam) =>
{
if (returnHwnd == IntPtr.Zero) returnHwnd = hWnd;
return true;
}, IntPtr.Zero);
return returnHwnd;
}
[DllImport("user32.dll")]
static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, int dwNewLong);
}