#include "Window.h" #include 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(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((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(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; } }