From 3992c472799105256d0775f7a50581b08b79016c Mon Sep 17 00:00:00 2001 From: Tenshi Date: Thu, 26 Oct 2023 18:32:19 +0200 Subject: [PATCH] Add windowManager class --- src/GUI/WindowManager.cpp | 157 ++++++++++++++++++++++++++++++++++++++ src/GUI/WindowManager.hpp | 47 ++++++++++++ src/main.cpp | 20 +++-- 3 files changed, 217 insertions(+), 7 deletions(-) create mode 100644 src/GUI/WindowManager.cpp create mode 100644 src/GUI/WindowManager.hpp diff --git a/src/GUI/WindowManager.cpp b/src/GUI/WindowManager.cpp new file mode 100644 index 0000000..8450a85 --- /dev/null +++ b/src/GUI/WindowManager.cpp @@ -0,0 +1,157 @@ +#include +#include +#include +#include "WindowManager.hpp" +#include "backends/imgui_impl_win32.h" + +extern IMGUI_IMPL_API LRESULT +ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +namespace Xash::GUI +{ + WindowManager::WindowManager(HINSTANCE instance) : hInstance(instance) + { + try + { + CreateWindowClass(); + InitWindow(); + InitIcon(); + mDx11.Init(hWindow); + ApplyDarkMode(); + } + catch (const std::exception &e) + { + std::cerr << e.what() << std::endl; + bIsRunning = false; + } + } + + WindowManager::~WindowManager() + { + if (hIcon) + { + DestroyIcon(hIcon); + } + if (hWindow) + { + DestroyWindow(hWindow); + } + if (bIsWindowClassRegistered) + { + UnregisterClassW(mWindowClass.lpszClassName, mWindowClass.hInstance); + } + } + + // PUBLIC METHODS + + bool WindowManager::IsRunning() const + { + return bIsRunning; + } + + void WindowManager::Display() + { + mDx11.Clear(); + mDx11.Display(); + } + + void WindowManager::Update() + { + HandleWindowMessages(); + } + + // PRIVATE METHODS + + void WindowManager::HandleWindowMessages() + { + MSG message = {0}; + constexpr UINT msgFilterMin = 0; + constexpr UINT msgFilterMax = 0; + + while (PeekMessageW(&message, nullptr, msgFilterMin, msgFilterMax, PM_REMOVE)) + { + TranslateMessage(&message); + DispatchMessageW(&message); + if (message.message == WM_QUIT) + { + bIsRunning = FALSE; + break; + } + } + } + + LRESULT CALLBACK + WindowManager::WindowProcedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + if (ImGui_ImplWin32_WndProcHandler(hwnd, uMsg, wParam, lParam)) + { + return true; + } + if (uMsg == WM_DESTROY) + { + PostQuitMessage(0); + return 0; + } + return DefWindowProcW(hwnd, uMsg, wParam, lParam); + } + + // INITIALIZATION METHODS + + bool WindowManager::InitWindow() + { + hWindow = CreateWindowExW( + WS_EX_ACCEPTFILES, mWindowClass.lpszClassName, WindowName, + WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, + WindowWidth, WindowHeight, nullptr, nullptr, mWindowClass.hInstance, nullptr + ); + if (!hWindow) + { + throw std::runtime_error("Failed to create window"); + } + ShowWindow(hWindow, SW_SHOWDEFAULT); + return true; + } + + void WindowManager::InitIcon() + { + constexpr int iconSize = 0; + + hIcon = (HICON)LoadImageW( + hInstance, IconPath, IMAGE_ICON, iconSize, iconSize, + LR_LOADFROMFILE | LR_DEFAULTSIZE + ); + if (!hIcon) + { + throw std::runtime_error("Failed to load icon"); + } + SendMessageW(hWindow, WM_SETICON, ICON_BIG, reinterpret_cast(hIcon)); + SendMessageW(hWindow, WM_SETICON, ICON_SMALL, reinterpret_cast(hIcon)); + } + + void WindowManager::ApplyDarkMode() + { + DwmSetWindowAttribute( + hWindow, DWMWINDOWATTRIBUTE::DWMWA_USE_IMMERSIVE_DARK_MODE, &bIsDarkMode, + sizeof(bIsDarkMode) + ); + } + + void WindowManager::CreateWindowClass() + { + constexpr UINT windowClassStyle = 0; + + mWindowClass.cbSize = sizeof(WNDCLASSEXW); + mWindowClass.style = windowClassStyle; + mWindowClass.lpfnWndProc = WindowProcedure; + mWindowClass.hInstance = hInstance; + mWindowClass.hIcon = hIcon; + mWindowClass.hIconSm = hIcon; + mWindowClass.lpszClassName = WindowName; + if (!RegisterClassExW(&mWindowClass)) + { + throw std::runtime_error("Failed to register window class"); + } + bIsWindowClassRegistered = true; + } + +} // namespace Xash::GUI diff --git a/src/GUI/WindowManager.hpp b/src/GUI/WindowManager.hpp new file mode 100644 index 0000000..5115d03 --- /dev/null +++ b/src/GUI/WindowManager.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include +#include "DirectX11.hpp" + +namespace Xash +{ + namespace GUI + { + class WindowManager + { + static constexpr LPCWSTR WindowName = L"Xash"; + static constexpr UINT WindowWidth = 700; + static constexpr UINT WindowHeight = 400; + static constexpr LPCWSTR IconPath = L"assets\\icon.ico"; + + public: + WindowManager(HINSTANCE hInstance); + ~WindowManager(); + + bool IsRunning() const; + void Update(); + void Display(); + + private: + bool InitWindow(); + void CreateWindowClass(); + void InitIcon(); + void ApplyDarkMode(); + void HandleWindowMessages(); + + static LRESULT CALLBACK + WindowProcedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + + HWND hWindow = nullptr; + HICON hIcon = nullptr; + HINSTANCE hInstance = nullptr; + WNDCLASSEXW mWindowClass = {0}; + + DirectX11 mDx11; + + BOOL bIsDarkMode = TRUE; + bool bIsRunning = true; + bool bIsWindowClassRegistered = false; + }; + } // namespace GUI +} // namespace Xash diff --git a/src/main.cpp b/src/main.cpp index 7ced69c..2a8b1ef 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,13 +1,19 @@ #include #include +#include "WindowManager.hpp" -int WINAPI wWinMain( - HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) +int WINAPI +wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) { -#ifndef NDEBUG - std::wcout << L"Debug mode" << std::endl; -#else - std::wcout << L"Release mode" << std::endl; -#endif + UNREFERENCED_PARAMETER(hPrevInstance); + UNREFERENCED_PARAMETER(pCmdLine); + UNREFERENCED_PARAMETER(nCmdShow); + + Xash::GUI::WindowManager windowManager(hInstance); + while (windowManager.IsRunning()) + { + windowManager.Update(); + windowManager.Display(); + } return 0; }