Files
2026-07-10 10:24:29 +08:00

297 lines
9.8 KiB
C#

using UnityEngine;
using System;
using System.Runtime.InteropServices;
//using GYEngine;
public class WindowsHelper
{
#if UNITY_STANDALONE_WIN
//设置当前窗口的显示状态
[DllImport("user32.dll")]
public static extern bool ShowWindow(System.IntPtr hwnd, int nCmdShow);
//获取当前激活窗口
[DllImport("user32.dll", EntryPoint = "GetForegroundWindow")]
public static extern System.IntPtr GetForegroundWindow();
[DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
//程序当前的激活窗口
[DllImport("user32.dll", EntryPoint = "GetActiveWindow")]
public static extern IntPtr GetActiveWindow();
//设置窗口边框
[DllImport("user32.dll")]
public static extern IntPtr SetWindowLong(IntPtr hwnd, int _nIndex, int dwNewLong);
//设置窗口位置,尺寸
[DllImport("user32.dll")]
public static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
//更改标题栏
[DllImport("user32.dll")]
public static extern int SetWindowText(IntPtr hWnd, string text);
//使用查找任务栏
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string strClassName, int nptWindowName);
[DllImport("User32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
//获取窗口位置以及大小
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetClientRect(IntPtr hWnd, ref RECT lpRect);
[DllImport("user32.dll", SetLastError = true)]
public static extern int GetSystemMetrics(int nIndex);
private static int SM_CXSCREEN = 0; //主屏幕分辨率宽度
private static int SM_CYSCREEN = 1; //主屏幕分辨率高度
private static int SM_CYCAPTION = 4; //标题栏高度
private static int SM_CXFULLSCREEN = 16; //最大化窗口宽度(减去任务栏)
private static int SM_CYFULLSCREEN = 17; //最大化窗口高度(减去任务栏)
public static Rect GetWorkingArea()
{
Rect rect = new Rect();
// 屏幕WorkingArea
rect.width = GetSystemMetrics(SM_CXFULLSCREEN);
rect.height = GetSystemMetrics(SM_CYFULLSCREEN);
return rect;
}
public static Rect GetScreen()
{
Rect rect = new Rect();
// 屏幕分辨率
rect.width = GetSystemMetrics(SM_CXSCREEN);
rect.height = GetSystemMetrics(SM_CYSCREEN);
// 标题栏高度
//int title = GetSystemMetrics(SM_CYCAPTION);
// 不最大化、不全屏的最大窗口高度
//int maxHeight = y1 - title;
return rect;
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left; //最左坐标
public int Top; //最上坐标
public int Right; //最右坐标
public int Bottom; //最下坐标
}
//边框参数
private const uint SWP_SHOWWINDOW = 0x0040;
private const int GWL_STYLE = -16;
private const int WS_BORDER = 1;
//隐藏标题栏图标
private const int WS_POPUP = 0x800000;
private const int WS_SYSMENU = 0x80000;
//最大最小化
private const int SW_SHOWMINIMIZED = 2;//(最小化窗口)
private const int SW_SHOWMAXIMIZED = 3;//最大化窗口
//去除标题栏保留边框
private const int WS_CAPTION = 0x00C00000;
private const int WS_THICKFRAME = 0x00040000;
private static IntPtr windowHandler = IntPtr.Zero;
public static void InitWindowHandler()
{
WindowsHelper.windowHandler = GetActiveWindow();
}
public static void SaveWindowPosAndSize()
{
if (windowHandler == IntPtr.Zero) return;
RECT clientrc = new RECT();
GetClientRect(windowHandler, ref clientrc); //获得窗口客户区大小
RECT windowrc = new RECT();
GetWindowRect(windowHandler, ref windowrc); //获得窗口大小
// Debug.Log($"[{clientrc.Top},{clientrc.Bottom},{clientrc.Left},{clientrc.Right}] [{windowrc.Top},{windowrc.Bottom},{windowrc.Left},{windowrc.Right}]");
int borderwidth = (windowrc.Right - windowrc.Left) - (clientrc.Right - clientrc.Left);
int borderheight = (windowrc.Bottom - windowrc.Top) - (clientrc.Bottom - clientrc.Top);
int width = Mathf.Abs(windowrc.Right - windowrc.Left);
int height = Mathf.Abs(windowrc.Top - windowrc.Bottom);
int x = windowrc.Left;
int y = windowrc.Top;
x += borderwidth / 2;
y += borderheight / 2;
width -= borderwidth;
height -= borderheight;
if (width < 375 || height < 812)
{
return;
}
//SettingManager.Instance.SetString("UNITY_STANDALONE_WIN_POS_AND_SIZE", string.Format($"{x}*{y}*{width}*{height}"));
}
//最小化窗口
public static void SetMinWindows()
{
if (windowHandler == IntPtr.Zero) return;
ShowWindow(windowHandler, SW_SHOWMINIMIZED);
//具体窗口参数看这 https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
}
/// <summary>
/// 最大化窗口
/// </summary>
public static void SetMaxWindows()
{
if (windowHandler == IntPtr.Zero) return;
int currMaxScreenHeight = Screen.currentResolution.height - GetTaskBarHeight();
SetWindowPos(windowHandler, 0, 0, 0, Screen.currentResolution.width, currMaxScreenHeight, SWP_SHOWWINDOW);
//ShowWindow(windowHandler, SW_SHOWMAXIMIZED);
}
public static bool SetCenterNoFrameWindow(int width, int height)
{
int startX = (Display.main.systemWidth - width) / 2;
int startY = (Display.main.systemHeight - height) / 2;
return SetNoFrameWindow(startX, startY, width, height);
}
public static bool SetUpperLeftNoFrameWindow(int width, int height)
{
int startX = 0;
int startY = 0;
return SetNoFrameWindow(startX, startY, width, height);
}
/// <summary>
/// 设置无边框,窗口位置及分辨率
/// </summary>
/// <param name="rect">尺寸数据</param>
public static bool SetNoFrameWindow(int x, int y, int width, int height)
{
if (windowHandler == IntPtr.Zero) return false;
SetForegroundWindow(windowHandler);
//去除上边栏(不可拖拽缩放)
SetWindowLong(windowHandler, GWL_STYLE, WS_POPUP);
//设置窗口位置及分辨率
bool result = SetWindowPos(windowHandler, 0, x, y, width, height, SWP_SHOWWINDOW);
return result;
}
public static bool SetCenterNoResizeWindow(int width, int height)
{
int startX = (Display.main.systemWidth - width) / 2;
int startY = (Display.main.systemHeight - height) / 2;
return SetNoResizeWindow(startX, startY, width, height);
}
public static bool SetUpperLeftNoResizeWindow(int width, int height)
{
int startX = 0;
int startY = 0;
return SetNoResizeWindow(startX, startY, width, height);
}
/// <summary>
/// 设置不可调整大小,窗口位置及分辨率
/// </summary>
/// <param name="rect">尺寸数据</param>
public static bool SetNoResizeWindow(int x, int y, int width, int height)
{
if (windowHandler == IntPtr.Zero) return false;
SetForegroundWindow(windowHandler);
//设置不可缩放
SetWindowLong(windowHandler, GWL_STYLE, GetWindowLong(windowHandler, GWL_STYLE) & ~WS_THICKFRAME);
RECT clientrc = new RECT();
GetClientRect(windowHandler, ref clientrc); //获得窗口客户区大小
RECT windowrc = new RECT();
GetWindowRect(windowHandler, ref windowrc); //获得窗口大小
int borderwidth = (windowrc.Right - windowrc.Left) - (clientrc.Right - clientrc.Left);
int borderheight = (windowrc.Bottom - windowrc.Top) - (clientrc.Bottom - clientrc.Top);
x -= borderwidth / 2;
y -= borderheight / 2;
width += borderwidth;
height += borderheight;
//设置窗口位置及分辨率
bool result = SetWindowPos(windowHandler, 0, x, y, width, height, SWP_SHOWWINDOW);
return result;
}
/// <summary>
/// 改变标题栏标题
/// </summary>
public static void ChangeTitleText()
{
if (windowHandler == IntPtr.Zero) return;
SetWindowText(windowHandler, string.Empty);
}
/// <summary>
/// 获取当前窗口尺寸
/// </summary>
/// <returns></returns>
public static Rect GetWindowInfo()
{
if (windowHandler == IntPtr.Zero) return new Rect();
RECT rect = new RECT();
Rect targetRect = new Rect();
GetWindowRect(windowHandler, ref rect);
targetRect.width = Mathf.Abs(rect.Right - rect.Left);
targetRect.height = Mathf.Abs(rect.Top - rect.Bottom);
targetRect.x = rect.Left;
targetRect.y = rect.Top;
return targetRect;
}
/// <summary>
/// 获取任务栏高度
/// </summary>
/// <returns>任务栏高度</returns>
private static int GetTaskBarHeight()
{
int taskbarHeight = 10;
IntPtr hWnd = FindWindow("Shell_TrayWnd", 0);
RECT rect = new RECT();
GetWindowRect(hWnd, ref rect);
taskbarHeight = rect.Bottom - rect.Top;
return taskbarHeight;
}
#endif
}