support fullscreen
This commit is contained in:
parent
59ac54063e
commit
ebe3fa1e6b
|
|
@ -64,6 +64,7 @@ namespace easy2d
|
||||||
options.width,
|
options.width,
|
||||||
options.height,
|
options.height,
|
||||||
options.icon,
|
options.icon,
|
||||||
|
options.fullscreen,
|
||||||
Application::WndProc,
|
Application::WndProc,
|
||||||
debug_
|
debug_
|
||||||
)
|
)
|
||||||
|
|
@ -264,14 +265,8 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
{
|
{
|
||||||
PAINTSTRUCT ps;
|
|
||||||
::BeginPaint(hwnd, &ps);
|
|
||||||
|
|
||||||
app->Update();
|
app->Update();
|
||||||
app->Render(hwnd);
|
app->Render(hwnd);
|
||||||
|
|
||||||
::EndPaint(hwnd, &ps);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ namespace easy2d
|
||||||
int height; // 高度
|
int height; // 高度
|
||||||
LPCWSTR icon; // 图标
|
LPCWSTR icon; // 图标
|
||||||
bool vsync; // 垂直同步
|
bool vsync; // 垂直同步
|
||||||
|
bool fullscreen; // 全屏模式
|
||||||
bool debug; // 调试模式
|
bool debug; // 调试模式
|
||||||
|
|
||||||
Options()
|
Options()
|
||||||
|
|
@ -43,6 +44,7 @@ namespace easy2d
|
||||||
, height(480)
|
, height(480)
|
||||||
, icon(nullptr)
|
, icon(nullptr)
|
||||||
, vsync(true)
|
, vsync(true)
|
||||||
|
, fullscreen(false)
|
||||||
, debug(false)
|
, debug(false)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,6 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
Scene::Scene()
|
Scene::Scene()
|
||||||
{
|
{
|
||||||
//AddListener(WindowEvent::Activate, Closure(this, &Scene::OnActivate));
|
|
||||||
//AddListener(WindowEvent::Deavtivate, Closure(this, &Scene::OnDeactivate));
|
|
||||||
|
|
||||||
scene_ = this;
|
scene_ = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,12 +43,4 @@ namespace easy2d
|
||||||
E2D_LOG(L"Scene exited");
|
E2D_LOG(L"Scene exited");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::OnDeactivate(Event const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scene::OnActivate(Event const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,5 @@ namespace easy2d
|
||||||
|
|
||||||
// 退出场景
|
// 退出场景
|
||||||
virtual void OnExit();
|
virtual void OnExit();
|
||||||
|
|
||||||
// 窗口获得焦点
|
|
||||||
virtual void OnActivate(Event const&);
|
|
||||||
|
|
||||||
// 窗口失去焦点
|
|
||||||
virtual void OnDeactivate(Event const&);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,9 @@
|
||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
#include "../math/scalar.hpp"
|
#include "../math/scalar.hpp"
|
||||||
|
|
||||||
#define WINDOW_STYLE WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME
|
#define WINDOW_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
|
||||||
#define REGISTER_CLASS L"Easy2DApp"
|
#define WINDOW_FULLSCREEN_STYLE WS_CLIPCHILDREN | WS_POPUP
|
||||||
|
#define E2D_WND_CLASS_NAME L"Easy2DAppWnd"
|
||||||
|
|
||||||
namespace easy2d
|
namespace easy2d
|
||||||
{
|
{
|
||||||
|
|
@ -32,7 +33,7 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
void GetContentScale(float* scale_x, float* scale_y);
|
void GetContentScale(float* scale_x, float* scale_y);
|
||||||
|
|
||||||
Rect LocateWindow(int width, int height, float scale_x, float scale_y);
|
void AdjustWindow(UINT width, UINT height, DWORD style, float scalex, float scaley, UINT* win_width, UINT* win_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::Window()
|
Window::Window()
|
||||||
|
|
@ -47,14 +48,14 @@ namespace easy2d
|
||||||
E2D_LOG(L"Destroying window");
|
E2D_LOG(L"Destroying window");
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT Window::Init(String title, int width, int height, LPCWSTR icon, WNDPROC proc, bool debug)
|
HRESULT Window::Init(String title, int width, int height, LPCWSTR icon, bool fullscreen, WNDPROC proc, bool debug)
|
||||||
{
|
{
|
||||||
E2D_LOG(L"Creating window");
|
E2D_LOG(L"Creating window");
|
||||||
|
|
||||||
HINSTANCE hinstance = GetModuleHandle(nullptr);
|
HINSTANCE hinstance = GetModuleHandle(nullptr);
|
||||||
WNDCLASSEX wcex = { 0 };
|
WNDCLASSEX wcex = { 0 };
|
||||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||||
wcex.lpszClassName = REGISTER_CLASS;
|
wcex.lpszClassName = E2D_WND_CLASS_NAME;
|
||||||
wcex.style = CS_HREDRAW | CS_VREDRAW /* | CS_DBLCLKS */;
|
wcex.style = CS_HREDRAW | CS_VREDRAW /* | CS_DBLCLKS */;
|
||||||
wcex.lpfnWndProc = proc;
|
wcex.lpfnWndProc = proc;
|
||||||
wcex.hIcon = nullptr;
|
wcex.hIcon = nullptr;
|
||||||
|
|
@ -67,7 +68,7 @@ namespace easy2d
|
||||||
|
|
||||||
if (icon)
|
if (icon)
|
||||||
{
|
{
|
||||||
wcex.hIcon = (HICON)::LoadImage(
|
wcex.hIcon = (HICON)::LoadImageW(
|
||||||
hinstance,
|
hinstance,
|
||||||
icon,
|
icon,
|
||||||
IMAGE_ICON,
|
IMAGE_ICON,
|
||||||
|
|
@ -78,23 +79,86 @@ namespace easy2d
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wcex.hIcon = ::LoadIcon(nullptr, IDI_APPLICATION);
|
wcex.hIcon = ::LoadIconW(nullptr, IDI_APPLICATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
::RegisterClassEx(&wcex);
|
::RegisterClassExW(&wcex);
|
||||||
|
|
||||||
|
int left = -1;
|
||||||
|
int top = -1;
|
||||||
|
|
||||||
|
HMONITOR monitor = nullptr;
|
||||||
|
MONITORINFOEX monitor_info_ex;
|
||||||
|
|
||||||
|
// Get the nearest monitor to this window
|
||||||
|
POINT anchor;
|
||||||
|
anchor.x = left;
|
||||||
|
anchor.y = top;
|
||||||
|
monitor = MonitorFromPoint(anchor, MONITOR_DEFAULTTOPRIMARY);
|
||||||
|
|
||||||
|
// Get the target monitor info
|
||||||
|
memset(&monitor_info_ex, 0, sizeof(MONITORINFOEX));
|
||||||
|
monitor_info_ex.cbSize = sizeof(MONITORINFOEX);
|
||||||
|
GetMonitorInfoW(monitor, &monitor_info_ex);
|
||||||
|
|
||||||
GetContentScale(&scale_x, &scale_y);
|
GetContentScale(&scale_x, &scale_y);
|
||||||
|
|
||||||
Rect client_rect = LocateWindow(width, height, scale_x, scale_y);
|
if (fullscreen)
|
||||||
|
{
|
||||||
|
top = monitor_info_ex.rcMonitor.top;
|
||||||
|
left = monitor_info_ex.rcMonitor.left;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UINT screenw = monitor_info_ex.rcWork.right - monitor_info_ex.rcWork.left;
|
||||||
|
UINT screenh = monitor_info_ex.rcWork.bottom - monitor_info_ex.rcWork.top;
|
||||||
|
|
||||||
|
UINT win_width, win_height;
|
||||||
|
AdjustWindow(
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
fullscreen ? (WINDOW_FULLSCREEN_STYLE) : (WINDOW_STYLE),
|
||||||
|
scale_x,
|
||||||
|
scale_y,
|
||||||
|
&win_width,
|
||||||
|
&win_height
|
||||||
|
);
|
||||||
|
|
||||||
|
left = monitor_info_ex.rcWork.left + (screenw - win_width) / 2;
|
||||||
|
top = monitor_info_ex.rcWork.top + (screenh - win_height) / 2;
|
||||||
|
width = win_width;
|
||||||
|
height = win_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width > monitor_info_ex.rcWork.right - left)
|
||||||
|
width = monitor_info_ex.rcWork.right - left;
|
||||||
|
|
||||||
|
if (height > monitor_info_ex.rcWork.bottom - top)
|
||||||
|
height = monitor_info_ex.rcWork.bottom - top;
|
||||||
|
|
||||||
|
if (fullscreen)
|
||||||
|
{
|
||||||
|
DEVMODE mode;
|
||||||
|
memset(&mode, 0, sizeof(mode));
|
||||||
|
mode.dmSize = sizeof(DEVMODE);
|
||||||
|
mode.dmBitsPerPel = fullscreen ? 32 : (::GetDeviceCaps(GetDC(0), BITSPIXEL));
|
||||||
|
mode.dmPelsWidth = width;
|
||||||
|
mode.dmPelsHeight = height;
|
||||||
|
mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
|
||||||
|
|
||||||
|
if (DISP_CHANGE_SUCCESSFUL != ::ChangeDisplaySettingsExW(monitor_info_ex.szDevice, &mode, NULL, CDS_FULLSCREEN, NULL))
|
||||||
|
logs::Errorln(L"ChangeDisplaySettings failed");
|
||||||
|
}
|
||||||
|
|
||||||
handle = ::CreateWindowExW(
|
handle = ::CreateWindowExW(
|
||||||
NULL,
|
fullscreen ? (WS_EX_TOPMOST) : 0,
|
||||||
REGISTER_CLASS,
|
E2D_WND_CLASS_NAME,
|
||||||
title.c_str(),
|
title.c_str(),
|
||||||
WINDOW_STYLE,
|
fullscreen ? (WINDOW_FULLSCREEN_STYLE) : (WINDOW_STYLE),
|
||||||
static_cast<int>(client_rect.origin.x),
|
left,
|
||||||
static_cast<int>(client_rect.origin.y),
|
top,
|
||||||
static_cast<int>(client_rect.size.x),
|
width,
|
||||||
static_cast<int>(client_rect.size.y),
|
height,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
hinstance,
|
hinstance,
|
||||||
|
|
@ -103,7 +167,7 @@ namespace easy2d
|
||||||
|
|
||||||
if (handle == nullptr)
|
if (handle == nullptr)
|
||||||
{
|
{
|
||||||
::UnregisterClass(REGISTER_CLASS, hinstance);
|
::UnregisterClass(E2D_WND_CLASS_NAME, hinstance);
|
||||||
return HRESULT_FROM_WIN32(GetLastError());
|
return HRESULT_FROM_WIN32(GetLastError());
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
@ -150,22 +214,6 @@ namespace easy2d
|
||||||
return GetSize().y;
|
return GetSize().y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::SetSize(int width, int height)
|
|
||||||
{
|
|
||||||
if (handle)
|
|
||||||
{
|
|
||||||
Rect rect = LocateWindow(width, height, scale_x, scale_y);
|
|
||||||
::MoveWindow(
|
|
||||||
handle,
|
|
||||||
static_cast<int>(rect.origin.x),
|
|
||||||
static_cast<int>(rect.origin.y),
|
|
||||||
static_cast<int>(rect.size.x),
|
|
||||||
static_cast<int>(rect.size.y),
|
|
||||||
TRUE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::SetIcon(LPCWSTR icon_resource)
|
void Window::SetIcon(LPCWSTR icon_resource)
|
||||||
{
|
{
|
||||||
if (handle)
|
if (handle)
|
||||||
|
|
@ -222,34 +270,28 @@ namespace easy2d
|
||||||
*scale_y = ydpi / DEFAULT_SCREEN_DPI;
|
*scale_y = ydpi / DEFAULT_SCREEN_DPI;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect LocateWindow(int width, int height, float scale_x, float scale_y)
|
void AdjustWindow(UINT width, UINT height, DWORD style, float scalex, float scaley, UINT* win_width, UINT* win_height)
|
||||||
{
|
{
|
||||||
int max_width = ::GetSystemMetrics(SM_CXSCREEN);
|
RECT rc;
|
||||||
int max_height = ::GetSystemMetrics(SM_CYSCREEN);
|
::SetRect(&rc, 0, 0, (int)math::Ceil(width * scalex), (int)math::Ceil(height * scaley));
|
||||||
RECT rect =
|
::AdjustWindowRect(&rc, style, false);
|
||||||
{
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
static_cast<LONG>(math::Ceil(width * scale_x)),
|
|
||||||
static_cast<LONG>(math::Ceil(height * scale_y))
|
|
||||||
};
|
|
||||||
|
|
||||||
::AdjustWindowRectEx(&rect, WINDOW_STYLE, FALSE, NULL);
|
*win_width = rc.right - rc.left;
|
||||||
width = static_cast<int>(rect.right - rect.left);
|
*win_height = rc.bottom - rc.top;
|
||||||
height = static_cast<int>(rect.bottom - rect.top);
|
|
||||||
|
|
||||||
if (max_width < width || max_height < height)
|
HMONITOR monitor = ::MonitorFromWindow(NULL, MONITOR_DEFAULTTONEAREST);
|
||||||
logs::Warningln(L"The window is larger than screen!");
|
MONITORINFO monitor_info;
|
||||||
|
::memset(&monitor_info, 0, sizeof(MONITORINFO));
|
||||||
|
monitor_info.cbSize = sizeof(MONITORINFO);
|
||||||
|
::GetMonitorInfoW(monitor, &monitor_info);
|
||||||
|
|
||||||
width = std::min(width, max_width);
|
long max_width = monitor_info.rcWork.right - monitor_info.rcWork.left;
|
||||||
height = std::min(height, max_height);
|
long max_height = monitor_info.rcWork.bottom - monitor_info.rcWork.top;
|
||||||
|
|
||||||
return Rect(
|
if (*win_width > static_cast<UINT>(max_width))
|
||||||
static_cast<float>((max_width - width) / 2),
|
*win_width = max_width;
|
||||||
static_cast<float>((max_height - height) / 2),
|
if (*win_height > static_cast<UINT>(max_height))
|
||||||
static_cast<float>(width),
|
*win_height = max_height;
|
||||||
static_cast<float>(height)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ namespace easy2d
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
LPCWSTR icon,
|
LPCWSTR icon,
|
||||||
|
bool fullscreen,
|
||||||
WNDPROC proc,
|
WNDPROC proc,
|
||||||
bool debug
|
bool debug
|
||||||
);
|
);
|
||||||
|
|
@ -42,9 +43,6 @@ namespace easy2d
|
||||||
// 获取标题
|
// 获取标题
|
||||||
String GetTitle() const;
|
String GetTitle() const;
|
||||||
|
|
||||||
// 设置标题
|
|
||||||
void SetTitle(String const& title);
|
|
||||||
|
|
||||||
// 获取窗口大小
|
// 获取窗口大小
|
||||||
Size GetSize() const;
|
Size GetSize() const;
|
||||||
|
|
||||||
|
|
@ -54,8 +52,8 @@ namespace easy2d
|
||||||
// 获取窗口高度
|
// 获取窗口高度
|
||||||
float GetHeight() const;
|
float GetHeight() const;
|
||||||
|
|
||||||
// 重设窗口大小
|
// ÉèÖñêÌâ
|
||||||
void SetSize(int width, int height);
|
void SetTitle(String const& title);
|
||||||
|
|
||||||
// 设置窗口图标
|
// 设置窗口图标
|
||||||
void SetIcon(LPCWSTR icon_resource);
|
void SetIcon(LPCWSTR icon_resource);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue