208 lines
3.8 KiB
C++
208 lines
3.8 KiB
C++
|
#include "Window.h"
|
||
|
|
||
|
#include <Windows.h>
|
||
|
#include <windowsx.h>
|
||
|
|
||
|
#include <iostream>
|
||
|
#include <map>
|
||
|
|
||
|
#include "vec2.h"
|
||
|
|
||
|
namespace {
|
||
|
// Only one Window can be created per HWND
|
||
|
std::map<HWND, Window*> g_windows;
|
||
|
}
|
||
|
|
||
|
LRESULT CALLBACK main_wnd_proc(HWND h_wnd, UINT msg, WPARAM w_param, LPARAM l_param) {
|
||
|
auto w = g_windows.find(h_wnd);
|
||
|
if (w == g_windows.end())
|
||
|
{
|
||
|
return DefWindowProc(h_wnd, msg, w_param, l_param);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return w->second->wnd_proc(h_wnd, msg, w_param, l_param);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Window::Window(const char* class_name, HINSTANCE h_instance)
|
||
|
: m_class_name(class_name), m_h_instance(h_instance)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
Window::~Window()
|
||
|
{
|
||
|
if (m_h_wnd != nullptr)
|
||
|
{
|
||
|
g_windows.erase(m_h_wnd);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LRESULT CALLBACK Window::wnd_proc(HWND h_wnd, UINT msg, WPARAM w_param, LPARAM l_param)
|
||
|
{
|
||
|
switch (msg)
|
||
|
{
|
||
|
case WM_KEYDOWN:
|
||
|
case WM_SYSKEYDOWN:
|
||
|
m_input_manager.key_down(l_param);
|
||
|
return DefWindowProc(h_wnd, msg, w_param, l_param);
|
||
|
case WM_KEYUP:
|
||
|
case WM_SYSKEYUP:
|
||
|
m_input_manager.key_up((unsigned long)l_param);
|
||
|
break;
|
||
|
case WM_LBUTTONDOWN:
|
||
|
m_input_manager.key_down(VK_LBUTTON);
|
||
|
break;
|
||
|
case WM_LBUTTONUP:
|
||
|
m_input_manager.key_up(VK_LBUTTON);
|
||
|
break;
|
||
|
case WM_RBUTTONDOWN:
|
||
|
m_input_manager.key_down(VK_RBUTTON);
|
||
|
break;
|
||
|
case WM_RBUTTONUP:
|
||
|
m_input_manager.key_up(VK_RBUTTON);
|
||
|
break;
|
||
|
case WM_MBUTTONDOWN:
|
||
|
m_input_manager.key_down(VK_MBUTTON);
|
||
|
break;
|
||
|
case WM_MBUTTONUP:
|
||
|
m_input_manager.key_up(VK_MBUTTON);
|
||
|
break;
|
||
|
case WM_MOUSEMOVE:
|
||
|
m_input_manager.mouse_move(ivec2(GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param)));
|
||
|
break;
|
||
|
case WM_MOUSEWHEEL:
|
||
|
m_input_manager.mouse_scroll(GET_WHEEL_DELTA_WPARAM(w_param) / WHEEL_DELTA);
|
||
|
break;
|
||
|
case WM_DESTROY:
|
||
|
PostQuitMessage(0);
|
||
|
break;
|
||
|
}
|
||
|
return DefWindowProc(h_wnd, msg, w_param, l_param);
|
||
|
}
|
||
|
|
||
|
bool Window::register_class()
|
||
|
{
|
||
|
m_wc.style = 0;
|
||
|
|
||
|
m_wc.cbSize = sizeof(WNDCLASSEX);
|
||
|
m_wc.cbClsExtra = 0;
|
||
|
m_wc.cbWndExtra = 0;
|
||
|
|
||
|
m_wc.hInstance = m_h_instance;
|
||
|
|
||
|
m_wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||
|
m_wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
||
|
m_wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||
|
m_wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
|
||
|
|
||
|
m_wc.lpszClassName = m_class_name;
|
||
|
m_wc.lpszMenuName = NULL;
|
||
|
|
||
|
m_wc.lpfnWndProc = main_wnd_proc;
|
||
|
|
||
|
return RegisterClassEx(&m_wc);
|
||
|
}
|
||
|
|
||
|
bool Window::create_window(const char* title, int x, int y, int w, int h)
|
||
|
{
|
||
|
if (m_h_wnd != NULL)
|
||
|
{
|
||
|
g_windows.erase(m_h_wnd);
|
||
|
}
|
||
|
|
||
|
// Fix for window border with width and height
|
||
|
DWORD style = WS_POPUP | WS_VISIBLE | WS_SYSMENU;
|
||
|
RECT window_rect = { 0, 0, w, h };
|
||
|
AdjustWindowRect(&window_rect, style, false);
|
||
|
int width = window_rect.right - window_rect.left;
|
||
|
int height = window_rect.bottom - window_rect.top;
|
||
|
|
||
|
if (x == -1)
|
||
|
{
|
||
|
// Center x-position
|
||
|
x = GetSystemMetrics(SM_CXSCREEN) / 2 - width / 2;
|
||
|
}
|
||
|
|
||
|
if (y == -1)
|
||
|
{
|
||
|
// Center y-position
|
||
|
y = GetSystemMetrics(SM_CYSCREEN) / 2 - height / 2;
|
||
|
}
|
||
|
|
||
|
m_h_wnd = CreateWindow
|
||
|
(
|
||
|
m_class_name,
|
||
|
title,
|
||
|
style,
|
||
|
x, y,
|
||
|
width, height,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
m_h_instance,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
if (m_h_wnd != NULL)
|
||
|
{
|
||
|
// TODO: Figure out why value_type is needed here...
|
||
|
g_windows.insert(std::map<HWND, Window*>::value_type(m_h_wnd, this));
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
MessageResponse Window::handle_message()
|
||
|
{
|
||
|
MSG msg = { 0 };
|
||
|
if (!PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
|
||
|
{
|
||
|
return NO_MESSAGE;
|
||
|
}
|
||
|
if (msg.message == WM_QUIT)
|
||
|
{
|
||
|
return QUIT_MESSAGE;
|
||
|
}
|
||
|
TranslateMessage(&msg);
|
||
|
DispatchMessage(&msg);
|
||
|
return HANDLED_MESSAGE;
|
||
|
}
|
||
|
|
||
|
void Window::show(int cmd_show)
|
||
|
{
|
||
|
ShowWindow(m_h_wnd, cmd_show);
|
||
|
}
|
||
|
|
||
|
void Window::update()
|
||
|
{
|
||
|
UpdateWindow(m_h_wnd);
|
||
|
}
|
||
|
|
||
|
void Window::close()
|
||
|
{
|
||
|
CloseWindow(m_h_wnd);
|
||
|
}
|
||
|
|
||
|
void Window::set_h_glrc(HGLRC h_glrc)
|
||
|
{
|
||
|
m_h_glrc = h_glrc;
|
||
|
}
|
||
|
|
||
|
HGLRC Window::get_h_glrc()
|
||
|
{
|
||
|
return m_h_glrc;
|
||
|
}
|
||
|
|
||
|
HWND Window::get_h_wnd()
|
||
|
{
|
||
|
return m_h_wnd;
|
||
|
}
|
||
|
|
||
|
const InputManager & Window::get_input_manager()
|
||
|
{
|
||
|
return m_input_manager;
|
||
|
}
|