隐藏Window类创建过程

This commit is contained in:
Nomango 2018-07-03 23:39:00 +08:00
parent 59dd575e5b
commit 5c0fc8fc1e
3 changed files with 75 additions and 48 deletions

View File

@ -8,8 +8,9 @@ e2d::Window * e2d::Window::_instance = nullptr;
e2d::Window::Window() e2d::Window::Window()
: _hWnd(nullptr) : _hWnd(nullptr)
, _size() , _size(640, 480)
, _title() , _title(L"Easy2D Game")
, _iconID(0)
{ {
} }
@ -44,13 +45,12 @@ void e2d::Window::destroyInstance()
} }
} }
bool e2d::Window::create(const String& title, int width, int height) HWND e2d::Window::__create()
{ {
// 注册窗口类 // 注册窗口类
WNDCLASSEX wcex = { 0 }; WNDCLASSEX wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEX); wcex.cbSize = sizeof(WNDCLASSEX);
wcex.lpszClassName = L"Easy2DApp"; wcex.lpszClassName = L"Easy2DApp";
wcex.hIcon = nullptr;
wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = Window::WndProc; wcex.lpfnWndProc = Window::WndProc;
wcex.cbClsExtra = 0; wcex.cbClsExtra = 0;
@ -60,6 +60,22 @@ bool e2d::Window::create(const String& title, int width, int height)
wcex.lpszMenuName = nullptr; wcex.lpszMenuName = nullptr;
wcex.hCursor = ::LoadCursor(nullptr, IDC_ARROW); wcex.hCursor = ::LoadCursor(nullptr, IDC_ARROW);
if (this->_iconID != 0)
{
wcex.hIcon = (HICON)::LoadImage(
HINST_THISCOMPONENT,
MAKEINTRESOURCE(this->_iconID),
IMAGE_ICON,
0,
0,
LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE
);
}
else
{
wcex.hIcon = nullptr;
}
RegisterClassEx(&wcex); RegisterClassEx(&wcex);
// 因为 CreateWindow 函数使用的是像素大小,获取系统的 DPI 以使它 // 因为 CreateWindow 函数使用的是像素大小,获取系统的 DPI 以使它
@ -67,11 +83,11 @@ bool e2d::Window::create(const String& title, int width, int height)
float dpiScaleX = 0.f, dpiScaleY = 0.f; float dpiScaleX = 0.f, dpiScaleY = 0.f;
Renderer::getFactory()->GetDesktopDpi(&dpiScaleX, &dpiScaleY); Renderer::getFactory()->GetDesktopDpi(&dpiScaleX, &dpiScaleY);
int nWidth = static_cast<int>(ceil(width * dpiScaleX / 96.f)); int nWidth = static_cast<int>(ceil(this->_size.width * dpiScaleX / 96.f));
int nHeight = static_cast<int>(ceil(height * dpiScaleY / 96.f)); int nHeight = static_cast<int>(ceil(this->_size.height * dpiScaleY / 96.f));
// 计算窗口大小 // 计算窗口大小
DWORD dwStyle = WS_OVERLAPPEDWINDOW &~ WS_MAXIMIZEBOX &~ WS_THICKFRAME; DWORD dwStyle = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX &~WS_THICKFRAME;
RECT wr = { 0, 0, static_cast<LONG>(nWidth), static_cast<LONG>(nHeight) }; RECT wr = { 0, 0, static_cast<LONG>(nWidth), static_cast<LONG>(nHeight) };
::AdjustWindowRectEx(&wr, dwStyle, FALSE, NULL); ::AdjustWindowRectEx(&wr, dwStyle, FALSE, NULL);
// 获取新的宽高 // 获取新的宽高
@ -83,12 +99,12 @@ bool e2d::Window::create(const String& title, int width, int height)
int screenHeight = ::GetSystemMetrics(SM_CYSCREEN); int screenHeight = ::GetSystemMetrics(SM_CYSCREEN);
// 创建窗口 // 创建窗口
_hWnd = ::CreateWindowEx( HWND hWnd = ::CreateWindowEx(
NULL, NULL,
L"Easy2DApp", L"Easy2DApp",
(LPCTSTR)title, (LPCTSTR)this->_title,
dwStyle, dwStyle,
(screenWidth - nWidth) / 2, (screenHeight - nHeight) / 2, (screenWidth - nWidth) / 2, (screenHeight - nHeight) / 2,
nWidth, nHeight, nWidth, nHeight,
nullptr, nullptr,
nullptr, nullptr,
@ -96,7 +112,7 @@ bool e2d::Window::create(const String& title, int width, int height)
nullptr nullptr
); );
HRESULT hr = _hWnd ? S_OK : E_FAIL; HRESULT hr = hWnd ? S_OK : E_FAIL;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
@ -109,16 +125,12 @@ bool e2d::Window::create(const String& title, int width, int height)
HMENU hmenu = ::GetSystemMenu(consoleHWnd, FALSE); HMENU hmenu = ::GetSystemMenu(consoleHWnd, FALSE);
::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND); ::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND);
} }
this->_size = Size(width, height);
this->_title = title;
return true;
} }
else else
{ {
::UnregisterClass(L"Easy2DApp", HINST_THISCOMPONENT); ::UnregisterClass(L"Easy2DApp", HINST_THISCOMPONENT);
this->error(L"Create Window Failed!");
return false;
} }
return hWnd;
} }
void e2d::Window::__poll() void e2d::Window::__poll()
@ -154,43 +166,61 @@ e2d::String e2d::Window::getTitle()
HWND e2d::Window::getHWnd() HWND e2d::Window::getHWnd()
{ {
if (!_hWnd)
{
_hWnd = this->__create();
if (_hWnd == nullptr)
{
throw SystemException(L"注册窗口失败");
}
}
return _hWnd; return _hWnd;
} }
void e2d::Window::setSize(int width, int height) void e2d::Window::setSize(int width, int height)
{ {
// 计算窗口大小 this->_size = Size(width, height);
DWORD dwStyle = WS_OVERLAPPEDWINDOW &~ WS_MAXIMIZEBOX &~ WS_THICKFRAME; if (_hWnd)
RECT wr = { 0, 0, static_cast<LONG>(width), static_cast<LONG>(height) }; {
::AdjustWindowRectEx(&wr, dwStyle, FALSE, NULL); // 计算窗口大小
// 获取新的宽高 DWORD dwStyle = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX &~WS_THICKFRAME;
width = static_cast<int>(wr.right - wr.left); RECT wr = { 0, 0, static_cast<LONG>(width), static_cast<LONG>(height) };
height = static_cast<int>(wr.bottom - wr.top); ::AdjustWindowRectEx(&wr, dwStyle, FALSE, NULL);
// 获取屏幕分辨率 // 获取新的宽高
int screenWidth = ::GetSystemMetrics(SM_CXSCREEN); width = static_cast<int>(wr.right - wr.left);
int screenHeight = ::GetSystemMetrics(SM_CYSCREEN); height = static_cast<int>(wr.bottom - wr.top);
// 当输入的窗口大小比分辨率大时,给出警告 // 获取屏幕分辨率
WARN_IF(screenWidth < width || screenHeight < height, "The window is larger than screen!"); int screenWidth = ::GetSystemMetrics(SM_CXSCREEN);
// 取最小值 int screenHeight = ::GetSystemMetrics(SM_CYSCREEN);
width = min(width, screenWidth); // 当输入的窗口大小比分辨率大时,给出警告
height = min(height, screenHeight); WARN_IF(screenWidth < width || screenHeight < height, "The window is larger than screen!");
// 修改窗口大小,并设置窗口在屏幕居中 // 取最小值
::MoveWindow(_hWnd, (screenWidth - width) / 2, (screenHeight - height) / 2, width, height, TRUE); width = min(width, screenWidth);
height = min(height, screenHeight);
// 修改窗口大小,并设置窗口在屏幕居中
::MoveWindow(_hWnd, (screenWidth - width) / 2, (screenHeight - height) / 2, width, height, TRUE);
}
} }
void e2d::Window::setTitle(const String& title) void e2d::Window::setTitle(const String& title)
{ {
// 设置窗口标题 this->_title = title;
::SetWindowText(_hWnd, (LPCWSTR)title); if (_hWnd)
{
::SetWindowText(_hWnd, (LPCWSTR)title);
}
} }
void e2d::Window::setIcon(int iconID) void e2d::Window::setIcon(int iconID)
{ {
HINSTANCE hInstance = ::GetModuleHandle(nullptr); this->_iconID = iconID;
HICON hIcon = (HICON)::LoadImage(hInstance, MAKEINTRESOURCE(iconID), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); if (_hWnd)
// 设置窗口的图标 {
::SendMessage(_hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); HICON hIcon = (HICON)::LoadImage(HINST_THISCOMPONENT, MAKEINTRESOURCE(iconID), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
::SendMessage(_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); // 设置窗口的图标
::SendMessage(_hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
::SendMessage(_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
}
} }
void e2d::Window::setCursor(Cursor cursor) void e2d::Window::setCursor(Cursor cursor)

View File

@ -36,7 +36,7 @@ e2d::Player * e2d::Player::getInstance()
if (FAILED(hr = XAudio2Create(&_instance->_xAudio2, 0)) || if (FAILED(hr = XAudio2Create(&_instance->_xAudio2, 0)) ||
FAILED(hr = _instance->_xAudio2->CreateMasteringVoice(&_instance->_masteringVoice))) FAILED(hr = _instance->_xAudio2->CreateMasteringVoice(&_instance->_masteringVoice)))
{ {
throw SystemException("初始化 XAudio2 组件失败"); throw SystemException(L"初始化 XAudio2 组件失败");
} }
} }
return _instance; return _instance;

View File

@ -86,13 +86,6 @@ public:
// 销毁窗口实例 // 销毁窗口实例
static void destroyInstance(); static void destroyInstance();
// 创建新窗口
bool create(
const String& title,
int width,
int height
);
// 修改窗口大小 // 修改窗口大小
void setSize( void setSize(
int width, /* 窗口宽度 */ int width, /* 窗口宽度 */
@ -164,6 +157,9 @@ private:
E2D_DISABLE_COPY(Window); E2D_DISABLE_COPY(Window);
// ×¢²á´°¿Ú
HWND __create();
// 处理窗口消息 // 处理窗口消息
void __poll(); void __poll();
@ -179,6 +175,7 @@ private:
HWND _hWnd; HWND _hWnd;
Size _size; Size _size;
String _title; String _title;
int _iconID;
static Window * _instance; static Window * _instance;
}; };