forked from github_mirror/framelesshelper
Minor improvements.
1. Use const more. 2. Add some missing ResolveWin32APIs() call 3. Move updateQtFrame to WinNativeEventFilter Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
parent
ae62a8fb49
commit
136b865853
|
@ -2,43 +2,17 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QMargins>
|
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#ifdef QT_QUICK_LIB
|
#ifdef QT_QUICK_LIB
|
||||||
#include <QQmlContext>
|
#include <QQmlContext>
|
||||||
#include <QQuickItem>
|
#include <QQuickItem>
|
||||||
#include <QQuickView>
|
#include <QQuickView>
|
||||||
#else
|
|
||||||
#include <QWindow>
|
|
||||||
#endif
|
#endif
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <qpa/qplatformnativeinterface.h>
|
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(QMargins)
|
|
||||||
|
|
||||||
static const int m_defaultTitleBarHeight = 30;
|
|
||||||
static const int m_defaultButtonWidth = 45;
|
static const int m_defaultButtonWidth = 45;
|
||||||
|
|
||||||
static void updateQtFrame(QWindow *const window, const int titleBarHeight) {
|
|
||||||
if (window && (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};
|
|
||||||
const QVariant marginsVar = QVariant::fromValue(margins);
|
|
||||||
// The dynamic property takes effect when creating the platform
|
|
||||||
// window.
|
|
||||||
window->setProperty("_q_windowsCustomMargins", marginsVar);
|
|
||||||
// If a platform window exists, change via native interface.
|
|
||||||
QPlatformWindow *platformWindow = window->handle();
|
|
||||||
if (platformWindow) {
|
|
||||||
QGuiApplication::platformNativeInterface()->setWindowProperty(
|
|
||||||
platformWindow, QString::fromUtf8("WindowsCustomMargins"),
|
|
||||||
marginsVar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef QT_QUICK_LIB
|
#ifdef QT_QUICK_LIB
|
||||||
class MyQuickView : public QQuickView {
|
class MyQuickView : public QQuickView {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -139,10 +113,6 @@ int main(int argc, char *argv[]) {
|
||||||
data_widget->ignoreObjects << minimizeButton << maximizeButton
|
data_widget->ignoreObjects << minimizeButton << maximizeButton
|
||||||
<< closeButton;
|
<< closeButton;
|
||||||
}
|
}
|
||||||
const int tbh_widget = WinNativeEventFilter::getSystemMetric(
|
|
||||||
hWnd_widget, WinNativeEventFilter::SystemMetric::TitleBarHeight, false);
|
|
||||||
updateQtFrame(widget.windowHandle(),
|
|
||||||
(tbh_widget > 0 ? tbh_widget : m_defaultTitleBarHeight));
|
|
||||||
widget.resize(800, 600);
|
widget.resize(800, 600);
|
||||||
WinNativeEventFilter::moveWindowToDesktopCenter(hWnd_widget);
|
WinNativeEventFilter::moveWindowToDesktopCenter(hWnd_widget);
|
||||||
widget.show();
|
widget.show();
|
||||||
|
@ -151,9 +121,8 @@ int main(int argc, char *argv[]) {
|
||||||
// Qt Quick example:
|
// Qt Quick example:
|
||||||
MyQuickView view;
|
MyQuickView view;
|
||||||
const auto hWnd_qml = reinterpret_cast<HWND>(view.winId());
|
const auto hWnd_qml = reinterpret_cast<HWND>(view.winId());
|
||||||
const int tbh_qml_sys = WinNativeEventFilter::getSystemMetric(
|
const int tbh_qml = WinNativeEventFilter::getSystemMetric(
|
||||||
hWnd_qml, WinNativeEventFilter::SystemMetric::TitleBarHeight, false);
|
hWnd_qml, WinNativeEventFilter::SystemMetric::TitleBarHeight, false);
|
||||||
const int tbh_qml = tbh_qml_sys > 0 ? tbh_qml_sys : m_defaultTitleBarHeight;
|
|
||||||
view.rootContext()->setContextProperty(QString::fromUtf8("$TitleBarHeight"),
|
view.rootContext()->setContextProperty(QString::fromUtf8("$TitleBarHeight"),
|
||||||
tbh_qml);
|
tbh_qml);
|
||||||
view.setSource(QUrl(QString::fromUtf8("qrc:///qml/main.qml")));
|
view.setSource(QUrl(QString::fromUtf8("qrc:///qml/main.qml")));
|
||||||
|
@ -182,7 +151,6 @@ int main(int argc, char *argv[]) {
|
||||||
QObject::connect(rootObject, SIGNAL(closeButtonClicked()), &view,
|
QObject::connect(rootObject, SIGNAL(closeButtonClicked()), &view,
|
||||||
SLOT(close()));
|
SLOT(close()));
|
||||||
WinNativeEventFilter::addFramelessWindow(hWnd_qml);
|
WinNativeEventFilter::addFramelessWindow(hWnd_qml);
|
||||||
updateQtFrame(&view, tbh_qml);
|
|
||||||
view.resize(800, 600);
|
view.resize(800, 600);
|
||||||
WinNativeEventFilter::moveWindowToDesktopCenter(hWnd_qml);
|
WinNativeEventFilter::moveWindowToDesktopCenter(hWnd_qml);
|
||||||
view.show();
|
view.show();
|
||||||
|
|
|
@ -27,6 +27,9 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QLibrary>
|
#include <QLibrary>
|
||||||
|
#include <QMargins>
|
||||||
|
#include <QWindow>
|
||||||
|
#include <qpa/qplatformnativeinterface.h>
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
|
||||||
#include <QOperatingSystemVersion>
|
#include <QOperatingSystemVersion>
|
||||||
#else
|
#else
|
||||||
|
@ -40,6 +43,8 @@
|
||||||
#endif
|
#endif
|
||||||
#include <QtMath>
|
#include <QtMath>
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QMargins)
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// All the following enums, structs and function prototypes are copied from
|
// All the following enums, structs and function prototypes are copied from
|
||||||
|
@ -184,6 +189,9 @@ const UINT m_defaultDotsPerInch = USER_DEFAULT_SCREEN_DPI;
|
||||||
|
|
||||||
const qreal m_defaultDevicePixelRatio = 1.0;
|
const qreal m_defaultDevicePixelRatio = 1.0;
|
||||||
|
|
||||||
|
const int m_defaultBorderWidth = 8, m_defaultBorderHeight = 8,
|
||||||
|
m_defaultTitleBarHeight = 30;
|
||||||
|
|
||||||
int m_borderWidth = -1, m_borderHeight = -1, m_titleBarHeight = -1;
|
int m_borderWidth = -1, m_borderHeight = -1, m_titleBarHeight = -1;
|
||||||
|
|
||||||
using HPAINTBUFFER = HANDLE;
|
using HPAINTBUFFER = HANDLE;
|
||||||
|
@ -491,7 +499,7 @@ BOOL IsDwmCompositionEnabled() {
|
||||||
return SUCCEEDED(m_lpDwmIsCompositionEnabled(&enabled)) && enabled;
|
return SUCCEEDED(m_lpDwmIsCompositionEnabled(&enabled)) && enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
WINDOWINFO GetInfoForWindow(HWND handle) {
|
WINDOWINFO GetInfoForWindow(const HWND handle) {
|
||||||
WINDOWINFO windowInfo;
|
WINDOWINFO windowInfo;
|
||||||
SecureZeroMemory(&windowInfo, sizeof(windowInfo));
|
SecureZeroMemory(&windowInfo, sizeof(windowInfo));
|
||||||
windowInfo.cbSize = sizeof(windowInfo);
|
windowInfo.cbSize = sizeof(windowInfo);
|
||||||
|
@ -501,7 +509,7 @@ WINDOWINFO GetInfoForWindow(HWND handle) {
|
||||||
return windowInfo;
|
return windowInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
MONITORINFO GetMonitorInfoForWindow(HWND handle) {
|
MONITORINFO GetMonitorInfoForWindow(const HWND handle) {
|
||||||
MONITORINFO monitorInfo;
|
MONITORINFO monitorInfo;
|
||||||
SecureZeroMemory(&monitorInfo, sizeof(monitorInfo));
|
SecureZeroMemory(&monitorInfo, sizeof(monitorInfo));
|
||||||
monitorInfo.cbSize = sizeof(monitorInfo);
|
monitorInfo.cbSize = sizeof(monitorInfo);
|
||||||
|
@ -515,7 +523,7 @@ MONITORINFO GetMonitorInfoForWindow(HWND handle) {
|
||||||
return monitorInfo;
|
return monitorInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL IsFullScreen(HWND handle) {
|
BOOL IsFullScreen(const HWND handle) {
|
||||||
if (handle && m_lpIsWindow(handle)) {
|
if (handle && m_lpIsWindow(handle)) {
|
||||||
const WINDOWINFO windowInfo = GetInfoForWindow(handle);
|
const WINDOWINFO windowInfo = GetInfoForWindow(handle);
|
||||||
const MONITORINFO monitorInfo = GetMonitorInfoForWindow(handle);
|
const MONITORINFO monitorInfo = GetMonitorInfoForWindow(handle);
|
||||||
|
@ -528,7 +536,7 @@ BOOL IsFullScreen(HWND handle) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL IsTopLevel(HWND handle) {
|
BOOL IsTopLevel(const HWND handle) {
|
||||||
if (handle && m_lpIsWindow(handle)) {
|
if (handle && m_lpIsWindow(handle)) {
|
||||||
if (m_lpGetWindowLongPtrW(handle, GWL_STYLE) & WS_CHILD) {
|
if (m_lpGetWindowLongPtrW(handle, GWL_STYLE) & WS_CHILD) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -542,8 +550,8 @@ BOOL IsTopLevel(HWND handle) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT GetDotsPerInchForWindow(HWND handle) {
|
UINT GetDotsPerInchForWindow(const HWND handle) {
|
||||||
const auto getScreenDpi = [](UINT defaultValue) -> UINT {
|
const auto getScreenDpi = [](const UINT defaultValue) -> UINT {
|
||||||
#if 0
|
#if 0
|
||||||
if (m_lpD2D1CreateFactory) {
|
if (m_lpD2D1CreateFactory) {
|
||||||
// Using Direct2D to get the screen DPI.
|
// Using Direct2D to get the screen DPI.
|
||||||
|
@ -607,9 +615,9 @@ UINT GetDotsPerInchForWindow(HWND handle) {
|
||||||
return getScreenDpi(m_defaultDotsPerInch);
|
return getScreenDpi(m_defaultDotsPerInch);
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal GetPreferedNumber(qreal num) {
|
qreal GetPreferedNumber(const qreal num) {
|
||||||
qreal result = -1.0;
|
qreal result = -1.0;
|
||||||
const auto getRoundedNumber = [](qreal in) -> qreal {
|
const auto getRoundedNumber = [](const qreal in) -> qreal {
|
||||||
// If the given number is not very large, we assume it's a
|
// If the given number is not very large, we assume it's a
|
||||||
// device pixel ratio (DPR), otherwise we assume it's a DPI.
|
// device pixel ratio (DPR), otherwise we assume it's a DPI.
|
||||||
if (in < m_defaultDotsPerInch) {
|
if (in < m_defaultDotsPerInch) {
|
||||||
|
@ -660,7 +668,7 @@ qreal GetPreferedNumber(qreal num) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal GetDevicePixelRatioForWindow(HWND handle) {
|
qreal GetDevicePixelRatioForWindow(const HWND handle) {
|
||||||
qreal result = m_defaultDevicePixelRatio;
|
qreal result = m_defaultDevicePixelRatio;
|
||||||
if (handle && m_lpIsWindow(handle)) {
|
if (handle && m_lpIsWindow(handle)) {
|
||||||
result = static_cast<qreal>(GetDotsPerInchForWindow(handle)) /
|
result = static_cast<qreal>(GetDotsPerInchForWindow(handle)) /
|
||||||
|
@ -669,7 +677,8 @@ qreal GetDevicePixelRatioForWindow(HWND handle) {
|
||||||
return GetPreferedNumber(result);
|
return GetPreferedNumber(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
RECT GetFrameSizeForWindow(HWND handle, bool includingTitleBar = false) {
|
RECT GetFrameSizeForWindow(const HWND handle,
|
||||||
|
const bool includingTitleBar = false) {
|
||||||
RECT rect = {0, 0, 0, 0};
|
RECT rect = {0, 0, 0, 0};
|
||||||
if (handle && m_lpIsWindow(handle)) {
|
if (handle && m_lpIsWindow(handle)) {
|
||||||
const auto style = m_lpGetWindowLongPtrW(handle, GWL_STYLE);
|
const auto style = m_lpGetWindowLongPtrW(handle, GWL_STYLE);
|
||||||
|
@ -703,7 +712,7 @@ RECT GetFrameSizeForWindow(HWND handle, bool includingTitleBar = false) {
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateFrameMarginsForWindow(HWND handle) {
|
void UpdateFrameMarginsForWindow(const HWND handle) {
|
||||||
if (handle && m_lpIsWindow(handle)) {
|
if (handle && m_lpIsWindow(handle)) {
|
||||||
MARGINS margins = {0, 0, 0, 0};
|
MARGINS margins = {0, 0, 0, 0};
|
||||||
if (IsDwmCompositionEnabled()) {
|
if (IsDwmCompositionEnabled()) {
|
||||||
|
@ -729,7 +738,7 @@ void UpdateFrameMarginsForWindow(HWND handle) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetSystemMetricsForWindow(HWND handle, int index) {
|
int GetSystemMetricsForWindow(const HWND handle, const int index) {
|
||||||
if (handle && m_lpIsWindow(handle)) {
|
if (handle && m_lpIsWindow(handle)) {
|
||||||
if (m_lpGetSystemMetricsForDpi) {
|
if (m_lpGetSystemMetricsForDpi) {
|
||||||
return m_lpGetSystemMetricsForDpi(
|
return m_lpGetSystemMetricsForDpi(
|
||||||
|
@ -744,7 +753,7 @@ int GetSystemMetricsForWindow(HWND handle, int index) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void createUserData(HWND handle,
|
void createUserData(const HWND handle,
|
||||||
const WinNativeEventFilter::WINDOWDATA *data = nullptr) {
|
const WinNativeEventFilter::WINDOWDATA *data = nullptr) {
|
||||||
if (handle && m_lpIsWindow(handle)) {
|
if (handle && m_lpIsWindow(handle)) {
|
||||||
const auto userData = reinterpret_cast<WinNativeEventFilter::WINDOW *>(
|
const auto userData = reinterpret_cast<WinNativeEventFilter::WINDOW *>(
|
||||||
|
@ -804,26 +813,29 @@ QVector<HWND> WinNativeEventFilter::framelessWindows() {
|
||||||
return m_framelessWindows;
|
return m_framelessWindows;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinNativeEventFilter::setFramelessWindows(QVector<HWND> windows) {
|
void WinNativeEventFilter::setFramelessWindows(const QVector<HWND> &windows) {
|
||||||
if (!windows.isEmpty() && (windows != m_framelessWindows)) {
|
if (!windows.isEmpty() && (windows != m_framelessWindows)) {
|
||||||
m_framelessWindows = windows;
|
m_framelessWindows = windows;
|
||||||
for (auto &&window : qAsConst(m_framelessWindows)) {
|
for (auto &&window : qAsConst(m_framelessWindows)) {
|
||||||
createUserData(window);
|
createUserData(window);
|
||||||
|
updateQtFrame_internal(window);
|
||||||
}
|
}
|
||||||
install();
|
install();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinNativeEventFilter::addFramelessWindow(HWND window,
|
void WinNativeEventFilter::addFramelessWindow(const HWND window,
|
||||||
const WINDOWDATA *data,
|
const WINDOWDATA *data,
|
||||||
bool center, int x, int y,
|
const bool center, const int x,
|
||||||
int width, int height) {
|
const int y, const int width,
|
||||||
|
const int height) {
|
||||||
ResolveWin32APIs();
|
ResolveWin32APIs();
|
||||||
if (window && m_lpIsWindow(window) &&
|
if (window && m_lpIsWindow(window) &&
|
||||||
!m_framelessWindows.contains(window)) {
|
!m_framelessWindows.contains(window)) {
|
||||||
m_framelessWindows.append(window);
|
m_framelessWindows.append(window);
|
||||||
createUserData(window, data);
|
createUserData(window, data);
|
||||||
install();
|
install();
|
||||||
|
updateQtFrame_internal(window);
|
||||||
}
|
}
|
||||||
if ((x > 0) && (y > 0) && (width > 0) && (height > 0)) {
|
if ((x > 0) && (y > 0) && (width > 0) && (height > 0)) {
|
||||||
setWindowGeometry(window, x, y, width, height);
|
setWindowGeometry(window, x, y, width, height);
|
||||||
|
@ -833,7 +845,7 @@ void WinNativeEventFilter::addFramelessWindow(HWND window,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinNativeEventFilter::removeFramelessWindow(HWND window) {
|
void WinNativeEventFilter::removeFramelessWindow(const HWND window) {
|
||||||
if (window && m_framelessWindows.contains(window)) {
|
if (window && m_framelessWindows.contains(window)) {
|
||||||
m_framelessWindows.removeAll(window);
|
m_framelessWindows.removeAll(window);
|
||||||
}
|
}
|
||||||
|
@ -1242,7 +1254,7 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
|
||||||
*result = HTTRANSPARENT;
|
*result = HTTRANSPARENT;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const auto getHTResult = [](HWND _hWnd, LPARAM _lParam,
|
const auto getHTResult = [](const HWND _hWnd, const LPARAM _lParam,
|
||||||
const WINDOW *_data) -> LRESULT {
|
const WINDOW *_data) -> LRESULT {
|
||||||
const auto isInSpecificAreas = [](const int x, const int y,
|
const auto isInSpecificAreas = [](const int x, const int y,
|
||||||
const QVector<QRect> &areas,
|
const QVector<QRect> &areas,
|
||||||
|
@ -1407,38 +1419,38 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
|
||||||
const MONITORINFO monitorInfo = GetMonitorInfoForWindow(msg->hwnd);
|
const MONITORINFO monitorInfo = GetMonitorInfoForWindow(msg->hwnd);
|
||||||
const RECT rcWorkArea = monitorInfo.rcWork;
|
const RECT rcWorkArea = monitorInfo.rcWork;
|
||||||
const RECT rcMonitorArea = monitorInfo.rcMonitor;
|
const RECT rcMonitorArea = monitorInfo.rcMonitor;
|
||||||
auto &mmi = *reinterpret_cast<LPMINMAXINFO>(msg->lParam);
|
const auto mmi = reinterpret_cast<LPMINMAXINFO>(msg->lParam);
|
||||||
if (isWin8OrGreator()) {
|
if (isWin8OrGreator()) {
|
||||||
// Works fine on Windows 8/8.1/10
|
// Works fine on Windows 8/8.1/10
|
||||||
mmi.ptMaxPosition.x =
|
mmi->ptMaxPosition.x =
|
||||||
qAbs(rcWorkArea.left - rcMonitorArea.left);
|
qAbs(rcWorkArea.left - rcMonitorArea.left);
|
||||||
mmi.ptMaxPosition.y = qAbs(rcWorkArea.top - rcMonitorArea.top);
|
mmi->ptMaxPosition.y = qAbs(rcWorkArea.top - rcMonitorArea.top);
|
||||||
} else {
|
} else {
|
||||||
// ### FIXME: Buggy on Windows 7:
|
// ### FIXME: Buggy on Windows 7:
|
||||||
// The origin of coordinates is the top left edge of the
|
// The origin of coordinates is the top left edge of the
|
||||||
// monitor's work area. Why? It should be the top left edge of
|
// monitor's work area. Why? It should be the top left edge of
|
||||||
// the monitor's area.
|
// the monitor's area.
|
||||||
mmi.ptMaxPosition.x = rcMonitorArea.left;
|
mmi->ptMaxPosition.x = rcMonitorArea.left;
|
||||||
mmi.ptMaxPosition.y = rcMonitorArea.top;
|
mmi->ptMaxPosition.y = rcMonitorArea.top;
|
||||||
}
|
}
|
||||||
if (data->windowData.maximumSize.isEmpty()) {
|
if (data->windowData.maximumSize.isEmpty()) {
|
||||||
mmi.ptMaxSize.x = qAbs(rcWorkArea.right - rcWorkArea.left);
|
mmi->ptMaxSize.x = qAbs(rcWorkArea.right - rcWorkArea.left);
|
||||||
mmi.ptMaxSize.y = qAbs(rcWorkArea.bottom - rcWorkArea.top);
|
mmi->ptMaxSize.y = qAbs(rcWorkArea.bottom - rcWorkArea.top);
|
||||||
} else {
|
} else {
|
||||||
mmi.ptMaxSize.x =
|
mmi->ptMaxSize.x =
|
||||||
qRound(GetDevicePixelRatioForWindow(msg->hwnd) *
|
qRound(GetDevicePixelRatioForWindow(msg->hwnd) *
|
||||||
data->windowData.maximumSize.width());
|
data->windowData.maximumSize.width());
|
||||||
mmi.ptMaxSize.y =
|
mmi->ptMaxSize.y =
|
||||||
qRound(GetDevicePixelRatioForWindow(msg->hwnd) *
|
qRound(GetDevicePixelRatioForWindow(msg->hwnd) *
|
||||||
data->windowData.maximumSize.height());
|
data->windowData.maximumSize.height());
|
||||||
}
|
}
|
||||||
mmi.ptMaxTrackSize.x = mmi.ptMaxSize.x;
|
mmi->ptMaxTrackSize.x = mmi->ptMaxSize.x;
|
||||||
mmi.ptMaxTrackSize.y = mmi.ptMaxSize.y;
|
mmi->ptMaxTrackSize.y = mmi->ptMaxSize.y;
|
||||||
if (!data->windowData.minimumSize.isEmpty()) {
|
if (!data->windowData.minimumSize.isEmpty()) {
|
||||||
mmi.ptMinTrackSize.x =
|
mmi->ptMinTrackSize.x =
|
||||||
qRound(GetDevicePixelRatioForWindow(msg->hwnd) *
|
qRound(GetDevicePixelRatioForWindow(msg->hwnd) *
|
||||||
data->windowData.minimumSize.width());
|
data->windowData.minimumSize.width());
|
||||||
mmi.ptMinTrackSize.y =
|
mmi->ptMinTrackSize.y =
|
||||||
qRound(GetDevicePixelRatioForWindow(msg->hwnd) *
|
qRound(GetDevicePixelRatioForWindow(msg->hwnd) *
|
||||||
data->windowData.minimumSize.height());
|
data->windowData.minimumSize.height());
|
||||||
}
|
}
|
||||||
|
@ -1497,7 +1509,8 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinNativeEventFilter::setWindowData(HWND window, const WINDOWDATA *data) {
|
void WinNativeEventFilter::setWindowData(const HWND window,
|
||||||
|
const WINDOWDATA *data) {
|
||||||
ResolveWin32APIs();
|
ResolveWin32APIs();
|
||||||
if (window && m_lpIsWindow(window) && data) {
|
if (window && m_lpIsWindow(window) && data) {
|
||||||
createUserData(window, data);
|
createUserData(window, data);
|
||||||
|
@ -1505,27 +1518,30 @@ void WinNativeEventFilter::setWindowData(HWND window, const WINDOWDATA *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
WinNativeEventFilter::WINDOWDATA *
|
WinNativeEventFilter::WINDOWDATA *
|
||||||
WinNativeEventFilter::windowData(HWND window) {
|
WinNativeEventFilter::windowData(const HWND window) {
|
||||||
ResolveWin32APIs();
|
ResolveWin32APIs();
|
||||||
if (window && m_lpIsWindow(window)) {
|
if (window && m_lpIsWindow(window)) {
|
||||||
createUserData(window);
|
createUserData(window);
|
||||||
return &reinterpret_cast<WINDOW *>(
|
return &(reinterpret_cast<WINDOW *>(
|
||||||
m_lpGetWindowLongPtrW(window, GWLP_USERDATA))
|
m_lpGetWindowLongPtrW(window, GWLP_USERDATA))
|
||||||
->windowData;
|
->windowData);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinNativeEventFilter::setBorderWidth(int bw) { m_borderWidth = bw; }
|
void WinNativeEventFilter::setBorderWidth(const int bw) { m_borderWidth = bw; }
|
||||||
|
|
||||||
void WinNativeEventFilter::setBorderHeight(int bh) { m_borderHeight = bh; }
|
void WinNativeEventFilter::setBorderHeight(const int bh) {
|
||||||
|
m_borderHeight = bh;
|
||||||
|
}
|
||||||
|
|
||||||
void WinNativeEventFilter::setTitleBarHeight(int tbh) {
|
void WinNativeEventFilter::setTitleBarHeight(const int tbh) {
|
||||||
m_titleBarHeight = tbh;
|
m_titleBarHeight = tbh;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinNativeEventFilter::updateWindow(HWND handle, bool triggerFrameChange,
|
void WinNativeEventFilter::updateWindow(const HWND handle,
|
||||||
bool redraw) {
|
const bool triggerFrameChange,
|
||||||
|
const bool redraw) {
|
||||||
ResolveWin32APIs();
|
ResolveWin32APIs();
|
||||||
if (handle && m_lpIsWindow(handle)) {
|
if (handle && m_lpIsWindow(handle)) {
|
||||||
if (triggerFrameChange) {
|
if (triggerFrameChange) {
|
||||||
|
@ -1540,8 +1556,9 @@ void WinNativeEventFilter::updateWindow(HWND handle, bool triggerFrameChange,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int WinNativeEventFilter::getSystemMetric(HWND handle, SystemMetric metric,
|
int WinNativeEventFilter::getSystemMetric(const HWND handle,
|
||||||
bool dpiAware) {
|
const SystemMetric metric,
|
||||||
|
const bool dpiAware) {
|
||||||
ResolveWin32APIs();
|
ResolveWin32APIs();
|
||||||
const qreal dpr = dpiAware ? GetDevicePixelRatioForWindow(handle)
|
const qreal dpr = dpiAware ? GetDevicePixelRatioForWindow(handle)
|
||||||
: m_defaultDevicePixelRatio;
|
: m_defaultDevicePixelRatio;
|
||||||
|
@ -1555,12 +1572,13 @@ int WinNativeEventFilter::getSystemMetric(HWND handle, SystemMetric metric,
|
||||||
if (bw > 0) {
|
if (bw > 0) {
|
||||||
return qRound(bw * dpr);
|
return qRound(bw * dpr);
|
||||||
} else {
|
} else {
|
||||||
const int result = m_lpGetSystemMetrics(SM_CXSIZEFRAME) +
|
const int result_nondpi = m_lpGetSystemMetrics(SM_CXSIZEFRAME) +
|
||||||
m_lpGetSystemMetrics(SM_CXPADDEDBORDER);
|
m_lpGetSystemMetrics(SM_CXPADDEDBORDER);
|
||||||
const int result_dpi =
|
const int result_dpi =
|
||||||
GetSystemMetricsForWindow(handle, SM_CXSIZEFRAME) +
|
GetSystemMetricsForWindow(handle, SM_CXSIZEFRAME) +
|
||||||
GetSystemMetricsForWindow(handle, SM_CXPADDEDBORDER);
|
GetSystemMetricsForWindow(handle, SM_CXPADDEDBORDER);
|
||||||
return dpiAware ? result_dpi : result;
|
const int result = dpiAware ? result_dpi : result_nondpi;
|
||||||
|
return result > 0 ? result : qRound(m_defaultBorderWidth * dpr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case SystemMetric::BorderHeight: {
|
case SystemMetric::BorderHeight: {
|
||||||
|
@ -1568,12 +1586,14 @@ int WinNativeEventFilter::getSystemMetric(HWND handle, SystemMetric metric,
|
||||||
if (bh > 0) {
|
if (bh > 0) {
|
||||||
return qRound(bh * dpr);
|
return qRound(bh * dpr);
|
||||||
} else {
|
} else {
|
||||||
const int result = m_lpGetSystemMetrics(SM_CYSIZEFRAME) +
|
const int result_nondpi = m_lpGetSystemMetrics(SM_CYSIZEFRAME) +
|
||||||
m_lpGetSystemMetrics(SM_CXPADDEDBORDER);
|
m_lpGetSystemMetrics(SM_CXPADDEDBORDER);
|
||||||
const int result_dpi =
|
const int result_dpi =
|
||||||
GetSystemMetricsForWindow(handle, SM_CYSIZEFRAME) +
|
GetSystemMetricsForWindow(handle, SM_CYSIZEFRAME) +
|
||||||
GetSystemMetricsForWindow(handle, SM_CXPADDEDBORDER);
|
GetSystemMetricsForWindow(handle, SM_CXPADDEDBORDER);
|
||||||
return dpiAware ? result_dpi : result;
|
const int result = dpiAware ? result_dpi : result_nondpi;
|
||||||
|
return result > 0 ? result
|
||||||
|
: qRound(m_defaultBorderHeight * dpr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case SystemMetric::TitleBarHeight: {
|
case SystemMetric::TitleBarHeight: {
|
||||||
|
@ -1581,40 +1601,43 @@ int WinNativeEventFilter::getSystemMetric(HWND handle, SystemMetric metric,
|
||||||
if (tbh > 0) {
|
if (tbh > 0) {
|
||||||
return qRound(tbh * dpr);
|
return qRound(tbh * dpr);
|
||||||
} else {
|
} else {
|
||||||
const int result = m_lpGetSystemMetrics(SM_CYCAPTION);
|
const int result_nondpi = m_lpGetSystemMetrics(SM_CYCAPTION);
|
||||||
const int result_dpi =
|
const int result_dpi =
|
||||||
GetSystemMetricsForWindow(handle, SM_CYCAPTION);
|
GetSystemMetricsForWindow(handle, SM_CYCAPTION);
|
||||||
return dpiAware ? result_dpi : result;
|
const int result = dpiAware ? result_dpi : result_nondpi;
|
||||||
|
return result > 0 ? result
|
||||||
|
: qRound(m_defaultTitleBarHeight * dpr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (metric) {
|
switch (metric) {
|
||||||
case SystemMetric::BorderWidth: {
|
case SystemMetric::BorderWidth:
|
||||||
if (m_borderWidth > 0) {
|
if (m_borderWidth > 0) {
|
||||||
return qRound(m_borderWidth * dpr);
|
return qRound(m_borderWidth * dpr);
|
||||||
|
} else {
|
||||||
|
return qRound(m_defaultBorderWidth * dpr);
|
||||||
}
|
}
|
||||||
break;
|
case SystemMetric::BorderHeight:
|
||||||
}
|
|
||||||
case SystemMetric::BorderHeight: {
|
|
||||||
if (m_borderHeight > 0) {
|
if (m_borderHeight > 0) {
|
||||||
return qRound(m_borderHeight * dpr);
|
return qRound(m_borderHeight * dpr);
|
||||||
|
} else {
|
||||||
|
return qRound(m_defaultBorderHeight * dpr);
|
||||||
}
|
}
|
||||||
break;
|
case SystemMetric::TitleBarHeight:
|
||||||
}
|
|
||||||
case SystemMetric::TitleBarHeight: {
|
|
||||||
if (m_titleBarHeight > 0) {
|
if (m_titleBarHeight > 0) {
|
||||||
return qRound(m_titleBarHeight * dpr);
|
return qRound(m_titleBarHeight * dpr);
|
||||||
}
|
} else {
|
||||||
break;
|
return qRound(m_defaultTitleBarHeight * dpr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinNativeEventFilter::setWindowGeometry(HWND handle, const int x,
|
void WinNativeEventFilter::setWindowGeometry(const HWND handle, const int x,
|
||||||
const int y, const int width,
|
const int y, const int width,
|
||||||
const int height) {
|
const int height) {
|
||||||
|
ResolveWin32APIs();
|
||||||
if (handle && m_lpIsWindow(handle) && (x > 0) && (y > 0) && (width > 0) &&
|
if (handle && m_lpIsWindow(handle) && (x > 0) && (y > 0) && (width > 0) &&
|
||||||
(height > 0)) {
|
(height > 0)) {
|
||||||
const qreal dpr = GetDevicePixelRatioForWindow(handle);
|
const qreal dpr = GetDevicePixelRatioForWindow(handle);
|
||||||
|
@ -1627,7 +1650,8 @@ void WinNativeEventFilter::setWindowGeometry(HWND handle, const int x,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinNativeEventFilter::moveWindowToDesktopCenter(HWND handle) {
|
void WinNativeEventFilter::moveWindowToDesktopCenter(const HWND handle) {
|
||||||
|
ResolveWin32APIs();
|
||||||
if (handle && m_lpIsWindow(handle)) {
|
if (handle && m_lpIsWindow(handle)) {
|
||||||
const WINDOWINFO windowInfo = GetInfoForWindow(handle);
|
const WINDOWINFO windowInfo = GetInfoForWindow(handle);
|
||||||
const MONITORINFO monitorInfo = GetMonitorInfoForWindow(handle);
|
const MONITORINFO monitorInfo = GetMonitorInfoForWindow(handle);
|
||||||
|
@ -1646,3 +1670,46 @@ void WinNativeEventFilter::moveWindowToDesktopCenter(HWND handle) {
|
||||||
ww, wh, TRUE);
|
ww, wh, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WinNativeEventFilter::updateQtFrame(QWindow *const window,
|
||||||
|
const int titleBarHeight) {
|
||||||
|
if (window && (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};
|
||||||
|
const QVariant marginsVar = QVariant::fromValue(margins);
|
||||||
|
// The dynamic property takes effect when creating the platform
|
||||||
|
// window.
|
||||||
|
window->setProperty("_q_windowsCustomMargins", marginsVar);
|
||||||
|
// If a platform window exists, change via native interface.
|
||||||
|
QPlatformWindow *platformWindow = window->handle();
|
||||||
|
if (platformWindow) {
|
||||||
|
QGuiApplication::platformNativeInterface()->setWindowProperty(
|
||||||
|
platformWindow, QString::fromUtf8("WindowsCustomMargins"),
|
||||||
|
marginsVar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinNativeEventFilter::updateQtFrame_internal(const HWND handle) {
|
||||||
|
ResolveWin32APIs();
|
||||||
|
if (handle && m_lpIsWindow(handle)) {
|
||||||
|
const int tbh =
|
||||||
|
getSystemMetric(handle, SystemMetric::TitleBarHeight, false);
|
||||||
|
const auto wid = reinterpret_cast<WId>(handle);
|
||||||
|
#ifdef QT_WIDGETS_LIB
|
||||||
|
const QWidget *const widget = QWidget::find(wid);
|
||||||
|
if (widget && widget->isTopLevel()) {
|
||||||
|
QWindow *const window = widget->windowHandle();
|
||||||
|
if (window) {
|
||||||
|
updateQtFrame(window, tbh);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
QWindow *const window = QWindow::fromWinId(wid);
|
||||||
|
if (window) {
|
||||||
|
updateQtFrame(window, tbh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -34,6 +34,10 @@
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <qt_windows.h>
|
#include <qt_windows.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QWindow)
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
|
#if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
|
||||||
#define Q_DISABLE_MOVE(Class) \
|
#define Q_DISABLE_MOVE(Class) \
|
||||||
Class(Class &&) = delete; \
|
Class(Class &&) = delete; \
|
||||||
|
@ -70,53 +74,60 @@ public:
|
||||||
|
|
||||||
// Frameless windows handle list
|
// Frameless windows handle list
|
||||||
static QVector<HWND> framelessWindows();
|
static QVector<HWND> framelessWindows();
|
||||||
static void setFramelessWindows(QVector<HWND> windows);
|
static void setFramelessWindows(const QVector<HWND> &windows);
|
||||||
// Make the given window become frameless.
|
// Make the given window become frameless.
|
||||||
// The width and height will be scaled automatically according to DPI. Don't
|
// 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
|
// scale them yourself. Just pass the original value. If you don't want to
|
||||||
// change them, pass negative values to the parameters.
|
// change them, pass negative values to the parameters.
|
||||||
static void addFramelessWindow(HWND window,
|
static void addFramelessWindow(const HWND window,
|
||||||
const WINDOWDATA *data = nullptr,
|
const WINDOWDATA *data = nullptr,
|
||||||
bool center = false, int x = -1, int y = -1,
|
const bool center = false, const int x = -1,
|
||||||
int width = -1, int height = -1);
|
const int y = -1, const int width = -1,
|
||||||
static void removeFramelessWindow(HWND window);
|
const int height = -1);
|
||||||
|
static void removeFramelessWindow(const HWND window);
|
||||||
static void clearFramelessWindows();
|
static void clearFramelessWindows();
|
||||||
|
|
||||||
// Set borderWidth, borderHeight or titleBarHeight to a negative value to
|
// Set borderWidth, borderHeight or titleBarHeight to a negative value to
|
||||||
// restore default behavior.
|
// restore default behavior.
|
||||||
// Note that it can only affect one specific window.
|
// Note that it can only affect one specific window.
|
||||||
// If you want to change these values globally, use setBorderWidth instead.
|
// If you want to change these values globally, use setBorderWidth instead.
|
||||||
static void setWindowData(HWND window, const WINDOWDATA *data);
|
static void setWindowData(const HWND window, const WINDOWDATA *data);
|
||||||
// You can modify the given window's data directly, it's the same with using
|
// You can modify the given window's data directly, it's the same with using
|
||||||
// setWindowData.
|
// setWindowData.
|
||||||
static WINDOWDATA *windowData(HWND window);
|
static WINDOWDATA *windowData(const HWND window);
|
||||||
|
|
||||||
// Change settings globally, not a specific window.
|
// Change settings globally, not a specific window.
|
||||||
// These values will be scaled automatically according to DPI, don't scale
|
// These values will be scaled automatically according to DPI, don't scale
|
||||||
// them yourself. Just pass the original value.
|
// them yourself. Just pass the original value.
|
||||||
static void setBorderWidth(int bw);
|
static void setBorderWidth(const int bw);
|
||||||
static void setBorderHeight(int bh);
|
static void setBorderHeight(const int bh);
|
||||||
static void setTitleBarHeight(int tbh);
|
static void setTitleBarHeight(const int tbh);
|
||||||
|
|
||||||
// System metric value of the given window (if the pointer is null,
|
// System metric value of the given window (if the pointer is null,
|
||||||
// return the system's standard value).
|
// return the system's standard value).
|
||||||
static int getSystemMetric(HWND handle, SystemMetric metric,
|
static int getSystemMetric(const HWND handle, const SystemMetric metric,
|
||||||
bool dpiAware = true);
|
const bool dpiAware = true);
|
||||||
|
|
||||||
// Use this function to trigger a frame change event or redraw a
|
// Use this function to trigger a frame change event or redraw a
|
||||||
// specific window. Useful when you want to let some changes
|
// specific window. Useful when you want to let some changes
|
||||||
// in effect immediately.
|
// in effect immediately.
|
||||||
static void updateWindow(HWND handle, bool triggerFrameChange = true,
|
static void updateWindow(const HWND handle,
|
||||||
bool redraw = true);
|
const bool triggerFrameChange = true,
|
||||||
|
const bool redraw = true);
|
||||||
|
|
||||||
// Change the geometry of a window through Win32 API.
|
// Change the geometry of a window through Win32 API.
|
||||||
// The width and height will be scaled automatically according to DPI. So
|
// The width and height will be scaled automatically according to DPI. So
|
||||||
// just pass the original value.
|
// just pass the original value.
|
||||||
static void setWindowGeometry(HWND handle, const int x, const int y,
|
static void setWindowGeometry(const HWND handle, const int x, const int y,
|
||||||
const int width, const int height);
|
const int width, const int height);
|
||||||
|
|
||||||
// Move the window to the center of the desktop.
|
// Move the window to the center of the desktop.
|
||||||
static void moveWindowToDesktopCenter(HWND handle);
|
static void moveWindowToDesktopCenter(const HWND 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
|
||||||
|
// change the geometry of the window. That's not what we want.
|
||||||
|
static void updateQtFrame(QWindow *const window, const int titleBarHeight);
|
||||||
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||||
bool nativeEventFilter(const QByteArray &eventType, void *message,
|
bool nativeEventFilter(const QByteArray &eventType, void *message,
|
||||||
|
@ -131,4 +142,6 @@ private:
|
||||||
// will happen.
|
// will happen.
|
||||||
static void install();
|
static void install();
|
||||||
static void uninstall();
|
static void uninstall();
|
||||||
|
|
||||||
|
static void updateQtFrame_internal(const HWND handle);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue