最近在做窗口模式切换和设置分辨率,发现Unity只有设置窗口或全屏切换的API,没有设置无边框窗口的API。于是我就在在网上找到了一种设置方法。
注意,该方法仅限windows系统。
引用用windows的user32.dll库,调用库里的方法,来设置窗口无边框:
/// <summary>
/// 使用查找任务栏
/// </summary>
/// <param name="strClassName"></param>
/// <param name="nptWindowName"></param>
/// <returns></returns>
[DllImport("user32.dll")]
static extern IntPtr FindWindow(string strClassName, int nptWindowName);
/// <summary>
/// 获取当前窗口
/// </summary>
/// <returns></returns>
[DllImport("user32.dll")] static extern IntPtr GetForegroundWindow();
/// <summary>
/// 获取窗口位置以及大小
/// </summary>
/// <param name="hWnd"></param>
/// <param name="lpRect"></param>
/// <returns></returns>
[DllImport("user32.dll")] static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left; //最左坐标
public int Top; //最上坐标
public int Right; //最右坐标
public int Bottom; //最下坐标
}
/// <summary>
/// 设置窗口位置,尺寸
/// </summary>
/// <param name="hWnd"></param>
/// <param name="hWndInsertAfter"></param>
/// <param name="X"></param>
/// <param name="Y"></param>
/// <param name="cx"></param>
/// <param name="cy"></param>
/// <param name="uFlags"></param>
/// <returns></returns>
[DllImport("user32.dll")] static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
/// <summary>
/// 设置windows自带边框
/// </summary>
/// <param name="hwnd"></param>
/// <param name="_nIndex"></param>
/// <param name="dwNewLong"></param>
/// <returns></returns>
[DllImport("user32.dll")] static extern IntPtr SetWindowLong(IntPtr hwnd, int _nIndex, int dwNewLong);
设置无边框模式时要注意,只能在窗口模式下设置无边框,全屏模式下设置无边框只会退出全屏变成窗口模式,所以在全屏模式下要先设置为窗口模式,再设置无边框。文章来源:https://www.toymoban.com/news/detail-844601.html
/// <summary>
/// 除任务栏外最大化窗口(无边框)
/// </summary>
public void WitnOutBorder()
{
//如果是全屏模式,要切换成窗口模式
if (Screen.fullScreen)
{
//新的分辨率(exe文件新的宽高) 这个是Unity里的设置屏幕大小,
//Screen.SetResolution((int)m_ScreenPosition.width, (int)m_ScreenPosition.height, false);
Screen.fullScreen = false;
}
StartCoroutine(WitnOutBorderCoroutine());
}
/// <summary>
/// 除任务栏外最大化窗口(无边框)协程
/// </summary>
private IEnumerator WitnOutBorderCoroutine()
{
//等待游戏变成窗口模式
while (Screen.fullScreen)
{
yield return null;
}
//新的屏幕宽度
m_ScreenPosition.width = m_Resolutions[0].width;
//新的屏幕高度=当前屏幕分辨率的高度-状态栏的高度
int currMaxScreenHeight = m_Resolutions[0].height - GetTaskBarHeight();
m_ScreenPosition.height = currMaxScreenHeight;
//m_ScreenPosition.x = (int)((Screen.currentResolution.width - m_ScreenPosition.width) / 2);//宽度居中
//m_ScreenPosition.y = (int)((Screen.currentResolution.height - m_ScreenPosition.height) / 2);//高度居中
//设置无框
SetWindowLong(GetForegroundWindow(), GWL_STYLE, WS_BORDER);
//exe居左上显示;
bool result = SetWindowPos(GetForegroundWindow(), 0, 0, 0, (int)m_ScreenPosition.width, (int)m_ScreenPosition.height, SWP_SHOWWINDOW);
//exe居中显示;
// bool result = SetWindowPos(GetForegroundWindow(), 0, (int)m_ScreenPosition.x, (int)m_ScreenPosition.y, (int)m_ScreenPosition.width, (int)m_ScreenPosition.height, SWP_SHOWWINDOW);
m_CurrResolution = string.Format("{0}x{1}", m_Resolutions[0].width, m_Resolutions[0].height);
GameEntry.Setting.SetString(Constant.Setting.Resolution, m_CurrResolution);
GameEntry.Setting.Save();
}
下面为窗口设置完整代码:文章来源地址https://www.toymoban.com/news/detail-844601.html
using GameFramework;
using GameMain;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using UnityEngine;
/// <summary>
/// 窗口模式
/// </summary>
public enum WindowMode
{
/// <summary>
/// 全屏
/// </summary>
FullScreen = 0,
/// <summary>
/// 窗口
/// </summary>
Windowed = 1,
/// <summary>
/// 无边框
/// </summary>
WitnOutBorder = 2
}
public class WindowSetting : MonoSingLeton<WindowSetting>
{
/// <summary>
/// 当前窗口模式
/// </summary>
private WindowMode m_CurrWindowMode;
/// <summary>
/// 当前窗口模式
/// </summary>
public WindowMode CurrWindowMode { get { return m_CurrWindowMode; } }
/// <summary>
/// 分辨率
/// </summary>
private string m_CurrResolution = string.Empty;
/// <summary>
/// 屏幕分辨率
/// </summary>
public string CurrResolution { get { return m_CurrResolution; } }
/// <summary>
/// 使用查找任务栏
/// </summary>
/// <param name="strClassName"></param>
/// <param name="nptWindowName"></param>
/// <returns></returns>
[DllImport("user32.dll")]
static extern IntPtr FindWindow(string strClassName, int nptWindowName);
/// <summary>
/// 获取当前窗口
/// </summary>
/// <returns></returns>
[DllImport("user32.dll")] static extern IntPtr GetForegroundWindow();
/// <summary>
/// 获取窗口位置以及大小
/// </summary>
/// <param name="hWnd"></param>
/// <param name="lpRect"></param>
/// <returns></returns>
[DllImport("user32.dll")] static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left; //最左坐标
public int Top; //最上坐标
public int Right; //最右坐标
public int Bottom; //最下坐标
}
/// <summary>
/// 设置窗口位置,尺寸
/// </summary>
/// <param name="hWnd"></param>
/// <param name="hWndInsertAfter"></param>
/// <param name="X"></param>
/// <param name="Y"></param>
/// <param name="cx"></param>
/// <param name="cy"></param>
/// <param name="uFlags"></param>
/// <returns></returns>
[DllImport("user32.dll")] static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
/// <summary>
/// 设置windows自带边框
/// </summary>
/// <param name="hwnd"></param>
/// <param name="_nIndex"></param>
/// <param name="dwNewLong"></param>
/// <returns></returns>
[DllImport("user32.dll")] static extern IntPtr SetWindowLong(IntPtr hwnd, int _nIndex, int dwNewLong);
const uint SWP_SHOWWINDOW = 0x0040;
const int GWL_STYLE = -16;
const int WS_BORDER = 1;
/// <summary>
/// 所有可选分辨率
/// </summary>
Resolution[] m_Resolutions;
/// <summary>
/// 当前屏幕可用分辨率
/// </summary>
public Resolution[] Resolutions { get { return m_Resolutions; } }
/// <summary>
/// 当前屏幕可用分辨率字典
/// </summary>
Dictionary<string, Resolution> m_ResolutionDic;
/// <summary>
/// 当前屏幕可用分辨率字典
/// </summary>
public Dictionary<string, Resolution> ResolutionDic { get { return m_ResolutionDic; } }
/// <summary>
/// 最终的屏幕的位置和长宽
/// </summary>
private Rect m_ScreenPosition;
protected override void Init()
{
base.Init();
m_ResolutionDic = new Dictionary<string, Resolution>();
for (int i = 0; i < Screen.resolutions.Length; i++)
{
string str = Utility.Text.Format("{0}x{1}", Screen.resolutions[i].width, Screen.resolutions[i].height);
m_ResolutionDic[str] = Screen.resolutions[i];
}
m_Resolutions = m_ResolutionDic.Values.ToArray();
Array.Reverse(m_Resolutions);
//获取保存在本地的窗口模式
m_CurrWindowMode = (WindowMode)GameEntry.Setting.GetInt(Constant.Setting.WindowMode, 0);
//获取保存在本地的分辨率
m_CurrResolution = GameEntry.Setting.GetString(Constant.Setting.Resolution, string.Format("{0}x{1}", m_Resolutions[0].width, m_Resolutions[0].height));
#if UNITY_EDITOR
#else
if(m_CurrWindowMode == WindowMode.WitnOutBorder)
{
WitnOutBorder();
}
#endif
}
public override void Dispose()
{
StopAllCoroutines();
base.Dispose();
}
/// <summary>
/// 设置窗口模式
/// </summary>
/// <param name="windowMode"></param>
public void SetWindowMode(WindowMode windowMode)
{
switch (windowMode)
{
case WindowMode.FullScreen:
SetResolution(m_CurrResolution, true);
break;
case WindowMode.Windowed:
SetResolution(m_CurrResolution, false);
break;
case WindowMode.WitnOutBorder:
WitnOutBorder();
break;
}
m_CurrWindowMode = windowMode;
//将当前窗口模式保存到本地
GameEntry.Setting.SetInt(Constant.Setting.WindowMode, (int)m_CurrWindowMode);
GameEntry.Setting.Save();
}
/// <summary>
/// 获取当前分辨率
/// </summary>
public Resolution GetCurrResolution()
{
if (m_ResolutionDic.ContainsKey(m_CurrResolution))
{
return m_ResolutionDic[m_CurrResolution];
}
return m_Resolutions[0];
}
/// <summary>
/// 设置分辨率
/// </summary>
/// <param name="width">宽</param>
/// <param name="height">高</param>
/// <param name="fullScreen">是否全屏</param>
public void SetResolution(int width, int height, bool fullScreen)
{
Screen.SetResolution(width, height, fullScreen);
m_CurrResolution = string.Format("{0}x{1}", width, height);
if (fullScreen)
m_CurrWindowMode = WindowMode.FullScreen;
else
m_CurrWindowMode = WindowMode.Windowed;
//将当前分辨率保存到本地
GameEntry.Setting.SetString(Constant.Setting.Resolution, m_CurrResolution);
GameEntry.Setting.Save();
}
/// <summary>
/// 设置分辨率
/// </summary>
/// <param name="index">当前屏幕可用分辨率m_Resolutions数组的下标</param>
/// <param name="fullScreen">是否全屏</param>
public void SetResolution(int index, bool fullScreen)
{
if (index < 0 && index > m_Resolutions.Length)
{
//错误index索引超出范围
return;
}
Screen.SetResolution(m_Resolutions[index].width, m_Resolutions[index].height, fullScreen);
m_CurrResolution = string.Format("{0}x{1}", m_Resolutions[index].width, m_Resolutions[index].height);
if (fullScreen)
m_CurrWindowMode = WindowMode.FullScreen;
else
m_CurrWindowMode = WindowMode.Windowed;
//将当前分辨率保存到本地
GameEntry.Setting.SetString(Constant.Setting.Resolution, m_CurrResolution);
GameEntry.Setting.Save();
}
/// <summary>
/// 设置分辨率
/// </summary>
/// <param name="resolutionStr"></param>
/// <param name="fullScreen"></param>
public void SetResolution(string resolutionStr, bool fullScreen)
{
if (m_ResolutionDic.ContainsKey(resolutionStr))
{
Resolution resolution = m_ResolutionDic[resolutionStr];
Screen.SetResolution(resolution.width, resolution.height, fullScreen);
m_CurrResolution = resolutionStr;
//将当前分辨率保存到本地
GameEntry.Setting.SetString(Constant.Setting.Resolution, m_CurrResolution);
GameEntry.Setting.Save();
}
}
/// <summary>
/// 获取当前窗口尺寸
/// </summary>
/// <returns></returns>
public Rect GetWindowInfo()
{
RECT rect = new RECT();
Rect targetRect = new Rect();
GetWindowRect(GetForegroundWindow(), 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 int GetTaskBarHeight()
{
int taskbarHeight = 10;
IntPtr hWnd = FindWindow("Shell_TrayWnd", 0); //找到任务栏窗口
RECT rect = new RECT();
GetWindowRect(hWnd, ref rect); //获取任务栏的窗口位置及大小
taskbarHeight = (int)(rect.Bottom - rect.Top); //得到任务栏的高度
return taskbarHeight;
}
/// <summary>
/// 除任务栏外最大化窗口(无边框)
/// </summary>
public void WitnOutBorder()
{
//如果是全屏模式,要切换成窗口模式
if (Screen.fullScreen)
{
//新的分辨率(exe文件新的宽高) 这个是Unity里的设置屏幕大小,
//Screen.SetResolution((int)m_ScreenPosition.width, (int)m_ScreenPosition.height, false);
Screen.fullScreen = false;
}
StartCoroutine(WitnOutBorderCoroutine());
}
/// <summary>
/// 除任务栏外最大化窗口(无边框)协程
/// </summary>
private IEnumerator WitnOutBorderCoroutine()
{
//等待游戏变成窗口模式
while (Screen.fullScreen)
{
yield return null;
}
//新的屏幕宽度
m_ScreenPosition.width = m_Resolutions[0].width;
//新的屏幕高度=当前屏幕分辨率的高度-状态栏的高度
int currMaxScreenHeight = m_Resolutions[0].height - GetTaskBarHeight();
m_ScreenPosition.height = currMaxScreenHeight;
//m_ScreenPosition.x = (int)((Screen.currentResolution.width - m_ScreenPosition.width) / 2);//宽度居中
//m_ScreenPosition.y = (int)((Screen.currentResolution.height - m_ScreenPosition.height) / 2);//高度居中
//设置无框
SetWindowLong(GetForegroundWindow(), GWL_STYLE, WS_BORDER);
//exe居左上显示;
bool result = SetWindowPos(GetForegroundWindow(), 0, 0, 0, (int)m_ScreenPosition.width, (int)m_ScreenPosition.height, SWP_SHOWWINDOW);
//exe居中显示;
// bool result = SetWindowPos(GetForegroundWindow(), 0, (int)m_ScreenPosition.x, (int)m_ScreenPosition.y, (int)m_ScreenPosition.width, (int)m_ScreenPosition.height, SWP_SHOWWINDOW);
m_CurrResolution = string.Format("{0}x{1}", m_Resolutions[0].width, m_Resolutions[0].height);
//将当前分辨率保存到本地
GameEntry.Setting.SetString(Constant.Setting.Resolution, m_CurrResolution);
GameEntry.Setting.Save();
}
/// <summary>
/// 设置全屏无边框
/// </summary>
private void Setposition()
{
SetWindowLong(GetForegroundWindow(), GWL_STYLE, WS_BORDER); //无边框
bool result = SetWindowPos(GetForegroundWindow(), 0, 0, 0, m_Resolutions[0].width, m_Resolutions[0].height, SWP_SHOWWINDOW);
}
}
到了这里,关于Unity 设置无边框窗口的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!