193 lines
4.8 KiB
C++

#include "Window.h"
#include <hidusage.h>
namespace eg3d {
bool eg3d::Window::mWndClassInitialized = false;
const char * eg3d::Window::sWndClassName = "eg3d_winclass";
Window * Window::pMainWindow = nullptr;
Window::Window(bool show, WinFn pWindowFunction) : pWindowFunction(pWindowFunction == nullptr ? smWindowFunc : pWindowFunction), pmEventHandler(nullptr) // ha nullptr van megadva, akkor visszaáll az eredeti függvényre
{
initializeWndClass(this->pWindowFunction); // window class inicializálása
create(); // ablak létrehozása
registerRawInputDevice(); // RID-ok regisztrálása
this->show(show);
}
Window::~Window()
{
DestroyWindow(mHWND);
}
void Window::initializeWndClass(WinFn pWindowFunction)
{
if (!mWndClassInitialized) // ha nincs még inicializálva a window class
{
WNDCLASSEX wcl;
wcl.hInstance = gEntryArgs.hThisInstance;
wcl.lpszClassName = sWndClassName;
wcl.lpfnWndProc = pWindowFunction;
wcl.style = 0;
wcl.cbSize = sizeof(WNDCLASSEX);
wcl.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
wcl.hIconSm = LoadIcon(nullptr, IDI_WINLOGO);
wcl.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcl.lpszMenuName = nullptr;
wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.hbrBackground = static_cast<HBRUSH>(GetStockObject(DKGRAY_BRUSH));
if (!RegisterClassEx(&wcl))
{
ERRBOX("Couldn't register window class for eg3d::Window");
}
mWndClassInitialized = true;
}
}
void Window::setSize(unsigned width, unsigned height) const
{
RECT winRect = getRect(); // ablak-téglalap lekérése
// terület beállítása
winRect.right = winRect.left + width;
winRect.bottom = winRect.top + height;
// keret hozzáadása
AdjustWindowRect(&winRect, GetWindowLong(mHWND, GWL_STYLE), false);
//SetWindowPos(mHWND, HWND_TOP, winRect.left, winRect.top, width, height, 0);
SetWindowPos(mHWND, HWND_TOP, winRect.top, winRect.left, winRect.right - winRect.left, winRect.bottom - winRect.top, 0);
UpdateWindow(mHWND);
}
SIZE Window::getSize() const
{
SIZE result;
RECT clientRect = getClientRect();
result.cx = clientRect.right - clientRect.left;
result.cy = clientRect.bottom - clientRect.top;
return result;
}
void Window::setTitle(const std::string& title) const
{
SetWindowTextA(mHWND, title.c_str());
}
std::string Window::getTitle() const
{
int titleLength = GetWindowTextLengthA(mHWND);
auto szTitle = new char[titleLength + 1];
GetWindowTextA(mHWND, szTitle, titleLength + 1);
std::string title(szTitle);
delete[] szTitle;
return title;
}
void Window::show(bool show) const
{
ShowWindow(mHWND, show ? SW_SHOW : SW_HIDE);
}
RECT Window::getRect() const
{
RECT winRect;
GetWindowRect(mHWND, &winRect);
return winRect;
}
RECT Window::getClientRect() const
{
RECT clRect;
GetClientRect(mHWND, &clRect);
return clRect;
}
////////////////////////////////////////////
LRESULT Window::smWindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
Window * pWindow = static_cast<Window *>((void *)GetWindowLongPtrA(hwnd, GWLP_USERDATA)); // ablakhoz rendelt eseménykezelõ elkérése
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default: // minden egyéb esemény kezelése
if (pWindow != nullptr && pWindow->getEventHandler() != nullptr) { // ha meg van adva eseménykezelõ
if (pWindow->getEventHandler()->processEvent(hwnd, message, wParam, lParam) != 0) { // ha nem lett lekezelve az esemény
return DefWindowProc(hwnd, message, wParam, lParam); // ...akkor rábízzuk a rendszerre
}
}
return DefWindowProc(hwnd, message, wParam, lParam); // ...akkor rábízzuk a rendszerre
}
return 0;
}
void Window::registerRawInputDevice()
{
RAWINPUTDEVICE device;
device.usUsagePage = HID_USAGE_PAGE_GENERIC;
device.usUsage = HID_USAGE_GENERIC_MOUSE;
device.dwFlags = RIDEV_INPUTSINK;
device.hwndTarget = mHWND;
RegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE));
}
void Window::create()
{
// ablak létrehozása
mHWND = CreateWindowA(sWndClassName,
"window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
HWND_DESKTOP,
nullptr,
gEntryArgs.hThisInstance,
nullptr);
SetWindowLongPtrA(mHWND, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
}
HWND Window::getHandle() const {
return mHWND;
}
double Window::getAspectRatio() const {
SIZE size = getSize();
return (double) size.cx / (double) size.cy;
}
void Window::setThisAsMainWindow() {
pMainWindow = this;
}
void Window::setEventHandler(EventHandler *pEH) {
pmEventHandler = pEH;
}
EventHandler *Window::getEventHandler() const {
return pmEventHandler;
}
}