Magic_Game/core/Base/Window.cpp

338 lines
6.8 KiB
C++
Raw Normal View History

2018-04-21 21:24:46 +08:00
#include "..\e2dbase.h"
#include "..\e2dmanager.h"
2018-01-30 16:45:38 +08:00
#include <imm.h>
#pragma comment (lib ,"imm32.lib")
// <20><><EFBFBD>ھ<EFBFBD><DABE><EFBFBD>
static HWND s_HWnd = nullptr;
// <20>Ƿ<EFBFBD><C7B7>򿪿<EFBFBD><F2BFAABF><EFBFBD>̨
static bool s_bShowConsole = false;
bool e2d::Window::__init()
2018-01-30 16:45:38 +08:00
{
// ע<><EFBFBD><E1B4B0><EFBFBD><EFBFBD>
2018-03-01 00:19:09 +08:00
WNDCLASSEX wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEX);
2018-01-30 16:45:38 +08:00
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = Window::WndProc;
2018-01-30 16:45:38 +08:00
wcex.cbClsExtra = 0;
wcex.cbWndExtra = sizeof(LONG_PTR);
wcex.hInstance = HINST_THISCOMPONENT;
wcex.hbrBackground = NULL;
wcex.lpszMenuName = NULL;
wcex.hCursor = LoadCursor(NULL, IDI_APPLICATION);
wcex.lpszClassName = L"Easy2DApp";
wcex.hIcon = NULL;
2018-01-30 16:45:38 +08:00
RegisterClassEx(&wcex);
// <20><>Ϊ CreateWindow <20><><EFBFBD><EFBFBD>ʹ<EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD>ȡϵͳ<CFB5><CDB3> DPI <20><>ʹ<EFBFBD><CAB9>
// <20><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2018-02-27 21:07:43 +08:00
float dpiX, dpiY;
2018-01-30 16:45:38 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>ǰ<EFBFBD><C7B0>ϵͳ DPI<50><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵҲ<D6B5><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Renderer::getID2D1Factory()->GetDesktopDpi(&dpiX, &dpiY);
2018-01-30 16:45:38 +08:00
UINT nWidth = static_cast<UINT>(ceil(640 * dpiX / 96.f));
UINT nHeight = static_cast<UINT>(ceil(480 * dpiY / 96.f));
2018-01-30 16:45:38 +08:00
// <20><>ȡ<EFBFBD><C8A1>Ļ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD>
UINT screenWidth = static_cast<UINT>(::GetSystemMetrics(SM_CXSCREEN));
UINT screenHeight = static_cast<UINT>(::GetSystemMetrics(SM_CYSCREEN));
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4>ڴ<EFBFBD>С<EFBFBD>ȷֱ<C8B7><D6B1>ʴ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
WARN_IF(screenWidth < nWidth || screenHeight < nHeight, "The window is larger than screen!");
// ȡ<><C8A1>Сֵ
nWidth = min(nWidth, screenWidth);
nHeight = min(nHeight, screenHeight);
// <20><><EFBFBD><EFBFBD>ڴ<EFBFBD>С
DWORD dwStyle = WS_OVERLAPPEDWINDOW &~ WS_MAXIMIZEBOX;
RECT wr = { 0, 0, static_cast<LONG>(nWidth), static_cast<LONG>(nHeight) };
::AdjustWindowRectEx(&wr, dwStyle, FALSE, NULL);
// <20><>ȡ<EFBFBD>µĿ<C2B5><C4BF><EFBFBD>
nWidth = wr.right - wr.left;
nHeight = wr.bottom - wr.top;
2018-01-30 16:45:38 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
s_HWnd = ::CreateWindowEx(
NULL,
2018-01-30 16:45:38 +08:00
L"Easy2DApp",
L"Easy2D Game",
dwStyle,
(screenWidth - nWidth) / 2, (screenHeight - nHeight) / 2,
nWidth, nHeight,
2018-01-30 16:45:38 +08:00
NULL,
NULL,
HINST_THISCOMPONENT,
NULL
);
HRESULT hr = s_HWnd ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Window::setTypewritingEnable(false);
2018-01-30 16:45:38 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD>̨
HWND hwnd = ::GetConsoleWindow();
if (hwnd)
{
// <20><><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD>̨<EFBFBD>رհ<D8B1>ť
HMENU hmenu = ::GetSystemMenu(hwnd, FALSE);
::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND);
// Ĭ<><C4AC><EFBFBD><EFBFBD><EFBFBD>ؿ<EFBFBD><D8BF><EFBFBD>̨
if (!s_bShowConsole)
{
::ShowWindow(hwnd, SW_HIDE);
}
}
}
else
{
::UnregisterClass(L"Easy2DApp", HINST_THISCOMPONENT);
2018-01-30 16:45:38 +08:00
}
if (FAILED(hr))
{
::MessageBox(nullptr, L"Create Window Failed!", L"Error", MB_OK);
2018-01-30 16:45:38 +08:00
}
return SUCCEEDED(hr);
}
void e2d::Window::__uninit()
2018-01-30 16:45:38 +08:00
{
2018-02-04 21:24:27 +08:00
// <20>رտ<D8B1><D5BF><EFBFBD>̨
2018-01-30 16:45:38 +08:00
if (::GetConsoleWindow())
{
::FreeConsole();
}
2018-02-04 21:24:27 +08:00
// <20>رմ<D8B1><D5B4><EFBFBD>
if (s_HWnd)
{
::DestroyWindow(s_HWnd);
s_HWnd = nullptr;
}
2018-01-30 16:45:38 +08:00
}
void e2d::Window::__poll()
2018-01-30 16:45:38 +08:00
{
static MSG msg;
while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
2018-02-27 21:07:43 +08:00
double e2d::Window::getWidth()
2018-01-30 16:45:38 +08:00
{
if (s_HWnd)
{
// <20><>ȡ<EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD>С
tagRECT rcClient;
::GetClientRect(s_HWnd, &rcClient);
return rcClient.right - rcClient.left;
}
return 0;
2018-01-30 16:45:38 +08:00
}
2018-02-27 21:07:43 +08:00
double e2d::Window::getHeight()
2018-01-30 16:45:38 +08:00
{
if (s_HWnd)
{
// <20><>ȡ<EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD>С
tagRECT rcClient;
::GetClientRect(s_HWnd, &rcClient);
return rcClient.bottom - rcClient.top;
}
return 0;
2018-01-30 16:45:38 +08:00
}
e2d::Size e2d::Window::getSize()
2018-01-30 16:45:38 +08:00
{
if (s_HWnd)
{
// <20><>ȡ<EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD>С
tagRECT rcClient;
::GetClientRect(s_HWnd, &rcClient);
return Size(rcClient.right - rcClient.left, rcClient.bottom - rcClient.top);
}
return Size();
2018-01-30 16:45:38 +08:00
}
HWND e2d::Window::getHWnd()
2018-01-30 16:45:38 +08:00
{
return s_HWnd;
}
void e2d::Window::setSize(UINT32 width, UINT32 height)
2018-01-30 16:45:38 +08:00
{
// <20><><EFBFBD><EFBFBD>ڴ<EFBFBD>С
DWORD dwStyle = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX;
RECT wr = { 0, 0, static_cast<LONG>(width), static_cast<LONG>(height) };
::AdjustWindowRectEx(&wr, dwStyle, FALSE, NULL);
// <20><>ȡ<EFBFBD>µĿ<C2B5><C4BF><EFBFBD>
width = wr.right - wr.left;
height = wr.bottom - wr.top;
2018-01-30 16:45:38 +08:00
// <20><>ȡ<EFBFBD><C8A1>Ļ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD>
int screenWidth = ::GetSystemMetrics(SM_CXSCREEN);
int screenHeight = ::GetSystemMetrics(SM_CYSCREEN);
// <20>޸Ĵ<DEB8><C4B4>ڴ<EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD>
::MoveWindow(s_HWnd, (screenWidth - width) / 2, (screenHeight - height) / 2, width, height, TRUE);
}
void e2d::Window::setTitle(String title)
2018-01-30 16:45:38 +08:00
{
// <20><><EFBFBD>ô<EFBFBD><C3B4>ڱ<EFBFBD><DAB1><EFBFBD>
2018-02-01 09:38:25 +08:00
::SetWindowText(s_HWnd, title);
2018-01-30 16:45:38 +08:00
}
void e2d::Window::setIcon(LPCTSTR pIconID)
{
HINSTANCE hInstance = ::GetModuleHandle(NULL);
HICON hIcon = (HICON)::LoadImage(hInstance, pIconID, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
// <20><><EFBFBD>ô<EFBFBD><C3B4>ڵ<EFBFBD>ͼ<EFBFBD><CDBC>
::SendMessage(s_HWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
::SendMessage(s_HWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
}
e2d::String e2d::Window::getTitle()
2018-01-30 16:45:38 +08:00
{
wchar_t wszTitle[MAX_PATH] = { 0 };
::GetWindowText(s_HWnd, wszTitle, MAX_PATH);
return wszTitle;
}
void e2d::Window::showConsole(bool show /* = true */)
2018-01-30 16:45:38 +08:00
{
s_bShowConsole = show;
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD><D1B4>ڵĿ<DAB5><C4BF><EFBFBD>̨<EFBFBD><CCA8><EFBFBD><EFBFBD>
HWND hwnd = ::GetConsoleWindow();
// <20>رտ<D8B1><D5BF><EFBFBD>̨
if (show)
{
if (hwnd)
{
::ShowWindow(hwnd, SW_SHOWNORMAL);
}
else
{
// <20><>ʾһ<CABE><D2BB><EFBFBD>¿<EFBFBD><C2BF><EFBFBD>̨
if (::AllocConsole())
{
hwnd = ::GetConsoleWindow();
// <20>ض<EFBFBD><D8B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
FILE * stdoutStream, * stdinStream, * stderrStream;
freopen_s(&stdoutStream, "conout$", "w+t", stdout);
freopen_s(&stdinStream, "conin$", "r+t", stdin);
2018-02-01 22:07:44 +08:00
freopen_s(&stderrStream, "conout$", "w+t", stderr);
2018-01-30 16:45:38 +08:00
// <20><><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD>̨<EFBFBD>رհ<D8B1>ť
HMENU hmenu = ::GetSystemMenu(hwnd, FALSE);
::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND);
}
else
{
MessageBox(nullptr, L"Alloc Console Failed!", L"Error", MB_OK);
}
}
}
else
{
if (hwnd)
{
::ShowWindow(hwnd, SW_HIDE);
}
}
}
void e2d::Window::setTypewritingEnable(bool bEnable)
2018-01-30 16:45:38 +08:00
{
static HIMC hImc = nullptr;
if (bEnable)
{
if (hImc != nullptr)
{
::ImmAssociateContext(Window::getHWnd(), hImc);
2018-01-30 16:45:38 +08:00
hImc = nullptr;
}
}
else
{
if (hImc == nullptr)
{
hImc = ::ImmAssociateContext(Window::getHWnd(), nullptr);
2018-01-30 16:45:38 +08:00
}
}
}
LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
2018-01-30 16:45:38 +08:00
{
LRESULT result = 0;
switch (message)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>С<EFBFBD><EFBFBD><E4BBAF>Ϣ
case WM_SIZE:
{
UINT width = LOWORD(lParam);
UINT height = HIWORD(lParam);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD>һ<EFBFBD><D2BB> WM_SIZE <20><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ
// Ŀ<><C4BF><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܻ<EFBFBD><DCBB><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ժ<EFBFBD><D4BA><EFBFBD><EFBFBD>п<EFBFBD><D0BF>ܵ<EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>ε<EFBFBD><CEB5><EFBFBD> EndDraw ʱ<><CAB1><EFBFBD><EFBFBD>
2018-04-17 01:11:56 +08:00
auto pRT = Renderer::getRenderTarget();
if (pRT) pRT->Resize(D2D1::SizeU(width, height));
2018-01-30 16:45:38 +08:00
}
break;
// <20><><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1>ʱ仯<CAB1><E4BBAF>Ϣ
case WM_DISPLAYCHANGE:
{
// <20>ػ<EFBFBD><D8BB>ͻ<EFBFBD><CDBB><EFBFBD>
InvalidateRect(hWnd, NULL, FALSE);
}
result = 0;
break;
// <20>ػ洰<D8BB><E6B4B0>
case WM_PAINT:
{
e2d::Renderer::__render();
2018-01-30 16:45:38 +08:00
ValidateRect(hWnd, NULL);
}
result = 0;
break;
// <20><><EFBFBD>ڹر<DAB9><D8B1><EFBFBD>Ϣ
case WM_CLOSE:
{
e2d::Scene * pCurrentScene = e2d::SceneManager::getCurrentScene();
2018-01-30 16:45:38 +08:00
if (!pCurrentScene || pCurrentScene->onCloseWindow())
{
e2d::Game::quit();
2018-01-30 16:45:38 +08:00
}
}
result = 0;
break;
case WM_DESTROY:
{
PostQuitMessage(0);
}
result = 1;
break;
default:
{
result = DefWindowProc(hWnd, message, wParam, lParam);
}
}
return result;
}