功能实现:去除unity发布的exe程序的windows窗口边框,最小化当前程序,并实现窗口拖动。
1,先导入系统方法,并设置一些系统参数 : 代码如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
using System;
/*xbb
* 系统方法类
* */
public class WindowsTools {
//设置当前窗口的显示状态
[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")]
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")]
public static extern bool ReleaseCapture();
[DllImport("user32.dll")]
public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
//边框参数
const uint SWP_SHOWWINDOW = 0x0040;
const int GWL_STYLE = -16;
const int WS_BORDER = 1;
const int WS_POPUP = 0x800000;
const int SW_SHOWMINIMIZED = 2;//(最小化窗口)
//最小化窗口
public void SetMinWindows()
{
ShowWindow(GetForegroundWindow(), SW_SHOWMINIMIZED);
//具体窗口参数看这 https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
}
//设置无边框,并设置框体大小,位置
public void SetNoFrameWindow(Rect rect)
{
SetWindowLong(GetForegroundWindow(), GWL_STYLE, WS_POPUP);
bool result = SetWindowPos(GetForegroundWindow(), 0, (int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height, SWP_SHOWWINDOW);
}
//拖动窗口
public void DragWindow(IntPtr window)
{
ReleaseCapture();
SendMessage(window, 0xA1, 0x02, 0);
SendMessage(window, 0x0202, 0, 0);
}
}
2,随便写一个自己使用方便的方法管理类:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
/*xbb
*
* */
public class WindowsToolMgr : Singleton<WindowsToolMgr>
{
//系统方法类实体
public WindowsTools winTool = new WindowsTools();
//当前Unity程序进程
private static IntPtr currentWindow;
void Start()
{
currentWindow = WindowsTools.GetForegroundWindow();
}
//最小化窗口
public void MinWindows()
{
winTool.SetMinWindows();
}
//设置无边框窗口
public void SetNoFrame()
{
//窗口大小 以此为例
float windowWidth = 1024;
float windowHeight = 768;
//计算框体显示位置
float posX = (Screen.currentResolution.width - windowWidth) / 2;
float posY = (Screen.currentResolution.height - windowHeight) / 2;
Rect _rect = new Rect(posX, posY, windowWidth, windowHeight);
winTool.SetNoFrameWindow(_rect);
}
/// <summary>
/// 全屏
/// </summary>
public void FullScreen()
{
if (Screen.fullScreen)
{
Screen.SetResolution(1024, 768, false);
}
else
{
Screen.SetResolution(Screen.currentResolution.width, Screen.currentResolution.height, true);
}
//等待当前帧完成 再去除边框
StartCoroutine(IE_NoFrame());
}
private IEnumerator IE_NoFrame()
{
yield return new WaitForEndOfFrame();
yield return new WaitForFixedUpdate();
if (!Screen.fullScreen)
{
SetNoFrame();
}
}
//窗口拖动
public void Drag()
{
winTool.DragWindow(currentWindow);
}
}
3,好了,功能脚本有了,现在弄几个Botton测试一下功能:
初始效果:
去边框效果:
最小化效果: 当前窗口隐藏了(托管在任务栏)
但是Bug来了,我们一般时场景初始化的时候把窗口边框去掉,这个没问题,但是中途切换屏幕全屏之后,再切换回来,窗口边框又出现了!!! 效果如下:
问题原因:当我们执行取消全屏 Screen.SetResolution(1024, 768, false); 时,窗口边框又出来了!!。
那么是不是我们在取消全屏之后再执行一下去边框就可以了呢?如下:
结果发现然并卵,,这个坑啊,,在这里提醒各位兄弟!!!
在unity API 中发现了这个 :
最后那我们在当前帧完成之后再执行去边框就OK了。 如下:
拖动窗口功能:
1,实现UI拖动窗口功能
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
/*xbb
* 拖动窗口UI
* */
public class WindowDragObject : MonoBehaviour, IPointerDownHandler, IPointerExitHandler, IPointerUpHandler
{
private bool isDrag = false;
void Update()
{
if (isDrag ==true)
{
WindowsToolMgr.Instance.Drag();
}
}
public void OnPointerExit(PointerEventData eventData)
{
isDrag = false;
}
public void OnPointerUp(PointerEventData eventData)
{
isDrag = false;
}
public void OnPointerDown(PointerEventData eventData)
{
isDrag = true;
}
}
2,为UI添加功能脚本,并测试,效果如下
以上纯属个人总结, 欢迎各位同仁指正。
最后,奉上工程文件地址。
http://pan.baidu.com/s/1kUTQKmz