diff --git a/framelesshelper_windows.pro b/framelesshelper_windows.pro index cb23ce4..3f920e7 100644 --- a/framelesshelper_windows.pro +++ b/framelesshelper_windows.pro @@ -14,8 +14,7 @@ DEFINES += \ _CRT_SECURE_NO_WARNINGS \ QT_NO_CAST_FROM_ASCII \ QT_NO_CAST_TO_ASCII \ - FRAMELESSHELPER_STATIC \ - WNEF_WIN10_HAS_WINDOW_FRAME + FRAMELESSHELPER_STATIC LINK_TO_SYSTEM_DLL { DEFINES += WNEF_LINK_SYSLIB LIBS += -luser32 -lgdi32 -ldwmapi -lshcore diff --git a/framelessquickhelper.cpp b/framelessquickhelper.cpp index f9bf66b..b2987af 100644 --- a/framelessquickhelper.cpp +++ b/framelessquickhelper.cpp @@ -38,7 +38,7 @@ const int m_defaultBorderWidth = 8, m_defaultBorderHeight = 8, m_defaultTitleBar #else FramelessHelper m_framelessHelper; #endif -} +} // namespace FramelessQuickHelper::FramelessQuickHelper(QQuickItem *parent) : QQuickItem(parent) {} @@ -47,11 +47,8 @@ int FramelessQuickHelper::borderWidth() const #ifdef Q_OS_WINDOWS const auto win = window(); if (win) { - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - return WinNativeEventFilter::getSystemMetric( - hWnd, WinNativeEventFilter::SystemMetric::BorderWidth); - } + return WinNativeEventFilter::getSystemMetric(win, + WinNativeEventFilter::SystemMetric::BorderWidth); } return m_defaultBorderWidth; #else @@ -64,13 +61,10 @@ void FramelessQuickHelper::setBorderWidth(const int val) #ifdef Q_OS_WINDOWS const auto win = window(); if (win) { - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->borderWidth = val; - Q_EMIT borderWidthChanged(val); - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->borderWidth = val; + Q_EMIT borderWidthChanged(val); } } #else @@ -84,11 +78,8 @@ int FramelessQuickHelper::borderHeight() const #ifdef Q_OS_WINDOWS const auto win = window(); if (win) { - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - return WinNativeEventFilter::getSystemMetric( - hWnd, WinNativeEventFilter::SystemMetric::BorderHeight); - } + return WinNativeEventFilter::getSystemMetric( + win, WinNativeEventFilter::SystemMetric::BorderHeight); } return m_defaultBorderHeight; #else @@ -101,13 +92,10 @@ void FramelessQuickHelper::setBorderHeight(const int val) #ifdef Q_OS_WINDOWS const auto win = window(); if (win) { - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->borderHeight = val; - Q_EMIT borderHeightChanged(val); - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->borderHeight = val; + Q_EMIT borderHeightChanged(val); } } #else @@ -121,11 +109,8 @@ int FramelessQuickHelper::titleBarHeight() const #ifdef Q_OS_WINDOWS const auto win = window(); if (win) { - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - return WinNativeEventFilter::getSystemMetric( - hWnd, WinNativeEventFilter::SystemMetric::TitleBarHeight); - } + return WinNativeEventFilter::getSystemMetric( + win, WinNativeEventFilter::SystemMetric::TitleBarHeight); } return m_defaultTitleBarHeight; #else @@ -138,13 +123,10 @@ void FramelessQuickHelper::setTitleBarHeight(const int val) #ifdef Q_OS_WINDOWS const auto win = window(); if (win) { - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->titleBarHeight = val; - Q_EMIT titleBarHeightChanged(val); - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->titleBarHeight = val; + Q_EMIT titleBarHeightChanged(val); } } #else @@ -158,12 +140,9 @@ bool FramelessQuickHelper::resizable() const const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - return !data->fixedSize; - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + return !data->fixedSize; } #else return m_framelessHelper.getResizable(win); @@ -177,16 +156,14 @@ void FramelessQuickHelper::setResizable(const bool val) const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->fixedSize = !val; - Q_EMIT resizableChanged(val); - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->fixedSize = !val; + Q_EMIT resizableChanged(val); } #else m_framelessHelper.setResizable(win, val); + Q_EMIT resizableChanged(val); #endif } } @@ -196,12 +173,9 @@ bool FramelessQuickHelper::titleBarEnabled() const const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - return !data->disableTitleBar; - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + return !data->disableTitleBar; } #else return m_framelessHelper.getTitleBarEnabled(win); @@ -215,16 +189,14 @@ void FramelessQuickHelper::setTitleBarEnabled(const bool val) const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->disableTitleBar = !val; - Q_EMIT titleBarEnabledChanged(val); - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->disableTitleBar = !val; + Q_EMIT titleBarEnabledChanged(val); } #else m_framelessHelper.setTitleBarEnabled(win, val); + Q_EMIT titleBarEnabledChanged(val); #endif } } @@ -234,18 +206,15 @@ QSize FramelessQuickHelper::minimumSize() const const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - return data->minimumSize; - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + return data->minimumSize; } #else return win->minimumSize(); #endif } - return {0, 0}; + return {}; } void FramelessQuickHelper::setMinimumSize(const QSize &val) @@ -253,13 +222,10 @@ void FramelessQuickHelper::setMinimumSize(const QSize &val) const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->minimumSize = val; - Q_EMIT minimumSizeChanged(val); - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->minimumSize = val; + Q_EMIT minimumSizeChanged(val); } #else win->setMinimumSize(val); @@ -273,18 +239,15 @@ QSize FramelessQuickHelper::maximumSize() const const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - return data->maximumSize; - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + return data->maximumSize; } #else return win->maximumSize(); #endif } - return {0, 0}; + return {}; } void FramelessQuickHelper::setMaximumSize(const QSize &val) @@ -292,13 +255,10 @@ void FramelessQuickHelper::setMaximumSize(const QSize &val) const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->maximumSize = val; - Q_EMIT maximumSizeChanged(val); - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->maximumSize = val; + Q_EMIT maximumSizeChanged(val); } #else win->setMaximumSize(val); @@ -312,10 +272,7 @@ void FramelessQuickHelper::removeWindowFrame(const bool center) const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - WinNativeEventFilter::addFramelessWindow(hWnd); - } + WinNativeEventFilter::addFramelessWindow(win); #else m_framelessHelper.removeWindowFrame(win); #endif @@ -367,10 +324,7 @@ void FramelessQuickHelper::moveWindowToDesktopCenter(const bool realCenter) if (win) { if (realCenter) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - WinNativeEventFilter::moveWindowToDesktopCenter(hWnd); - } + WinNativeEventFilter::moveWindowToDesktopCenter(win); #else FramelessHelper::moveWindowToDesktopCenter(win); #endif @@ -393,12 +347,9 @@ void FramelessQuickHelper::setIgnoreAreas(const QList &val) const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->ignoreAreas = val; - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->ignoreAreas = val; } #else m_framelessHelper.setIgnoreAreas(win, val); @@ -411,12 +362,9 @@ void FramelessQuickHelper::clearIgnoreAreas() const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->ignoreAreas.clear(); - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->ignoreAreas.clear(); } #else m_framelessHelper.clearIgnoreAreas(win); @@ -429,12 +377,9 @@ void FramelessQuickHelper::addIgnoreArea(const QRect &val) const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->ignoreAreas.append(val); - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->ignoreAreas.append(val); } #else m_framelessHelper.addIgnoreArea(win, val); @@ -447,12 +392,9 @@ void FramelessQuickHelper::setDraggableAreas(const QList &val) const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->draggableAreas = val; - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->draggableAreas = val; } #else m_framelessHelper.setDraggableAreas(win, val); @@ -465,12 +407,9 @@ void FramelessQuickHelper::clearDraggableAreas() const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->draggableAreas.clear(); - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->draggableAreas.clear(); } #else m_framelessHelper.clearDraggableAreas(win); @@ -483,12 +422,9 @@ void FramelessQuickHelper::addDraggableArea(const QRect &val) const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->draggableAreas.append(val); - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->draggableAreas.append(val); } #else m_framelessHelper.addDraggableArea(win, val); @@ -501,15 +437,12 @@ void FramelessQuickHelper::setIgnoreObjects(const QList &val) const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->ignoreObjects.clear(); - if (!val.isEmpty()) { - for (auto &&obj : qAsConst(val)) { - data->ignoreObjects.append(obj); - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->ignoreObjects.clear(); + if (!val.isEmpty()) { + for (auto &&obj : qAsConst(val)) { + data->ignoreObjects.append(obj); } } } @@ -530,12 +463,9 @@ void FramelessQuickHelper::clearIgnoreObjects() const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->ignoreObjects.clear(); - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->ignoreObjects.clear(); } #else m_framelessHelper.clearIgnoreObjects(win); @@ -545,15 +475,13 @@ void FramelessQuickHelper::clearIgnoreObjects() void FramelessQuickHelper::addIgnoreObject(QQuickItem *val) { + Q_ASSERT(val); const auto win = window(); - if (win && val) { + if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->ignoreObjects.append(val); - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->ignoreObjects.append(val); } #else m_framelessHelper.addIgnoreObject(win, val); @@ -566,15 +494,12 @@ void FramelessQuickHelper::setDraggableObjects(const QList &val) const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->draggableObjects.clear(); - if (!val.isEmpty()) { - for (auto &&obj : qAsConst(val)) { - data->draggableObjects.append(obj); - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->draggableObjects.clear(); + if (!val.isEmpty()) { + for (auto &&obj : qAsConst(val)) { + data->draggableObjects.append(obj); } } } @@ -595,12 +520,9 @@ void FramelessQuickHelper::clearDraggableObjects() const auto win = window(); if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->draggableObjects.clear(); - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->draggableObjects.clear(); } #else m_framelessHelper.clearDraggableObjects(win); @@ -610,15 +532,13 @@ void FramelessQuickHelper::clearDraggableObjects() void FramelessQuickHelper::addDraggableObject(QQuickItem *val) { + Q_ASSERT(val); const auto win = window(); - if (win && val) { + if (win) { #ifdef Q_OS_WINDOWS - const auto hWnd = reinterpret_cast(win->winId()); - if (hWnd) { - const auto data = WinNativeEventFilter::windowData(hWnd); - if (data) { - data->draggableObjects.append(val); - } + const auto data = WinNativeEventFilter::windowData(win); + if (data) { + data->draggableObjects.append(val); } #else m_framelessHelper.addDraggableObject(win, val); diff --git a/main_windows.cpp b/main_windows.cpp index f58f4fc..a57f7ed 100644 --- a/main_windows.cpp +++ b/main_windows.cpp @@ -147,14 +147,13 @@ int main(int argc, char *argv[]) mainLayout->addStretch(); widget.setLayout(mainLayout); widget.setWindowTitle(QObject::tr("Hello, World!")); - const auto hWnd_widget = reinterpret_cast(widget.winId()); - WinNativeEventFilter::addFramelessWindow(hWnd_widget); - const auto data_widget = WinNativeEventFilter::windowData(hWnd_widget); + WinNativeEventFilter::addFramelessWindow(&widget); + const auto data_widget = WinNativeEventFilter::windowData(&widget); if (data_widget) { data_widget->ignoreObjects << minimizeButton << maximizeButton << closeButton; } widget.resize(800, 600); - WinNativeEventFilter::moveWindowToDesktopCenter(hWnd_widget); + WinNativeEventFilter::moveWindowToDesktopCenter(&widget); widget.show(); #ifdef QT_QUICK_LIB diff --git a/winnativeeventfilter.cpp b/winnativeeventfilter.cpp index 24914be..4f531c7 100644 --- a/winnativeeventfilter.cpp +++ b/winnativeeventfilter.cpp @@ -22,6 +22,10 @@ * SOFTWARE. */ +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + #include "winnativeeventfilter.h" #include @@ -30,6 +34,7 @@ #include #include #include +#include #if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) #include #else @@ -56,8 +61,6 @@ Q_DECLARE_METATYPE(QMargins) -namespace { - #if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) #define qAsConst(i) std::as_const(i) #endif @@ -97,52 +100,6 @@ namespace { #define ABM_GETAUTOHIDEBAREX 0x0000000b #endif -const UINT m_defaultDotsPerInch = USER_DEFAULT_SCREEN_DPI; - -const qreal m_defaultDevicePixelRatio = 1.0; - -bool isWin8OrGreater() -{ -#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) - return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8; -#else - return QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8; -#endif -} - -bool isWin8Point1OrGreater() -{ -#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) - return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8_1; -#else - return QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8_1; -#endif -} - -bool isWin10OrGreater(const int ver) -{ -#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) - return QOperatingSystemVersion::current() - >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, ver); -#else - Q_UNUSED(ver) - return QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS10; -#endif -} - -bool shouldHaveWindowFrame() -{ -#ifdef WNEF_WIN10_HAS_WINDOW_FRAME -#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) - return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10; -#else - return QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS10; -#endif -#else - return false; -#endif -} - #ifndef WNEF_GENERATE_WINAPI #define WNEF_GENERATE_WINAPI(funcName, resultType, ...) \ using _WNEF_WINAPI_##funcName = resultType(WINAPI *)(__VA_ARGS__); \ @@ -189,6 +146,54 @@ bool shouldHaveWindowFrame() #endif #endif +namespace { + +const UINT m_defaultDotsPerInch = USER_DEFAULT_SCREEN_DPI; + +const qreal m_defaultDevicePixelRatio = 1.0; + +bool isWin8OrGreater() +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) + return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8; +#else + return QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8; +#endif +} + +bool isWin8Point1OrGreater() +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) + return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8_1; +#else + return QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8_1; +#endif +} + +bool isWin10OrGreater(const int ver) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) + return QOperatingSystemVersion::current() + >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, ver); +#else + Q_UNUSED(ver) + return QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS10; +#endif +} + +bool shouldHaveWindowFrame() +{ +#if 1 +#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) + return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10; +#else + return QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS10; +#endif +#else + return false; +#endif +} + #ifndef WNEF_LINK_SYSLIB // All the following enums, structs and function prototypes are copied from @@ -552,10 +557,11 @@ BOOL IsDwmCompositionEnabled() WINDOWINFO GetInfoForWindow(const HWND handle) { + Q_ASSERT(handle); WINDOWINFO windowInfo; SecureZeroMemory(&windowInfo, sizeof(windowInfo)); windowInfo.cbSize = sizeof(windowInfo); - if (handle && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { WNEF_EXECUTE_WINAPI(GetWindowInfo, handle, &windowInfo) } return windowInfo; @@ -563,10 +569,11 @@ WINDOWINFO GetInfoForWindow(const HWND handle) MONITORINFO GetMonitorInfoForWindow(const HWND handle) { + Q_ASSERT(handle); MONITORINFO monitorInfo; SecureZeroMemory(&monitorInfo, sizeof(monitorInfo)); monitorInfo.cbSize = sizeof(monitorInfo); - if (handle && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { const HMONITOR monitor = WNEF_EXECUTE_WINAPI_RETURN(MonitorFromWindow, nullptr, handle, @@ -580,7 +587,8 @@ MONITORINFO GetMonitorInfoForWindow(const HWND handle) BOOL IsFullScreen(const HWND handle) { - if (handle && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { + Q_ASSERT(handle); + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { const WINDOWINFO windowInfo = GetInfoForWindow(handle); const MONITORINFO monitorInfo = GetMonitorInfoForWindow(handle); // The only way to judge whether a window is fullscreen or not @@ -600,7 +608,8 @@ BOOL IsFullScreen(const HWND handle) BOOL IsTopLevel(const HWND handle) { - if (handle && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { + Q_ASSERT(handle); + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { if (WNEF_EXECUTE_WINAPI_RETURN(GetWindowLongPtrW, 0, handle, GWL_STYLE) & WS_CHILD) { return FALSE; } @@ -613,7 +622,20 @@ BOOL IsTopLevel(const HWND handle) return FALSE; } -UINT GetDotsPerInchForWindow(const HWND handle) +BOOL IsApplicationDpiAware() +{ + if (m_lpGetProcessDpiAwareness) { + PROCESS_DPI_AWARENESS awareness = PROCESS_DPI_UNAWARE; + WNEF_EXECUTE_WINAPI(GetProcessDpiAwareness, + WNEF_EXECUTE_WINAPI_RETURN(GetCurrentProcess, nullptr), + &awareness) + return (awareness != PROCESS_DPI_UNAWARE); + } else { + return WNEF_EXECUTE_WINAPI_RETURN(IsProcessDPIAware, FALSE); + } +} + +UINT GetDotsPerInchForSystem() { const auto getScreenDpi = [](const UINT defaultValue) -> UINT { #if 0 @@ -645,36 +667,13 @@ UINT GetDotsPerInchForWindow(const HWND handle) } return defaultValue; }; - bool dpiEnabled = false; - if (m_lpGetProcessDpiAwareness) { - PROCESS_DPI_AWARENESS awareness = PROCESS_DPI_UNAWARE; - WNEF_EXECUTE_WINAPI(GetProcessDpiAwareness, - WNEF_EXECUTE_WINAPI_RETURN(GetCurrentProcess, nullptr), - &awareness) - dpiEnabled = awareness != PROCESS_DPI_UNAWARE; - } else { - dpiEnabled = WNEF_EXECUTE_WINAPI_RETURN(IsProcessDPIAware, FALSE); - } - if (!dpiEnabled) { - // Return hard-coded DPI if DPI scaling is disabled. - return m_defaultDotsPerInch; - } - if (!handle || !WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { - if (m_lpGetSystemDpiForProcess) { - return WNEF_EXECUTE_WINAPI_RETURN(GetSystemDpiForProcess, - 0, - WNEF_EXECUTE_WINAPI_RETURN(GetCurrentProcess, - nullptr)); - } else if (m_lpGetDpiForSystem) { - return WNEF_EXECUTE_WINAPI_RETURN(GetDpiForSystem, 0); - } - return getScreenDpi(m_defaultDotsPerInch); - } - if (m_lpGetDpiForWindow) { - return WNEF_EXECUTE_WINAPI_RETURN(GetDpiForWindow, 0, handle); - } - if (m_lpGetDpiForMonitor) { + if (m_lpGetSystemDpiForProcess) { + return WNEF_EXECUTE_WINAPI_RETURN(GetSystemDpiForProcess, + 0, + WNEF_EXECUTE_WINAPI_RETURN(GetCurrentProcess, nullptr)); + } else if (m_lpGetDpiForMonitor) { UINT dpiX = m_defaultDotsPerInch, dpiY = m_defaultDotsPerInch; + /* WNEF_EXECUTE_WINAPI(GetDpiForMonitor, WNEF_EXECUTE_WINAPI_RETURN(MonitorFromWindow, nullptr, @@ -683,12 +682,28 @@ UINT GetDotsPerInchForWindow(const HWND handle) MDT_EFFECTIVE_DPI, &dpiX, &dpiY) + */ // The values of *dpiX and *dpiY are identical. - return dpiX; + return dpiX == dpiY ? dpiY : dpiX; + } else if (m_lpGetDpiForSystem) { + return WNEF_EXECUTE_WINAPI_RETURN(GetDpiForSystem, 0); } return getScreenDpi(m_defaultDotsPerInch); } +UINT GetDotsPerInchForWindow(const HWND handle) +{ + Q_ASSERT(handle); + if (!IsApplicationDpiAware()) { + // Return hard-coded DPI if DPI scaling is disabled. + return m_defaultDotsPerInch; + } + if (m_lpGetDpiForWindow && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { + return WNEF_EXECUTE_WINAPI_RETURN(GetDpiForWindow, 0, handle); + } + return GetDotsPerInchForSystem(); +} + qreal GetPreferedNumber(const qreal num) { qreal result = -1.0; @@ -740,8 +755,9 @@ qreal GetPreferedNumber(const qreal num) qreal GetDevicePixelRatioForWindow(const HWND handle) { + Q_ASSERT(handle); qreal result = m_defaultDevicePixelRatio; - if (handle && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { result = static_cast(GetDotsPerInchForWindow(handle)) / static_cast(m_defaultDotsPerInch); } @@ -750,8 +766,9 @@ qreal GetDevicePixelRatioForWindow(const HWND handle) RECT GetFrameSizeForWindow(const HWND handle, const BOOL includingTitleBar = FALSE) { + Q_ASSERT(handle); RECT rect = {0, 0, 0, 0}; - if (handle && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { const auto style = WNEF_EXECUTE_WINAPI_RETURN(GetWindowLongPtrW, 0, handle, GWL_STYLE); // It's the same with using GetSystemMetrics, the returned values // of the two functions are identical. @@ -785,7 +802,8 @@ RECT GetFrameSizeForWindow(const HWND handle, const BOOL includingTitleBar = FAL void UpdateFrameMarginsForWindow(const HWND handle) { - if (handle && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { + Q_ASSERT(handle); + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { MARGINS margins = {0, 0, 0, 0}; // The frame shadow is drawn on the non-client area and thus we have // to make sure the non-client area rendering is enabled first. @@ -808,7 +826,8 @@ void UpdateFrameMarginsForWindow(const HWND handle) // there, we just can't see it). if (shouldHaveWindowFrame()) { const auto GetTopBorderHeight = [](const HWND handle) -> int { - if (handle && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { + Q_ASSERT(handle); + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { if (IsMaximized(handle) || IsFullScreen(handle) || !IsDwmCompositionEnabled()) { return 0; } @@ -827,7 +846,8 @@ void UpdateFrameMarginsForWindow(const HWND handle) int GetSystemMetricsForWindow(const HWND handle, const int index) { - if (handle && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { + Q_ASSERT(handle); + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { if (m_lpGetSystemMetricsForDpi) { return WNEF_EXECUTE_WINAPI_RETURN(GetSystemMetricsForDpi, 0, @@ -844,19 +864,20 @@ int GetSystemMetricsForWindow(const HWND handle, const int index) void createUserData(const HWND handle, const WinNativeEventFilter::WINDOWDATA *data = nullptr) { - if (handle && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { - const auto userData = reinterpret_cast( + Q_ASSERT(handle); + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { + const auto userData = reinterpret_cast( WNEF_EXECUTE_WINAPI_RETURN(GetWindowLongPtrW, 0, handle, GWLP_USERDATA)); if (userData) { if (data) { - userData->windowData = *data; + *userData = *data; } } else { // Yes, this is a memory leak, but it doesn't hurt much, unless your // application has thousands of windows. - WinNativeEventFilter::WINDOW *_data = new WinNativeEventFilter::WINDOW; + auto *_data = new WinNativeEventFilter::WINDOWDATA; if (data) { - _data->windowData = *data; + *_data = *data; } WNEF_EXECUTE_WINAPI(SetWindowLongPtrW, handle, @@ -869,7 +890,8 @@ void createUserData(const HWND handle, const WinNativeEventFilter::WINDOWDATA *d QWindow *findQWindowFromRawHandle(const HWND handle) { - if (handle && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { + Q_ASSERT(handle); + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { const auto wid = reinterpret_cast(handle); const auto windows = QGuiApplication::topLevelWindows(); for (auto &&window : qAsConst(windows)) { @@ -890,6 +912,21 @@ void qCoreAppFixup() } } +HWND getHWNDFromQObject(QObject *object) +{ + Q_ASSERT(object); + WId wid = 0; +#ifdef QT_WIDGETS_LIB + if (object->isWidgetType()) { + wid = qobject_cast(object)->winId(); + } +#endif + if (object->isWindowType()) { + wid = qobject_cast(object)->winId(); + } + return reinterpret_cast(wid); +} + // The standard values of border width, border height and title bar height // when DPI is 96. const int m_defaultBorderWidth = 8, m_defaultBorderHeight = 8, m_defaultTitleBarHeight = 30; @@ -902,7 +939,7 @@ const int kAutoHideTaskbarThicknessPy = kAutoHideTaskbarThicknessPx; QScopedPointer m_instance; -QList m_framelessWindows; +QList m_framelessWindows = {}; } // namespace @@ -934,25 +971,7 @@ void WinNativeEventFilter::uninstall() } } -QList WinNativeEventFilter::framelessWindows() -{ - return m_framelessWindows; -} - -void WinNativeEventFilter::setFramelessWindows(const QList &windows) -{ - qCoreAppFixup(); - if (!windows.isEmpty() && (windows != m_framelessWindows)) { - m_framelessWindows = windows; - for (auto &&window : qAsConst(m_framelessWindows)) { - createUserData(window); - updateQtFrame_internal(window); - } - install(); - } -} - -void WinNativeEventFilter::addFramelessWindow(const HWND window, +void WinNativeEventFilter::addFramelessWindow(void *window, const WINDOWDATA *data, const bool center, const int x, @@ -960,30 +979,51 @@ void WinNativeEventFilter::addFramelessWindow(const HWND window, const int width, const int height) { + Q_ASSERT(window); ResolveWin32APIs(); qCoreAppFixup(); - if (window && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, window) - && !m_framelessWindows.contains(window)) { - m_framelessWindows.append(window); - createUserData(window, data); + const auto hwnd = reinterpret_cast(window); + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, hwnd) && !m_framelessWindows.contains(hwnd)) { + m_framelessWindows.append(hwnd); + createUserData(hwnd, data); install(); - updateQtFrame_internal(window); - } - if ((x > 0) && (y > 0) && (width > 0) && (height > 0)) { - setWindowGeometry(window, x, y, width, height); - } - if (center) { - moveWindowToDesktopCenter(window); + updateQtFrame_internal(hwnd); + if ((x > 0) && (y > 0) && (width > 0) && (height > 0)) { + setWindowGeometry(hwnd, x, y, width, height); + } + if (center) { + moveWindowToDesktopCenter(hwnd); + } } } -void WinNativeEventFilter::removeFramelessWindow(const HWND window) +void WinNativeEventFilter::addFramelessWindow(QObject *window, + const WINDOWDATA *data, + const bool center, + const int x, + const int y, + const int width, + const int height) { - if (window && m_framelessWindows.contains(window)) { - m_framelessWindows.removeAll(window); + Q_ASSERT(window); + addFramelessWindow(getHWNDFromQObject(window), data, center, x, y, width, height); +} + +void WinNativeEventFilter::removeFramelessWindow(void *window) +{ + Q_ASSERT(window); + const auto hwnd = reinterpret_cast(window); + if (m_framelessWindows.contains(hwnd)) { + m_framelessWindows.removeAll(hwnd); } } +void WinNativeEventFilter::removeFramelessWindow(QObject *window) +{ + Q_ASSERT(window); + removeFramelessWindow(getHWNDFromQObject(window)); +} + void WinNativeEventFilter::clearFramelessWindows() { if (!m_framelessWindows.isEmpty()) { @@ -1062,12 +1102,12 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, } if (!data->initialized) { // Avoid initializing a same window twice. - data->initialized = TRUE; + data->initialized = true; // Don't restore the window styles to default when you are // developing Qt Quick applications because the QWindow // will disappear once you do it. However, Qt Widgets applications // are not affected. Don't know why currently. - if (data->windowData.restoreDefaultWindowStyle) { + if (data->restoreDefaultWindowStyle) { // Restore default window style. // WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU // | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX @@ -1084,7 +1124,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS) updateWindow(msg->hwnd, true, false); } - if (data->windowData.enableLayeredWindow) { + if (data->enableLayeredWindow) { // Turn our window into a layered window to get better // performance and hopefully, to get rid of some strange bugs at // the same time. But this will break the Arcylic effect @@ -1457,7 +1497,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, // another branch, if you are interested in it, you can give it a // try. - if (data->windowData.mouseTransparent) { + if (data->mouseTransparent) { // Mouse events will be passed to the parent window. *result = HTTRANSPARENT; return true; @@ -1528,29 +1568,28 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, const POINT globalMouse{GET_X_LPARAM(msg->lParam), GET_Y_LPARAM(msg->lParam)}; POINT localMouse = globalMouse; WNEF_EXECUTE_WINAPI(ScreenToClient, msg->hwnd, &localMouse) - const auto &_data = data->windowData; const qreal dpr = GetDevicePixelRatioForWindow(msg->hwnd); const bool isInIgnoreAreas = isInSpecificAreas(localMouse.x, localMouse.y, - _data.ignoreAreas, + data->ignoreAreas, dpr); - const bool customDragAreas = !_data.draggableAreas.isEmpty(); + const bool customDragAreas = !data->draggableAreas.isEmpty(); const bool isInDraggableAreas = customDragAreas ? isInSpecificAreas(localMouse.x, localMouse.y, - _data.draggableAreas, + data->draggableAreas, dpr) : true; #if defined(QT_WIDGETS_LIB) || defined(QT_QUICK_LIB) const bool isInIgnoreObjects = isInSpecificObjects(globalMouse.x, globalMouse.y, - _data.ignoreObjects, + data->ignoreObjects, dpr); - const bool customDragObjects = !_data.draggableObjects.isEmpty(); + const bool customDragObjects = !data->draggableObjects.isEmpty(); const bool isInDraggableObjects = customDragObjects ? isInSpecificObjects(globalMouse.x, globalMouse.y, - _data.draggableObjects, + data->draggableObjects, dpr) : true; #else @@ -1567,7 +1606,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, const LONG tbh = getSystemMetric(msg->hwnd, SystemMetric::TitleBarHeight, true); const bool isTitleBar = (customDrag ? (isInDraggableAreas && isInDraggableObjects) : (localMouse.y <= (tbh + bh))) - && isResizePermitted && !_data.disableTitleBar; + && isResizePermitted && !data->disableTitleBar; const bool isTop = (localMouse.y <= bh) && isResizePermitted; if (shouldHaveWindowFrame()) { // This will handle the left, right and bottom parts of the frame @@ -1601,6 +1640,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, const auto getHTResult = [isTitleBar, localMouse, bh, isTop](const HWND _hWnd, const WINDOWDATA &_data) -> LRESULT { + Q_ASSERT(_hWnd); RECT clientRect = {0, 0, 0, 0}; WNEF_EXECUTE_WINAPI(GetClientRect, _hWnd, &clientRect) const LONG ww = clientRect.right; @@ -1652,7 +1692,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, } return HTCLIENT; }; - *result = getHTResult(msg->hwnd, _data); + *result = getHTResult(msg->hwnd, *data); return true; } } @@ -1675,22 +1715,22 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, mmi->ptMaxPosition.x = rcMonitorArea.left; mmi->ptMaxPosition.y = rcMonitorArea.top; } - if (data->windowData.maximumSize.isEmpty()) { + if (data->maximumSize.isEmpty()) { mmi->ptMaxSize.x = qAbs(rcWorkArea.right - rcWorkArea.left); mmi->ptMaxSize.y = qAbs(rcWorkArea.bottom - rcWorkArea.top); } else { mmi->ptMaxSize.x = qRound(GetDevicePixelRatioForWindow(msg->hwnd) - * data->windowData.maximumSize.width()); + * data->maximumSize.width()); mmi->ptMaxSize.y = qRound(GetDevicePixelRatioForWindow(msg->hwnd) - * data->windowData.maximumSize.height()); + * data->maximumSize.height()); } mmi->ptMaxTrackSize.x = mmi->ptMaxSize.x; mmi->ptMaxTrackSize.y = mmi->ptMaxSize.y; - if (!data->windowData.minimumSize.isEmpty()) { + if (!data->minimumSize.isEmpty()) { mmi->ptMinTrackSize.x = qRound(GetDevicePixelRatioForWindow(msg->hwnd) - * data->windowData.minimumSize.width()); + * data->minimumSize.width()); mmi->ptMinTrackSize.y = qRound(GetDevicePixelRatioForWindow(msg->hwnd) - * data->windowData.minimumSize.height()); + * data->minimumSize.height()); } *result = 0; return true; @@ -1754,26 +1794,41 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType, return false; } -void WinNativeEventFilter::setWindowData(const HWND window, const WINDOWDATA *data) +void WinNativeEventFilter::setWindowData(void *window, const WINDOWDATA *data) { + Q_ASSERT(window); ResolveWin32APIs(); - if (window && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, window) && data) { - createUserData(window, data); + const auto hwnd = reinterpret_cast(window); + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, hwnd) && data) { + createUserData(hwnd, data); } } -WinNativeEventFilter::WINDOWDATA *WinNativeEventFilter::windowData(const HWND window) +void WinNativeEventFilter::setWindowData(QObject *window, const WINDOWDATA *data) { + Q_ASSERT(window); + setWindowData(getHWNDFromQObject(window), data); +} + +WinNativeEventFilter::WINDOWDATA *WinNativeEventFilter::windowData(void *window) +{ + Q_ASSERT(window); ResolveWin32APIs(); - if (window && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, window)) { - createUserData(window); - return &(reinterpret_cast( - WNEF_EXECUTE_WINAPI_RETURN(GetWindowLongPtrW, 0, window, GWLP_USERDATA)) - ->windowData); + const auto hwnd = reinterpret_cast(window); + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, hwnd)) { + createUserData(hwnd); + return reinterpret_cast( + WNEF_EXECUTE_WINAPI_RETURN(GetWindowLongPtrW, 0, hwnd, GWLP_USERDATA)); } return nullptr; } +WinNativeEventFilter::WINDOWDATA *WinNativeEventFilter::windowData(QObject *window) +{ + Q_ASSERT(window); + return windowData(getHWNDFromQObject(window)); +} + void WinNativeEventFilter::setBorderWidth(const int bw) { m_borderWidth = bw; @@ -1789,15 +1844,17 @@ void WinNativeEventFilter::setTitleBarHeight(const int tbh) m_titleBarHeight = tbh; } -void WinNativeEventFilter::updateWindow(const HWND handle, +void WinNativeEventFilter::updateWindow(void *handle, const bool triggerFrameChange, const bool redraw) { + Q_ASSERT(handle); ResolveWin32APIs(); - if (handle && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { + const auto hwnd = reinterpret_cast(handle); + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, hwnd)) { if (triggerFrameChange) { WNEF_EXECUTE_WINAPI(SetWindowPos, - handle, + hwnd, nullptr, 0, 0, @@ -1808,7 +1865,7 @@ void WinNativeEventFilter::updateWindow(const HWND handle, } if (redraw) { WNEF_EXECUTE_WINAPI(RedrawWindow, - handle, + hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOCHILDREN) @@ -1816,54 +1873,56 @@ void WinNativeEventFilter::updateWindow(const HWND handle, } } -int WinNativeEventFilter::getSystemMetric(const HWND handle, +int WinNativeEventFilter::getSystemMetric(void *handle, const SystemMetric metric, const bool dpiAware) { + Q_ASSERT(handle); ResolveWin32APIs(); - const qreal dpr = dpiAware ? GetDevicePixelRatioForWindow(handle) : m_defaultDevicePixelRatio; - if (handle && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { - createUserData(handle); - const auto userData = reinterpret_cast( - WNEF_EXECUTE_WINAPI_RETURN(GetWindowLongPtrW, 0, handle, GWLP_USERDATA)); + const auto hwnd = reinterpret_cast(handle); + const qreal dpr = dpiAware ? GetDevicePixelRatioForWindow(hwnd) : m_defaultDevicePixelRatio; + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, hwnd)) { + createUserData(hwnd); + const auto userData = reinterpret_cast( + WNEF_EXECUTE_WINAPI_RETURN(GetWindowLongPtrW, 0, hwnd, GWLP_USERDATA)); switch (metric) { case SystemMetric::BorderWidth: { - const int bw = userData->windowData.borderWidth; + const int bw = userData->borderWidth; if (bw > 0) { return qRound(bw * dpr); } else { const int result_nondpi = WNEF_EXECUTE_WINAPI_RETURN(GetSystemMetrics, 0, SM_CXSIZEFRAME) + WNEF_EXECUTE_WINAPI_RETURN(GetSystemMetrics, 0, SM_CXPADDEDBORDER); - const int result_dpi = GetSystemMetricsForWindow(handle, SM_CXSIZEFRAME) - + GetSystemMetricsForWindow(handle, SM_CXPADDEDBORDER); + const int result_dpi = GetSystemMetricsForWindow(hwnd, SM_CXSIZEFRAME) + + GetSystemMetricsForWindow(hwnd, SM_CXPADDEDBORDER); const int result = dpiAware ? result_dpi : result_nondpi; return result > 0 ? result : qRound(m_defaultBorderWidth * dpr); } } case SystemMetric::BorderHeight: { - const int bh = userData->windowData.borderHeight; + const int bh = userData->borderHeight; if (bh > 0) { return qRound(bh * dpr); } else { const int result_nondpi = WNEF_EXECUTE_WINAPI_RETURN(GetSystemMetrics, 0, SM_CYSIZEFRAME) + WNEF_EXECUTE_WINAPI_RETURN(GetSystemMetrics, 0, SM_CXPADDEDBORDER); - const int result_dpi = GetSystemMetricsForWindow(handle, SM_CYSIZEFRAME) - + GetSystemMetricsForWindow(handle, SM_CXPADDEDBORDER); + const int result_dpi = GetSystemMetricsForWindow(hwnd, SM_CYSIZEFRAME) + + GetSystemMetricsForWindow(hwnd, SM_CXPADDEDBORDER); const int result = dpiAware ? result_dpi : result_nondpi; return result > 0 ? result : qRound(m_defaultBorderHeight * dpr); } } case SystemMetric::TitleBarHeight: { - const int tbh = userData->windowData.titleBarHeight; + const int tbh = userData->titleBarHeight; if (tbh > 0) { return qRound(tbh * dpr); } else { const int result_nondpi = WNEF_EXECUTE_WINAPI_RETURN(GetSystemMetrics, 0, SM_CYCAPTION); - const int result_dpi = GetSystemMetricsForWindow(handle, SM_CYCAPTION); + const int result_dpi = GetSystemMetricsForWindow(hwnd, SM_CYCAPTION); const int result = dpiAware ? result_dpi : result_nondpi; return result > 0 ? result : qRound(m_defaultTitleBarHeight * dpr); } @@ -1894,26 +1953,30 @@ int WinNativeEventFilter::getSystemMetric(const HWND handle, } void WinNativeEventFilter::setWindowGeometry( - const HWND handle, const int x, const int y, const int width, const int height) + void *handle, const int x, const int y, const int width, const int height) { + Q_ASSERT(handle); ResolveWin32APIs(); - if (handle && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle) && (x > 0) && (y > 0) - && (width > 0) && (height > 0)) { - const qreal dpr = GetDevicePixelRatioForWindow(handle); + const auto hwnd = reinterpret_cast(handle); + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, hwnd) && (x > 0) && (y > 0) && (width > 0) + && (height > 0)) { + const qreal dpr = GetDevicePixelRatioForWindow(hwnd); // Why not use SetWindowPos? Actually we can, but MoveWindow // sends the WM_WINDOWPOSCHANGING, WM_WINDOWPOSCHANGED, WM_MOVE, // WM_SIZE, and WM_NCCALCSIZE messages to the window. // SetWindowPos only sends WM_WINDOWPOSCHANGED. - WNEF_EXECUTE_WINAPI(MoveWindow, handle, x, y, qRound(width * dpr), qRound(height * dpr), TRUE) + WNEF_EXECUTE_WINAPI(MoveWindow, hwnd, x, y, qRound(width * dpr), qRound(height * dpr), TRUE) } } -void WinNativeEventFilter::moveWindowToDesktopCenter(const HWND handle) +void WinNativeEventFilter::moveWindowToDesktopCenter(void *handle) { + Q_ASSERT(handle); ResolveWin32APIs(); - if (handle && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { - const WINDOWINFO windowInfo = GetInfoForWindow(handle); - const MONITORINFO monitorInfo = GetMonitorInfoForWindow(handle); + const auto hwnd = reinterpret_cast(handle); + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, hwnd)) { + const WINDOWINFO windowInfo = GetInfoForWindow(hwnd); + const MONITORINFO monitorInfo = GetMonitorInfoForWindow(hwnd); // If we want to move a window to the center of the desktop, // I think we should use rcMonitor, the monitor's whole area, // to calculate the new coordinates of our window, not rcWork. @@ -1922,7 +1985,7 @@ void WinNativeEventFilter::moveWindowToDesktopCenter(const HWND handle) const LONG ww = qAbs(windowInfo.rcWindow.right - windowInfo.rcWindow.left); const LONG wh = qAbs(windowInfo.rcWindow.bottom - windowInfo.rcWindow.top); WNEF_EXECUTE_WINAPI(MoveWindow, - handle, + hwnd, qRound((mw - ww) / 2.0), qRound((mh - wh) / 2.0), ww, @@ -1933,7 +1996,8 @@ void WinNativeEventFilter::moveWindowToDesktopCenter(const HWND handle) void WinNativeEventFilter::updateQtFrame(QWindow *window, const int titleBarHeight) { - if (window && (titleBarHeight > 0)) { + Q_ASSERT(window); + if (titleBarHeight > 0) { // Reduce top frame to zero since we paint it ourselves. Use // device pixel to avoid rounding errors. const QMargins margins = {0, -titleBarHeight, 0, 0}; @@ -1960,10 +2024,12 @@ void WinNativeEventFilter::updateQtFrame(QWindow *window, const int titleBarHeig } } -void WinNativeEventFilter::updateQtFrame_internal(const HWND handle) +void WinNativeEventFilter::updateQtFrame_internal(void *handle) { + Q_ASSERT(handle); ResolveWin32APIs(); - if (handle && WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) { + const auto hwnd = reinterpret_cast(handle); + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, hwnd)) { const int tbh = getSystemMetric(handle, SystemMetric::TitleBarHeight); #ifdef QT_WIDGETS_LIB const QWidget *widget = QWidget::find(reinterpret_cast(handle)); @@ -1975,7 +2041,7 @@ void WinNativeEventFilter::updateQtFrame_internal(const HWND handle) } } #endif - QWindow *window = findQWindowFromRawHandle(handle); + QWindow *window = findQWindowFromRawHandle(hwnd); if (window) { updateQtFrame(window, tbh); } diff --git a/winnativeeventfilter.h b/winnativeeventfilter.h index 313ae2b..bf8faa5 100644 --- a/winnativeeventfilter.h +++ b/winnativeeventfilter.h @@ -24,15 +24,10 @@ #pragma once -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif - #include "framelesshelper_global.h" #include #include #include -#include QT_BEGIN_NAMESPACE QT_FORWARD_DECLARE_CLASS(QWindow) @@ -53,52 +48,55 @@ class FRAMELESSHELPER_EXPORT WinNativeEventFilter : public QAbstractNativeEventF Q_DISABLE_COPY_MOVE(WinNativeEventFilter) public: - using WINDOWDATA = struct _WINDOWDATA + using WINDOW = struct _WINDOW { - BOOL fixedSize = FALSE, mouseTransparent = FALSE, restoreDefaultWindowStyle = FALSE, - enableLayeredWindow = FALSE, disableTitleBar = FALSE; + bool initialized = false, fixedSize = false, mouseTransparent = false, + restoreDefaultWindowStyle = false, enableLayeredWindow = false, + disableTitleBar = false; int borderWidth = -1, borderHeight = -1, titleBarHeight = -1; QList ignoreAreas = {}, draggableAreas = {}; QList> ignoreObjects = {}, draggableObjects = {}; - QSize maximumSize = {-1, -1}, minimumSize = {-1, -1}; - }; - - using WINDOW = struct _WINDOW - { - BOOL initialized = FALSE; - WINDOWDATA windowData; + QSize maximumSize = {}, minimumSize = {}; }; + using WINDOWDATA = WINDOW; enum class SystemMetric { BorderWidth, BorderHeight, TitleBarHeight }; explicit WinNativeEventFilter(); ~WinNativeEventFilter() override; - // Frameless windows handle list - static QList framelessWindows(); - static void setFramelessWindows(const QList &windows); // Make the given window become frameless. // The width and height will be scaled automatically according to DPI. Don't // scale them yourself. Just pass the original value. If you don't want to // change them, pass negative values to the parameters. - static void addFramelessWindow(const HWND window, + static void addFramelessWindow(void *window, const WINDOWDATA *data = nullptr, const bool center = false, const int x = -1, const int y = -1, const int width = -1, const int height = -1); - static void removeFramelessWindow(const HWND window); + static void addFramelessWindow(QObject *window, + const WINDOWDATA *data = nullptr, + const bool center = false, + const int x = -1, + const int y = -1, + const int width = -1, + const int height = -1); + static void removeFramelessWindow(void *window); + static void removeFramelessWindow(QObject *window); static void clearFramelessWindows(); // Set borderWidth, borderHeight or titleBarHeight to a negative value to // restore default behavior. // Note that it can only affect one specific window. // If you want to change these values globally, use setBorderWidth instead. - static void setWindowData(const HWND window, const WINDOWDATA *data); + static void setWindowData(void *window, const WINDOWDATA *data); + static void setWindowData(QObject *window, const WINDOWDATA *data); // You can modify the given window's data directly, it's the same with using // setWindowData. - static WINDOWDATA *windowData(const HWND window); + static WINDOWDATA *windowData(void *window); + static WINDOWDATA *windowData(QObject *window); // Change settings globally, not a specific window. // These values will be scaled automatically according to DPI, don't scale @@ -109,14 +107,12 @@ public: // System metric value of the given window (if the pointer is null, // return the system's standard value). - static int getSystemMetric(const HWND handle, - const SystemMetric metric, - const bool dpiAware = false); + static int getSystemMetric(void *handle, const SystemMetric metric, const bool dpiAware = false); // Use this function to trigger a frame change event or redraw a // specific window. Useful when you want to let some changes // in effect immediately. - static void updateWindow(const HWND handle, + static void updateWindow(void *handle, const bool triggerFrameChange = true, const bool redraw = true); @@ -124,10 +120,10 @@ public: // The width and height will be scaled automatically according to DPI. So // just pass the original value. static void setWindowGeometry( - const HWND handle, const int x, const int y, const int width, const int height); + void *handle, const int x, const int y, const int width, const int height); // Move the window to the center of the desktop. - static void moveWindowToDesktopCenter(const HWND handle); + static void moveWindowToDesktopCenter(void *handle); // Update Qt's internal data about the window frame, otherwise Qt will // take the size of the window frame into account when anyone is trying to @@ -146,5 +142,5 @@ private: static void install(); static void uninstall(); - static void updateQtFrame_internal(const HWND handle); + static void updateQtFrame_internal(void *handle); };