From 073ad117ba8dc106875e26d09af9036d685c14e8 Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Sat, 17 Oct 2020 13:08:47 +0800 Subject: [PATCH] Minor tweaks. Signed-off-by: Yuhang Zhao <2546789017@qq.com> --- examples/Win32Demo/widget.cpp | 15 +--------- framelesswindowsmanager.cpp | 9 ++---- winnativeeventfilter.cpp | 56 ++++++++++++++++++++++------------- winnativeeventfilter.h | 4 +-- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/examples/Win32Demo/widget.cpp b/examples/Win32Demo/widget.cpp index 06363e3..8ab5768 100644 --- a/examples/Win32Demo/widget.cpp +++ b/examples/Win32Demo/widget.cpp @@ -107,20 +107,7 @@ Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) connect(ui->resizableCB, &QCheckBox::stateChanged, this, [this](int state) { const bool enable = state == Qt::Checked; ui->maximizeButton->setEnabled(enable); - const auto data = WinNativeEventFilter::windowData(this); - if (data) { - data->fixedSize = !enable; - updateWindow(this); - } - if (!ui->customizeTitleBarCB->isChecked()) { - if (enable) { - setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint); - } else { - setWindowFlags(windowFlags() & ~Qt::WindowMaximizeButtonHint); - } - show(); - WinNativeEventFilter::setWindowResizable(getRawHandle(this), enable); - } + WinNativeEventFilter::setWindowResizable(getRawHandle(this), enable); }); QStyleOption option; diff --git a/framelesswindowsmanager.cpp b/framelesswindowsmanager.cpp index 80ef70a..83961a0 100644 --- a/framelesswindowsmanager.cpp +++ b/framelesswindowsmanager.cpp @@ -327,7 +327,7 @@ bool FramelessWindowsManager::getResizable(QObject *window) Q_ASSERT(window); #ifdef Q_OS_WINDOWS const auto data = WinNativeEventFilter::windowData(window); - return data ? !data->fixedSize : false; + return data ? !data->fixedSize : true; #else return coreData()->framelessHelper.getResizable(window); #endif @@ -337,10 +337,7 @@ void FramelessWindowsManager::setResizable(QObject *window, const bool value) { Q_ASSERT(window); #ifdef Q_OS_WINDOWS - const auto data = WinNativeEventFilter::windowData(window); - if (data) { - data->fixedSize = !value; - } + WinNativeEventFilter::setWindowResizable(getRawHandleFromWindow(window), value); #else coreData()->framelessHelper.setResizable(window, value); #endif @@ -441,7 +438,7 @@ bool FramelessWindowsManager::getTitleBarEnabled(QObject *window) Q_ASSERT(window); #ifdef Q_OS_WINDOWS const auto data = WinNativeEventFilter::windowData(window); - return data ? !data->disableTitleBar : false; + return data ? !data->disableTitleBar : true; #else return coreData()->framelessHelper.getTitleBarEnabled(window); #endif diff --git a/winnativeeventfilter.cpp b/winnativeeventfilter.cpp index 223844a..7ebcb03 100644 --- a/winnativeeventfilter.cpp +++ b/winnativeeventfilter.cpp @@ -658,8 +658,18 @@ const UINT m_defaultDotsPerInch = USER_DEFAULT_SCREEN_DPI; const qreal m_defaultDevicePixelRatio = 1.0; +bool shouldUseNativeTitleBar() +{ + return qEnvironmentVariableIsSet("WNEF_USE_NATIVE_TITLE_BAR"); +} + bool shouldHaveWindowFrame() { + if (shouldUseNativeTitleBar()) { + // We have to use the original window frame unconditionally if we + // want to use the native title bar. + return true; + } const bool should = qEnvironmentVariableIsSet("WNEF_PRESERVE_WINDOW_FRAME"); const bool force = qEnvironmentVariableIsSet("WNEF_FORCE_PRESERVE_WINDOW_FRAME"); if (should || force) { @@ -679,11 +689,6 @@ bool shouldHaveWindowFrame() return false; } -bool shouldUseNativeTitleBar() -{ - return qEnvironmentVariableIsSet("WNEF_USE_NATIVE_TITLE_BAR"); -} - BOOL IsDwmCompositionEnabled() { // Since Win8, DWM composition is always enabled and can't be disabled. @@ -1162,7 +1167,7 @@ void install() } } -void uninstall() +[[maybe_unused]] void uninstall() { if (!coreData()->m_instance.isNull()) { qApp->removeNativeEventFilter(coreData()->m_instance.data()); @@ -1603,8 +1608,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, if (shouldHaveWindowFrame()) { *result = 0; } - if (!shouldHaveWindowFrame() && !IsFullScreen(msg->hwnd) && !IsMaximized(msg->hwnd) - && !IsMinimized(msg->hwnd)) { + if (!shouldHaveWindowFrame() && !IsFullScreen(msg->hwnd) && !IsMaximized(msg->hwnd)) { // Fix the flickering problem when resizing. // Don't modify the left, right or bottom edge because // a border line will be seen (at least on Win10). @@ -1617,7 +1621,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, // area. case WM_NCUAHDRAWCAPTION: case WM_NCUAHDRAWFRAME: { - if (shouldHaveWindowFrame() || shouldUseNativeTitleBar()) { + if (shouldHaveWindowFrame()) { break; } else { *result = 0; @@ -1627,8 +1631,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, case WM_NCPAINT: { // 边框阴影处于非客户区的范围,因此如果直接阻止非客户区的绘制,会导致边框阴影丢失 - if (!IsDwmCompositionEnabled() && !shouldHaveWindowFrame() - && !shouldUseNativeTitleBar()) { + if (!IsDwmCompositionEnabled() && !shouldHaveWindowFrame()) { // Only block WM_NCPAINT when DWM composition is disabled. If // it's blocked when DWM composition is enabled, the frame // shadow won't be drawn. @@ -1639,7 +1642,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, } } case WM_NCACTIVATE: { - if (shouldHaveWindowFrame() || shouldUseNativeTitleBar()) { + if (shouldHaveWindowFrame()) { break; } else { if (IsDwmCompositionEnabled()) { @@ -2316,14 +2319,22 @@ bool WinNativeEventFilter::displaySystemMenu(void *handle, WNEF_EXECUTE_WINAPI(SetMenuItemInfoW, hMenu, SC_MAXIMIZE, FALSE, &mii) WNEF_EXECUTE_WINAPI(SetMenuItemInfoW, hMenu, SC_MINIMIZE, FALSE, &mii) mii.fState = MF_GRAYED; - if (IsFullScreen(hwnd) || IsMaximized(hwnd)) { + const auto data = windowData(hwnd); + const bool fixedSize = data ? data->fixedSize : false; + if (fixedSize) { WNEF_EXECUTE_WINAPI(SetMenuItemInfoW, hMenu, SC_SIZE, FALSE, &mii) - WNEF_EXECUTE_WINAPI(SetMenuItemInfoW, hMenu, SC_MOVE, FALSE, &mii) WNEF_EXECUTE_WINAPI(SetMenuItemInfoW, hMenu, SC_MAXIMIZE, FALSE, &mii) - } else if (IsMinimized(hwnd)) { - WNEF_EXECUTE_WINAPI(SetMenuItemInfoW, hMenu, SC_MINIMIZE, FALSE, &mii) - } else { WNEF_EXECUTE_WINAPI(SetMenuItemInfoW, hMenu, SC_RESTORE, FALSE, &mii) + } else { + if (IsFullScreen(hwnd) || IsMaximized(hwnd)) { + WNEF_EXECUTE_WINAPI(SetMenuItemInfoW, hMenu, SC_SIZE, FALSE, &mii) + WNEF_EXECUTE_WINAPI(SetMenuItemInfoW, hMenu, SC_MOVE, FALSE, &mii) + WNEF_EXECUTE_WINAPI(SetMenuItemInfoW, hMenu, SC_MAXIMIZE, FALSE, &mii) + } else if (IsMinimized(hwnd)) { + WNEF_EXECUTE_WINAPI(SetMenuItemInfoW, hMenu, SC_MINIMIZE, FALSE, &mii) + } else { + WNEF_EXECUTE_WINAPI(SetMenuItemInfoW, hMenu, SC_RESTORE, FALSE, &mii) + } } const LPARAM cmd = WNEF_EXECUTE_WINAPI_RETURN(TrackPopupMenu, 0, @@ -2403,10 +2414,15 @@ void WinNativeEventFilter::setWindowResizable(void *handle, const bool resizable Q_ASSERT(handle); const auto hwnd = reinterpret_cast(handle); if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, hwnd)) { + const auto data = windowData(hwnd); + if (data) { + data->fixedSize = !resizable; + } const auto originalStyle = WNEF_EXECUTE_WINAPI_RETURN(GetWindowLongPtrW, 0, hwnd, GWL_STYLE); - const auto diffStyle = WS_MAXIMIZEBOX | WS_THICKFRAME; - const auto resizableStyle = originalStyle | diffStyle; - const auto fixedSizeStyle = originalStyle & ~diffStyle; + const auto keyResizeStyle = WS_MAXIMIZEBOX | WS_THICKFRAME; + const auto keyFixedStyle = WS_DLGFRAME; + const auto resizableStyle = (originalStyle & ~keyFixedStyle) | keyResizeStyle | WS_CAPTION; + const auto fixedSizeStyle = (originalStyle & ~keyResizeStyle) | keyFixedStyle; WNEF_EXECUTE_WINAPI(SetWindowLongPtrW, hwnd, GWL_STYLE, diff --git a/winnativeeventfilter.h b/winnativeeventfilter.h index 27f5ce7..98680b8 100644 --- a/winnativeeventfilter.h +++ b/winnativeeventfilter.h @@ -146,8 +146,8 @@ public: // Thin wrapper of DwmExtendFrameIntoClientArea(). static void updateFrameMargins(void *handle /* HWND */); - // Helper function. Designed for normal windows only. - // Don't use it on frameless windows! + // A resizable window can be resized and maximized, however, a fixed size + // window can only be moved and minimized, it can't be resized and maximized. static void setWindowResizable(void *handle /* HWND */, const bool resizable = true); ///////////////////////////////////////////////