From 9fd4699c9f660eb8ea2333b76f6e4cecb5d85d70 Mon Sep 17 00:00:00 2001 From: xtex Date: Mon, 20 Sep 2021 10:57:52 +0800 Subject: [PATCH] feat: keep console window on Windows for debug builds --- source/window/win_window.cpp | 522 ++++++++++++++++++----------------- 1 file changed, 262 insertions(+), 260 deletions(-) diff --git a/source/window/win_window.cpp b/source/window/win_window.cpp index 8ddfea13e..3c913ae8c 100644 --- a/source/window/win_window.cpp +++ b/source/window/win_window.cpp @@ -1,261 +1,263 @@ -#include "window.hpp" - - -#if defined(OS_WINDOWS) - - #include - #include - - #include - #include - #include - - #include - - #include - #define GLFW_EXPOSE_NATIVE_WIN32 - #include - #undef GLFW_EXPOSE_NATIVE_WIN32 - - #include - #include - #include - - namespace hex { - - static LONG_PTR oldWndProc; - static float titleBarHeight; - static ImGuiMouseCursor mouseCursorIcon; - - static bool isTaskbarAutoHideEnabled(UINT edge, RECT monitor) { - APPBARDATA data = { .cbSize = sizeof(APPBARDATA), .uEdge = edge, .rc = monitor }; - return ::SHAppBarMessage(ABM_GETAUTOHIDEBAR, &data); - } - - static LRESULT windowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - switch (uMsg) { - case WM_NCCALCSIZE: { - RECT &rect = *reinterpret_cast(lParam); - RECT client = rect; - - DefWindowProcW(hwnd, WM_NCCALCSIZE, wParam, lParam); - - if (IsMaximized(hwnd)) { - WINDOWINFO windowInfo = { .cbSize = sizeof(WINDOWINFO) }; - GetWindowInfo(hwnd, &windowInfo); - rect = RECT { - .left = static_cast(client.left + windowInfo.cyWindowBorders), - .top = static_cast(client.top + windowInfo.cyWindowBorders), - .right = static_cast(client.right - windowInfo.cyWindowBorders), - .bottom = static_cast(client.bottom - windowInfo.cyWindowBorders) - }; - - HMONITOR hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY); - MONITORINFO monitorInfo = { .cbSize = sizeof(MONITORINFO) }; - GetMonitorInfoW(hMonitor, &monitorInfo); - - if (EqualRect(&rect, &monitorInfo.rcMonitor)) { - if (isTaskbarAutoHideEnabled(ABE_BOTTOM, monitorInfo.rcMonitor)) - rect.bottom--; - else if (isTaskbarAutoHideEnabled(ABE_LEFT, monitorInfo.rcMonitor)) - rect.left++; - else if (isTaskbarAutoHideEnabled(ABE_TOP, monitorInfo.rcMonitor)) - rect.top++; - else if (isTaskbarAutoHideEnabled(ABE_RIGHT, monitorInfo.rcMonitor)) - rect.right--; - } - } else { - rect = client; - } - - return 0; - } - case WM_SETCURSOR: { - auto cursorPos = LOWORD(lParam); - - switch (cursorPos) { - case HTRIGHT: - case HTLEFT: - mouseCursorIcon = ImGuiMouseCursor_ResizeEW; - return TRUE; - case HTTOP: - case HTBOTTOM: - mouseCursorIcon = ImGuiMouseCursor_ResizeNS; - return TRUE; - case HTTOPLEFT: - case HTBOTTOMRIGHT: - mouseCursorIcon = ImGuiMouseCursor_ResizeNWSE; - return TRUE; - case HTTOPRIGHT: - case HTBOTTOMLEFT: - mouseCursorIcon = ImGuiMouseCursor_ResizeNESW; - return TRUE; - default: - mouseCursorIcon = ImGuiMouseCursor_None; - return TRUE; - } - } - case WM_NCHITTEST: { - POINT cursor = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - - const POINT border{ - static_cast((::GetSystemMetrics(SM_CXFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER)) * SharedData::globalScale / 2.0F), - static_cast((::GetSystemMetrics(SM_CYFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER)) * SharedData::globalScale / 2.0F) - }; - - RECT window; - if (!::GetWindowRect(hwnd, &window)) { - return HTNOWHERE; - } - - constexpr auto RegionClient = 0b0000; - constexpr auto RegionLeft = 0b0001; - constexpr auto RegionRight = 0b0010; - constexpr auto RegionTop = 0b0100; - constexpr auto RegionBottom = 0b1000; - - const auto result = - RegionLeft * (cursor.x < (window.left + border.x)) | - RegionRight * (cursor.x >= (window.right - border.x)) | - RegionTop * (cursor.y < (window.top + border.y)) | - RegionBottom * (cursor.y >= (window.bottom - border.y)); - - switch (result) { - case RegionLeft: - return HTLEFT; - case RegionRight: - return HTRIGHT; - case RegionTop: - return HTTOP; - case RegionBottom: - return HTBOTTOM; - case RegionTop | RegionLeft: - return HTTOPLEFT; - case RegionTop | RegionRight: - return HTTOPRIGHT; - case RegionBottom | RegionLeft: - return HTBOTTOMLEFT; - case RegionBottom | RegionRight: - return HTBOTTOMRIGHT; - case RegionClient: - default: - if ((cursor.y < (window.top + titleBarHeight * 2)) && !ImGui::IsAnyItemHovered()) - return HTCAPTION; - else break; - } - break; - } - case WM_SETTINGCHANGE: - { - if (LPCTSTR(lParam) == std::string_view("ImmersiveColorSet")) { - EventManager::post(); - } - - break; - } - default: break; - } - - return CallWindowProc((WNDPROC)oldWndProc, hwnd, uMsg, wParam, lParam); - } - - - void Window::initNative() { - auto hConsoleWindow = ::GetConsoleWindow(); - ::ShowWindow(hConsoleWindow, FALSE); - - auto hConsole = ::GetStdHandle(STD_OUTPUT_HANDLE); - if (hConsole != INVALID_HANDLE_VALUE) { - DWORD mode = 0; - if (::GetConsoleMode(hConsole, &mode)) { - mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; - ::SetConsoleMode(hConsole, mode); - } - } - } - - void Window::setupNativeWindow() { - auto hwnd = glfwGetWin32Window(this->m_window); - - oldWndProc = ::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)windowProc); - - MARGINS borderless = {1,1,1,1}; - ::DwmExtendFrameIntoClientArea(hwnd, &borderless); - - ::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS | SWP_NOSIZE | SWP_NOMOVE); - ::SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_POPUP | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION | WS_SYSMENU); - - bool themeFollowSystem = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color") == 0; - EventManager::subscribe(this, [themeFollowSystem]{ - if (!themeFollowSystem) return; - - HKEY hkey; - if (RegOpenKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", &hkey) == ERROR_SUCCESS) { - DWORD value = 0; - DWORD size = sizeof(DWORD); - - auto error = RegQueryValueEx(hkey, "AppsUseLightTheme", nullptr, nullptr, reinterpret_cast(&value), &size); - if (error == ERROR_SUCCESS) { - EventManager::post(value == 0 ? 1 : 2); - } - } - }); - - if (themeFollowSystem) - EventManager::post(); - } - - void Window::updateNativeWindow() { - titleBarHeight = ImGui::GetCurrentWindow()->MenuBarHeight(); - - if (mouseCursorIcon != ImGuiMouseCursor_None) - ImGui::SetMouseCursor(mouseCursorIcon); - } - - void Window::drawTitleBar() { - auto buttonSize = ImVec2(titleBarHeight * 1.5F, titleBarHeight - 1); - - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); - ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_MenuBarBg)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabActive)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabHovered)); - - ImGui::SetCursorPosX(ImGui::GetWindowWidth() - buttonSize.x * 6); - #if defined(DEBUG) - if (ImGui::TitleBarButton(ICON_VS_DEBUG, buttonSize)) - hex::openWebpage("https://imhex.werwolv.net/debug"); - ImGui::InfoTooltip("hex.menu.debug_build"_lang); - #endif - if (ImGui::TitleBarButton(ICON_VS_SMILEY, buttonSize)) - hex::openWebpage("mailto://hey@werwolv.net"); - ImGui::InfoTooltip("hex.menu.feedback"_lang); - - ImGui::SetCursorPosX(ImGui::GetWindowWidth() - buttonSize.x * 3); - if (ImGui::TitleBarButton(ICON_VS_CHROME_MINIMIZE, buttonSize)) - glfwIconifyWindow(this->m_window); - if (glfwGetWindowAttrib(this->m_window, GLFW_MAXIMIZED)) { - if (ImGui::TitleBarButton(ICON_VS_CHROME_RESTORE, buttonSize)) - glfwRestoreWindow(this->m_window); - } else { - if (ImGui::TitleBarButton(ICON_VS_CHROME_MAXIMIZE, buttonSize)) - glfwMaximizeWindow(this->m_window); - } - - ImGui::PushStyleColor(ImGuiCol_ButtonActive, 0xFF7A70F1); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, 0xFF2311E8); - - - if (ImGui::TitleBarButton(ICON_VS_CHROME_CLOSE, buttonSize)) { - ImHexApi::Common::closeImHex(); - } - - ImGui::PopStyleColor(5); - ImGui::PopStyleVar(); - - ImGui::SetCursorPosX((ImGui::GetWindowWidth() - ImGui::CalcTextSize(this->m_windowTitle.c_str()).x) / 2); - ImGui::TextUnformatted(this->m_windowTitle.c_str()); - } - - } - +#include "window.hpp" + + +#if defined(OS_WINDOWS) + + #include + #include + + #include + #include + #include + + #include + + #include + #define GLFW_EXPOSE_NATIVE_WIN32 + #include + #undef GLFW_EXPOSE_NATIVE_WIN32 + + #include + #include + #include + + namespace hex { + + static LONG_PTR oldWndProc; + static float titleBarHeight; + static ImGuiMouseCursor mouseCursorIcon; + + static bool isTaskbarAutoHideEnabled(UINT edge, RECT monitor) { + APPBARDATA data = { .cbSize = sizeof(APPBARDATA), .uEdge = edge, .rc = monitor }; + return ::SHAppBarMessage(ABM_GETAUTOHIDEBAR, &data); + } + + static LRESULT windowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + switch (uMsg) { + case WM_NCCALCSIZE: { + RECT &rect = *reinterpret_cast(lParam); + RECT client = rect; + + DefWindowProcW(hwnd, WM_NCCALCSIZE, wParam, lParam); + + if (IsMaximized(hwnd)) { + WINDOWINFO windowInfo = { .cbSize = sizeof(WINDOWINFO) }; + GetWindowInfo(hwnd, &windowInfo); + rect = RECT { + .left = static_cast(client.left + windowInfo.cyWindowBorders), + .top = static_cast(client.top + windowInfo.cyWindowBorders), + .right = static_cast(client.right - windowInfo.cyWindowBorders), + .bottom = static_cast(client.bottom - windowInfo.cyWindowBorders) + }; + + HMONITOR hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY); + MONITORINFO monitorInfo = { .cbSize = sizeof(MONITORINFO) }; + GetMonitorInfoW(hMonitor, &monitorInfo); + + if (EqualRect(&rect, &monitorInfo.rcMonitor)) { + if (isTaskbarAutoHideEnabled(ABE_BOTTOM, monitorInfo.rcMonitor)) + rect.bottom--; + else if (isTaskbarAutoHideEnabled(ABE_LEFT, monitorInfo.rcMonitor)) + rect.left++; + else if (isTaskbarAutoHideEnabled(ABE_TOP, monitorInfo.rcMonitor)) + rect.top++; + else if (isTaskbarAutoHideEnabled(ABE_RIGHT, monitorInfo.rcMonitor)) + rect.right--; + } + } else { + rect = client; + } + + return 0; + } + case WM_SETCURSOR: { + auto cursorPos = LOWORD(lParam); + + switch (cursorPos) { + case HTRIGHT: + case HTLEFT: + mouseCursorIcon = ImGuiMouseCursor_ResizeEW; + return TRUE; + case HTTOP: + case HTBOTTOM: + mouseCursorIcon = ImGuiMouseCursor_ResizeNS; + return TRUE; + case HTTOPLEFT: + case HTBOTTOMRIGHT: + mouseCursorIcon = ImGuiMouseCursor_ResizeNWSE; + return TRUE; + case HTTOPRIGHT: + case HTBOTTOMLEFT: + mouseCursorIcon = ImGuiMouseCursor_ResizeNESW; + return TRUE; + default: + mouseCursorIcon = ImGuiMouseCursor_None; + return TRUE; + } + } + case WM_NCHITTEST: { + POINT cursor = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + + const POINT border{ + static_cast((::GetSystemMetrics(SM_CXFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER)) * SharedData::globalScale / 2.0F), + static_cast((::GetSystemMetrics(SM_CYFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER)) * SharedData::globalScale / 2.0F) + }; + + RECT window; + if (!::GetWindowRect(hwnd, &window)) { + return HTNOWHERE; + } + + constexpr auto RegionClient = 0b0000; + constexpr auto RegionLeft = 0b0001; + constexpr auto RegionRight = 0b0010; + constexpr auto RegionTop = 0b0100; + constexpr auto RegionBottom = 0b1000; + + const auto result = + RegionLeft * (cursor.x < (window.left + border.x)) | + RegionRight * (cursor.x >= (window.right - border.x)) | + RegionTop * (cursor.y < (window.top + border.y)) | + RegionBottom * (cursor.y >= (window.bottom - border.y)); + + switch (result) { + case RegionLeft: + return HTLEFT; + case RegionRight: + return HTRIGHT; + case RegionTop: + return HTTOP; + case RegionBottom: + return HTBOTTOM; + case RegionTop | RegionLeft: + return HTTOPLEFT; + case RegionTop | RegionRight: + return HTTOPRIGHT; + case RegionBottom | RegionLeft: + return HTBOTTOMLEFT; + case RegionBottom | RegionRight: + return HTBOTTOMRIGHT; + case RegionClient: + default: + if ((cursor.y < (window.top + titleBarHeight * 2)) && !ImGui::IsAnyItemHovered()) + return HTCAPTION; + else break; + } + break; + } + case WM_SETTINGCHANGE: + { + if (LPCTSTR(lParam) == std::string_view("ImmersiveColorSet")) { + EventManager::post(); + } + + break; + } + default: break; + } + + return CallWindowProc((WNDPROC)oldWndProc, hwnd, uMsg, wParam, lParam); + } + + + void Window::initNative() { + auto hConsoleWindow = ::GetConsoleWindow(); + #if !defined(DEBUG) + ::ShowWindow(hConsoleWindow, FALSE); + #endif + + auto hConsole = ::GetStdHandle(STD_OUTPUT_HANDLE); + if (hConsole != INVALID_HANDLE_VALUE) { + DWORD mode = 0; + if (::GetConsoleMode(hConsole, &mode)) { + mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + ::SetConsoleMode(hConsole, mode); + } + } + } + + void Window::setupNativeWindow() { + auto hwnd = glfwGetWin32Window(this->m_window); + + oldWndProc = ::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)windowProc); + + MARGINS borderless = {1,1,1,1}; + ::DwmExtendFrameIntoClientArea(hwnd, &borderless); + + ::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS | SWP_NOSIZE | SWP_NOMOVE); + ::SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_POPUP | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION | WS_SYSMENU); + + bool themeFollowSystem = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color") == 0; + EventManager::subscribe(this, [themeFollowSystem]{ + if (!themeFollowSystem) return; + + HKEY hkey; + if (RegOpenKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", &hkey) == ERROR_SUCCESS) { + DWORD value = 0; + DWORD size = sizeof(DWORD); + + auto error = RegQueryValueEx(hkey, "AppsUseLightTheme", nullptr, nullptr, reinterpret_cast(&value), &size); + if (error == ERROR_SUCCESS) { + EventManager::post(value == 0 ? 1 : 2); + } + } + }); + + if (themeFollowSystem) + EventManager::post(); + } + + void Window::updateNativeWindow() { + titleBarHeight = ImGui::GetCurrentWindow()->MenuBarHeight(); + + if (mouseCursorIcon != ImGuiMouseCursor_None) + ImGui::SetMouseCursor(mouseCursorIcon); + } + + void Window::drawTitleBar() { + auto buttonSize = ImVec2(titleBarHeight * 1.5F, titleBarHeight - 1); + + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_MenuBarBg)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabActive)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetColorU32(ImGuiCol_ScrollbarGrabHovered)); + + ImGui::SetCursorPosX(ImGui::GetWindowWidth() - buttonSize.x * 6); + #if defined(DEBUG) + if (ImGui::TitleBarButton(ICON_VS_DEBUG, buttonSize)) + hex::openWebpage("https://imhex.werwolv.net/debug"); + ImGui::InfoTooltip("hex.menu.debug_build"_lang); + #endif + if (ImGui::TitleBarButton(ICON_VS_SMILEY, buttonSize)) + hex::openWebpage("mailto://hey@werwolv.net"); + ImGui::InfoTooltip("hex.menu.feedback"_lang); + + ImGui::SetCursorPosX(ImGui::GetWindowWidth() - buttonSize.x * 3); + if (ImGui::TitleBarButton(ICON_VS_CHROME_MINIMIZE, buttonSize)) + glfwIconifyWindow(this->m_window); + if (glfwGetWindowAttrib(this->m_window, GLFW_MAXIMIZED)) { + if (ImGui::TitleBarButton(ICON_VS_CHROME_RESTORE, buttonSize)) + glfwRestoreWindow(this->m_window); + } else { + if (ImGui::TitleBarButton(ICON_VS_CHROME_MAXIMIZE, buttonSize)) + glfwMaximizeWindow(this->m_window); + } + + ImGui::PushStyleColor(ImGuiCol_ButtonActive, 0xFF7A70F1); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, 0xFF2311E8); + + + if (ImGui::TitleBarButton(ICON_VS_CHROME_CLOSE, buttonSize)) { + ImHexApi::Common::closeImHex(); + } + + ImGui::PopStyleColor(5); + ImGui::PopStyleVar(); + + ImGui::SetCursorPosX((ImGui::GetWindowWidth() - ImGui::CalcTextSize(this->m_windowTitle.c_str()).x) / 2); + ImGui::TextUnformatted(this->m_windowTitle.c_str()); + } + + } + #endif \ No newline at end of file