#ifndef OSE_VIDEO_WINDOW_HPP #define OSE_VIDEO_WINDOW_HPP #include #include #include #include "point.hpp" #include "size.hpp" #include "video_exception.hpp" namespace ose { namespace video { class window { public: window::window(const std::string &, const size &, const point &, bool); ~window(); bool is_fullscreen() const; size get_size() const; void set_size(const size &); point get_position() const; void set_position(const point &) private: std::string window_name_; size window_size_; point window_pos_; bool fullscreen_; LRESULT procedure(HWND, UINT, WPARAM, LPARAM); static LRESULT CALLBACK static_procedure(HWND, UINT, WPARAM, LPARAM); void initialize_opengl(); HWND window_handle_; bool active_; }; } } #endif #include "window.hpp" namespace ose { namespace video { window::window(const std::string &window_name, const size &window_size, const point &window_pos, bool fullscreen) { window_name_ = window_name; window_size_ = window_size; window_pos_ = window_pos; fullscreen_ = fullscreen; WNDCLASSEX wcx; wcx.cbClsExtra = 0; wcx.cbSize = sizeof(wcx); wcx.cbWndExtra = 0; wcx.hbrBackground = static_cast(GetStockObject(BLACK_BRUSH)); wcx.hCursor = LoadCursor(0, IDC_ARROW); wcx.hIcon = LoadIcon(0, IDI_WINLOGO); wcx.hIconSm = wcx.hIcon; wcx.hInstance = GetModuleHandle(0); wcx.lpfnWndProc = static_procedure; wcx.lpszClassName = window_name_.c_str(); wcx.lpszMenuName = 0; wcx.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; if(!RegisterClassEx( &wcx)) throw video_exception("Failed to create rendering window"); int winStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE; if(fullscreen_) winStyle = WS_POPUP | WS_VISIBLE; RECT winRect; SetRect(&winRect, 0, 0, static_cast(window_size_.get_width()), static_cast(window_size_.get_height())); if(!fullscreen_) AdjustWindowRectEx(&winRect, winStyle, false, 0); window_handle_ = CreateWindowEx(0, window_name.c_str(), window_name.c_str(), winStyle, 0, 0, winRect.right, winRect.bottom, 0, 0, wcx.hInstance, this); if(!window_handle_) throw video_exception("Failed to create rendering window"); if(fullscreen_) { DEVMODE dm = { 0 }; dm.dmSize = sizeof(dm); dm.dmBitsPerPel = 32; dm.dmPelsWidth = static_cast(window_size_.get_width()); dm.dmPelsHeight = static_cast(window_size_.get_height()); dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; if(ChangeDisplaySettings(&dm, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) throw video_exception("Failed to switch to requested resolution"); } ShowCursor(false); active_ = true; } window::~window() { ShowCursor(true); if(window_handle_) DestroyWindow(window_handle_); UnregisterClass(window_name_.c_str(), GetModuleHandle(0)); } bool window::is_fullscreen() const { return fullscreen_; } size window::get_size() const { return window_size_; } void window::set_size(const size &window_size) { window_size_ = window_size; } point window::get_position() const { return window_pos_; } void window::set_position(const point &window_pos) { window_pos_ = window_pos; } LRESULT window::procedure(HWND window, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CLOSE: PostQuitMessage(0); break; case WM_ACTIVATE: if(is_fullscreen()) { if (LOWORD(wParam) == WA_INACTIVE) { ChangeDisplaySettings(0, 0); ShowWindow(window, SW_SHOWMINNOACTIVE); active_ = false; } else { ShowWindow(window, SW_SHOW); DEVMODE dm = { 0 }; dm.dmSize = sizeof(dm); dm.dmBitsPerPel = 32; dm.dmPelsWidth = static_cast(window_size_.get_width()); dm.dmPelsHeight = static_cast(window_size_.get_height()); dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; if(ChangeDisplaySettings(&dm, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) throw video_exception("Failed to switch to requested resolution"); active_ = true; } } break; default: return DefWindowProc(window, msg, wParam, lParam); } return 0; } LRESULT window::static_procedure(HWND window, UINT msg, WPARAM wParam, LPARAM lParam) { if(msg == WM_CREATE) SetWindowLongPtr(window, GWLP_USERDATA, reinterpret_cast( reinterpret_cast(lParam)->lpCreateParams)); ose::video::window *win = reinterpret_cast(GetWindowLongPtr(window, GWLP_USERDATA)); if(!win) return DefWindowProc(window, msg, wParam, lParam); return win->procedure(window, msg, wParam, lParam); } } }