From 908c5440d397f0403890b3ba3cfd03ee2739f1b8 Mon Sep 17 00:00:00 2001 From: McMassiveNZ <12842622+McMassiveNZ@users.noreply.github.com> Date: Wed, 3 May 2023 22:16:33 +0200 Subject: [PATCH] Abstracted Window + Pure Virtual Window class + Win32 Impl * TODO: do something about the while(window->PumpMessages()) --- .clang-format | 3 +- CMakeLists.txt | 10 +-- src/CMakeLists.txt | 32 ++++++--- src/main.cpp | 18 ++++- src/platform/win32_window.cpp | 123 ++++++++++++++++++++++++++++++++++ src/window.h | 26 +++++++ 6 files changed, 192 insertions(+), 20 deletions(-) create mode 100644 src/platform/win32_window.cpp create mode 100644 src/window.h diff --git a/.clang-format b/.clang-format index 8268ef7..5c8ef4d 100644 --- a/.clang-format +++ b/.clang-format @@ -145,5 +145,4 @@ UseTab: Always WhitespaceSensitiveMacros: - STRINGIZE - PP_STRINGIZE - - BOOST_PP_STRINGIZE -... \ No newline at end of file + - BOOST_PP_STRINGIZE \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 671cc0e..a5c9ec4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,17 +1,17 @@ cmake_minimum_required(VERSION 3.23) -project(blank-slate VERSION 1.0.0) +project(starter_window VERSION 1.0.0) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED true) set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "" FORCE) set_property(GLOBAL PROPERTY USE_FOLDERS ON) -OPTION(ENABLE_TESTS "Enable Unit Tests" ON) +OPTION(ENABLE_TESTS "Enable Unit Tests" OFF) OPTION(ENABLE_ALL_REASONABLE_WARNINGS "Enable all possible reasonable warnings" ON ) OPTION(ENABLE_WARNINGS_AS_ERRORS "Warnings are treated as Errors" ON) -OPTION(ENABLE_STATIC_ANALYSIS "Enable Static Analysis Tools" ON) -OPTION(ENABLE_SANITIZERS "Enable Sanitizer Tools" ON) +OPTION(ENABLE_STATIC_ANALYSIS "Enable Static Analysis Tools" OFF) +OPTION(ENABLE_SANITIZERS "Enable Sanitizer Tools" OFF) set(CMAKE_SCRIPTS_DIR ${CMAKE_CURRENT_LIST_DIR}/scripts/cmake) @@ -20,7 +20,7 @@ include(${CMAKE_SCRIPTS_DIR}/sanitizers.cmake) include(${CMAKE_SCRIPTS_DIR}/staticanalysis.cmake) if (ENABLE_TESTS) - message("Unit Testing Enabled") + message("-- Unit Testing Enabled") enable_testing() add_subdirectory(test) endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 93d2b4f..17caf24 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,29 +1,41 @@ -set(current_target blank_slate) +set(current_target starter_window) + +set(SOURCE_FILES) +set(STARTER_WINDOW_SRC + main.cpp + window.h +) +source_group("" FILES ${STARTER_WINDOW_SRC}) + +set(PLATFORM_SRC + platform/win32_window.cpp +) +source_group(platform FILES ${PLATFORM_SRC}) + +list(APPEND SOURCE_FILES ${PLATFORM_SRC}) +list(APPEND SOURCE_FILES ${STARTER_WINDOW_SRC}) add_executable( - ${current_target} - main.cpp + ${current_target} + ${SOURCE_FILES} ) -find_package(spdlog CONFIG REQUIRED) -target_link_libraries(${current_target} PRIVATE spdlog::spdlog spdlog::spdlog_header_only) - if( ENABLE_ALL_REASONABLE_WARNINGS ) - MESSAGE("Additional Warnings Enabled") + MESSAGE("-- Additional Warnings Enabled") target_enable_warnings(${current_target}) endif() if( ENABLE_WARNINGS_AS_ERRORS ) - MESSAGE("Warnings as Errors") + MESSAGE("-- Warnings as Errors") target_warnings_as_errors(${current_target}) endif() if( ENABLE_SANITIZERS ) - MESSAGE("Sanitizers Enabled") + MESSAGE("-- Sanitizers Enabled") target_enable_sanitizers(${current_target}) endif() if( ENABLE_STATIC_ANALYSIS ) - MESSAGE("Static Analysis Enabled") + MESSAGE("-- Static Analysis Enabled") target_enable_static_analysis(${current_target}) endif() diff --git a/src/main.cpp b/src/main.cpp index d75c935..f212782 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,20 @@ -#include +#include "window.h" + +constexpr int CW_USEDEFAULT = 0x80000000; auto main() -> int { - spdlog::trace("Hello, World!"); - return 0; + auto window = swCreateWindow({ + .x = CW_USEDEFAULT, + .y = CW_USEDEFAULT, + .width = CW_USEDEFAULT, + .height = CW_USEDEFAULT, + .name = "Starter Window" + }); + + while (window->PumpMessages()) + { + //do something + } } diff --git a/src/platform/win32_window.cpp b/src/platform/win32_window.cpp new file mode 100644 index 0000000..7c2ee6f --- /dev/null +++ b/src/platform/win32_window.cpp @@ -0,0 +1,123 @@ +#include "../window.h" + +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#include + +static LRESULT CALLBACK WindowProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_DESTROY: + { + PostQuitMessage(0); + return 0; + } + + case WM_PAINT: + { + PAINTSTRUCT ps = {}; + HDC hdc = BeginPaint(window, &ps); + FillRect(hdc, &ps.rcPaint, reinterpret_cast(COLOR_WINDOW + 1)); + EndPaint(window, &ps); + return 0; + } + } + return DefWindowProc(window, message, wParam, lParam); +} + +namespace starter_window +{ + +class Win32WindowImpl : public Window +{ +public: + Win32WindowImpl(); + ~Win32WindowImpl() override = default; + + Win32WindowImpl(const Win32WindowImpl&) = delete; + Win32WindowImpl& operator=(const Win32WindowImpl&) = delete; + + bool init(WindowCreateParams params); + bool PumpMessages() override; + + HINSTANCE hInstance; + HWND hWnd; +}; + +Win32WindowImpl::Win32WindowImpl() + : hInstance(GetModuleHandle(NULL)) + , hWnd(nullptr) +{ +} + +bool Win32WindowImpl::init(WindowCreateParams params) +{ + const char className[] = "Win32WindowImpl"; + + WNDCLASSEX wc = {}; + + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = WindowProc; + wc.hInstance = hInstance; + wc.lpszClassName = className; + + if (RegisterClassEx(&wc) == NULL) + { + MessageBox(nullptr, "Call to RegisterClass failed", NULL, MB_OK); + return false; + } + + HWND window = CreateWindowEx( + 0, + className, + params.name, + WS_OVERLAPPEDWINDOW, + params.x, params.y, params.width, params.height, + NULL, + NULL, + hInstance, + NULL); + + if (window == NULL) + { + MessageBox(nullptr, "Call to CreateWindow failed", NULL, MB_OK); + return false; + } + + ShowWindow(window, SW_SHOW); + return true; +} + +bool Win32WindowImpl::PumpMessages() +{ + MSG message = {}; + if (GetMessage(&message, NULL, 0, 0) != 0) + { + TranslateMessage(&message); + DispatchMessage(&message); + return true; + } + + // GetMessage returned WM_QUIT + return false; +} +} // namespace starter_window + +std::unique_ptr swCreateWindow(starter_window::WindowCreateParams params) +{ + auto result = std::make_unique(); + if (result->init(params) == false) + { + result = nullptr; + } + + return result; +} \ No newline at end of file diff --git a/src/window.h b/src/window.h new file mode 100644 index 0000000..d9d4938 --- /dev/null +++ b/src/window.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +namespace starter_window +{ + +struct WindowCreateParams +{ + int x; + int y; + int width; + int height; + const char* name; +}; + +class Window +{ +public: + virtual ~Window() = default; + virtual bool PumpMessages() = 0; +}; + +} + +std::unique_ptr swCreateWindow(starter_window::WindowCreateParams params);