-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSample_ChangeWindowMode.cs
More file actions
159 lines (150 loc) · 5.85 KB
/
Sample_ChangeWindowMode.cs
File metadata and controls
159 lines (150 loc) · 5.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
using System;
using System.Collections;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;
namespace Emptybraces.ChangeWindowModeSample
{
public enum Mode { Windowed, Borderless, Fullscreen }
public class Sample_ChangeWindowMode : MonoBehaviour
{
[SerializeField] Button _buttonWindowed;
[SerializeField] Button _buttonBorderless;
[SerializeField] Button _buttonFullscreen;
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left; // x position of upper-left corner
public int Top; // y position of upper-left corner
public int Right; // x position of lower-right corner
public int Bottom; // y position of lower-right corner
}
// index for style and extended style flag management
const int GWL_STYLE = -16, GWL_EXSTYLE = -20, WS_CAPTION = 0x00C00000;
[DllImport("user32.dll", EntryPoint = "SetWindowLong", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", EntryPoint = "GetWindowLong", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
public static extern IntPtr FindWindow(IntPtr ZeroOnly, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "SetWindowText", SetLastError = true)]
public static extern bool SetWindowText(IntPtr hWnd, string lpString);
[DllImport("user32.dll", EntryPoint = "GetWindowRect", SetLastError = true)] public static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);
[DllImport("user32.dll", EntryPoint = "GetClientRect", SetLastError = true)]
public static extern bool GetClientRect(IntPtr hWnd, out RECT rect);
[DllImport("user32.dll", EntryPoint = "GetDesktopWindow", SetLastError = true)]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll", EntryPoint = "SetWindowPos", SetLastError = true)]
public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int uFlags);
IntPtr _hWnd;
int _borderWidth;
int _captionHeight;
#if UNITY_EDITOR
void OnGUI()
{
GUI.Label(new Rect(100, 100, 1000, 100), "Process results cannot be checked on the editor.");
}
#endif
void Start()
{
_hWnd = FindWindow(IntPtr.Zero, Application.productName);
#if !UNITY_EDITOR
SetWindowText(_hWnd, "Custom Window Title Name");
#endif
GetDecorationSize();
_buttonWindowed.onClick.AddListener(() => SetResolution(1280, 720, Mode.Windowed));
_buttonBorderless.onClick.AddListener(() => SetResolution(1280, 720, Mode.Borderless));
_buttonFullscreen.onClick.AddListener(() => SetResolution(1280, 720, Mode.Fullscreen));
}
void Update()
{
if (Input.GetKey(KeyCode.Escape))
Application.Quit();
}
public void SetResolution(int w, int h, Mode mode)
{
if (Application.isEditor)
return;
StartCoroutine(__Local(w, h, mode));
IEnumerator __Local(int w, int h, Mode mode)
{
switch (mode)
{
case Mode.Windowed:
Screen.SetResolution(w, h, false);
yield return null;
// ウィンドウスタイルの変更
var flags = (int)GetWindowLongPtr(_hWnd, GWL_STYLE);
flags |= WS_CAPTION;
SetWindowLongPtr(_hWnd, GWL_STYLE, flags);
GetDecorationSize();
// 位置の修正
var position = GetCenteredPosition(w, h, mode);
var windowWidth = w + _borderWidth * 2;
var windowHeight = h + _captionHeight + _borderWidth * 2;
SetWindowPos(_hWnd, -2, (int)position.x, (int)position.y, windowWidth, windowHeight, 0x0020);
break;
case Mode.Borderless:
h -= _captionHeight;
Screen.SetResolution(w, h, false);
yield return null;
flags = (int)GetWindowLongPtr(_hWnd, GWL_STYLE);
flags &= ~WS_CAPTION;
SetWindowLongPtr(_hWnd, GWL_STYLE, flags);
// 位置の修正
position = GetCenteredPosition(w, h, mode);
SetWindowPos(_hWnd, -2, (int)position.x, (int)position.y, w, h, 0x0020);
break;
case Mode.Fullscreen:
Screen.SetResolution(w, h, true);
break;
}
yield break;
}
Vector2 GetCenteredPosition(int w, int h, Mode mode)
{
// desktop rect
RECT desktopRect;
if (!GetWindowRect(GetDesktopWindow(), out desktopRect))
return Vector2.zero;
int desktopWidth = desktopRect.Right - desktopRect.Left;
int desktopHeight = desktopRect.Bottom - desktopRect.Top;
// determine the centered position for the specified resolution
int xPos, yPos;
if (mode == Mode.Windowed)
{
xPos = (desktopWidth - (w + _borderWidth * 2)) / 2;
yPos = (desktopHeight - (h + _borderWidth * 2 + _captionHeight)) / 2;
}
else
{
xPos = (desktopWidth - w) / 2;
yPos = (desktopHeight - h) / 2;
}
return new Vector2(xPos, yPos);
}
}
/// <summary>
/// Gets the window's current decoration size. If the window is in borderless mode, the results will be 0.
/// </summary>
bool GetDecorationSize()
{
if (_borderWidth != 0 || _captionHeight != 0)
return true;
// window and client rects
RECT windowRect, clientRect;
if (!GetWindowRect(_hWnd, out windowRect)) return false;
if (!GetClientRect(_hWnd, out clientRect)) return false;
// calculate decoration size
int decorationWidth = (windowRect.Right - windowRect.Left) - (clientRect.Right - clientRect.Left);
int decorationHeight = (windowRect.Bottom - windowRect.Top) - (clientRect.Bottom - clientRect.Top);
// some important assumptions are made here:
// 1) the window's frame only has border on the left and right
// 2) the window's frame only has an equal thickness border on the bottom
_borderWidth = decorationWidth / 2;
_captionHeight = decorationHeight - _borderWidth * 2;
Debug.Log(_borderWidth + " " + _captionHeight);
return true;
}
}
}