From cc5942dfe663d41090d8669441227879d9bcb546 Mon Sep 17 00:00:00 2001 From: Stephen Foster Date: Tue, 12 Dec 2023 17:53:11 -0800 Subject: [PATCH] Added a glClearColor picker --- .../BorderlessWindow.cpp | 391 ++++++++++++++++++ imgui-borderless-win32/BorderlessWindow.cpp | 4 +- imgui-borderless-win32/imgui.ini | 31 +- imgui-borderless-win32/main.cpp | 10 +- 4 files changed, 419 insertions(+), 17 deletions(-) create mode 100644 enc_temp_folder/6088e8e6d756bf16e33c6a196778ef2f/BorderlessWindow.cpp diff --git a/enc_temp_folder/6088e8e6d756bf16e33c6a196778ef2f/BorderlessWindow.cpp b/enc_temp_folder/6088e8e6d756bf16e33c6a196778ef2f/BorderlessWindow.cpp new file mode 100644 index 0000000..84da5f9 --- /dev/null +++ b/enc_temp_folder/6088e8e6d756bf16e33c6a196778ef2f/BorderlessWindow.cpp @@ -0,0 +1,391 @@ +// Adapted from https://github.com/melak47/BorderlessWindow + +#include "BorderlessWindow.hpp" + +#include +#include + +#include +#include +#include +#include +#include + + +namespace +{ + static UINT timer_id = 0; + static std::unordered_map s_BorderlessInstanceMap; + + enum class Style : DWORD + { + windowed = WS_OVERLAPPEDWINDOW | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, + aero_borderless = WS_POPUP | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX, + basic_borderless = WS_POPUP | WS_THICKFRAME | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX + }; + + BOOL is_maximized(HWND hwnd) + { + WINDOWPLACEMENT placement{}; + if (!::GetWindowPlacement(hwnd, &placement)) return false; + return placement.showCmd == SW_MAXIMIZE; + } + + BOOL is_composition_enabled() + { + BOOL composition_enabled = FALSE; + bool success = ::DwmIsCompositionEnabled(&composition_enabled) == S_OK; + return composition_enabled && success; + } + + Style select_borderless_style() + { + return is_composition_enabled() ? Style::aero_borderless : Style::basic_borderless; + } + + VOID set_shadow(HWND handle, BOOL enabled) + { + if (is_composition_enabled()) + { + static CONST MARGINS shadow_state[2]{ { 0,0,0,0 },{ 1,1,1,1 } }; + ::DwmExtendFrameIntoClientArea(handle, &shadow_state[enabled]); + } + } + + VOID adjust_maximized_client_rect(HWND window, RECT& rect) + { + if (!is_maximized(window)) return; + + HMONITOR monitor = ::MonitorFromWindow(window, MONITOR_DEFAULTTONULL); + if (!monitor) return; + + MONITORINFO monitor_info{}; + monitor_info.cbSize = sizeof(monitor_info); + if (!::GetMonitorInfoW(monitor, &monitor_info)) return; + + // when maximized, make the client area fill just the monitor (without task bar) rect, + // not the whole window rect which extends beyond the monitor. + rect = monitor_info.rcWork; + } + + std::system_error last_error(const std::string& msg) + { + return std::system_error(std::error_code(::GetLastError(), std::system_category()), msg); + } + + CONST WCHAR* window_class(WNDPROC wndproc) + { + static CONST WCHAR* window_class_name = [&] + { + WNDCLASSEXW wcx{}; + wcx.cbSize = sizeof(wcx); + wcx.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wcx.hInstance = nullptr; + wcx.lpfnWndProc = wndproc; + wcx.lpszClassName = L"BorderlessWindowClass"; + wcx.hbrBackground = NULL; + wcx.hCursor = ::LoadCursorW(nullptr, IDC_ARROW); + + const ATOM result = ::RegisterClassExW(&wcx); + if (!result) throw last_error("failed to register window class"); + + return wcx.lpszClassName; + }(); + + return window_class_name; + } + + unique_handle create_window(WNDPROC wndproc, void* userdata) + { + HWND handle = CreateWindowExW(0, window_class(wndproc), L"Borderless Window", + static_cast(Style::aero_borderless), CW_USEDEFAULT, CW_USEDEFAULT, + 1280, 720, nullptr, nullptr, nullptr, userdata + ); + + if (!handle) throw last_error("failed to create window"); + + + return unique_handle{ handle }; + } +} + +BorderlessWindow::BorderlessWindow() + : m_hHWND{ create_window(&this->BorderlessWindow::WndProc, this) } +{ + s_BorderlessInstanceMap.insert({ m_hHWND.get(), this }); + GetClassNameW(m_hHWND.get(), m_wstrWC, 256); + set_composition(true); + set_borderless(true); + set_borderless_shadow(true); + ::ShowWindow(m_hHWND.get(), SW_SHOW); + +#ifdef BORDERLESS_DEBUG + AllocConsole(); + + freopen("CONIN$", "r", stdin); + freopen("CONOUT$", "w", stdout); + freopen("CONOUT$", "w", stderr); +#endif +} + +BorderlessWindow::BorderlessWindow(std::function render) + : m_hHWND{ create_window(&BorderlessWindow::WndProc, this) }, m_fRender(render) +{ + GetClassNameW(m_hHWND.get(), m_wstrWC, 256); + set_composition(true); + set_borderless(true); + set_borderless_shadow(true); + ::ShowWindow(m_hHWND.get(), SW_SHOW); +} + +VOID BorderlessWindow::set_composition(BOOL enabled) +{ + DWM_BLURBEHIND bb = { 0 }; + HRGN hRgn = CreateRectRgn(0, 0, -1, -1); + bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; + bb.hRgnBlur = hRgn; + bb.fEnable = TRUE; + DwmEnableBlurBehindWindow(m_hHWND.get(), &bb); +} + +VOID BorderlessWindow::set_borderless(BOOL enabled) +{ + Style new_style = (enabled) ? select_borderless_style() : Style::windowed; + Style old_style = static_cast