Unity使用Windows原生user32.dll接口调整窗口分辨率
使用user32.dll的API
//窗口样式
[DllImport("user32.dll")]
static extern IntPtr SetWindowLong(IntPtr hwnd, int _nIndex, int dwNewLong);
//窗口分辨率和位置
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
//获取当前激活窗口
[DllImport("user32.dll", EntryPoint = "GetForegroundWindow")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern IntPtr FindWindow(string strClassName, int nptWindowName);
//窗口拖动
[DllImport("user32.dll")]
public static extern bool ReleaseCapture();
[DllImport("user32.dll")]
public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
[DllImport("user32.dll", SetLastError = true)]
//得到窗口的样式
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
public static extern bool ShowWindow(System.IntPtr hwnd, int nCmdShow);
//获取窗口位置以及大小
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
使用的参数
private const int SWP_SHOWWINDOW = 0x0040;
//边框样式
private const int GWL_STYLE = -16;
private const int GWL_EXSTYLE = -20;
//窗口有细线边框
private const int WS_BORDER = 1;
//窗口有一个最大化按钮
private const int WS_MAXIMIZEBOX = 0x00010000;
//窗口有一个最小化按钮
private const int WS_MINIMIZEBOX = 0x00020000;
//窗口是一个重叠窗口。重叠窗口有标题栏和边框。
private const int WS_OVERLAPPED = 0x00000000;
//有标题栏
private const int WS_TILEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
//隐藏标题栏图标
private const int WS_POPUP = 0x800000;
//窗口的标题栏上有一个窗口菜单。也必须指定ws_CAPTION样式。
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;
无标题栏窗口分辨率修改
/// <summary>
/// 隐藏标题栏修改分辨率
/// </summary>
/// <param name="winWidth"></param>
/// <param name="winHeight"></param>
/// <param name="winPosX"></param>
/// <param name="winPosY"></param>
void ChangeScreenSizeHide(int winWidth, int winHeight, int winPosX, int winPosY)
{
if (titleBarStyles== TitleBarStyles.Show)
{
//去除标题栏(不可拖拽缩放);一定要加SetWindowPos()设置才会立即生效
SetWindowLong(GetForegroundWindow(), GWL_STYLE, WS_POPUP);
//去除标题栏(可拖拽缩放)
//SetWindowLong(GetForegroundWindow(), GWL_STYLE, GetWindowLong(GetForegroundWindow(), GWL_STYLE) & ~WS_CAPTION | WS_THICKFRAME);
}
ChangeScreenSize(winWidth, winHeight, winPosX, winPosY);
titleBarStyles = TitleBarStyles.Hide;
}
有标题栏窗口分辨率修改
//不隐藏标题栏修改分辨率
void ChangeScreenSizeShow(int winWidth, int winHeight, int winPosX, int winPosY)
{
if (titleBarStyles == TitleBarStyles.Hide)
{
SetWindowLong(GetForegroundWindow(), GWL_STYLE, GetWindowLong(GetForegroundWindow(), GWL_STYLE) | WS_TILEDWINDOW);
}
ChangeScreenSize(winWidth, winHeight, winPosX, winPosY);
titleBarStyles = TitleBarStyles.Show;
}
窗口最大化
/// <summary>
/// 窗口最大化
/// </summary>
public void SetMaxWindows()
{
int currMaxScreenHeight = Screen.currentResolution.height - GetTaskBarHeight();
SetWindowPos(GetForegroundWindow(), 0, 0, 0, Screen.currentResolution.width, currMaxScreenHeight, SWP_SHOWWINDOW);
}
/// <summary>
/// 获取任务栏高度
/// </summary>
/// <returns>任务栏高度</returns>
private int GetTaskBarHeight()
{
int taskbarHeight = 0;
IntPtr hWnd = FindWindow("Shell_TrayWnd", 0);
RECT rect = new RECT();
GetWindowRect(hWnd, ref rect);
taskbarHeight = (int)rect.Bottom - (int)rect.Top;
Debug.Log(taskbarHeight);
return taskbarHeight;
}
窗口最小化
/// <summary>
/// 最小化窗口
/// </summary>
public void SetMinWindows()
{
ShowWindow(GetForegroundWindow(), SW_SHOWMINIMIZED);
}
窗口拖动
/// <summary>
/// 拖动窗口
/// </summary>
/// <param name="window">当前句柄</param>
public void DragWindow()
{
ReleaseCapture();
SendMessage(GetForegroundWindow(), 0xA1, 0x02, 0);
SendMessage(GetForegroundWindow(), 0x0202, 0, 0);
}
全屏
/// <summary>
/// 全屏
/// </summary>
public void SetFullScreen()
{
ShowWindow(GetForegroundWindow(), SW_SHOWMAXIMIZED);
}
完整代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;
public class ScreenResolution : MonoBehaviour
{
//窗口样式
[DllImport("user32.dll")]
static extern IntPtr SetWindowLong(IntPtr hwnd, int _nIndex, int dwNewLong);
//窗口分辨率和位置
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
//获取当前激活窗口
[DllImport("user32.dll", EntryPoint = "GetForegroundWindow")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern IntPtr FindWindow(string strClassName, int nptWindowName);
//窗口拖动
[DllImport("user32.dll")]
public static extern bool ReleaseCapture();
[DllImport("user32.dll")]
public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
[DllImport("user32.dll", SetLastError = true)]
//得到窗口的样式
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
public static extern bool ShowWindow(System.IntPtr hwnd, int nCmdShow);
//获取窗口位置以及大小
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left; //最左坐标
public int Top; //最上坐标
public int Right; //最右坐标
public int Bottom; //最下坐标
}
public enum TitleBarStyles
{
Hide, Show
}
private const int SWP_SHOWWINDOW = 0x0040;
//边框样式
private const int GWL_STYLE = -16;
private const int GWL_EXSTYLE = -20;
//窗口有细线边框
private const int WS_BORDER = 1;
//窗口有一个最大化按钮
private const int WS_MAXIMIZEBOX = 0x00010000;
//窗口有一个最小化按钮
private const int WS_MINIMIZEBOX = 0x00020000;
//窗口是一个重叠窗口。重叠窗口有标题栏和边框。
private const int WS_OVERLAPPED = 0x00000000;
//有标题栏
private const int WS_TILEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
//隐藏标题栏图标
private const int WS_POPUP = 0x800000;
//窗口的标题栏上有一个窗口菜单。也必须指定ws_CAPTION样式。
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;
/// <summary>
/// 隐藏标题栏修改分辨率
/// </summary>
/// <param name="winWidth"></param>
/// <param name="winHeight"></param>
/// <param name="winPosX"></param>
/// <param name="winPosY"></param>
void ChangeScreenSizeHide(int winWidth, int winHeight, int winPosX, int winPosY)
{
if (titleBarStyles== TitleBarStyles.Show)
{
//去除标题栏(不可拖拽缩放);一定要加SetWindowPos()设置才会立即生效
SetWindowLong(GetForegroundWindow(), GWL_STYLE, WS_POPUP);
//去除标题栏(可拖拽缩放)
//SetWindowLong(GetForegroundWindow(), GWL_STYLE, GetWindowLong(GetForegroundWindow(), GWL_STYLE) & ~WS_CAPTION | WS_THICKFRAME);
}
ChangeScreenSize(winWidth, winHeight, winPosX, winPosY);
titleBarStyles = TitleBarStyles.Hide;
}
//不隐藏标题栏修改分辨率
void ChangeScreenSizeShow(int winWidth, int winHeight, int winPosX, int winPosY)
{
if (titleBarStyles == TitleBarStyles.Hide)
{
SetWindowLong(GetForegroundWindow(), GWL_STYLE, GetWindowLong(GetForegroundWindow(), GWL_STYLE) | WS_TILEDWINDOW);
}
ChangeScreenSize(winWidth, winHeight, winPosX, winPosY);
titleBarStyles = TitleBarStyles.Show;
}
/// <summary>
/// 修改分辨率
/// </summary>
/// <param name="winWidth"></param>
/// <param name="winHeight"></param>
/// <param name="winPosX"></param>
/// <param name="winPosY"></param>
/// <param name="winPoscy"></param>
void ChangeScreenSize(int winWidth, int winHeight, int winPosX, int winPosY)
{
SetWindowPos(GetForegroundWindow(), 0, winPosX - (int)(winWidth * 0.5f), winPosY - (int)(winHeight * 0.5f), winWidth, winHeight, SWP_SHOWWINDOW);
}
void Delay(float seconds, Action onFinished)
{
StartCoroutine(DelayCoroutione(seconds, onFinished));
}
private IEnumerator DelayCoroutione(float seconds, Action onFinished)
{
yield return new WaitForSeconds(seconds);
onFinished();
}
/// <summary>
/// 窗口最大化
/// </summary>
public void SetMaxWindows()
{
int currMaxScreenHeight = Screen.currentResolution.height - GetTaskBarHeight();
ChangeScreenSizeHide(Screen.currentResolution.width, currMaxScreenHeight, (int)(Screen.currentResolution.width * 0.5f), (int)(currMaxScreenHeight * 0.5f));
// SetWindowPos(GetForegroundWindow(), 0, 0, 0, Screen.currentResolution.width, currMaxScreenHeight, SWP_SHOWWINDOW);
}
/// <summary>
/// 获取任务栏高度
/// </summary>
/// <returns>任务栏高度</returns>
private int GetTaskBarHeight()
{
int taskbarHeight = 0;
IntPtr hWnd = FindWindow("Shell_TrayWnd", 0);
RECT rect = new RECT();
GetWindowRect(hWnd, ref rect);
taskbarHeight = (int)rect.Bottom - (int)rect.Top;
Debug.Log(taskbarHeight);
return taskbarHeight;
}
/// <summary>
/// 拖动窗口
/// </summary>
/// <param name="window">当前句柄</param>
public void DragWindow()
{
ReleaseCapture();
SendMessage(GetForegroundWindow(), 0xA1, 0x02, 0);
SendMessage(GetForegroundWindow(), 0x0202, 0, 0);
}
/// <summary>
/// 最小化窗口
/// </summary>
public void SetMinWindows()
{
ShowWindow(GetForegroundWindow(), SW_SHOWMINIMIZED);
}
/// <summary>
/// 全屏
/// </summary>
public void SetFullScreen()
{
ShowWindow(GetForegroundWindow(), SW_SHOWMAXIMIZED);
}
}