| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | // Copyright (c) 2016-2018 Kiwano - Nomango
 | 
					
						
							|  |  |  | // 
 | 
					
						
							|  |  |  | // Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
					
						
							|  |  |  | // of this software and associated documentation files (the "Software"), to deal
 | 
					
						
							|  |  |  | // in the Software without restriction, including without limitation the rights
 | 
					
						
							|  |  |  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
					
						
							|  |  |  | // copies of the Software, and to permit persons to whom the Software is
 | 
					
						
							|  |  |  | // furnished to do so, subject to the following conditions:
 | 
					
						
							|  |  |  | // 
 | 
					
						
							|  |  |  | // The above copyright notice and this permission notice shall be included in
 | 
					
						
							|  |  |  | // all copies or substantial portions of the Software.
 | 
					
						
							|  |  |  | // 
 | 
					
						
							|  |  |  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
					
						
							|  |  |  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
					
						
							|  |  |  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
					
						
							|  |  |  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
					
						
							|  |  |  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
					
						
							|  |  |  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
					
						
							|  |  |  | // THE SOFTWARE.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-13 14:33:15 +08:00
										 |  |  | #include <kiwano/platform/Window.h>
 | 
					
						
							| 
									
										
										
										
											2019-10-11 21:55:29 +08:00
										 |  |  | #include <kiwano/platform/Application.h>
 | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | #include <kiwano/core/event/MouseEvent.h>
 | 
					
						
							|  |  |  | #include <kiwano/core/event/KeyEvent.h>
 | 
					
						
							|  |  |  | #include <kiwano/core/event/WindowEvent.h>
 | 
					
						
							|  |  |  | #include <kiwano/core/Logger.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <imm.h>  // ImmAssociateContext
 | 
					
						
							|  |  |  | #pragma comment(lib, "imm32.lib")
 | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-20 23:51:12 +08:00
										 |  |  | #define WINDOW_FIXED_STYLE		WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
 | 
					
						
							|  |  |  | #define WINDOW_RESIZABLE_STYLE	WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX
 | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | #define WINDOW_FULLSCREEN_STYLE	WS_CLIPCHILDREN | WS_POPUP
 | 
					
						
							|  |  |  | #define KGE_WND_CLASS_NAME		L"KiwanoAppWnd"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace kiwano | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	namespace | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		MONITORINFOEX GetMoniterInfoEx(HWND hwnd); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 11:26:41 +08:00
										 |  |  | 		void AdjustWindow(uint32_t width, uint32_t height, DWORD style, uint32_t* win_width, uint32_t* win_height); | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-29 22:23:13 +08:00
										 |  |  | 		void ChangeFullScreenResolution(int width, int height, WCHAR* device_name); | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		void RestoreResolution(WCHAR* device_name); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 11:26:41 +08:00
										 |  |  | 	WindowConfig::WindowConfig(String const& title, uint32_t width, uint32_t height, uint32_t icon, bool resizable, bool fullscreen) | 
					
						
							| 
									
										
										
										
											2019-08-23 13:00:43 +08:00
										 |  |  | 		: title(title) | 
					
						
							|  |  |  | 		, width(width) | 
					
						
							|  |  |  | 		, height(height) | 
					
						
							|  |  |  | 		, icon(icon) | 
					
						
							|  |  |  | 		, resizable(resizable) | 
					
						
							|  |  |  | 		, fullscreen(fullscreen) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	Window::Window() | 
					
						
							|  |  |  | 		: handle_(nullptr) | 
					
						
							|  |  |  | 		, width_(0) | 
					
						
							|  |  |  | 		, height_(0) | 
					
						
							|  |  |  | 		, device_name_(nullptr) | 
					
						
							|  |  |  | 		, is_fullscreen_(false) | 
					
						
							| 
									
										
										
										
											2019-08-20 23:51:12 +08:00
										 |  |  | 		, resizable_(false) | 
					
						
							| 
									
										
										
										
											2019-08-21 16:33:41 +08:00
										 |  |  | 		, mouse_cursor_(CursorType::Arrow) | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Window::~Window() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 	void Window::Init(WindowConfig const& config) | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		HINSTANCE hinst		= GetModuleHandleW(nullptr); | 
					
						
							|  |  |  | 		WNDCLASSEX wcex		= { 0 }; | 
					
						
							|  |  |  | 		wcex.cbSize			= sizeof(WNDCLASSEX); | 
					
						
							|  |  |  | 		wcex.lpszClassName	= KGE_WND_CLASS_NAME; | 
					
						
							|  |  |  | 		wcex.style			= CS_HREDRAW | CS_VREDRAW /* | CS_DBLCLKS */; | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 		wcex.lpfnWndProc	= Window::WndProc; | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 		wcex.hIcon			= nullptr; | 
					
						
							|  |  |  | 		wcex.cbClsExtra		= 0; | 
					
						
							|  |  |  | 		wcex.cbWndExtra		= sizeof(LONG_PTR); | 
					
						
							|  |  |  | 		wcex.hInstance		= hinst; | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 		wcex.hbrBackground	= (HBRUSH)(::GetStockObject(BLACK_BRUSH)); | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 		wcex.lpszMenuName	= nullptr; | 
					
						
							| 
									
										
										
										
											2019-08-20 23:51:12 +08:00
										 |  |  | 		wcex.hCursor		= ::LoadCursorW(hinst, IDC_ARROW); | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-23 13:00:43 +08:00
										 |  |  | 		if (config.icon) | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-08-23 13:00:43 +08:00
										 |  |  | 			wcex.hIcon = (HICON)::LoadImageW(hinst, MAKEINTRESOURCE(config.icon), IMAGE_ICON, 0, 0, | 
					
						
							|  |  |  | 				LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		::RegisterClassExW(&wcex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Get the nearest monitor to this window
 | 
					
						
							|  |  |  | 		HMONITOR monitor = ::MonitorFromPoint(POINT{ 0, 0 }, MONITOR_DEFAULTTOPRIMARY); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Get the target monitor info
 | 
					
						
							|  |  |  | 		MONITORINFOEX monitor_info_ex; | 
					
						
							|  |  |  | 		memset(&monitor_info_ex, 0, sizeof(MONITORINFOEX)); | 
					
						
							|  |  |  | 		monitor_info_ex.cbSize = sizeof(MONITORINFOEX); | 
					
						
							|  |  |  | 		::GetMonitorInfoW(monitor, &monitor_info_ex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Save the device name
 | 
					
						
							| 
									
										
										
										
											2019-09-29 22:23:13 +08:00
										 |  |  | 		int len = lstrlenW(monitor_info_ex.szDevice); | 
					
						
							| 
									
										
										
										
											2019-10-12 11:26:41 +08:00
										 |  |  | 		device_name_ = new wchar_t[len + 1]; | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 		lstrcpyW(device_name_, monitor_info_ex.szDevice); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 11:26:41 +08:00
										 |  |  | 		uint32_t width = config.width; | 
					
						
							|  |  |  | 		uint32_t height = config.height; | 
					
						
							| 
									
										
										
										
											2019-09-29 22:23:13 +08:00
										 |  |  | 		int left = -1; | 
					
						
							|  |  |  | 		int top = -1; | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-23 13:00:43 +08:00
										 |  |  | 		resizable_ = config.resizable; | 
					
						
							|  |  |  | 		is_fullscreen_ = config.fullscreen; | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (is_fullscreen_) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			top = monitor_info_ex.rcMonitor.top; | 
					
						
							|  |  |  | 			left = monitor_info_ex.rcMonitor.left; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 11:26:41 +08:00
										 |  |  | 			if (width > static_cast<uint32_t>(monitor_info_ex.rcWork.right - left)) | 
					
						
							|  |  |  | 				width = static_cast<uint32_t>(monitor_info_ex.rcWork.right - left); | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 11:26:41 +08:00
										 |  |  | 			if (height > static_cast<uint32_t>(monitor_info_ex.rcWork.bottom - top)) | 
					
						
							|  |  |  | 				height = static_cast<uint32_t>(monitor_info_ex.rcWork.bottom - top); | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-10-12 11:26:41 +08:00
										 |  |  | 			uint32_t screenw = monitor_info_ex.rcWork.right - monitor_info_ex.rcWork.left; | 
					
						
							|  |  |  | 			uint32_t screenh = monitor_info_ex.rcWork.bottom - monitor_info_ex.rcWork.top; | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 11:26:41 +08:00
										 |  |  | 			uint32_t win_width, win_height; | 
					
						
							| 
									
										
										
										
											2019-12-31 10:37:29 +08:00
										 |  |  | 			AdjustWindow(width, height, GetWindowStyle(), &win_width, &win_height); | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			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; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		handle_ = ::CreateWindowExW( | 
					
						
							|  |  |  | 			is_fullscreen_ ? WS_EX_TOPMOST : 0, | 
					
						
							|  |  |  | 			KGE_WND_CLASS_NAME, | 
					
						
							| 
									
										
										
										
											2019-08-23 13:00:43 +08:00
										 |  |  | 			config.title.c_str(), | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 			GetWindowStyle(), | 
					
						
							|  |  |  | 			left, | 
					
						
							|  |  |  | 			top, | 
					
						
							|  |  |  | 			width, | 
					
						
							|  |  |  | 			height, | 
					
						
							|  |  |  | 			nullptr, | 
					
						
							|  |  |  | 			nullptr, | 
					
						
							|  |  |  | 			hinst, | 
					
						
							|  |  |  | 			nullptr | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (handle_ == nullptr) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			::UnregisterClass(KGE_WND_CLASS_NAME, hinst); | 
					
						
							| 
									
										
										
										
											2019-12-30 14:24:29 +08:00
										 |  |  | 			win32::ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError())); | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 		width_ = width; | 
					
						
							|  |  |  | 		height_ = height; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// disable imm
 | 
					
						
							|  |  |  | 		::ImmAssociateContext(handle_, nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// use Application instance in message loop
 | 
					
						
							|  |  |  | 		::SetWindowLongPtr(handle_, GWLP_USERDATA, LONG_PTR(this)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 		::ShowWindow(handle_, SW_SHOWNORMAL); | 
					
						
							|  |  |  | 		::UpdateWindow(handle_); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (is_fullscreen_) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			ChangeFullScreenResolution(width_, height_, device_name_); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 	EventPtr Window::PollEvent() | 
					
						
							| 
									
										
										
										
											2019-10-12 08:54:10 +08:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 		MSG msg; | 
					
						
							|  |  |  | 		while (::PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE)) | 
					
						
							| 
									
										
										
										
											2019-10-12 08:54:10 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			::TranslateMessage(&msg); | 
					
						
							|  |  |  | 			::DispatchMessageW(&msg); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		EventPtr evt; | 
					
						
							|  |  |  | 		if (!event_queue_.empty()) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			evt = event_queue_.front(); | 
					
						
							|  |  |  | 			event_queue_.pop(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return evt; | 
					
						
							| 
									
										
										
										
											2019-10-12 08:54:10 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	String Window::GetTitle() const | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (handle_) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-09-29 22:23:13 +08:00
										 |  |  | 			wchar_t title[256]; | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 			::GetWindowTextW(handle_, title, 256); | 
					
						
							|  |  |  | 			return title; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return String(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	void Window::SetTitle(String const& title) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (handle_) | 
					
						
							|  |  |  | 			::SetWindowTextW(handle_, title.c_str()); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Size Window::GetSize() const | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return Size{ | 
					
						
							| 
									
										
										
										
											2019-09-29 22:23:13 +08:00
										 |  |  | 			static_cast<float>(width_), | 
					
						
							|  |  |  | 			static_cast<float>(height_) | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-29 22:23:13 +08:00
										 |  |  | 	float Window::GetWidth() const | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-09-29 22:23:13 +08:00
										 |  |  | 		return static_cast<float>(width_); | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-29 22:23:13 +08:00
										 |  |  | 	float Window::GetHeight() const | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-09-29 22:23:13 +08:00
										 |  |  | 		return static_cast<float>(height_); | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 11:26:41 +08:00
										 |  |  | 	void Window::SetIcon(uint32_t icon_resource) | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		if (handle_) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			HINSTANCE hinstance = GetModuleHandle(nullptr); | 
					
						
							| 
									
										
										
										
											2019-08-21 16:33:41 +08:00
										 |  |  | 			HICON icon = (HICON)::LoadImageW( | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 				hinstance, | 
					
						
							| 
									
										
										
										
											2019-08-19 09:28:59 +08:00
										 |  |  | 				MAKEINTRESOURCE(icon_resource), | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 				IMAGE_ICON, | 
					
						
							|  |  |  | 				0, | 
					
						
							|  |  |  | 				0, | 
					
						
							|  |  |  | 				LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			::SendMessage(handle_, WM_SETICON, ICON_BIG, (LPARAM)icon); | 
					
						
							|  |  |  | 			::SendMessage(handle_, WM_SETICON, ICON_SMALL, (LPARAM)icon); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-29 22:23:13 +08:00
										 |  |  | 	void Window::Resize(int width, int height) | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		if (handle_ && !is_fullscreen_) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-09-29 22:23:13 +08:00
										 |  |  | 			RECT rc = { 0, 0, int(width), int(height) }; | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 			::AdjustWindowRect(&rc, GetWindowStyle(), false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			width = rc.right - rc.left; | 
					
						
							|  |  |  | 			height = rc.bottom - rc.top; | 
					
						
							|  |  |  | 			::SetWindowPos(handle_, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-29 22:23:13 +08:00
										 |  |  | 	void Window::SetFullscreen(bool fullscreen, int width, int height) | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		if (is_fullscreen_ != fullscreen || width != width_ || height != height_) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			is_fullscreen_ = fullscreen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (is_fullscreen_) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				// move window to (0, 0) before display switch
 | 
					
						
							|  |  |  | 				::SetWindowPos(handle_, HWND_TOPMOST, 0, 0, width_, height_, SWP_NOACTIVATE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				ChangeFullScreenResolution(width, height, device_name_); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				MONITORINFOEX info = GetMoniterInfoEx(handle_); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				::SetWindowLongPtr(handle_, GWL_STYLE, GetWindowStyle()); | 
					
						
							|  |  |  | 				::SetWindowPos(handle_, HWND_TOPMOST, info.rcMonitor.top, info.rcMonitor.left, width, height, SWP_NOACTIVATE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				width_ = width; | 
					
						
							|  |  |  | 				height_ = height; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				RestoreResolution(device_name_); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				MONITORINFOEX info = GetMoniterInfoEx(handle_); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 11:26:41 +08:00
										 |  |  | 				uint32_t screenw = info.rcWork.right - info.rcWork.left; | 
					
						
							|  |  |  | 				uint32_t screenh = info.rcWork.bottom - info.rcWork.top; | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 11:26:41 +08:00
										 |  |  | 				uint32_t win_width, win_height; | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 				AdjustWindow(width, height, GetWindowStyle(), &win_width, &win_height); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-29 22:23:13 +08:00
										 |  |  | 				int left = screenw > win_width ? ((screenw - win_width) / 2) : 0; | 
					
						
							|  |  |  | 				int top = screenh > win_height ? ((screenh - win_height) / 2) : 0; | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				::SetWindowLongPtr(handle_, GWL_STYLE, GetWindowStyle()); | 
					
						
							|  |  |  | 				::SetWindowPos(handle_, HWND_NOTOPMOST, left, top, win_width, win_height, SWP_DRAWFRAME | SWP_FRAMECHANGED); | 
					
						
							|  |  |  | 				 | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 				// Update window rect
 | 
					
						
							|  |  |  | 				RECT rc; | 
					
						
							|  |  |  | 				::GetClientRect(handle_, &rc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				width_ = static_cast<uint32_t>(rc.right - rc.left); | 
					
						
							|  |  |  | 				height_ = static_cast<uint32_t>(rc.bottom - rc.top); | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			::ShowWindow(handle_, SW_SHOWNORMAL); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-21 16:33:41 +08:00
										 |  |  | 	void Window::SetCursor(CursorType cursor) | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-08-20 23:51:12 +08:00
										 |  |  | 		mouse_cursor_ = cursor; | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 	WindowHandle Window::GetHandle() const | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		return handle_; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 	bool Window::ShouldClose() | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 		return handle_ == nullptr; | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 	void Window::PushEvent(EventPtr evt) | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 		event_queue_.push(evt); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	void Window::Destroy() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (is_fullscreen_) | 
					
						
							|  |  |  | 			RestoreResolution(device_name_); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (device_name_) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			delete[] device_name_; | 
					
						
							|  |  |  | 			device_name_ = nullptr; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 		if (handle_) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			::DestroyWindow(handle_); | 
					
						
							|  |  |  | 			handle_ = nullptr; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | #if defined(KGE_WIN32)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	DWORD Window::GetWindowStyle() const | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return is_fullscreen_ ? (WINDOW_FULLSCREEN_STYLE) : (resizable_ ? (WINDOW_RESIZABLE_STYLE) : (WINDOW_FIXED_STYLE)); | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-20 23:51:12 +08:00
										 |  |  | 	void Window::UpdateCursor() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		LPTSTR win32_cursor = IDC_ARROW; | 
					
						
							|  |  |  | 		switch (mouse_cursor_) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-08-21 16:33:41 +08:00
										 |  |  | 		case CursorType::Arrow:		win32_cursor = IDC_ARROW; break; | 
					
						
							|  |  |  | 		case CursorType::TextInput:	win32_cursor = IDC_IBEAM; break; | 
					
						
							|  |  |  | 		case CursorType::SizeAll:	win32_cursor = IDC_SIZEALL; break; | 
					
						
							|  |  |  | 		case CursorType::SizeWE:	win32_cursor = IDC_SIZEWE; break; | 
					
						
							|  |  |  | 		case CursorType::SizeNS:	win32_cursor = IDC_SIZENS; break; | 
					
						
							|  |  |  | 		case CursorType::SizeNESW:	win32_cursor = IDC_SIZENESW; break; | 
					
						
							|  |  |  | 		case CursorType::SizeNWSE:	win32_cursor = IDC_SIZENWSE; break; | 
					
						
							|  |  |  | 		case CursorType::Hand:		win32_cursor = IDC_HAND; break; | 
					
						
							| 
									
										
										
										
											2019-08-20 23:51:12 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		::SetCursor(::LoadCursorW(nullptr, win32_cursor)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	void Window::SetActive(bool actived) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (!handle_) | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (is_fullscreen_) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (actived) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				ChangeFullScreenResolution(width_, height_, device_name_); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				MONITORINFOEX info = GetMoniterInfoEx(handle_); | 
					
						
							|  |  |  | 				::SetWindowPos(handle_, HWND_TOPMOST, info.rcMonitor.top, info.rcMonitor.left, width_, height_, SWP_NOACTIVATE); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				RestoreResolution(device_name_); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				::SetWindowPos(handle_, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); | 
					
						
							|  |  |  | 				::ShowWindow(handle_, SW_MINIMIZE); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 	LRESULT CALLBACK Window::WndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam) | 
					
						
							| 
									
										
										
										
											2019-12-17 20:47:55 +08:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 		Window* window = reinterpret_cast<Window*>(static_cast<LONG_PTR>(::GetWindowLongPtrW(hwnd, GWLP_USERDATA))); | 
					
						
							|  |  |  | 		if (window == nullptr) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			return ::DefWindowProcW(hwnd, msg, wparam, lparam); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-12-17 20:47:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 		switch (msg) | 
					
						
							| 
									
										
										
										
											2019-12-17 20:47:55 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 		case WM_KEYDOWN: | 
					
						
							|  |  |  | 		case WM_SYSKEYDOWN: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			KeyDownEventPtr evt = new KeyDownEvent; | 
					
						
							|  |  |  | 			evt->code = static_cast<int>(wparam); | 
					
						
							|  |  |  | 			window->PushEvent(evt); | 
					
						
							| 
									
										
										
										
											2019-12-17 20:47:55 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2019-12-17 20:47:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 		case WM_KEYUP: | 
					
						
							|  |  |  | 		case WM_SYSKEYUP: | 
					
						
							| 
									
										
										
										
											2019-12-17 20:47:55 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 			KeyUpEventPtr evt = new KeyUpEvent; | 
					
						
							|  |  |  | 			evt->code = static_cast<int>(wparam); | 
					
						
							|  |  |  | 			window->PushEvent(evt); | 
					
						
							| 
									
										
										
										
											2019-12-17 20:47:55 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_CHAR: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			KeyCharEventPtr evt = new KeyCharEvent; | 
					
						
							|  |  |  | 			evt->value = static_cast<char>(wparam); | 
					
						
							|  |  |  | 			window->PushEvent(evt); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: | 
					
						
							|  |  |  | 		case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: | 
					
						
							|  |  |  | 		case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			MouseDownEventPtr evt = new MouseDownEvent; | 
					
						
							|  |  |  | 			evt->pos = Point(((float)(int)(short)LOWORD(lparam)), ((float)(int)(short)HIWORD(lparam))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if		(msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { evt->button = MouseButton::Left; } | 
					
						
							|  |  |  | 			else if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { evt->button = MouseButton::Right; } | 
					
						
							|  |  |  | 			else if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { evt->button = MouseButton::Middle; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			window->PushEvent(evt); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_LBUTTONUP: | 
					
						
							|  |  |  | 		case WM_MBUTTONUP: | 
					
						
							|  |  |  | 		case WM_RBUTTONUP: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			MouseUpEventPtr evt = new MouseUpEvent; | 
					
						
							|  |  |  | 			evt->pos = Point(((float)(int)(short)LOWORD(lparam)), ((float)(int)(short)HIWORD(lparam))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if		(msg == WM_LBUTTONUP)	{ evt->button = MouseButton::Left; } | 
					
						
							|  |  |  | 			else if (msg == WM_RBUTTONUP)	{ evt->button = MouseButton::Right; } | 
					
						
							|  |  |  | 			else if (msg == WM_MBUTTONUP)	{ evt->button = MouseButton::Middle; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			window->PushEvent(evt); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_MOUSEMOVE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			MouseMoveEventPtr evt = new MouseMoveEvent; | 
					
						
							|  |  |  | 			evt->pos = Point(((float)(int)(short)LOWORD(lparam)), ((float)(int)(short)HIWORD(lparam))); | 
					
						
							|  |  |  | 			window->PushEvent(evt); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_MOUSEWHEEL: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			MouseWheelEventPtr evt = new MouseWheelEvent; | 
					
						
							|  |  |  | 			evt->pos = Point(((float)(int)(short)LOWORD(lparam)), ((float)(int)(short)HIWORD(lparam))); | 
					
						
							|  |  |  | 			evt->wheel = GET_WHEEL_DELTA_WPARAM(wparam) / (float)WHEEL_DELTA; | 
					
						
							|  |  |  | 			window->PushEvent(evt); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_SIZE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (SIZE_MAXHIDE == wparam || SIZE_MINIMIZED == wparam) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				KGE_SYS_LOG(L"Window minimized"); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				// KGE_SYS_LOG(L"Window resized");
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				window->width_ = ((uint32_t)(short)LOWORD(lparam)); | 
					
						
							|  |  |  | 				window->height_ = ((uint32_t)(short)HIWORD(lparam)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				WindowResizedEventPtr evt = new WindowResizedEvent; | 
					
						
							|  |  |  | 				evt->width = window->width_; | 
					
						
							|  |  |  | 				evt->height = window->height_; | 
					
						
							|  |  |  | 				window->PushEvent(evt); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_MOVE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			int x = ((int)(short)LOWORD(lparam)); | 
					
						
							|  |  |  | 			int y = ((int)(short)HIWORD(lparam)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			WindowMovedEventPtr evt = new WindowMovedEvent; | 
					
						
							|  |  |  | 			evt->x = x; | 
					
						
							|  |  |  | 			evt->y = y; | 
					
						
							|  |  |  | 			window->PushEvent(evt); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_ACTIVATE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			bool active = (LOWORD(wparam) != WA_INACTIVE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			window->SetActive(active); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			WindowFocusChangedEventPtr evt = new WindowFocusChangedEvent; | 
					
						
							|  |  |  | 			evt->focus = active; | 
					
						
							|  |  |  | 			window->PushEvent(evt); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_SETTEXT: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			KGE_SYS_LOG(L"Window title changed"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			WindowTitleChangedEventPtr evt = new WindowTitleChangedEvent; | 
					
						
							|  |  |  | 			evt->title.assign(reinterpret_cast<const wchar_t*>(lparam)); | 
					
						
							|  |  |  | 			window->PushEvent(evt); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_SETICON: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			KGE_SYS_LOG(L"Window icon changed"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_DISPLAYCHANGE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			KGE_SYS_LOG(L"The display resolution has changed"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			::InvalidateRect(hwnd, nullptr, FALSE); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_SETCURSOR: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			window->UpdateCursor(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_CLOSE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			KGE_SYS_LOG(L"Window is closing"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			WindowClosedEventPtr evt = new WindowClosedEvent; | 
					
						
							|  |  |  | 			window->PushEvent(evt); | 
					
						
							|  |  |  | 			window->Destroy(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case WM_DESTROY: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			KGE_SYS_LOG(L"Window was destroyed"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			::PostQuitMessage(0); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return ::DefWindowProcW(hwnd, msg, wparam, lparam); | 
					
						
							| 
									
										
										
										
											2019-12-17 20:47:55 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 	namespace | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		MONITORINFOEX GetMoniterInfoEx(HWND hwnd) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			HMONITOR monitor = ::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); | 
					
						
							|  |  |  | 			MONITORINFOEX monitor_info; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			memset(&monitor_info, 0, sizeof(MONITORINFOEX)); | 
					
						
							|  |  |  | 			monitor_info.cbSize = sizeof(MONITORINFOEX); | 
					
						
							|  |  |  | 			::GetMonitorInfoW(monitor, &monitor_info); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return monitor_info; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 11:26:41 +08:00
										 |  |  | 		void AdjustWindow(uint32_t width, uint32_t height, DWORD style, uint32_t* win_width, uint32_t* win_height) | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			RECT rc; | 
					
						
							| 
									
										
										
										
											2019-09-29 22:23:13 +08:00
										 |  |  | 			::SetRect(&rc, 0, 0, (int)width, (int)height); | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 			::AdjustWindowRect(&rc, style, false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			*win_width = rc.right - rc.left; | 
					
						
							|  |  |  | 			*win_height = rc.bottom - rc.top; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			MONITORINFOEX info = GetMoniterInfoEx(NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 11:26:41 +08:00
										 |  |  | 			uint32_t screenw = info.rcWork.right - info.rcWork.left; | 
					
						
							|  |  |  | 			uint32_t screenh = info.rcWork.bottom - info.rcWork.top; | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (*win_width > screenw) | 
					
						
							|  |  |  | 				*win_width = screenw; | 
					
						
							|  |  |  | 			if (*win_height > screenh) | 
					
						
							|  |  |  | 				*win_height = screenh; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-29 22:23:13 +08:00
										 |  |  | 		void ChangeFullScreenResolution(int width, int height, WCHAR* device_name) | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			DEVMODE mode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			memset(&mode, 0, sizeof(mode)); | 
					
						
							|  |  |  | 			mode.dmSize = sizeof(DEVMODE); | 
					
						
							|  |  |  | 			mode.dmBitsPerPel = ::GetDeviceCaps(::GetDC(0), BITSPIXEL);; | 
					
						
							|  |  |  | 			mode.dmPelsWidth = width; | 
					
						
							|  |  |  | 			mode.dmPelsHeight = height; | 
					
						
							|  |  |  | 			mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (::ChangeDisplaySettingsExW(device_name, &mode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) | 
					
						
							| 
									
										
										
										
											2019-12-17 20:47:55 +08:00
										 |  |  | 				KGE_ERROR(L"ChangeDisplaySettings failed"); | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void RestoreResolution(WCHAR* device_name) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			::ChangeDisplaySettingsExW(device_name, NULL, NULL, 0, NULL); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-08-23 13:00:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 18:33:42 +08:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 21:52:49 +08:00
										 |  |  | } |