|
|
|
|
Quelle 0001-Satisfy-Windows-7-compatibility.patch Sprache: unbekannt
|
|
Spracherkennung für: .patch vermutete Sprache: MT940 {MT940[52] VDM[45] ADA[30]} [Methode: maximale Elemente, drei Dimensionen]
From f59945015c99cb02260553676c036c90ba48ea05 Mon Sep 17 00: 00: 00 2001
From: Fatih Uzunoglu <fuzun54@outlook.com>
Date: Mon, 22 Jan 2024 21: 37: 39 + 0200
Subject: [PATCH] Satisfy Windows 7 compatibility
---
cmake/QtBaseConfigureTests.cmake | 10 + -
src/corelib/CMakeLists.txt | 22 ++ --
src/corelib/global/qt_windows.h | 6 + -
src/corelib/io/qfilesystemengine_win.cpp | 5 +
src/corelib/kernel/qeventdispatcher_win.cpp | 10 + -
src/corelib/kernel/qfunctions_win.cpp | 13 + -
src/corelib/thread/qfutex_win_p.h | 42 +++++ -
src/corelib/thread/qmutex.cpp | 4 + -
src/corelib/thread/qmutex_p.h | 2 +
src/corelib/thread/qmutex_win.cpp | 30 +++++
src/corelib/thread/qthread_win.cpp | 25 ++ --
src/gui/CMakeLists.txt | 1 -
src/gui/rhi/qrhid3d11.cpp | 5 + -
src/gui/rhi/qrhid3d12.cpp | 87 ++++++++++ ---
.../text/windows/qwindowsfontdatabasebase.cpp | 14 + -
.../networklistmanager/CMakeLists.txt | 1 -
src/plugins/platforms/direct2d/CMakeLists.txt | 2 -
.../direct2d/qwindowsdirect2dcontext.cpp | 1 +
src/plugins/platforms/windows/CMakeLists.txt | 2 -
.../platforms/windows/qtwindowsglobal.h | 4 +
.../platforms/windows/qwin10helpers.cpp | 24 +++ -
.../platforms/windows/qwindowscontext.cpp | 120 +++++++++++++++ ---
.../platforms/windows/qwindowscontext.h | 95 ++++++++++++++
.../platforms/windows/qwindowsdrag.cpp | 10 + -
.../platforms/windows/qwindowskeymapper.cpp | 17 ++ -
.../windows/qwindowspointerhandler.cpp | 33 +++ --
.../platforms/windows/qwindowsscreen.cpp | 18 ++ -
.../platforms/windows/qwindowstheme.cpp | 6 + -
.../platforms/windows/qwindowswindow.cpp | 48 +++++ --
src/widgets/styles/qwindowsstyle.cpp | 26 +++ -
30 files changed, 570 insertions(+), 113 deletions( -)
create mode 100644 src/corelib/thread/qmutex_win.cpp
diff --git a/cmake/QtBaseConfigureTests.cmake b/cmake/QtBaseConfigureTests.cmake
index d41fac2e18e.. 9490de8fa12 100644
--- a/cmake/QtBaseConfigureTests.cmake
+++ b/cmake/QtBaseConfigureTests.cmake
@@ -163,16 +163,16 @@ function(qt_internal_ensure_latest_win_nt_api)
#if !defined(_WIN32_WINNT) && !defined(WINVER)
#error "_WIN32_WINNT and WINVER are not defined"
#endif
- #if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0A00)
+ #if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0601)
#error "_WIN32_WINNT version too low"
#endif
- #if defined(WINVER) && (WINVER < 0x0A00)
+ #if defined(WINVER) && (WINVER < 0x0601)
#error "WINVER version too low"
#endif
int main() { return 0; }
- ]=] HAVE_WIN10_WIN32_WINNT)
- if(NOT HAVE_WIN10_WIN32_WINNT)
- list(APPEND QT_PLATFORM_DEFINITIONS _WIN32_WINNT=0x0A00 WINVER=0x0A00)
+ ]=] HAVE_WIN7_WIN32_WINNT)
+ if(NOT HAVE_WIN7_WIN32_WINNT)
+ list(APPEND QT_PLATFORM_DEFINITIONS _WIN32_WINNT= 0x0601 WINVER= 0x0601)
set(QT_PLATFORM_DEFINITIONS ${QT_PLATFORM_DEFINITIONS}
CACHE STRING "Qt platform specific pre-processor defines" FORCE)
endif()
diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt
index b6be7a8d49d..db57eed2b05 100644
--- a/src/corelib/CMakeLists.txt
+++ b/src/corelib/CMakeLists.txt
@@ -538,16 +538,17 @@ qt_internal_extend_target(Core CONDITION QT_FEATURE_animation
animation/qvariantanimation.cpp animation/qvariantanimation.h animation/qvariantan imation_p.h
)
-# This needs to be done before one below adds kernel32 because the symbols we use
-# from synchronization also appears in kernel32 in the version of MinGW we use in CI.
-# However, when picking the symbols from libkernel32.a it will try to load the symbols
-# from the wrong DLL at runtime and crash!
+# Do not include synchronization, because
+# MinGW redirects it to api-ms-win-core-synch-l1-2-0.a
+# Which seems to be available on Windows 7 (for some reason)
+# but is broken. Use the symbols from kernel32 instead.
qt_internal_extend_target(Core CONDITION QT_FEATURE_thread AND WIN32
SOURCES
thread/qfutex_win_p.h
+ thread/qmutex_win.cpp
thread/qwaitcondition_win.cpp
- LIBRARIES
- synchronization
+ # LIBRARIES
+ # synchronization
)
qt_internal_extend_target(Core CONDITION WIN32
@@ -866,10 +867,10 @@ qt_internal_extend_target(Core CONDITION WASM
)
# On MS-Win, clang has two flavors, one of which immitates MSVC (so claims to be it)
-qt_internal_extend_target(Core CONDITION MSVC
- LIBRARIES
- runtimeobject
-)
+# qt_internal_extend_target(Core CONDITION MSVC
+# LIBRARIES
+# runtimeobject
+# )
qt_internal_extend_target(Core CONDITION QT_FEATURE_icu
SOURCES
@@ -1426,6 +1427,7 @@ qt_internal_extend_target(Core CONDITION QT_FEATURE_ctf
set_source_files_properties(
thread/qmutex_mac.cpp
thread/qmutex_unix.cpp
+ thread/qmutex_win.cpp
PROPERTIES HEADER_FILE_ONLY ON)
# Remove QT_NO_CAST_TO_ASCII to ensure that the symbols are included in the library.
diff --git a/src/corelib/global/qt_windows.h b/src/corelib/global/qt_windows.h
index 5586d0b9272..eb0264b4ee2 100644
--- a/src/corelib/global/qt_windows.h
+++ b/src/corelib/global/qt_windows.h
@@ -10,16 +10,16 @@
#endif
#ifndef WINVER
-# define WINVER 0x0A00 // _WIN32_WINNT_WIN10
+# define WINVER 0x0601
#endif
#ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x0A00
+# define _WIN32_WINNT 0x0601
#endif
#ifndef _WIN32_IE
# define _WIN32_IE 0x0A00
#endif
#ifndef NTDDI_VERSION
-# define NTDDI_VERSION 0x0A00000C // NTDDI_WIN10_NI
+# define NTDDI_VERSION 0x06010000
#endif
#ifndef NOMINMAX
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 8300c3b5eea..8795463a74e 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -1,6 +1,11 @@
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0602)
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0602 // Windows 8, to access FILE_ID_INFO
+#endif
+
#include "qfilesystemengine_p.h"
#include "qoperatingsystemversion.h"
#include "qplatformdefs.h"
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index a7663b24813..78ad3d3edeb 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -362,7 +362,15 @@ void QEventDispatcherWin32Private::registerTimer(WinTimerInfo *t)
if (!ok) {
// user normal timers for (Very)CoarseTimers, or if no more multimedia timers available
- ok = SetCoalescableTimer(internalHwnd, t->timerId, interval, nullptr, tolerance);
+
+ typedef UINT_PTR (*SetCoalescableTimerCompat)(HWND, UINT_PTR, UINT, TIMERPROC, ULONG);
+ static SetCoalescableTimerCompat setCoalescableTimer = []() {
+ QSystemLibrary user32dll(QLatin1String("user32"));
+ return (SetCoalescableTimerCompat)(user32dll.resolve("SetCoalescableTimer"));
+ }();
+
+ if (setCoalescableTimer)
+ ok = setCoalescableTimer(internalHwnd, t->timerId, interval, nullptr, tolerance);
}
if (!ok)
ok = SetTimer(internalHwnd, t->timerId, interval, nullptr);
diff --git a/src/corelib/kernel/qfunctions_win.cpp b/src/corelib/kernel/qfunctions_win.cpp
index 048fdbc934c..c1761868888 100644
--- a/src/corelib/kernel/qfunctions_win.cpp
+++ b/src/corelib/kernel/qfunctions_win.cpp
@@ -4,6 +4,7 @@
#include "qfunctions_win_p.h"
#include <QtCore/qdebug.h>
+#include <QtCore/private/qsystemlibrary_p.h>
#include <combaseapi.h>
#include <objbase.h>
@@ -47,7 +48,17 @@ bool qt_win_hasPackageIdentity()
#if defined(HAS_APPMODEL)
static const bool hasPackageIdentity = []() {
UINT32 length = 0;
- switch (const auto result = GetCurrentPackageFullName(&length, nullptr)) {
+
+ typedef LONG (*GetCurrentPackageFullNameCompat)(UINT32*, PWSTR);
+ static GetCurrentPackageFullNameCompat getCurrentPackageFullName = []() {
+ QSystemLibrary kernel32dll(QLatin1String("kernel32"));
+ return (GetCurrentPackageFullNameCompat)(kernel32dll.resolve("GetCurrentPackageFullName"));
+ }();
+
+ if (!getCurrentPackageFullName)
+ return false;
+
+ switch (const auto result = getCurrentPackageFullName(&length, nullptr)) {
case ERROR_INSUFFICIENT_BUFFER:
return true;
case APPMODEL_ERROR_NO_PACKAGE:
diff --git a/src/corelib/thread/qfutex_win_p.h b/src/corelib/thread/qfutex_win_p.h
index 75a12bd82c1..3d2aa021db6 100644
--- a/src/corelib/thread/qfutex_win_p.h
+++ b/src/corelib/thread/qfutex_win_p.h
@@ -18,37 +18,65 @@
#include <private/qglobal_p.h>
#include <qdeadlinetimer.h>
#include <qtsan_impl.h>
+#include <QtCore/private/qsystemlibrary_p.h>
#include <qt_windows.h>
-#define QT_ALWAYS_USE_FUTEX
-
QT_BEGIN_NAMESPACE
namespace QtWindowsFutex {
-constexpr inline bool futexAvailable() { return true; }
+typedef BOOL(*WaitOnAddressCompat)( _In_ volatile VOID *Address, _In_ PVOID CompareAddress, _In_ SIZE_T AddressSize, _In_ DWORD dwMilliseconds);
+typedef void(*WakeByAddressAllCompat)(_In_ PVOID Address);
+typedef void(*WakeByAddressSingleCompat)(_In_ PVOID Address);
+
+struct FutexFuncs {
+ WaitOnAddressCompat waitOnAddress = nullptr;
+ WakeByAddressAllCompat wakeByAddressAll = nullptr;
+ WakeByAddressSingleCompat wakeByAddressSingle = nullptr;
+};
+
+inline const FutexFuncs futexFuncs = []() {
+ FutexFuncs funcs;
+
+ QSystemLibrary synchWin8ApiSet(QLatin1String("api-ms-win-core-synch-l1-2-0"));
+
+ funcs.waitOnAddress = (WaitOnAddressCompat)(synchWin8ApiSet.resolve("WaitOnAddress"));
+ funcs.wakeByAddressAll = (WakeByAddressAllCompat)(synchWin8ApiSet.resolve("WakeByAddressAll"));
+ funcs.wakeByAddressSingle = (WakeByAddressSingleCompat)(synchWin8ApiSet.resolve("WakeByAddressSingle"));
+
+ return funcs;
+}();
+
+inline bool futexAvailable()
+{
+ return (futexFuncs.waitOnAddress && futexFuncs.wakeByAddressAll && futexFuncs.wakeByAddressSingle);
+}
template <typename Atomic>
inline void futexWait(Atomic &futex, typename Atomic::Type expectedValue)
{
+ assert(futexFuncs.waitOnAddress);
QtTsan::futexRelease(&futex);
- WaitOnAddress(&futex, &expectedValue, sizeof(expectedValue), INFINITE);
+ futexFuncs.waitOnAddress(&futex, &expectedValue, sizeof(expectedValue), INFINITE);
QtTsan::futexAcquire(&futex);
}
template <typename Atomic>
inline bool futexWait(Atomic &futex, typename Atomic::Type expectedValue, QDeadlineTimer deadline)
{
+ assert(futexFuncs.waitOnAddress);
using namespace std::chrono;
- BOOL r = WaitOnAddress(&futex, &expectedValue, sizeof(expectedValue), DWORD(deadline.remainingTime()));
+ BOOL r = futexFuncs.waitOnAddress(&futex, &expectedValue, sizeof(expectedValue), DWORD(deadline.remainingTime()));
return r || GetLastError() != ERROR_TIMEOUT;
}
template <typename Atomic> inline void futexWakeAll(Atomic &futex)
{
- WakeByAddressAll(&futex);
+ assert(futexFuncs.wakeByAddressAll);
+ futexFuncs.wakeByAddressAll(&futex);
}
template <typename Atomic> inline void futexWakeOne(Atomic &futex)
{
- WakeByAddressSingle(&futex);
+ assert(futexFuncs.wakeByAddressSingle);
+ futexFuncs.wakeByAddressSingle(&futex);
}
} // namespace QtWindowsFutex
namespace QtFutex = QtWindowsFutex;
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index 1b8f76f1230..0659d4dc068 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -911,10 +911,12 @@ void QMutexPrivate::derefWaiters(int value) noexcept
QT_END_NAMESPACE
-#if defined(QT_ALWAYS_USE_FUTEX)
+#if defined(Q_OS_LINUX) && defined(QT_ALWAYS_USE_FUTEX)
// nothing
#elif defined(Q_OS_DARWIN)
# include "qmutex_mac.cpp"
+#elif defined(Q_OS_WIN)
+# include "qmutex_win.cpp"
#else
# include "qmutex_unix.cpp"
#endif
diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h
index aabb66fa550..a16d5082154 100644
--- a/src/corelib/thread/qmutex_p.h
+++ b/src/corelib/thread/qmutex_p.h
@@ -86,6 +86,8 @@ public:
semaphore_t mach_semaphore;
#elif defined(Q_OS_UNIX)
sem_t semaphore;
+#elif defined(Q_OS_WIN)
+ Qt::HANDLE event;
#endif
};
diff --git a/src/corelib/thread/qmutex_win.cpp b/src/corelib/thread/qmutex_win.cpp
new file mode 100644
index 00000000000..ce3586a90b7
--- /dev/null
+++ b/src/corelib/thread/qmutex_win.cpp
@@ -0,0 +1,30 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qmutex.h"
+#include <qatomic.h>
+#include "qmutex_p.h"
+#include <qt_windows.h>
+
+QT_BEGIN_NAMESPACE
+
+QMutexPrivate::QMutexPrivate()
+{
+ event = CreateEvent(0, FALSE, FALSE, 0);
+
+ if (!event)
+ qWarning("QMutexPrivate::QMutexPrivate: Cannot create event");
+}
+
+QMutexPrivate::~QMutexPrivate()
+{ CloseHandle(event); }
+
+bool QMutexPrivate::wait(QDeadlineTimer timeout)
+{
+ return (WaitForSingleObjectEx(event, timeout.isForever() ? INFINITE : timeout.remainingTime(), FALSE) == WAIT_OBJECT_0);
+}
+
+void QMutexPrivate::wakeUp() noexcept
+{ SetEvent(event); }
+
+QT_END_NAMESPACE
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index 88ba6dc8f62..2d17f1b4dee 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -11,6 +11,7 @@
#include <private/qcoreapplication_p.h>
#include <private/qeventdispatcher_win_p.h>
+#include <private/qsystemlibrary_p.h>
#include "qloggingcategory.h"
#include <qt_windows.h>
@@ -20,17 +21,6 @@
#endif // _MT
#include <process.h>
-extern "C" {
-// MinGW is missing the declaration of SetThreadDescription:
-WINBASEAPI
-HRESULT
-WINAPI
-SetThreadDescription(
- _In_ HANDLE hThread,
- _In_ PCWSTR lpThreadDescription
- );
-}
-
QT_BEGIN_NAMESPACE
#if QT_CONFIG(thread)
@@ -264,7 +254,18 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
QString threadName = std::exchange(thr->d_func()->objectName, {});
if (Q_LIKELY(threadName.isEmpty()))
threadName = QString::fromUtf8(thr->metaObject()->className());
- SetThreadDescription(GetCurrentThread(), reinterpret_cast<const wchar_t *>(threadName.utf16()));
+
+ {
+ typedef HRESULT (*SetThreadDescriptionFunc)(HANDLE, PCWSTR);
+
+ static SetThreadDescriptionFunc setThreadDescription = []() {
+ QSystemLibrary kernel32(QLatin1String("kernel32"));
+ return (SetThreadDescriptionFunc)(kernel32.resolve("SetThreadDescription"));
+ }();
+
+ if (setThreadDescription)
+ setThreadDescription(GetCurrentThread(), reinterpret_cast<const wchar_t *>(threadName.utf16()));
+ }
emit thr->started(QThread::QPrivateSignal());
QThread::setTerminationEnabled(true);
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index 2cc72625131..16c8086decc 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -479,7 +479,6 @@ qt_internal_extend_target(Gui CONDITION WIN32
d3d11
dxgi
dxguid
- d3d12
ATTRIBUTION_FILE_DIR_PATHS
../3rdparty/D3D12MemoryAllocator
)
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index 9e2e0c4e81c..9a0b5721abc 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -8,6 +8,7 @@
#include <qmath.h>
#include <QtCore/qcryptographichash.h>
#include <QtCore/private/qsystemerror_p.h>
+#include <QtCore/private/qsystemlibrary_p.h>
#include "qrhid3dhelpers_p.h"
#include <cstdio>
@@ -185,9 +186,9 @@ inline Int aligned(Int v, Int byteAlign)
static IDXGIFactory1 *createDXGIFactory2()
{
IDXGIFactory1 *result = nullptr;
- const HRESULT hr = CreateDXGIFactory2(0, __uuidof(IDXGIFactory2), reinterpret_cast<void **>(&result));
+ const HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory2), reinterpret_cast<void **>(&result));
if (FAILED(hr)) {
- qWarning("CreateDXGIFactory2() failed to create DXGI factory: %s",
+ qWarning("CreateDXGIFactory1() failed to create DXGI factory: %s",
qPrintable(QSystemError::windowsComString(hr)));
result = nullptr;
}
diff --git a/src/gui/rhi/qrhid3d12.cpp b/src/gui/rhi/qrhid3d12.cpp
index f663c006346..2e8578d055d 100644
--- a/src/gui/rhi/qrhid3d12.cpp
+++ b/src/gui/rhi/qrhid3d12.cpp
@@ -5,6 +5,7 @@
#include "D3D12MemAlloc.h"
#include <qmath.h>
#include <QtCore/private/qsystemerror_p.h>
+#include <QtCore/private/qsystemlibrary_p.h>
#include <comdef.h>
#include "qrhid3dhelpers_p.h"
#include "cs_mipmap_p.h"
@@ -150,6 +151,17 @@ QT_BEGIN_NAMESPACE
\variable QRhiD3D12CommandBufferNativeHandles::commandList
*/
+typedef HRESULT (*D3D12SerializeVersionedRootSignatureFunc)(
+ const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *pRootSignature,
+ ID3DBlob **ppBlob,
+ ID3DBlob **ppErrorBlob
+);
+
+static const D3D12SerializeVersionedRootSignatureFunc d3D12SerializeVersionedRootSignature = []() {
+ QSystemLibrary d3d12lib(QStringLiteral("d3d12"));
+ return reinterpret_cast<D3D12SerializeVersionedRootSignatureFunc>(d3d12lib.resolve("D3D12SerializeVersionedRootSignature"));
+}();
+
// https://learn.microsoft.com/en-us/windows/win32/direct3d12/hardware-feature-levels
static const D3D_FEATURE_LEVEL MIN_FEATURE_LEVEL = D3D_FEATURE_LEVEL_11_0;
@@ -219,20 +231,30 @@ bool QRhiD3D12::create(QRhi::Flags flags)
UINT factoryFlags = 0;
if (debugLayer)
factoryFlags |= DXGI_CREATE_FACTORY_DEBUG;
- HRESULT hr = CreateDXGIFactory2(factoryFlags, __uuidof(IDXGIFactory2), reinterpret_cast<void **>(&dxgiFactory));
- if (FAILED(hr)) {
- // retry without debug, if it was requested (to match D3D11 backend behavior)
- if (debugLayer) {
+
+ HRESULT hr = E_FAIL;
+
+ if (debugLayer) {
+ typedef HRESULT (*CreateDXGIFactory2FuncPtr)(UINT Flags, REFIID riid, void **ppFactory);
+ CreateDXGIFactory2FuncPtr createDXGIFactory2 = nullptr;
+ QSystemLibrary dxgilib(QLatin1String("dxgi"));
+ createDXGIFactory2 = reinterpret_cast<CreateDXGIFactory2FuncPtr>(dxgilib.resolve("CreateDXGIFactory2"));
+ if (createDXGIFactory2) {
+ hr = createDXGIFactory2(factoryFlags, __uuidof(IDXGIFactory2), reinterpret_cast<void **>(&dxgiFactory));
+ }
+
+ if (FAILED(hr)) {
qCDebug(QRHI_LOG_INFO, "Debug layer was requested but is not available. "
"Attempting to create DXGIFactory2 without it.");
- factoryFlags &= ~DXGI_CREATE_FACTORY_DEBUG;
- hr = CreateDXGIFactory2(factoryFlags, __uuidof(IDXGIFactory2), reinterpret_cast<void **>(&dxgiFactory));
- }
- if (SUCCEEDED(hr)) {
debugLayer = false;
- } else {
- qWarning("CreateDXGIFactory2() failed to create DXGI factory: %s",
- qPrintable(QSystemError::windowsComString(hr)));
+ }
+ }
+
+ if (!debugLayer) {
+ hr = CreateDXGIFactory1(__uuidof(IDXGIFactory2), reinterpret_cast<void **>(&dxgiFactory));
+ if (FAILED(hr)) {
+ qWarning("CreateDXGIFactory1() failed to create DXGI factory: %s",
+ qPrintable(QSystemError::windowsComString(hr)));
return false;
}
}
@@ -253,7 +275,18 @@ bool QRhiD3D12::create(QRhi::Flags flags)
if (debugLayer) {
ID3D12Debug1 *debug = nullptr;
- if (SUCCEEDED(D3D12GetDebugInterface(__uuidof(ID3D12Debug1), reinterpret_cast<void **>(&debug)))) {
+
+ QSystemLibrary d3d12lib(QStringLiteral("d3d12"));
+
+ typedef HRESULT (*D3D12GetDebugInterfaceFunc)(
+ REFIID riid,
+ void **ppvDebug
+ );
+ static const auto d3D12GetDebugInterface = reinterpret_cast<D3D12GetDebugInterfaceFunc>(d3d12lib.resolve("D3D12GetDebugInterface"));
+
+ if (!d3D12GetDebugInterface) {
+ qWarning("Can not enable D3D12 debug layer. Symbol D3D12GetDebugInterface is missing, is D3D12 installed properly?");
+ } else if (SUCCEEDED(d3D12GetDebugInterface(__uuidof(ID3D12Debug1), reinterpret_cast<void **>(&debug)))) {
qCDebug(QRHI_LOG_INFO, "Enabling D3D12 debug layer");
debug->EnableDebugLayer();
debug->Release();
@@ -321,7 +354,22 @@ bool QRhiD3D12::create(QRhi::Flags flags)
if (minimumFeatureLevel == 0)
minimumFeatureLevel = MIN_FEATURE_LEVEL;
- hr = D3D12CreateDevice(activeAdapter,
+ QSystemLibrary d3d12lib(QStringLiteral("d3d12"));
+ typedef HRESULT (*D3D12CreateDeviceFunc)(
+ IUnknown *pAdapter,
+ D3D_FEATURE_LEVEL MinimumFeatureLevel,
+ REFIID riid,
+ void **ppDevice
+ );
+ D3D12CreateDeviceFunc d3D12CreateDevice = reinterpret_cast<D3D12CreateDeviceFunc>(d3d12lib.resolve("D3D12CreateDevice"));
+
+ if (!d3D12CreateDevice) {
+ qWarning("Symbol D3D12CreateDevice could not be resolved, RhiD3D12 will not be available. Is DirectX 12 installed?");
+ return false;
+ }
+
+
+ hr = d3D12CreateDevice(activeAdapter,
minimumFeatureLevel,
__uuidof(ID3D12Device2),
reinterpret_cast<void **>(&dev));
@@ -2819,7 +2867,12 @@ bool QD3D12MipmapGenerator::create(QRhiD3D12 *rhiD)
rsDesc.Desc_1_1.pStaticSamplers = &samplerDesc;
ID3DBlob *signature = nullptr;
- HRESULT hr = D3D12SerializeVersionedRootSignature(&rsDesc, &signature, nullptr);
+ if (!d3D12SerializeVersionedRootSignature) {
+ qWarning("Could not resolve D3D12SerializeVersionedRootSignature. Is D3D12 properly installed?");
+ return false;
+ }
+
+ HRESULT hr = d3D12SerializeVersionedRootSignature(&rsDesc, &signature, nullptr);
if (FAILED(hr)) {
qWarning("Failed to serialize root signature: %s", qPrintable(QSystemError::windowsComString(hr)));
return false;
@@ -5096,7 +5149,11 @@ QD3D12ObjectHandle QD3D12ShaderResourceBindings::createRootSignature(const QD3D1
rsDesc.Desc_1_1.Flags = D3D12_ROOT_SIGNATURE_FLAGS(rsFlags);
ID3DBlob *signature = nullptr;
- HRESULT hr = D3D12SerializeVersionedRootSignature(&rsDesc, &signature, nullptr);
+ if (!d3D12SerializeVersionedRootSignature) {
+ qWarning("Could not resolve D3D12SerializeVersionedRootSignature. Is D3D12 properly installed?");
+ return {};
+ }
+ HRESULT hr = d3D12SerializeVersionedRootSignature(&rsDesc, &signature, nullptr);
if (FAILED(hr)) {
qWarning("Failed to serialize root signature: %s", qPrintable(QSystemError::windowsComString(hr)));
return {};
diff --git a/src/gui/text/windows/qwindowsfontdatabasebase.cpp b/src/gui/text/windows/qwindowsfontdatabasebase.cpp
index 84e619b0d93..58af4939252 100644
--- a/src/gui/text/windows/qwindowsfontdatabasebase.cpp
+++ b/src/gui/text/windows/qwindowsfontdatabasebase.cpp
@@ -6,6 +6,7 @@
#include <QtCore/QThreadStorage>
#include <QtCore/QtEndian>
+#include <QtCore/private/qsystemlibrary_p.h>
#if QT_CONFIG(directwrite)
# if QT_CONFIG(directwrite3)
@@ -715,7 +716,18 @@ QFont QWindowsFontDatabaseBase::systemDefaultFont()
// Qt 6: Obtain default GUI font (typically "Segoe UI, 9pt", see QTBUG-58610)
NONCLIENTMETRICS ncm = {};
ncm.cbSize = sizeof(ncm);
- SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0, defaultVerticalDPI());
+
+ typedef BOOL (*SystemParametersInfoForDpiCompat)(UINT, UINT, PVOID, UINT, UINT);
+ static SystemParametersInfoForDpiCompat systemParametersInfoForDpi = []() {
+ QSystemLibrary user32dll(QLatin1String("user32"));
+ return (SystemParametersInfoForDpiCompat)(user32dll.resolve("SystemParametersInfoForDpi"));
+ }();
+
+ if (systemParametersInfoForDpi)
+ systemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0, defaultVerticalDPI());
+ else
+ SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);
+
const QFont systemFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMessageFont);
qCDebug(lcQpaFonts) << __FUNCTION__ << systemFont;
return systemFont;
diff --git a/src/plugins/networkinformation/networklistmanager/CMakeLists.txt b/src/plugins/networkinformation/networklistmanager/CMakeLists.txt
index acd3754f4e5..3c80ad3e1a2 100644
--- a/src/plugins/networkinformation/networklistmanager/CMakeLists.txt
+++ b/src/plugins/networkinformation/networklistmanager/CMakeLists.txt
@@ -16,7 +16,6 @@ qt_internal_add_plugin(QNLMNIPlugin
qt_internal_extend_target(QNLMNIPlugin CONDITION WIN32
LIBRARIES
- runtimeobject
oleaut32
)
diff --git a/src/plugins/platforms/direct2d/CMakeLists.txt b/src/plugins/platforms/direct2d/CMakeLists.txt
index 278af74af0b..e2f1969a321 100644
--- a/src/plugins/platforms/direct2d/CMakeLists.txt
+++ b/src/plugins/platforms/direct2d/CMakeLists.txt
@@ -75,10 +75,8 @@ qt_internal_add_plugin(QWindowsDirect2DIntegrationPlugin
winmm
winspool
wtsapi32
- shcore
comdlg32
d3d9
- runtimeobject
)
# Resources:
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
index 307ca2e550d..8f1199e2291 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtCore/qt_windows.h>
+#include <QtCore/private/qsystemlibrary_p.h>
#include "qwindowsdirect2dcontext.h"
#include "qwindowsdirect2dhelpers.h"
#include "qwindowsdirect2dintegration.h"
diff --git a/src/plugins/platforms/windows/CMakeLists.txt b/src/plugins/platforms/windows/CMakeLists.txt
index cc4460cb182..fb725ea6061 100644
--- a/src/plugins/platforms/windows/CMakeLists.txt
+++ b/src/plugins/platforms/windows/CMakeLists.txt
@@ -62,10 +62,8 @@ qt_internal_add_plugin(QWindowsIntegrationPlugin
winmm
winspool
wtsapi32
- shcore
comdlg32
d3d9
- runtimeobject
)
# Resources:
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index 96a72600eb9..067069d8de0 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -60,6 +60,10 @@
# define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ((HANDLE)-5)
#endif
+#ifndef WM_DPICHANGED_AFTERPARENT
+#define WM_DPICHANGED_AFTERPARENT 0x02E3
+#endif
+
QT_BEGIN_NAMESPACE
namespace QtWindows
diff --git a/src/plugins/platforms/windows/qwin10helpers.cpp b/src/plugins/platforms/windows/qwin10helpers.cpp
index 026e81cb0c7..78c9bf2ea04 100644
--- a/src/plugins/platforms/windows/qwin10helpers.cpp
+++ b/src/plugins/platforms/windows/qwin10helpers.cpp
@@ -4,6 +4,7 @@
#include "qwin10helpers.h"
#include <QtCore/qdebug.h>
+#include <QtCore/private/qsystemlibrary_p.h>
#include <winstring.h>
#include <roapi.h>
@@ -69,14 +70,33 @@ bool qt_windowsIsTabletMode(HWND hwnd)
HSTRING_HEADER uiViewSettingsIdRefHeader;
HSTRING uiViewSettingsIdHs = nullptr;
const auto uiViewSettingsIdLen = UINT32(sizeof(uiViewSettingsId) / sizeof(uiViewSettingsId[0]) - 1);
- if (FAILED(WindowsCreateStringReference(uiViewSettingsId, uiViewSettingsIdLen, &uiViewSettingsIdRefHeader, &uiViewSettingsIdHs)))
+
+ typedef HRESULT (*WindowsCreateStringReferenceCompat)(PCWSTR, UINT32, HSTRING_HEADER*, HSTRING*);
+ static WindowsCreateStringReferenceCompat windowsCreateStringReference = []() {
+ QSystemLibrary winrtstringapisetdll(QLatin1String("api-ms-win-core-winrt-string-l1-1-0"));
+ return (WindowsCreateStringReferenceCompat)(winrtstringapisetdll.resolve("WindowsCreateStringReference"));
+ }();
+
+ if (!windowsCreateStringReference)
+ return false;
+
+ if (FAILED(windowsCreateStringReference(uiViewSettingsId, uiViewSettingsIdLen, &uiViewSettingsIdRefHeader, &uiViewSettingsIdHs)))
return false;
IUIViewSettingsInterop *uiViewSettingsInterop = nullptr;
// __uuidof(IUIViewSettingsInterop);
const GUID uiViewSettingsInteropRefId = {0x3694dbf9, 0x8f68, 0x44be,{0x8f, 0xf5, 0x19, 0x5c, 0x98, 0xed, 0xe8, 0xa6}};
- HRESULT hr = RoGetActivationFactory(uiViewSettingsIdHs, uiViewSettingsInteropRefId,
+ typedef HRESULT (*RoGetActivationFactoryCompat)(HSTRING, REFIID, void **);
+ static RoGetActivationFactoryCompat roGetActivationFactory = []() {
+ QSystemLibrary combasedll(QLatin1String("combase"));
+ return (RoGetActivationFactoryCompat)(combasedll.resolve("RoGetActivationFactory"));
+ }();
+
+ if (!roGetActivationFactory)
+ return false;
+
+ HRESULT hr = roGetActivationFactory(uiViewSettingsIdHs, uiViewSettingsInteropRefId,
reinterpret_cast<void **>(&uiViewSettingsInterop));
if (FAILED(hr))
return false;
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 88e9da5557c..82433b04fdc 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -43,6 +43,8 @@
#include <QtCore/qsysinfo.h>
#include <QtCore/qscopedpointer.h>
#include <QtCore/quuid.h>
+#include <QtCore/qoperatingsystemversion.h>
+#include <QtCore/private/qsystemlibrary_p.h>
#include <QtCore/private/qwinregistry_p.h>
#if QT_CONFIG(cpp_winrt)
# include <QtCore/private/qfactorycacheregistration_p.h>
@@ -120,6 +122,85 @@ static inline bool sessionManagerInteractionBlocked()
static inline bool sessionManagerInteractionBlocked() { return false; }
#endif
+static inline int windowDpiAwareness(HWND hwnd)
+{
+ return QWindowsContext::user32dll.getWindowDpiAwarenessContext && QWindowsContext::user32dll.getAwarenessFromDpiAwarenessContext
+ ? QWindowsContext::user32dll.getAwarenessFromDpiAwarenessContext(QWindowsContext::user32dll.getWindowDpiAwarenessContext(hwnd))
+ : -1;
+}
+
+/*!
+ \class QWindowsUser32DLL
+ \brief Struct that contains dynamically resolved symbols of User32.dll.
+ The stub libraries shipped with the MinGW compiler miss some of the
+ functions. They need to be retrieved dynamically.
+ In addition, touch-related functions are available only from Windows onwards.
+ These need to resolved dynamically for Q_CC_MSVC as well.
+ \sa QWindowsShell32DLL
+ \internal
+*/
+
+void QWindowsUser32DLL::init()
+{
+ QSystemLibrary library(QStringLiteral("user32"));
+ setProcessDPIAware = (SetProcessDPIAware)library.resolve("SetProcessDPIAware");
+ setProcessDpiAwarenessContext = (SetProcessDpiAwarenessContext)library.resolve("SetProcessDpiAwarenessContext");
+ getThreadDpiAwarenessContext = (GetThreadDpiAwarenessContext)library.resolve("GetThreadDpiAwarenessContext");
+ areDpiAwarenessContextsEqual = (AreDpiAwarenessContextsEqual)library.resolve("AreDpiAwarenessContextsEqual");
+ isValidDpiAwarenessContext = (IsValidDpiAwarenessContext)library.resolve("IsValidDpiAwarenessContext");
+
+ addClipboardFormatListener = (AddClipboardFormatListener)library.resolve("AddClipboardFormatListener");
+ removeClipboardFormatListener = (RemoveClipboardFormatListener)library.resolve("RemoveClipboardFormatListener");
+
+ getDisplayAutoRotationPreferences = (GetDisplayAutoRotationPreferences)library.resolve("GetDisplayAutoRotationPreferences");
+ setDisplayAutoRotationPreferences = (SetDisplayAutoRotationPreferences)library.resolve("SetDisplayAutoRotationPreferences");
+
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8) {
+ enableMouseInPointer = (EnableMouseInPointer)library.resolve("EnableMouseInPointer");
+ getPointerType = (GetPointerType)library.resolve("GetPointerType");
+ getPointerInfo = (GetPointerInfo)library.resolve("GetPointerInfo");
+ getPointerDeviceRects = (GetPointerDeviceRects)library.resolve("GetPointerDeviceRects");
+ getPointerTouchInfo = (GetPointerTouchInfo)library.resolve("GetPointerTouchInfo");
+ getPointerFrameTouchInfo = (GetPointerFrameTouchInfo)library.resolve("GetPointerFrameTouchInfo");
+ getPointerFrameTouchInfoHistory = (GetPointerFrameTouchInfoHistory)library.resolve("GetPointerFrameTouchInfoHistory");
+ getPointerPenInfo = (GetPointerPenInfo)library.resolve("GetPointerPenInfo");
+ getPointerPenInfoHistory = (GetPointerPenInfoHistory)library.resolve("GetPointerPenInfoHistory");
+ skipPointerFrameMessages = (SkipPointerFrameMessages)library.resolve("SkipPointerFrameMessages");
+ }
+
+ if (QOperatingSystemVersion::current()
+ >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 14393)) {
+ adjustWindowRectEx = (AdjustWindowRectEx)library.resolve("AdjustWindowRectEx");
+ adjustWindowRectExForDpi = (AdjustWindowRectExForDpi)library.resolve("AdjustWindowRectExForDpi");
+ enableNonClientDpiScaling = (EnableNonClientDpiScaling)library.resolve("EnableNonClientDpiScaling");
+ getWindowDpiAwarenessContext = (GetWindowDpiAwarenessContext)library.resolve("GetWindowDpiAwarenessContext");
+ getAwarenessFromDpiAwarenessContext = (GetAwarenessFromDpiAwarenessContext)library.resolve("GetAwarenessFromDpiAwarenessContext");
+ systemParametersInfoForDpi = (SystemParametersInfoForDpi)library.resolve("SystemParametersInfoForDpi");
+ getDpiForWindow = (GetDpiForWindow)library.resolve("GetDpiForWindow");
+ getSystemMetricsForDpi = (GetSystemMetricsForDpi)library.resolve("GetSystemMetricsForDpi");
+ }
+}
+
+bool QWindowsUser32DLL::supportsPointerApi()
+{
+ return enableMouseInPointer && getPointerType && getPointerInfo && getPointerDeviceRects
+ && getPointerTouchInfo && getPointerFrameTouchInfo && getPointerFrameTouchInfoHistory
+ && getPointerPenInfo && getPointerPenInfoHistory && skipPointerFrameMessages;
+}
+
+void QWindowsShcoreDLL::init()
+{
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8_1)
+ return;
+ QSystemLibrary library(QStringLiteral("SHCore"));
+ getProcessDpiAwareness = (GetProcessDpiAwareness)library.resolve("GetProcessDpiAwareness");
+ setProcessDpiAwareness = (SetProcessDpiAwareness)library.resolve("SetProcessDpiAwareness");
+ getDpiForMonitor = (GetDpiForMonitor)library.resolve("GetDpiForMonitor");
+}
+
+QWindowsUser32DLL QWindowsContext::user32dll;
+QWindowsShcoreDLL QWindowsContext::shcoredll;
+
QWindowsContext *QWindowsContext::m_instance = nullptr;
/*!
@@ -160,6 +241,9 @@ bool QWindowsContextPrivate::m_v2DpiAware = false;
QWindowsContextPrivate::QWindowsContextPrivate()
: m_oleInitializeResult(OleInitialize(nullptr))
{
+ QWindowsContext::user32dll.init();
+ QWindowsContext::shcoredll.init();
+
if (m_pointerHandler.touchDevice())
m_systemInfo |= QWindowsContext::SI_SupportsTouch;
m_displayContext = GetDC(nullptr);
@@ -336,29 +420,31 @@ void QWindowsContext::setDetectAltGrModifier(bool a)
}
[[nodiscard]] static inline QtWindows::DpiAwareness
- dpiAwarenessContextToQtDpiAwareness(DPI_AWARENESS_CONTEXT context)
+ dpiAwarenessContextToQtDpiAwareness(PVOID context)
{
// IsValidDpiAwarenessContext() will handle the NULL pointer case.
- if (!IsValidDpiAwarenessContext(context))
+ if (!QWindowsContext::user32dll.isValidDpiAwarenessContext ||
+ !QWindowsContext::user32dll.areDpiAwarenessContextsEqual ||
+ !QWindowsContext::user32dll.isValidDpiAwarenessContext(context))
return QtWindows::DpiAwareness::Invalid;
- if (AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED))
+ if (QWindowsContext::user32dll.areDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED))
return QtWindows::DpiAwareness::Unaware_GdiScaled;
- if (AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2))
+ if (QWindowsContext::user32dll.areDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2))
return QtWindows::DpiAwareness::PerMonitorVersion2;
- if (AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE))
+ if (QWindowsContext::user32dll.areDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE))
return QtWindows::DpiAwareness::PerMonitor;
- if (AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_SYSTEM_AWARE))
+ if (QWindowsContext::user32dll.areDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_SYSTEM_AWARE))
return QtWindows::DpiAwareness::System;
- if (AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_UNAWARE))
+ if (QWindowsContext::user32dll.areDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_UNAWARE))
return QtWindows::DpiAwareness::Unaware;
return QtWindows::DpiAwareness::Invalid;
}
QtWindows::DpiAwareness QWindowsContext::windowDpiAwareness(HWND hwnd)
{
- if (!hwnd)
+ if (!user32dll.getWindowDpiAwarenessContext || !hwnd)
return QtWindows::DpiAwareness::Invalid;
- const auto context = GetWindowDpiAwarenessContext(hwnd);
+ const auto context = user32dll.getWindowDpiAwarenessContext(hwnd);
return dpiAwarenessContextToQtDpiAwareness(context);
}
@@ -371,7 +457,10 @@ QtWindows::DpiAwareness QWindowsContext::processDpiAwareness()
// return the default DPI_AWARENESS_CONTEXT for the process if
// SetThreadDpiAwarenessContext() was never called. So we can use
// it as an equivalent.
- const auto context = GetThreadDpiAwarenessContext();
+ if (!user32dll.getThreadDpiAwarenessContext)
+ return QtWindows::DpiAwareness::Invalid;
+
+ const auto context = user32dll.getThreadDpiAwarenessContext();
return dpiAwarenessContextToQtDpiAwareness(context);
}
@@ -431,11 +520,11 @@ bool QWindowsContext::setProcessDpiAwareness(QtWindows::DpiAwareness dpiAwarenes
if (processDpiAwareness() == dpiAwareness)
return true;
const auto context = qtDpiAwarenessToDpiAwarenessContext(dpiAwareness);
- if (!IsValidDpiAwarenessContext(context)) {
+ if (!user32dll.isValidDpiAwarenessContext || !user32dll.isValidDpiAwarenessContext(context)) {
qCWarning(lcQpaWindow) << dpiAwareness << "is not supported by current system.";
return false;
}
- if (!SetProcessDpiAwarenessContext(context)) {
+ if (!user32dll.setProcessDpiAwarenessContext || !user32dll.setProcessDpiAwarenessContext(context)) {
qCWarning(lcQpaWindow).noquote().nospace()
<< "SetProcessDpiAwarenessContext() failed: "
<< QSystemError::windowsString()
@@ -868,8 +957,8 @@ void QWindowsContext::forceNcCalcSize(HWND hwnd)
bool QWindowsContext::systemParametersInfo(unsigned action, unsigned param, void *out,
unsigned dpi)
{
- const BOOL result = dpi != 0
- ? SystemParametersInfoForDpi(action, param, out, 0, dpi)
+ const BOOL result = QWindowsContext::user32dll.systemParametersInfoForDpi != nullptr && dpi != 0
+ ? QWindowsContext::user32dll.systemParametersInfoForDpi(action, param, out, 0, dpi)
: SystemParametersInfo(action, param, out, 0);
return result == TRUE;
}
@@ -957,7 +1046,8 @@ static bool enableNonClientDpiScaling(HWND hwnd)
{
bool result = false;
if (QWindowsContext::windowDpiAwareness(hwnd) == QtWindows::DpiAwareness::PerMonitor) {
- result = EnableNonClientDpiScaling(hwnd) != FALSE;
+ if (QWindowsContext::user32dll.enableNonClientDpiScaling)
+ result = QWindowsContext::user32dll.enableNonClientDpiScaling(hwnd) != FALSE;
if (!result) {
const DWORD errorCode = GetLastError();
qErrnoWarning(int(errorCode), "EnableNonClientDpiScaling() failed for HWND %p (%lu)",
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 4e9be1af967..1916868ba0b 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -44,6 +44,98 @@ struct QWindowsContextPrivate;
class QPoint;
class QKeyEvent;
class QPointingDevice;
+
+struct QWindowsUser32DLL
+{
+ inline void init();
+ inline bool supportsPointerApi();
+
+ typedef BOOL (WINAPI *EnableMouseInPointer)(BOOL);
+ typedef BOOL (WINAPI *GetPointerType)(UINT32, PVOID);
+ typedef BOOL (WINAPI *GetPointerInfo)(UINT32, PVOID);
+ typedef BOOL (WINAPI *GetPointerDeviceRects)(HANDLE, RECT *, RECT *);
+ typedef BOOL (WINAPI *GetPointerTouchInfo)(UINT32, PVOID);
+ typedef BOOL (WINAPI *GetPointerFrameTouchInfo)(UINT32, UINT32 *, PVOID);
+ typedef BOOL (WINAPI *GetPointerFrameTouchInfoHistory)(UINT32, UINT32 *, UINT32 *, PVOID);
+ typedef BOOL (WINAPI *GetPointerPenInfo)(UINT32, PVOID);
+ typedef BOOL (WINAPI *GetPointerPenInfoHistory)(UINT32, UINT32 *, PVOID);
+ typedef BOOL (WINAPI *SkipPointerFrameMessages)(UINT32);
+ typedef BOOL (WINAPI *SetProcessDPIAware)();
+ typedef BOOL (WINAPI *SetProcessDpiAwarenessContext)(PVOID);
+ typedef BOOL (WINAPI *AddClipboardFormatListener)(HWND);
+ typedef BOOL (WINAPI *RemoveClipboardFormatListener)(HWND);
+ typedef BOOL (WINAPI *GetDisplayAutoRotationPreferences)(DWORD *);
+ typedef BOOL (WINAPI *SetDisplayAutoRotationPreferences)(DWORD);
+ typedef BOOL (WINAPI *AdjustWindowRectEx)(LPRECT,DWORD,BOOL,DWORD);
+ typedef BOOL (WINAPI *AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
+ typedef BOOL (WINAPI *EnableNonClientDpiScaling)(HWND);
+ typedef PVOID (WINAPI *GetWindowDpiAwarenessContext)(HWND);
+ typedef int (WINAPI *GetAwarenessFromDpiAwarenessContext)(PVOID);
+ typedef BOOL (WINAPI *SystemParametersInfoForDpi)(UINT, UINT, PVOID, UINT, UINT);
+ typedef int (WINAPI *GetDpiForWindow)(HWND);
+ typedef BOOL (WINAPI *GetSystemMetricsForDpi)(INT, UINT);
+ typedef BOOL (WINAPI *AreDpiAwarenessContextsEqual)(PVOID, PVOID);
+ typedef PVOID (WINAPI *GetThreadDpiAwarenessContext)();
+ typedef BOOL (WINAPI *IsValidDpiAwarenessContext)(PVOID);
+
+ // Windows pointer functions (Windows 8 or later).
+ EnableMouseInPointer enableMouseInPointer = nullptr;
+ GetPointerType getPointerType = nullptr;
+ GetPointerInfo getPointerInfo = nullptr;
+ GetPointerDeviceRects getPointerDeviceRects = nullptr;
+ GetPointerTouchInfo getPointerTouchInfo = nullptr;
+ GetPointerFrameTouchInfo getPointerFrameTouchInfo = nullptr;
+ GetPointerFrameTouchInfoHistory getPointerFrameTouchInfoHistory = nullptr;
+ GetPointerPenInfo getPointerPenInfo = nullptr;
+ GetPointerPenInfoHistory getPointerPenInfoHistory = nullptr;
+ SkipPointerFrameMessages skipPointerFrameMessages = nullptr;
+
+ // Windows Vista onwards
+ SetProcessDPIAware setProcessDPIAware = nullptr;
+
+ // Windows 10 version 1607 onwards
+ GetDpiForWindow getDpiForWindow = nullptr;
+ GetThreadDpiAwarenessContext getThreadDpiAwarenessContext = nullptr;
+
+ // Windows 10 version 1703 onwards
+ SetProcessDpiAwarenessContext setProcessDpiAwarenessContext = nullptr;
+ AreDpiAwarenessContextsEqual areDpiAwarenessContextsEqual = nullptr;
+
+ IsValidDpiAwarenessContext isValidDpiAwarenessContext = nullptr;
+
+ // Clipboard listeners are present on Windows Vista onwards
+ // but missing in MinGW 4.9 stub libs. Can be removed in MinGW 5.
+ AddClipboardFormatListener addClipboardFormatListener = nullptr;
+ RemoveClipboardFormatListener removeClipboardFormatListener = nullptr;
+
+ // Rotation API
+ GetDisplayAutoRotationPreferences getDisplayAutoRotationPreferences = nullptr;
+ SetDisplayAutoRotationPreferences setDisplayAutoRotationPreferences = nullptr;
+
+ AdjustWindowRectEx adjustWindowRectEx = nullptr;
+ AdjustWindowRectExForDpi adjustWindowRectExForDpi = nullptr;
+ EnableNonClientDpiScaling enableNonClientDpiScaling = nullptr;
+ GetWindowDpiAwarenessContext getWindowDpiAwarenessContext = nullptr;
+ GetAwarenessFromDpiAwarenessContext getAwarenessFromDpiAwarenessContext = nullptr;
+ SystemParametersInfoForDpi systemParametersInfoForDpi = nullptr;
+ GetSystemMetricsForDpi getSystemMetricsForDpi = nullptr;
+};
+
+// Shell scaling library (Windows 8.1 onwards)
+struct QWindowsShcoreDLL
+{
+ void init();
+ inline bool isValid() const { return getProcessDpiAwareness && setProcessDpiAwareness && getDpiForMonitor; }
+
+ typedef HRESULT (WINAPI *GetProcessDpiAwareness)(HANDLE,int *);
+ typedef HRESULT (WINAPI *SetProcessDpiAwareness)(int);
+ typedef HRESULT (WINAPI *GetDpiForMonitor)(HMONITOR,int,UINT *,UINT *);
+
+ GetProcessDpiAwareness getProcessDpiAwareness = nullptr;
+ SetProcessDpiAwareness setProcessDpiAwareness = nullptr;
+ GetDpiForMonitor getDpiForMonitor = nullptr;
+};
+
class QWindowsContext
{
Q_DISABLE_COPY_MOVE(QWindowsContext)
@@ -134,6 +226,9 @@ public:
QWindowsScreenManager &screenManager();
QWindowsTabletSupport *tabletSupport() const;
+ static QWindowsUser32DLL user32dll;
+ static QWindowsShcoreDLL shcoredll;
+
bool asyncExpose() const;
void setAsyncExpose(bool value);
diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp
index 5d3a47c22fd..b75c7122987 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.cpp
+++ b/src/plugins/platforms/windows/qwindowsdrag.cpp
@@ -1,6 +1,11 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+# if !defined(WINVER) || (WINVER < 0x0602)
+# undef WINVER
+# define WINVER 0x0602
+# endif
+
#include <QtCore/qt_windows.h>
#include "qwindowsdrag.h"
#include "qwindowscontext.h"
@@ -670,11 +675,14 @@ static HRESULT startDoDragDrop(LPDATAOBJECT pDataObj, LPDROPSOURCE pDropSource,
}
if (msg.message == WM_POINTERUPDATE) {
+ if (!QWindowsContext::user32dll.getPointerInfo)
+ return E_FAIL;
const quint32 pointerId = GET_POINTERID_WPARAM(msg.wParam);
POINTER_INFO pointerInfo{};
- if (!GetPointerInfo(pointerId, &pointerInfo))
+
+ if (!QWindowsContext::user32dll.getPointerInfo(pointerId, &pointerInfo))
return E_FAIL;
if (pointerInfo.pointerFlags & POINTER_FLAG_PRIMARY) {
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index 5b8e4e58ffe..ab6b19de478 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -732,14 +732,23 @@ static inline QString messageKeyText(const MSG &msg)
[[nodiscard]] static inline int getTitleBarHeight(const HWND hwnd)
{
- const UINT dpi = GetDpiForWindow(hwnd);
- const int captionHeight = GetSystemMetricsForDpi(SM_CYCAPTION, dpi);
+ UINT dpi;
+
+ if (QWindowsContext::user32dll.getDpiForWindow)
+ dpi = QWindowsContext::user32dll.getDpiForWindow(hwnd);
+ else
+ dpi = 96;
+
+ const int captionHeight = QWindowsContext::user32dll.getSystemMetricsForDpi ? QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CYCAPTION, dpi)
+ : GetSystemMetrics(SM_CYCAPTION);
if (IsZoomed(hwnd))
return captionHeight;
// The frame height should also be taken into account if the window
// is not maximized.
- const int frameHeight = GetSystemMetricsForDpi(SM_CYSIZEFRAME, dpi)
- + GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
+ const int frameHeight = (QWindowsContext::user32dll.getSystemMetricsForDpi ? QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CYSIZEFRAME, dpi)
+ : GetSystemMetrics(SM_CYSIZEFRAME))
+ + (QWindowsContext::user32dll.getSystemMetricsForDpi ? QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi)
+ : GetSystemMetrics(SM_CXPADDEDBORDER));
return captionHeight + frameHeight;
}
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
index 7995716444a..e1c0eb2e58f 100644
--- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
@@ -1,6 +1,11 @@
// Copyright (C) 2019 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+# if !defined(WINVER) || (WINVER < 0x0602)
+# undef WINVER
+# define WINVER 0x0602
+# endif
+
#include <QtCore/qt_windows.h>
#include "qwindowspointerhandler.h"
@@ -52,10 +57,17 @@ QWindowsPointerHandler::~QWindowsPointerHandler()
bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result)
{
+ if (!QWindowsContext::user32dll.getPointerType ||
+ !QWindowsContext::user32dll.getPointerFrameTouchInfo ||
+ !QWindowsContext::user32dll.getPointerFrameTouchInfoHistory ||
+ !QWindowsContext::user32dll.getPointerPenInfo ||
+ !QWindowsContext::user32dll.getPointerPenInfoHistory)
+ return false;
+
*result = 0;
const quint32 pointerId = GET_POINTERID_WPARAM(msg.wParam);
- if (!GetPointerType(pointerId, &m_pointerType)) {
+ if (!QWindowsContext::user32dll.getPointerType(pointerId, &m_pointerType)) {
qWarning() << "GetPointerType() failed:" << qt_error_string();
return false;
}
@@ -69,12 +81,12 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
}
case QT_PT_TOUCH: {
quint32 pointerCount = 0;
- if (!GetPointerFrameTouchInfo(pointerId, &pointerCount, nullptr)) {
+ if (!QWindowsContext::user32dll.getPointerFrameTouchInfo(pointerId, &pointerCount, nullptr)) {
qWarning() << "GetPointerFrameTouchInfo() failed:" << qt_error_string();
return false;
}
QVarLengthArray<POINTER_TOUCH_INFO, 10> touchInfo(pointerCount);
- if (!GetPointerFrameTouchInfo(pointerId, &pointerCount, touchInfo.data())) {
+ if (!QWindowsContext::user32dll.getPointerFrameTouchInfo(pointerId, &pointerCount, touchInfo.data())) {
qWarning() << "GetPointerFrameTouchInfo() failed:" << qt_error_string();
return false;
}
@@ -87,7 +99,7 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
// dispatch any skipped frames if event compression is disabled by the app
if (historyCount > 1 && !QCoreApplication::testAttribute(Qt::AA_CompressHighFrequencyEvents)) {
touchInfo.resize(pointerCount * historyCount);
- if (!GetPointerFrameTouchInfoHistory(pointerId,
+ if (!QWindowsContext::user32dll.getPointerFrameTouchInfoHistory(pointerId,
&historyCount,
&pointerCount,
touchInfo.data())) {
@@ -108,7 +120,7 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
}
case QT_PT_PEN: {
POINTER_PEN_INFO penInfo;
- if (!GetPointerPenInfo(pointerId, &penInfo)) {
+ if (!QWindowsContext::user32dll.getPointerPenInfo(pointerId, &penInfo)) {
qWarning() << "GetPointerPenInfo() failed:" << qt_error_string();
return false;
}
@@ -120,7 +132,7 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
|| !QCoreApplication::testAttribute(Qt::AA_CompressTabletEvents))) {
QVarLengthArray<POINTER_PEN_INFO, 10> penInfoHistory(historyCount);
- if (!GetPointerPenInfoHistory(pointerId, &historyCount, penInfoHistory.data())) {
+ if (!QWindowsContext::user32dll.getPointerPenInfoHistory(pointerId, &historyCount, penInfoHistory.data())) {
qWarning() << "GetPointerPenInfoHistory() failed:" << qt_error_string();
return false;
}
@@ -527,7 +539,8 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
inputIds.insert(touchPoint.id);
// Avoid getting repeated messages for this frame if there are multiple pointerIds
- SkipPointerFrameMessages(touchInfo[i].pointerInfo.pointerId);
+ if (QWindowsContext::user32dll.skipPointerFrameMessages)
+ QWindowsContext::user32dll.skipPointerFrameMessages(touchInfo[i].pointerInfo.pointerId);
}
// Some devices send touches for each finger in a different message/frame, instead of consolidating
@@ -574,7 +587,11 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
auto *penInfo = static_cast<POINTER_PEN_INFO *>(vPenInfo);
RECT pRect, dRect;
- if (!GetPointerDeviceRects(penInfo->pointerInfo.sourceDevice, &pRect, &dRect))
+
+ if (!QWindowsContext::user32dll.getPointerDeviceRects)
+ return false;
+
+ if (!QWindowsContext::user32dll.getPointerDeviceRects(penInfo->pointerInfo.sourceDevice, &pRect, &dRect))
return false;
const auto systemId = (qint64)penInfo->pointerInfo.sourceDevice;
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 6c86c47caac..14d10bef072 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -43,9 +43,12 @@ static inline QDpi deviceDPI(HDC hdc)
static inline QDpi monitorDPI(HMONITOR hMonitor)
{
+ if (!QWindowsContext::shcoredll.getDpiForMonitor)
+ return QDpi(96, 96);
+
UINT dpiX;
UINT dpiY;
- if (SUCCEEDED(GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY)))
+ if (SUCCEEDED(QWindowsContext::shcoredll.getDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY)))
return QDpi(dpiX, dpiY);
return {0, 0};
}
@@ -591,6 +594,9 @@ QRect QWindowsScreen::virtualGeometry(const QPlatformScreen *screen) // cf QScre
bool QWindowsScreen::setOrientationPreference(Qt::ScreenOrientation o)
{
+ if (!QWindowsContext::user32dll.setDisplayAutoRotationPreferences)
+ return false;
+
bool result = false;
ORIENTATION_PREFERENCE orientationPreference = ORIENTATION_PREFERENCE_NONE;
switch (o) {
@@ -609,7 +615,10 @@ bool QWindowsScreen::setOrientationPreference(Qt::ScreenOrientation o)
orientationPreference = ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED;
break;
}
- result = SetDisplayAutoRotationPreferences(orientationPreference);
+
+ static_assert(sizeof(ORIENTATION_PREFERENCE) == sizeof(DWORD), "Incompatible ORIENTATION_PREFERENCE <-> DWORD. Change qwindowscontext_p.h instead of casting.");
+
+ result = QWindowsContext::user32dll.setDisplayAutoRotationPreferences((DWORD)(orientationPreference));
return result;
}
@@ -617,7 +626,10 @@ Qt::ScreenOrientation QWindowsScreen::orientationPreference()
{
Qt::ScreenOrientation result = Qt::PrimaryOrientation;
ORIENTATION_PREFERENCE orientationPreference = ORIENTATION_PREFERENCE_NONE;
- if (GetDisplayAutoRotationPreferences(&orientationPreference)) {
+
+ static_assert(sizeof(ORIENTATION_PREFERENCE) == sizeof(DWORD), "Incompatible ORIENTATION_PREFERENCE <-> DWORD. Change qwindowscontext_p.h instead of casting.");
+
+ if (QWindowsContext::user32dll.getDisplayAutoRotationPreferences && QWindowsContext::user32dll.getDisplayAutoRotationPreferences((DWORD*)(&orientationPreference))) {
switch (orientationPreference) {
case ORIENTATION_PREFERENCE_NONE:
break;
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index 97b2dd339be..72f78c114fa 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -738,7 +738,11 @@ void QWindowsTheme::refreshFonts()
fixedFont.setStyleHint(QFont::TypeWriter);
LOGFONT lfIconTitleFont;
- SystemParametersInfoForDpi(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0, dpi);
+
+ if (QWindowsContext::user32dll.systemParametersInfoForDpi)
+ QWindowsContext::user32dll.systemParametersInfoForDpi(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0, dpi);
+ else
+ SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0);
const QFont iconTitleFont = QWindowsFontDatabase::LOGFONT_to_QFont(lfIconTitleFont, dpi);
m_fonts[SystemFont] = new QFont(QWindowsFontDatabase::systemDefaultFont());
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index f44a28f5636..06d7c7c5ad0 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -150,7 +150,7 @@ static QByteArray debugWinExStyle(DWORD exStyle)
rc += " WS_EX_NOACTIVATE";
if (exStyle & WS_EX_NOPARENTNOTIFY)
rc += " WS_EX_NOPARENTNOTIFY";
- if (exStyle & WS_EX_NOREDIRECTIONBITMAP)
+ if (exStyle & 0x00200000L /* WS_EX_NOREDIRECTIONBITMAP */)
rc += " WS_EX_NOREDIRECTIONBITMAP";
if (exStyle & WS_EX_RIGHT)
rc += " WS_EX_RIGHT";
@@ -525,8 +525,11 @@ static inline void updateGLWindowSettings(const QWindow *w, HWND hwnd, Qt::Windo
// The width of the padded border will always be 0 if DWM composition is
// disabled, but since it will always be enabled and can't be programtically
// disabled from Windows 8, we are safe to go.
- return GetSystemMetricsForDpi(SM_CXSIZEFRAME, dpi)
- + GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
+ if (QWindowsContext::user32dll.getSystemMetricsForDpi)
+ return QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CXSIZEFRAME, dpi)
+ + QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
+ else
+ return GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
}
/*!
@@ -536,11 +539,14 @@ static inline void updateGLWindowSettings(const QWindow *w, HWND hwnd, Qt::Windo
static QMargins invisibleMargins(QPoint screenPoint)
{
+ if (!QWindowsContext::shcoredll.getDpiForMonitor)
+ return QMargins();
+
POINT pt = {screenPoint.x(), screenPoint.y()};
if (HMONITOR hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL)) {
UINT dpiX;
UINT dpiY;
- if (SUCCEEDED(GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) {
+ if (SUCCEEDED(QWindowsContext::shcoredll.getDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) {
const int gap = getResizeBorderThickness(dpiX);
return QMargins(gap, 0, gap, gap);
}
@@ -550,7 +556,12 @@ static QMargins invisibleMargins(QPoint screenPoint)
[[nodiscard]] static inline QMargins invisibleMargins(const HWND hwnd)
{
- const UINT dpi = GetDpiForWindow(hwnd);
+ UINT dpi;
+ if (QWindowsContext::user32dll.getDpiForWindow)
+ dpi = QWindowsContext::user32dll.getDpiForWindow(hwnd);
+ else
+ dpi = 96;
+
const int gap = getResizeBorderThickness(dpi);
return QMargins(gap, 0, gap, gap);
}
@@ -843,7 +854,7 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag
// Currently only compatible with D3D surfaces, use it with care.
if (qEnvironmentVariableIntValue("QT_QPA_DISABLE_REDIRECTION_SURFACE"))
- exStyle |= WS_EX_NOREDIRECTIONBITMAP;
+ exStyle |= 0x00200000L /* WS_EX_NOREDIRECTIONBITMAP */;
}
}
@@ -1071,7 +1082,14 @@ QMargins QWindowsGeometryHint::frame(const QWindow *w, DWORD style, DWORD exStyl
return {};
RECT rect = {0,0,0,0};
style &= ~DWORD(WS_OVERLAPPED); // Not permitted, see docs.
- if (AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, unsigned(qRound(dpi))) == FALSE) {
+
+ BOOL x;
+ if (QWindowsContext::user32dll.adjustWindowRectExForDpi)
+ x = QWindowsContext::user32dll.adjustWindowRectExForDpi(&rect, style, FALSE, exStyle, unsigned(qRound(dpi)));
+ else
+ x = AdjustWindowRectEx(&rect, style, FALSE, exStyle);
+
+ if (x == FALSE) {
qErrnoWarning("%s: AdjustWindowRectExForDpi failed", __FUNCTION__);
}
const QMargins result(qAbs(rect.left), qAbs(rect.top),
@@ -1588,7 +1606,14 @@ void QWindowsWindow::initialize()
QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(w, obtainedGeometry);
}
}
- QWindowsWindow::setSavedDpi(GetDpiForWindow(handle()));
+
+ UINT dpi;
+ if (QWindowsContext::user32dll.getDpiForWindow)
+ dpi = QWindowsContext::user32dll.getDpiForWindow(handle());
+ else
+ dpi = 96;
+
+ QWindowsWindow::setSavedDpi(dpi);
}
QSurfaceFormat QWindowsWindow::format() const
@@ -2083,7 +2108,12 @@ void QWindowsWindow::handleDpiChanged(HWND hwnd, WPARAM wParam, LPARAM lParam)
void QWindowsWindow::handleDpiChangedAfterParent(HWND hwnd)
{
- const UINT dpi = GetDpiForWindow(hwnd);
+ UINT dpi;
+ if (QWindowsContext::user32dll.getDpiForWindow)
+ dpi = QWindowsContext::user32dll.getDpiForWindow(hwnd);
+ else
+ dpi = 96;
+
const qreal scale = dpiRelativeScale(dpi);
setSavedDpi(dpi);
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp
index a8407add019..11a6dd0ea1d 100644
--- a/src/widgets/styles/qwindowsstyle.cpp
+++ b/src/widgets/styles/qwindowsstyle.cpp
@@ -62,6 +62,7 @@
QT_BEGIN_NAMESPACE
#if defined(Q_OS_WIN)
+#include <QtCore/private/qsystemlibrary_p.h>
QT_BEGIN_INCLUDE_NAMESPACE
#include "qt_windows.h"
@@ -261,29 +262,42 @@ int QWindowsStylePrivate::pixelMetricFromSystemDp(QStyle::PixelMetric pm, const
// hardcode DPI to 1x 96 DPI.
const int dpi = 96;
+ typedef int (*GetSystemMetricsForDpiFunc)(int, UINT);
+ static GetSystemMetricsForDpiFunc getSystemMetricsForDpi = []() {
+ QSystemLibrary user32dll(QLatin1String("user32"));
+ return (GetSystemMetricsForDpiFunc)(user32dll.resolve("GetSystemMetricsForDpi"));
+ }();
+
+ typedef BOOL (*SystemParametersInfoForDpiFunc)(UINT, UINT, PVOID, UINT, UINT);
+ static SystemParametersInfoForDpiFunc systemParametersInfoForDpi = []() {
+ QSystemLibrary user32dll(QLatin1String("user32"));
+ return (SystemParametersInfoForDpiFunc)(user32dll.resolve("SystemParametersInfoForDpi"));
+ }();
+
switch (pm) {
case QStyle::PM_DockWidgetFrameWidth:
- return GetSystemMetricsForDpi(SM_CXFRAME, dpi);
+ return getSystemMetricsForDpi ? getSystemMetricsForDpi(SM_CXFRAME, dpi) : GetSystemMetrics(SM_CXFRAME);
case QStyle::PM_TitleBarHeight: {
const int resizeBorderThickness =
- GetSystemMetricsForDpi(SM_CXSIZEFRAME, dpi) + GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
+ (getSystemMetricsForDpi ? getSystemMetricsForDpi(SM_CXSIZEFRAME, dpi) : GetSystemMetrics(SM_CXSIZEFRAME)) +
+ (getSystemMetricsForDpi ? getSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi) : GetSystemMetrics(SM_CXPADDEDBORDER));
if (widget && (widget->windowType() == Qt::Tool))
- return GetSystemMetricsForDpi(SM_CYSMCAPTION, dpi) + resizeBorderThickness;
- return GetSystemMetricsForDpi(SM_CYCAPTION, dpi) + resizeBorderThickness;
+ return (getSystemMetricsForDpi ? getSystemMetricsForDpi(SM_CYSMCAPTION, dpi) : GetSystemMetrics(SM_CYSMCAPTION)) + resizeBorderThickness;
+ return (getSystemMetricsForDpi ? getSystemMetricsForDpi(SM_CYCAPTION, dpi) : GetSystemMetrics(SM_CYCAPTION)) + resizeBorderThickness;
}
case QStyle::PM_ScrollBarExtent:
{
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(NONCLIENTMETRICS);
- if (SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0, dpi))
+ if (systemParametersInfoForDpi ? systemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0, dpi) : SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0))
return qMax(ncm.iScrollHeight, ncm.iScrollWidth);
}
break;
case QStyle::PM_MdiSubWindowFrameWidth:
- return GetSystemMetricsForDpi(SM_CYFRAME, dpi);
+ return getSystemMetricsForDpi ? getSystemMetricsForDpi(SM_CYFRAME, dpi) : GetSystemMetrics(SM_CYFRAME);
default:
break;
--
2.53.0
[Dauer der Verarbeitung: 0.11 Sekunden, vorverarbeitet 2026-10-24]
|
2026-11-01
|
|
|
|
|
Neuigkeiten |
| Aktuelles |
| Motto des Tages |
|
Open Source Software |
|
|
|
Jenseits des Üblichen ....
|
|
Besucherstatistik |
|
|
| Statistik |
| #Sources=1104848 |
| #Domains=416967 |
|
|