forked from github_mirror/framelesshelper
Fix build on Qt before 5.14
1. The QWinRegistryKey class was introduced in 5.14.0. The implementation is quite clean, so just copy the sources files from Qt repo in case the user is linking against a version older than 5.14. 2. Fixes the rounding error of the self-painted frame border of the examples. 3. Other minor tweaks. Fixes: #95 Task-number: #94 Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
parent
fc307c83bf
commit
e3adb917a6
|
@ -42,17 +42,17 @@ endif()
|
|||
if(WIN32)
|
||||
list(APPEND SOURCES
|
||||
framelesshelper_windows.h
|
||||
qwinregistry_p.h
|
||||
qwinregistry.cpp
|
||||
utilities_win32.cpp
|
||||
framelesshelper_win32.h
|
||||
framelesshelper_win32.cpp
|
||||
)
|
||||
else()
|
||||
if(MACOS)
|
||||
elseif(APPLE)
|
||||
list(APPEND SOURCES utilities_macos.mm)
|
||||
else()
|
||||
elseif(UNIX)
|
||||
list(APPEND SOURCES utilities_linux.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32 AND BUILD_SHARED_LIBS)
|
||||
enable_language(RC)
|
||||
|
|
|
@ -17,6 +17,6 @@ win32 {
|
|||
win32 {
|
||||
CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../debug -lFramelessHelperd
|
||||
else: CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../release -lFramelessHelper
|
||||
} else: unix {
|
||||
} else {
|
||||
LIBS += -L$$OUT_PWD/../../bin -lFramelessHelper
|
||||
}
|
||||
|
|
|
@ -31,9 +31,9 @@ int main(int argc, char *argv[])
|
|||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round);
|
||||
#endif
|
||||
|
||||
QApplication application(argc, argv);
|
||||
|
|
|
@ -52,14 +52,14 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(par
|
|||
connect(this, &MainWindow::windowTitleChanged, titleBarWidget->titleLabel, &QLabel::setText);
|
||||
connect(titleBarWidget->closeButton, &QPushButton::clicked, this, &MainWindow::close);
|
||||
connect(titleBarWidget->minimizeButton, &QPushButton::clicked, this, &MainWindow::showMinimized);
|
||||
connect(titleBarWidget->maximizeButton, &QPushButton::clicked, [this](){
|
||||
connect(titleBarWidget->maximizeButton, &QPushButton::clicked, this, [this](){
|
||||
if (isMaximized() || isFullScreen()) {
|
||||
showNormal();
|
||||
} else {
|
||||
showMaximized();
|
||||
}
|
||||
});
|
||||
connect(this, &MainWindow::windowStateChanged, [this](){
|
||||
connect(this, &MainWindow::windowStateChanged, this, [this](){
|
||||
titleBarWidget->maximizeButton->setChecked(isMaximized());
|
||||
titleBarWidget->maximizeButton->setToolTip(isMaximized() ? tr("Restore") : tr("Maximize"));
|
||||
});
|
||||
|
@ -122,7 +122,6 @@ void MainWindow::paintEvent(QPaintEvent *event)
|
|||
{
|
||||
QMainWindow::paintEvent(event);
|
||||
if (windowState() == Qt::WindowNoState) {
|
||||
QPainter painter(this);
|
||||
const int w = width();
|
||||
const int h = height();
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
|
@ -136,7 +135,9 @@ void MainWindow::paintEvent(QPaintEvent *event)
|
|||
{w, h - 1, 0, h - 1},
|
||||
{0, h, 0, 0}
|
||||
};
|
||||
QPainter painter(this);
|
||||
painter.save();
|
||||
painter.setRenderHint(QPainter::Antialiasing, false);
|
||||
const ColorizationArea area = Utilities::getColorizationArea();
|
||||
const bool colorizedBorder = ((area == ColorizationArea::TitleBar_WindowBorder)
|
||||
|| (area == ColorizationArea::All));
|
||||
|
|
|
@ -33,9 +33,9 @@ int main(int argc, char *argv[])
|
|||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round);
|
||||
#endif
|
||||
|
||||
QGuiApplication application(argc, argv);
|
||||
|
|
|
@ -31,9 +31,9 @@ int main(int argc, char *argv[])
|
|||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round);
|
||||
#endif
|
||||
|
||||
QApplication application(argc, argv);
|
||||
|
|
|
@ -137,9 +137,6 @@ void Widget::paintEvent(QPaintEvent *event)
|
|||
{
|
||||
QWidget::paintEvent(event);
|
||||
if (!isMaximized() && !isFullScreen()) {
|
||||
QPainter painter(this);
|
||||
painter.save();
|
||||
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
|
||||
const auto w = static_cast<qreal>(width());
|
||||
const auto h = static_cast<qreal>(height());
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
|
@ -158,6 +155,9 @@ void Widget::paintEvent(QPaintEvent *event)
|
|||
|| (area == ColorizationArea::All));
|
||||
const QColor borderColor = (isActiveWindow() ? (colorizedBorder ? Utilities::getColorizationColor() : Qt::black) : Qt::darkGray);
|
||||
const auto borderThickness = static_cast<qreal>(Utilities::getWindowVisibleFrameBorderThickness(winId()));
|
||||
QPainter painter(this);
|
||||
painter.save();
|
||||
painter.setRenderHint(QPainter::Antialiasing, false);
|
||||
painter.setPen({borderColor, borderThickness});
|
||||
painter.drawLines(lines);
|
||||
painter.restore();
|
||||
|
|
10
lib.pro
10
lib.pro
|
@ -1,7 +1,7 @@
|
|||
TARGET = $$qtLibraryTarget(FramelessHelper)
|
||||
TEMPLATE = lib
|
||||
win32: DLLDESTDIR = $$OUT_PWD/bin
|
||||
else: unix: DESTDIR = $$OUT_PWD/bin
|
||||
else: DESTDIR = $$OUT_PWD/bin
|
||||
QT += core-private gui-private
|
||||
CONFIG += c++17 strict_c++ utf8_source warn_on
|
||||
DEFINES += \
|
||||
|
@ -28,10 +28,14 @@ qtHaveModule(quick) {
|
|||
win32 {
|
||||
HEADERS += \
|
||||
framelesshelper_windows.h \
|
||||
framelesshelper_win32.h
|
||||
framelesshelper_win32.h \
|
||||
qwinregistry_p.h
|
||||
SOURCES += \
|
||||
utilities_win32.cpp \
|
||||
framelesshelper_win32.cpp
|
||||
framelesshelper_win32.cpp \
|
||||
qwinregistry.cpp
|
||||
LIBS += -luser32 -lshell32
|
||||
RC_FILE = framelesshelper.rc
|
||||
}
|
||||
linux*: SOURCES += utilities_linux.cpp
|
||||
macx: SOURCES += utilities_macos.mm
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qwinregistry_p.h"
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
|
||||
|
||||
#include <QtCore/qvarlengtharray.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QWinRegistryKey::QWinRegistryKey() :
|
||||
m_key(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
// Open a key with the specified permissions (KEY_READ/KEY_WRITE).
|
||||
// "access" is to explicitly use the 32- or 64-bit branch.
|
||||
QWinRegistryKey::QWinRegistryKey(HKEY parentHandle, QStringView subKey,
|
||||
REGSAM permissions, REGSAM access)
|
||||
{
|
||||
if (RegOpenKeyEx(parentHandle, reinterpret_cast<const wchar_t *>(subKey.utf16()),
|
||||
0, permissions | access, &m_key) != ERROR_SUCCESS) {
|
||||
m_key = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QWinRegistryKey::~QWinRegistryKey()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void QWinRegistryKey::close()
|
||||
{
|
||||
if (isValid()) {
|
||||
RegCloseKey(m_key);
|
||||
m_key = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QString QWinRegistryKey::stringValue(QStringView subKey) const
|
||||
{
|
||||
QString result;
|
||||
if (!isValid())
|
||||
return result;
|
||||
DWORD type;
|
||||
DWORD size;
|
||||
auto subKeyC = reinterpret_cast<const wchar_t *>(subKey.utf16());
|
||||
if (RegQueryValueEx(m_key, subKeyC, nullptr, &type, nullptr, &size) != ERROR_SUCCESS
|
||||
|| (type != REG_SZ && type != REG_EXPAND_SZ) || size <= 2) {
|
||||
return result;
|
||||
}
|
||||
// Reserve more for rare cases where trailing '\0' are missing in registry.
|
||||
// Rely on 0-termination since strings of size 256 padded with 0 have been
|
||||
// observed (QTBUG-84455).
|
||||
size += 2;
|
||||
QVarLengthArray<unsigned char> buffer(static_cast<int>(size));
|
||||
std::fill(buffer.data(), buffer.data() + size, 0u);
|
||||
if (RegQueryValueEx(m_key, subKeyC, nullptr, &type, buffer.data(), &size) == ERROR_SUCCESS)
|
||||
result = QString::fromWCharArray(reinterpret_cast<const wchar_t *>(buffer.constData()));
|
||||
return result;
|
||||
}
|
||||
|
||||
QPair<DWORD, bool> QWinRegistryKey::dwordValue(QStringView subKey) const
|
||||
{
|
||||
if (!isValid())
|
||||
return qMakePair(0, false);
|
||||
DWORD type;
|
||||
auto subKeyC = reinterpret_cast<const wchar_t *>(subKey.utf16());
|
||||
if (RegQueryValueEx(m_key, subKeyC, nullptr, &type, nullptr, nullptr) != ERROR_SUCCESS
|
||||
|| type != REG_DWORD) {
|
||||
return qMakePair(0, false);
|
||||
}
|
||||
DWORD value = 0;
|
||||
DWORD size = sizeof(value);
|
||||
const bool ok =
|
||||
RegQueryValueEx(m_key, subKeyC, nullptr, nullptr,
|
||||
reinterpret_cast<unsigned char *>(&value), &size) == ERROR_SUCCESS;
|
||||
return qMakePair(value, ok);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
|
@ -0,0 +1,92 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
#include <QtCore/private/qwinregistry_p.h>
|
||||
#else // QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
#include <QtCore/qpair.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qstringview.h>
|
||||
#include <QtCore/qt_windows.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QWinRegistryKey
|
||||
{
|
||||
public:
|
||||
Q_DISABLE_COPY(QWinRegistryKey)
|
||||
|
||||
QWinRegistryKey();
|
||||
explicit QWinRegistryKey(HKEY parentHandle, QStringView subKey,
|
||||
REGSAM permissions = KEY_READ, REGSAM access = 0);
|
||||
~QWinRegistryKey();
|
||||
|
||||
QWinRegistryKey(QWinRegistryKey &&other) noexcept
|
||||
: m_key(qExchange(other.m_key, nullptr)) {}
|
||||
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QWinRegistryKey)
|
||||
void swap(QWinRegistryKey &other) noexcept { qSwap(m_key, other.m_key); }
|
||||
|
||||
bool isValid() const { return m_key != nullptr; }
|
||||
operator HKEY() const { return m_key; }
|
||||
void close();
|
||||
|
||||
QString stringValue(QStringView subKey) const;
|
||||
QPair<DWORD, bool> dwordValue(QStringView subKey) const;
|
||||
|
||||
private:
|
||||
HKEY m_key;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#include "utilities.h"
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/private/qwinregistry_p.h>
|
||||
#include <QtCore/private/qsystemlibrary_p.h>
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
|
||||
#include <QtCore/qoperatingsystemversion.h>
|
||||
|
@ -38,6 +37,7 @@
|
|||
#else
|
||||
#include <QtGui/qpa/qplatformwindow_p.h>
|
||||
#endif
|
||||
#include "qwinregistry_p.h"
|
||||
#include "framelesshelper_windows.h"
|
||||
|
||||
Q_DECLARE_METATYPE(QMargins)
|
||||
|
@ -319,22 +319,22 @@ QString Utilities::getSystemErrorMessage(const QString &function)
|
|||
|
||||
QColor Utilities::getColorizationColor()
|
||||
{
|
||||
const auto resultFromRegistry = []() -> QColor {
|
||||
QWinRegistryKey registry(HKEY_CURRENT_USER, QString::fromUtf8(kDwmRegistryKey));
|
||||
const auto result = registry.dwordValue(QStringLiteral("ColorizationColor"));
|
||||
return (result.second ? QColor::fromRgba(result.first) : Qt::darkGray);
|
||||
};
|
||||
static const auto pDwmGetColorizationColor =
|
||||
reinterpret_cast<HRESULT(WINAPI *)(DWORD *, BOOL *)>(QSystemLibrary::resolve(QStringLiteral("dwmapi"), "DwmGetColorizationColor"));
|
||||
if (!pDwmGetColorizationColor) {
|
||||
return Qt::darkGray;
|
||||
return resultFromRegistry();
|
||||
}
|
||||
DWORD color = 0;
|
||||
BOOL opaque = FALSE;
|
||||
const HRESULT hr = pDwmGetColorizationColor(&color, &opaque);
|
||||
if (FAILED(hr)) {
|
||||
qWarning() << __getSystemErrorMessage(QStringLiteral("DwmGetColorizationColor"), hr);
|
||||
QWinRegistryKey registry(HKEY_CURRENT_USER, QString::fromUtf8(kDwmRegistryKey));
|
||||
const auto result = registry.dwordValue(QStringLiteral("ColorizationColor"));
|
||||
if (!result.second) {
|
||||
return Qt::darkGray;
|
||||
}
|
||||
return QColor::fromRgba(result.first);
|
||||
return resultFromRegistry();
|
||||
}
|
||||
return QColor::fromRgba(color);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue