Skip to content

Commit

Permalink
Fix for runtime style swap in demo
Browse files Browse the repository at this point in the history
fixes #3
  • Loading branch information
Stehfyn committed Jul 20, 2024
1 parent 8506b7b commit 76e92da
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 62 deletions.
48 changes: 23 additions & 25 deletions imgui-borderless-win32/BorderlessWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,29 +95,27 @@ namespace
return window_class_name;
}

unique_handle create_window(WNDPROC wndproc, void* userdata)
HWND create_window(WNDPROC wndproc, void* userdata)
{
HWND handle = CreateWindowExW(0, window_class(wndproc), L"Borderless Window",
static_cast<DWORD>(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 };
return handle;
}
}

BorderlessWindow::BorderlessWindow()
: m_hHWND{ create_window(&this->BorderlessWindow::WndProc, this) }
: m_hWND{ 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);
s_BorderlessInstanceMap.insert({ m_hWND, this });
GetClassNameW(m_hWND, m_wstrWC, 256);
set_composition(m_bCompositionEnabled);
set_borderless(m_bBorderless);
set_borderless_shadow(m_bBorderless_shadow);
::ShowWindow(m_hWND, SW_SHOW);

#ifdef BORDERLESS_DEBUG
AllocConsole();
Expand All @@ -129,13 +127,13 @@ BorderlessWindow::BorderlessWindow()
}

BorderlessWindow::BorderlessWindow(std::function<void()> render)
: m_hHWND{ create_window(&BorderlessWindow::WndProc, this) }, m_fRender(render)
: m_hWND{ 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);
GetClassNameW(m_hWND, m_wstrWC, 256);
set_composition(m_bCompositionEnabled);
set_borderless(m_bBorderless);
set_borderless_shadow(m_bBorderless_shadow);
::ShowWindow(m_hWND, SW_SHOW);
}

VOID BorderlessWindow::set_composition(BOOL enabled)
Expand All @@ -145,26 +143,26 @@ VOID BorderlessWindow::set_composition(BOOL enabled)
bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
bb.hRgnBlur = hRgn;
bb.fEnable = TRUE;
DwmEnableBlurBehindWindow(m_hHWND.get(), &bb);
DwmEnableBlurBehindWindow(m_hWND, &bb);
}

VOID BorderlessWindow::set_borderless(BOOL enabled)
{
Style new_style = (enabled) ? select_borderless_style() : Style::windowed;
Style old_style = static_cast<Style>(::GetWindowLongPtrW(m_hHWND.get(), GWL_STYLE));
Style old_style = static_cast<Style>(::GetWindowLongPtrW(m_hWND, GWL_STYLE));

if (new_style != old_style)
{
m_bBorderless = enabled;

::SetWindowLongPtrW(m_hHWND.get(), GWL_STYLE, static_cast<LONG>(new_style));
::SetWindowLongPtrW(m_hWND, GWL_STYLE, static_cast<LONG>(new_style));

// when switching between borderless and windowed, restore appropriate shadow state
set_shadow(m_hHWND.get(), m_bBorderless_shadow && (new_style != Style::windowed));
set_shadow(m_hWND, m_bBorderless_shadow && (new_style != Style::windowed));

// redraw frame
::SetWindowPos(m_hHWND.get(), nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
::ShowWindow(m_hHWND.get(), SW_SHOW);
::SetWindowPos(m_hWND, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
::ShowWindow(m_hWND, SW_SHOW);
}
}

Expand All @@ -173,7 +171,7 @@ VOID BorderlessWindow::set_borderless_shadow(BOOL enabled)
if (m_bBorderless)
{
m_bBorderless_shadow = enabled;
set_shadow(m_hHWND.get(), enabled);
set_shadow(m_hWND, enabled);
}
}

Expand Down Expand Up @@ -348,7 +346,7 @@ LRESULT BorderlessWindow::hit_test(POINT cursor)
};

RECT window{};
if (!::GetWindowRect(m_hHWND.get(), &window)) return HTNOWHERE;
if (!::GetWindowRect(m_hWND, &window)) return HTNOWHERE;

CONST UINT drag = m_bBorderless_drag ? HTCAPTION : HTCLIENT;

Expand Down
11 changes: 1 addition & 10 deletions imgui-borderless-win32/BorderlessWindow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,6 @@

