All pastes #920876 Raw Edit

Anonymous

public text v1 · immutable
#920876 ·published 2008-02-27 17:58 UTC
rendered paste body
#ifndef OSE_VIDEO_WINDOW_HPP
#define OSE_VIDEO_WINDOW_HPP

#include <string>

#include <windows.h>
#include <GL/gl.h>

#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<HBRUSH>(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<int>(window_size_.get_width()),
				static_cast<int>(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<unsigned long>(window_size_.get_width());
				dm.dmPelsHeight = static_cast<unsigned long>(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<unsigned long>(window_size_.get_width());
						dm.dmPelsHeight = static_cast<unsigned long>(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<LONG>(
				reinterpret_cast<LPCREATESTRUCT>(lParam)->lpCreateParams));

			ose::video::window *win = reinterpret_cast<ose::video::window *>(GetWindowLongPtr(window, GWLP_USERDATA));

			if(!win)
				return DefWindowProc(window, msg, wParam, lParam);

			return win->procedure(window, msg, wParam, lParam);
		}

	}
}