#include "stdafx.h" #include "Window.h" #include "IResourceFactory.h" #define WINDOW_CLASS _T("BluFlameDX10IntroClass") Window::Window(IEngine& argEngine) : m_Engine(argEngine) , m_Fullscreen(false) , m_Active(true) , m_DeviceContext(NULL) , m_Handle(NULL) , m_Instance(NULL) , m_Title(L"") , m_Width(0) , m_Height(0) , m_SwapChain(NULL) { } Window::~Window() { ::SetWindowLong(m_Handle, GWL_USERDATA, PtrToLong(NULL)); if (m_Fullscreen) { ChangeDisplaySettings(NULL, 0); ShowCursor(TRUE); } //m_Engine.get_ResourceFactory().Delete(m_SwapChain); if (m_DeviceContext) { ReleaseDC(m_Handle, m_DeviceContext); m_Handle = NULL; } if (m_Handle) { DestroyWindow(m_Handle); m_Handle = NULL; } UnregisterClass(WINDOW_CLASS, m_Instance); m_Instance = NULL; m_Engine.get_ResourceFactory().DeleteSwapChain(*m_SwapChain); } BOOL CenterWindow(HWND hwnd) { RECT rect, rectP; int width, height; int screenwidth, screenheight; int x, y; GetWindowRect(hwnd, &rect); rectP.left = 0; rectP.top = 0; rectP.right = GetSystemMetrics(SM_CXSCREEN); rectP.bottom = GetSystemMetrics(SM_CYSCREEN); width = rect.right - rect.left; height = rect.bottom - rect.top; x = ((rectP.right-rectP.left) - width) / 2 + rectP.left; y = ((rectP.bottom-rectP.top) - height) / 2 + rectP.top; screenwidth = GetSystemMetrics(SM_CXSCREEN); screenheight = GetSystemMetrics(SM_CYSCREEN); if(x < 0) x = 0; if(y < 0) y = 0; if(x + width > screenwidth) x = screenwidth - width; if(y + height > screenheight) y = screenheight - height; MoveWindow(hwnd, x, y, width, height, FALSE); return TRUE; } void Window::Initialize(const string16& argTitle, int argWidth, int argHeight, bool argFullscreen) { m_Fullscreen = argFullscreen; m_Title = argTitle; m_Width = argWidth; m_Height = argHeight; WNDCLASS windowClass; DWORD exStyle; DWORD style; RECT windowRect; windowRect.left = (long)0; windowRect.right = (long)m_Width; windowRect.top = (long)0; windowRect.bottom = (long)m_Height; m_Instance = GetModuleHandle(NULL); windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; windowClass.lpfnWndProc = (WNDPROC)MessageCallback; windowClass.cbClsExtra = 0; windowClass.cbWndExtra = sizeof(this); windowClass.hInstance = m_Instance; windowClass.hIcon = LoadIcon(NULL, IDI_WINLOGO); windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); windowClass.hbrBackground = NULL; windowClass.lpszMenuName = NULL; windowClass.lpszClassName = WINDOW_CLASS; if (!RegisterClass(&windowClass)) throw _T("Cannot register window class!"); /*if (m_Fullscreen) { exStyle = WS_EX_APPWINDOW | WS_EX_TOPMOST; style = WS_POPUP | WS_VISIBLE; } else*/ { ShowCursor(TRUE); exStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; style = WS_OVERLAPPEDWINDOW; } AdjustWindowRectEx(&windowRect, style, FALSE, exStyle); if (!(m_Handle = CreateWindowEx( exStyle, WINDOW_CLASS, std::to_string8(m_Title).c_str(), style | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, NULL, NULL, m_Instance, this))) { throw _T("Cannot create Window!"); } CenterWindow(m_Handle); if (!(m_DeviceContext = GetDC(m_Handle))) throw _T("Cannot get Device Context!"); m_SwapChain = &m_Engine.get_ResourceFactory().CreateOrFindSwapChain(WINDOW_CLASS); m_SwapChain->SetWindowParameters(m_Handle, 0, 0, 0, DataFormat::Unknown, 1, // MultiSampleCount 0); // MultiSampleQuality m_SwapChain->set_VSync(true); ShowWindow(m_Handle, SW_SHOW); SetForegroundWindow(m_Handle); SetFocus(m_Handle); if (m_Fullscreen) m_SwapChain->set_Fullscreen(true); } LRESULT Window::MessageCallback(HWND argHandle, UINT argMessage, WPARAM argWParam, LPARAM argLParam) { Window* window; if (argMessage == WM_NCCREATE) { window = reinterpret_cast(((LPCREATESTRUCT)argLParam)->lpCreateParams); window->m_Handle = argHandle; ::SetWindowLong(argHandle, GWL_USERDATA, PtrToLong((PVOID)(reinterpret_cast(window)))); } else { window = reinterpret_cast(::GetWindowLong(argHandle, GWL_USERDATA)); } if (window != NULL) { return window->ProcessMessage(argMessage, argWParam, argLParam); } return DefWindowProc(argHandle, argMessage, argWParam, argLParam); } LRESULT Window::ProcessMessage(UINT argMessage, WPARAM argWParam, LPARAM argLParam) { switch (argMessage) { case WM_ACTIVATE: { if (!HIWORD(argWParam)) { set_Active(true); } else { set_Active(false); } return 0; } case WM_SYSCOMMAND: { switch (argWParam) { case SC_SCREENSAVE: case SC_MONITORPOWER: return 0; case SC_MINIMIZE: set_Active(false); break; case SC_RESTORE: set_Active(true); break; } break; } case WM_CLOSE: { PostQuitMessage(0); return 0; } case WM_KEYDOWN: { if (argWParam == 27) PostQuitMessage(0); return 0; } case WM_SIZE: { return 0; } } return DefWindowProc(m_Handle, argMessage, argWParam, argLParam); } void Window::SwapBuffers() { m_SwapChain->Present(); } void Window::set_Active(bool argActive) { m_Active = argActive; } bool Window::get_Active() { return m_Active; } void Window::set_Fullscreen(bool argFullscreen) { m_Fullscreen = argFullscreen; } bool Window::get_Fullscreen() { return m_Fullscreen; } void Window::set_VSync(bool argUseVSync) { m_SwapChain->set_VSync(argUseVSync); } bool Window::get_VSync() { return m_SwapChain->get_VSync(); } void Window::set_DeviceContext(HDC argDeviceContext) { m_DeviceContext = argDeviceContext; } HDC Window::get_DeviceContext() { return m_DeviceContext; } HWND Window::get_Handle() { return m_Handle; } void Window::set_Title(const string16& argTitle) { SetWindowText(m_Handle, std::to_string8(argTitle).c_str()); } string16 Window::get_Title() { char* text = ""; GetWindowText(m_Handle, text, GetWindowTextLength(m_Handle)); return std::to_string16(text); }