#define BORDERLESS_USE_IMGUI // Tell BorderlessWindow to call ImGui_ImplWin32_WndProcHandler in WndProc

struct hwnd_deleter {
using pointer = HWND;
auto operator()(HWND handle) const -> void {
::DestroyWindow(handle);
}
};

using unique_handle = std::unique_ptr<HWND, hwnd_deleter>;

class BorderlessWindow
{
public:
Expand All @@ -37,7 +28,7 @@ class BorderlessWindow
UINT get_width() CONST;
UINT get_height() CONST;

unique_handle m_hHWND;
HWND m_hWND;
LPWSTR m_wstrWC;

private:
Expand Down
23 changes: 14 additions & 9 deletions imgui-borderless-win32/imgui.ini
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ Collapsed=0
DockId=0x00000002,0

[Window][Example: Simple overlay]
Pos=355,86
Size=346,46
Pos=340,76
Size=339,46
Collapsed=0

[Window][Borderless Demo]
Expand All @@ -53,7 +53,7 @@ Size=224,316
Collapsed=0

[Window][Borderless Settings]
Pos=224,80
Pos=953,10
Size=109,58
Collapsed=0

Expand All @@ -73,22 +73,22 @@ Size=232,401
Collapsed=0

[Window][DWM Accent State]
Pos=18,85
Pos=13,74
Size=179,196
Collapsed=0

[Window][DWM Gradient]
Pos=20,291
Pos=12,273
Size=224,293
Collapsed=0

[Window][DWM Accent Flags]
Pos=354,9
Pos=15,9
Size=312,58
Collapsed=0

[Window][DWM Animation id]
Pos=13,11
Pos=340,9
Size=312,58
Collapsed=0

Expand Down Expand Up @@ -125,10 +125,15 @@ Size=224,58
Collapsed=0

[Window][glClearColor]
Pos=266,291
Pos=252,272
Size=224,293
Collapsed=0

[Window][ImGui Window Bg]
Pos=663,9
Size=277,58
Collapsed=0

[Table][0x47600645,3]
RefScale=16
Column 0 Width=56
Expand Down Expand Up @@ -213,7 +218,7 @@ Column 1 Width=84
Column 2 Width=126

[Docking][Data]
DockSpace ID=0x8B93E3BD Window=0xA787BDB4 Pos=296,111 Size=1280,720 Split=X
DockSpace ID=0x8B93E3BD Window=0xA787BDB4 Pos=-1430,-162 Size=1280,720 Split=X
DockNode ID=0x00000003 Parent=0x8B93E3BD SizeRef=836,720 Split=X
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=955,720 Split=Y
DockNode ID=0x00000009 Parent=0x00000001 SizeRef=1280,591 Split=X
Expand Down
60 changes: 42 additions & 18 deletions imgui-borderless-win32/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ reinterpret_cast<PFN_SET_WINDOW_COMPOSITION_ATTRIBUTE>(GetProcAddress(GetModuleH

#include <string>
#include <vector>

#include <iostream>
#include "BorderlessWindow.hpp"

// Data stored per platform window
Expand Down Expand Up @@ -117,18 +117,18 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,

BorderlessWindow window; // Instantiate our borderless window

if (!CreateDeviceWGL(window.m_hHWND.get(), &g_MainWindow))
if (!CreateDeviceWGL(window.m_hWND, &g_MainWindow))
{
CleanupDeviceWGL(window.m_hHWND.get(), &g_MainWindow);
::DestroyWindow(window.m_hHWND.get());
CleanupDeviceWGL(window.m_hWND, &g_MainWindow);
::DestroyWindow(window.m_hWND);
::UnregisterClassW((LPCWSTR)window.m_wstrWC, GetModuleHandle(NULL));
return 1;
}

wglMakeCurrent(g_MainWindow.hDC, g_hRC);

::ShowWindow(window.m_hHWND.get(), SW_SHOWDEFAULT);
::UpdateWindow(window.m_hHWND.get());
::ShowWindow(window.m_hWND, SW_SHOWDEFAULT);
::UpdateWindow(window.m_hWND);

IMGUI_CHECKVERSION();
ImGui::CreateContext();
Expand All @@ -150,7 +150,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
}

// Setup Platform/Renderer backends
ImGui_ImplWin32_InitForOpenGL(window.m_hHWND.get());
ImGui_ImplWin32_InitForOpenGL(window.m_hWND);
ImGui_ImplOpenGL3_Init();

if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
Expand All @@ -165,6 +165,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
platform_io.Renderer_SwapBuffers = Hook_Renderer_SwapBuffers;
platform_io.Platform_RenderWindow = Hook_Platform_RenderWindow;
}

//ImGui::GetIO().ConfigViewportsNoDecoration = false;

// Main loop
Expand All @@ -174,6 +175,9 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,

while (!done)
{
static bool swap_styles = false; // Make sure we swap styles outside the WndProc
static bool borderless = true; // Borderless Window's default constructs to borderless

while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
::TranslateMessage(&msg);
Expand All @@ -183,6 +187,14 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
}
if (done) break;

// If we want to swap styles
if (swap_styles)
{
borderless = !borderless;
window.set_borderless(borderless);
swap_styles = false;
}

static auto render = [&]() {
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplWin32_NewFrame();
Expand All @@ -202,14 +214,14 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
{
if (ImGui::Begin("Borderless Settings", 0, window_flags))
{
static SmartProperty<INT> window_mode{ 1 };
static SmartProperty<INT> window_mode{ static_cast<int>(borderless) };
ImGui::RadioButton("Windowed", &window_mode.m_Value, 0);
ImGui::RadioButton("Borderless", &window_mode.m_Value, 1);
if (window_mode.update()) window.set_borderless(window_mode.m_Value);
if (window_mode.update()) swap_styles = true;
}
ImGui::End();
}

// Borderless Demo
{
// DWM api is undocumented, and has varying behavior between Windows Releases
Expand All @@ -235,7 +247,13 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
ImGui::Begin("DWM Accent Flags", 0, window_flags);
ImGui::SeparatorText("DWM Accent Flags");
static SmartProperty<INT> accent_flags{ 1 };
ImGui::SliderInt("Accent Flags", &accent_flags.m_Value, 0, 255);
ImGui::InputInt("Accent Flags", &accent_flags.m_Value, 0, 255);
ImGui::End();

ImGui::Begin("DWM Animation id", 0, window_flags);
ImGui::SeparatorText("DWM Animation id");
static SmartProperty<INT> animation_id{ 0 };
ImGui::SliderInt("Accent Flags", &animation_id.m_Value, 0, 32);
ImGui::End();

ImGui::Begin("DWM Gradient", 0, window_flags);
Expand All @@ -251,19 +269,25 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
ImGui::ColorPicker4("##picker", (float*)&clear_color, ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview);
ImGui::End();

ImGui::Begin("DWM Animation id", 0, window_flags);
ImGui::SeparatorText("DWM Animation id");
static SmartProperty<INT> animation_id{ 0 };
ImGui::SliderInt("Accent Flags", &animation_id.m_Value, 0, 32);
ImGui::Begin("ImGui Window Bg", 0, window_flags);
ImGui::SeparatorText("ImGuiCol_WindowBgAlpha");
static SmartProperty<float> bg_alpha{ 1 };
ImGui::SliderFloat("BgAlpha", &bg_alpha.m_Value, 1, 0);
if (bg_alpha.update()) {
ImVec4 window_bg = ImGui::GetStyle().Colors[ImGuiCol_WindowBg];
window_bg.w = bg_alpha.m_Value;
ImGui::GetStyle().Colors[ImGuiCol_WindowBg] = window_bg;
}
ImGui::End();


accent_policy.update();
accent_flags.update();
gradient_col.update();
animation_id.update();


static bool init_accents = true; //to apply default initialization
static bool init_accents = false; //to apply default initialization
if (accent_policy.has_changed() || accent_flags.has_changed()
|| gradient_col.has_changed() || animation_id.has_changed()
|| init_accents)
Expand All @@ -283,7 +307,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
sizeof(policy)
};

SetWindowCompositionAttribute(window.m_hHWND.get(), &data);
SetWindowCompositionAttribute(window.m_hWND, &data);
}
}

Expand Down Expand Up @@ -365,7 +389,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
set_render = true;
}

render(); //render when we leave message loop
render(); // and render when we leave message loop
}

return 0;
Expand Down

0 comments on commit 76e92da

Please sign in to comment.