diff -urN b/src/corelib/io/qstandardpaths_win.cpp a/src/corelib/io/qstandardpaths_win.cpp
--- b/src/corelib/io/qstandardpaths_win.cpp	2023-09-13 19:02:48.000000000 +0300
+++ a/src/corelib/io/qstandardpaths_win.cpp	2025-01-07 15:33:44.255416200 +0200
@@ -12,6 +12,7 @@
 
 #include <qt_windows.h>
 #include <shlobj.h>
+#include <VersionHelpers.h>
 #include <intshcut.h>
 #include <qvarlengtharray.h>
 
@@ -60,20 +61,26 @@
 
 static bool isProcessLowIntegrity()
 {
+    if (!IsWindows8OrGreater())
+        return false;
+
     // same as GetCurrentProcessToken()
     const auto process_token = HANDLE(quintptr(-4));
 
     QVarLengthArray<char,256> token_info_buf(256);
     auto* token_info = reinterpret_cast<TOKEN_MANDATORY_LABEL*>(token_info_buf.data());
     DWORD token_info_length = token_info_buf.size();
-    if (!GetTokenInformation(process_token, TokenIntegrityLevel, token_info, token_info_length, &token_info_length)) {
+    if (!GetTokenInformation(process_token, TokenIntegrityLevel, token_info, token_info_length, &token_info_length)
+        && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
         // grow buffer and retry GetTokenInformation
         token_info_buf.resize(token_info_length);
         token_info = reinterpret_cast<TOKEN_MANDATORY_LABEL*>(token_info_buf.data());
         if (!GetTokenInformation(process_token, TokenIntegrityLevel, token_info, token_info_length, &token_info_length))
             return false; // assume "normal" process
     }
-
+    else
+        return false;
+    
     // The GetSidSubAuthorityCount return-code is undefined on failure, so
     // there's no point in checking before dereferencing
     DWORD integrity_level = *GetSidSubAuthority(token_info->Label.Sid, *GetSidSubAuthorityCount(token_info->Label.Sid) - 1);
diff -urN b/src/corelib/kernel/qeventdispatcher_win.cpp a/src/corelib/kernel/qeventdispatcher_win.cpp
--- b/src/corelib/kernel/qeventdispatcher_win.cpp	2023-09-13 19:02:48.000000000 +0300
+++ a/src/corelib/kernel/qeventdispatcher_win.cpp	2025-01-07 15:33:44.255416200 +0200
@@ -361,10 +361,15 @@
         ok = t->fastTimerId;
     }
 
-    if (!ok) {
+    typedef BOOL (WINAPI *SetCoalescableTimerFunc) (HWND, UINT_PTR, UINT, TIMERPROC, ULONG);
+    static SetCoalescableTimerFunc mySetCoalescableTimerFunc = 
+        (SetCoalescableTimerFunc)::GetProcAddress(::GetModuleHandle(L"User32"), "SetCoalescableTimer");
+
+    if (!ok && mySetCoalescableTimerFunc) {
         // user normal timers for (Very)CoarseTimers, or if no more multimedia timers available
-        ok = SetCoalescableTimer(internalHwnd, t->timerId, interval, nullptr, tolerance);
+        ok = mySetCoalescableTimerFunc(internalHwnd, t->timerId, interval, nullptr, tolerance);
     }
+    
     if (!ok)
         ok = SetTimer(internalHwnd, t->timerId, interval, nullptr);
 
diff -urN b/src/corelib/kernel/qfunctions_win.cpp a/src/corelib/kernel/qfunctions_win.cpp
--- b/src/corelib/kernel/qfunctions_win.cpp	2023-09-13 19:02:48.000000000 +0300
+++ a/src/corelib/kernel/qfunctions_win.cpp	2025-01-07 15:33:44.255916200 +0200
@@ -43,23 +43,33 @@
 */
 bool qt_win_hasPackageIdentity()
 {
+    typedef BOOL (WINAPI *GetCurrentPackageFullNameFunc) (UINT32 *, PWSTR);
+    static GetCurrentPackageFullNameFunc myGetCurrentPackageFullName = 
+        (GetCurrentPackageFullNameFunc)::GetProcAddress(::GetModuleHandle(L"kernel32"), "GetCurrentPackageFullName");
+
+    if (myGetCurrentPackageFullName)
+    {
 #if defined(HAS_APPMODEL)
-    static const bool hasPackageIdentity = []() {
-        UINT32 length = 0;
-        switch (const auto result = GetCurrentPackageFullName(&length, nullptr)) {
-        case ERROR_INSUFFICIENT_BUFFER:
-            return true;
-        case APPMODEL_ERROR_NO_PACKAGE:
-            return false;
-        default:
-            qWarning("Failed to resolve package identity (error code %ld)", result);
-            return false;
-        }
-    }();
-    return hasPackageIdentity;
+
+        static const bool hasPackageIdentity = []() {
+            UINT32 length = 0;
+            switch (const auto result = myGetCurrentPackageFullName(&length, nullptr)) {
+            case ERROR_INSUFFICIENT_BUFFER:
+                return true;
+            case APPMODEL_ERROR_NO_PACKAGE:
+                return false;
+            default:
+                qWarning("Failed to resolve package identity (error code %ld)", result);
+                return false;
+            }
+        }();
+        return hasPackageIdentity;
 #else
-    return false;
+        return false;
 #endif
+    }
+
+    return false;
 }
 
 QT_END_NAMESPACE
diff -urN b/src/corelib/thread/qfutex_p.h a/src/corelib/thread/qfutex_p.h
--- b/src/corelib/thread/qfutex_p.h	2023-09-13 19:02:48.000000000 +0300
+++ a/src/corelib/thread/qfutex_p.h	2025-01-07 15:33:44.255916200 +0200
@@ -107,39 +107,6 @@
 }
 namespace QtFutex = QtLinuxFutex;
 QT_END_NAMESPACE
-
-#elif defined(Q_OS_WIN)
-#  include <qt_windows.h>
-
-QT_BEGIN_NAMESPACE
-namespace QtWindowsFutex {
-#define QT_ALWAYS_USE_FUTEX
-constexpr inline bool futexAvailable() { return true; }
-
-template <typename Atomic>
-inline void futexWait(Atomic &futex, typename Atomic::Type expectedValue)
-{
-    QtTsan::futexRelease(&futex);
-    WaitOnAddress(&futex, &expectedValue, sizeof(expectedValue), INFINITE);
-    QtTsan::futexAcquire(&futex);
-}
-template <typename Atomic>
-inline bool futexWait(Atomic &futex, typename Atomic::Type expectedValue, qint64 nstimeout)
-{
-    BOOL r = WaitOnAddress(&futex, &expectedValue, sizeof(expectedValue), DWORD(nstimeout / 1000 / 1000));
-    return r || GetLastError() != ERROR_TIMEOUT;
-}
-template <typename Atomic> inline void futexWakeAll(Atomic &futex)
-{
-    WakeByAddressAll(&futex);
-}
-template <typename Atomic> inline void futexWakeOne(Atomic &futex)
-{
-    WakeByAddressSingle(&futex);
-}
-}
-namespace QtFutex = QtWindowsFutex;
-QT_END_NAMESPACE
 #else
 
 QT_BEGIN_NAMESPACE
diff -urN b/src/corelib/thread/qmutex.cpp a/src/corelib/thread/qmutex.cpp
--- b/src/corelib/thread/qmutex.cpp	2023-09-13 19:02:48.000000000 +0300
+++ a/src/corelib/thread/qmutex.cpp	2025-01-07 15:33:44.256416300 +0200
@@ -915,8 +915,10 @@
 
 #if defined(QT_ALWAYS_USE_FUTEX)
 // nothing
-#elif defined(Q_OS_DARWIN)
+#elif defined(Q_OS_MAC)
 #  include "qmutex_mac.cpp"
+#elif defined(Q_OS_WIN)
+#  include "qmutex_win.cpp"
 #else
 #  include "qmutex_unix.cpp"
-#endif
+#endif
\ No newline at end of file
diff -urN b/src/corelib/thread/qmutex_p.h a/src/corelib/thread/qmutex_p.h
--- b/src/corelib/thread/qmutex_p.h	2023-09-13 19:02:48.000000000 +0300
+++ a/src/corelib/thread/qmutex_p.h	2025-01-07 15:33:44.256416300 +0200
@@ -86,6 +86,8 @@
     semaphore_t mach_semaphore;
 #elif defined(Q_OS_UNIX)
     sem_t semaphore;
+#elif defined(Q_OS_WIN)
+    Qt::HANDLE event;
 #endif
 };
 
diff -urN b/src/corelib/thread/qmutex_win.cpp a/src/corelib/thread/qmutex_win.cpp
--- b/src/corelib/thread/qmutex_win.cpp	1970-01-01 02:00:00.000000000 +0200
+++ a/src/corelib/thread/qmutex_win.cpp	2025-01-07 15:33:44.256916300 +0200
@@ -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
\ No newline at end of file
diff -urN b/src/gui/rhi/qrhid3d11.cpp a/src/gui/rhi/qrhid3d11.cpp
--- b/src/gui/rhi/qrhid3d11.cpp	2023-09-13 19:02:48.000000000 +0300
+++ a/src/gui/rhi/qrhid3d11.cpp	2025-01-07 15:33:44.257416400 +0200
@@ -10,6 +10,8 @@
 #include <QtCore/private/qsystemerror_p.h>
 #include "qrhid3dhelpers_p.h"
 
+#include <VersionHelpers.h>
+
 QT_BEGIN_NAMESPACE
 
 using namespace Qt::StringLiterals;
@@ -155,13 +157,22 @@
 
 static IDXGIFactory1 *createDXGIFactory2()
 {
+    typedef HRESULT(WINAPI* CreateDXGIFactory2Func) (UINT flags, REFIID riid, void** factory);
+    static CreateDXGIFactory2Func myCreateDXGIFactory2 =
+        (CreateDXGIFactory2Func)::GetProcAddress(::GetModuleHandle(L"dxgi"), "CreateDXGIFactory2");
+
     IDXGIFactory1 *result = nullptr;
-    const HRESULT hr = CreateDXGIFactory2(0, __uuidof(IDXGIFactory2), reinterpret_cast<void **>(&result));
-    if (FAILED(hr)) {
-        qWarning("CreateDXGIFactory2() failed to create DXGI factory: %s",
-            qPrintable(QSystemError::windowsComString(hr)));
-        result = nullptr;
+
+    if (myCreateDXGIFactory2)
+    {
+        const HRESULT hr = myCreateDXGIFactory2(0, __uuidof(IDXGIFactory2), reinterpret_cast<void **>(&result));
+        if (FAILED(hr)) {
+            qWarning("CreateDXGIFactory2() failed to create DXGI factory: %s",
+                qPrintable(QSystemError::windowsComString(hr)));
+            result = nullptr;
+        }
     }
+    
     return result;
 }
 
@@ -4994,6 +5005,15 @@
 
 bool QD3D11SwapChain::createOrResize()
 {
+    if (IsWindows10OrGreater())
+    {
+        // continue
+    }
+    else
+    {
+        return createOrResizeWin7();
+    }
+
     // Can be called multiple times due to window resizes - that is not the
     // same as a simple destroy+create (as with other resources). Just need to
     // resize the buffers then.
@@ -5262,4 +5282,9 @@
     return true;
 }
 
+bool QD3D11SwapChain::createOrResizeWin7()
+{
+    return false; // not implemented yet ;(
+}
+
 QT_END_NAMESPACE
diff -urN b/src/gui/rhi/qrhid3d11_p.h a/src/gui/rhi/qrhid3d11_p.h
--- b/src/gui/rhi/qrhid3d11_p.h	2023-09-13 19:02:48.000000000 +0300
+++ a/src/gui/rhi/qrhid3d11_p.h	2025-01-07 15:33:44.257916500 +0200
@@ -587,6 +587,8 @@
     QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
     bool createOrResize() override;
 
+    bool createOrResizeWin7();
+
     void releaseBuffers();
     bool newColorBuffer(const QSize &size, DXGI_FORMAT format, DXGI_SAMPLE_DESC sampleDesc,
                         ID3D11Texture2D **tex, ID3D11RenderTargetView **rtv) const;
diff -urN b/src/gui/rhi/qrhid3d12.cpp a/src/gui/rhi/qrhid3d12.cpp
--- b/src/gui/rhi/qrhid3d12.cpp	2023-09-13 19:02:48.000000000 +0300
+++ a/src/gui/rhi/qrhid3d12.cpp	2025-01-07 15:33:44.258916600 +0200
@@ -169,12 +169,28 @@
 
 bool QRhiD3D12::create(QRhi::Flags flags)
 {
+    typedef HRESULT(WINAPI* CreateDXGIFactory2Func) (UINT flags, REFIID riid, void** factory);
+    typedef HRESULT(WINAPI* D3D12CreateDeviceFunc) (IUnknown *, D3D_FEATURE_LEVEL, REFIID, void **);
+    typedef HRESULT(WINAPI* D3D12GetDebugInterfaceFunc) (REFIID, void **);
+
+    static CreateDXGIFactory2Func myCreateDXGIFactory2 =
+        (CreateDXGIFactory2Func)::GetProcAddress(::GetModuleHandle(L"dxgi"), "CreateDXGIFactory2");
+
+    static D3D12CreateDeviceFunc myD3D12CreateDevice =
+        (D3D12CreateDeviceFunc)::GetProcAddress(::GetModuleHandle(L"D3d12"), "D3D12CreateDevice");
+
+    static D3D12GetDebugInterfaceFunc myD3D12GetDebugInterface =
+        (D3D12GetDebugInterfaceFunc)::GetProcAddress(::GetModuleHandle(L"D3d12"), "D3D12GetDebugInterface");
+
+    if (!myCreateDXGIFactory2 || !myD3D12CreateDevice || !myD3D12GetDebugInterface)
+        return false;
+
     rhiFlags = flags;
 
     UINT factoryFlags = 0;
     if (debugLayer)
         factoryFlags |= DXGI_CREATE_FACTORY_DEBUG;
-    HRESULT hr = CreateDXGIFactory2(factoryFlags, __uuidof(IDXGIFactory2), reinterpret_cast<void **>(&dxgiFactory));
+    HRESULT hr = myCreateDXGIFactory2(factoryFlags, __uuidof(IDXGIFactory2), reinterpret_cast<void **>(&dxgiFactory));
     if (FAILED(hr)) {
         qWarning("CreateDXGIFactory2() failed to create DXGI factory: %s",
                  qPrintable(QSystemError::windowsComString(hr)));
@@ -192,7 +208,7 @@
 
     if (debugLayer) {
         ID3D12Debug1 *debug = nullptr;
-        if (SUCCEEDED(D3D12GetDebugInterface(__uuidof(ID3D12Debug1), reinterpret_cast<void **>(&debug)))) {
+        if (SUCCEEDED(myD3D12GetDebugInterface(__uuidof(ID3D12Debug1), reinterpret_cast<void **>(&debug)))) {
             qCDebug(QRHI_LOG_INFO, "Enabling D3D12 debug layer");
             debug->EnableDebugLayer();
             debug->Release();
@@ -262,7 +278,7 @@
         if (minimumFeatureLevel == 0)
             minimumFeatureLevel = MIN_FEATURE_LEVEL;
 
-        hr = D3D12CreateDevice(activeAdapter,
+        hr = myD3D12CreateDevice(activeAdapter,
                                minimumFeatureLevel,
                                __uuidof(ID3D12Device),
                                reinterpret_cast<void **>(&dev));
@@ -2520,6 +2536,9 @@
     return descriptor;
 }
 
+typedef HRESULT(WINAPI* D3D12SerializeVersionedRootSignatureFunc) (const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *, ID3DBlob **, ID3DBlob **);
+D3D12SerializeVersionedRootSignatureFunc myD3D12SerializeVersionedRootSignature = nullptr;
+
 bool QD3D12MipmapGenerator::create(QRhiD3D12 *rhiD)
 {
     this->rhiD = rhiD;
@@ -2564,8 +2583,15 @@
     rsDesc.Desc_1_1.NumStaticSamplers = 1;
     rsDesc.Desc_1_1.pStaticSamplers = &samplerDesc;
 
+    if (!myD3D12SerializeVersionedRootSignature)
+        myD3D12SerializeVersionedRootSignature =
+        (D3D12SerializeVersionedRootSignatureFunc)::GetProcAddress(::GetModuleHandle(L"D3d12"), "D3D12SerializeVersionedRootSignature");
+
+    if (!myD3D12SerializeVersionedRootSignature)
+        return false;
+
     ID3DBlob *signature = nullptr;
-    HRESULT hr = D3D12SerializeVersionedRootSignature(&rsDesc, &signature, nullptr);
+    HRESULT hr = myD3D12SerializeVersionedRootSignature(&rsDesc, &signature, nullptr);
     if (FAILED(hr)) {
         qWarning("Failed to serialize root signature: %s", qPrintable(QSystemError::windowsComString(hr)));
         return false;
@@ -4834,8 +4860,15 @@
     }
     rsDesc.Desc_1_1.Flags = D3D12_ROOT_SIGNATURE_FLAGS(rsFlags);
 
+    if (!myD3D12SerializeVersionedRootSignature)
+        myD3D12SerializeVersionedRootSignature =
+        (D3D12SerializeVersionedRootSignatureFunc)::GetProcAddress(::GetModuleHandle(L"D3d12"), "D3D12SerializeVersionedRootSignature");
+
+    if (!myD3D12SerializeVersionedRootSignature)
+        return {};
+
     ID3DBlob *signature = nullptr;
-    HRESULT hr = D3D12SerializeVersionedRootSignature(&rsDesc, &signature, nullptr);
+    HRESULT hr = myD3D12SerializeVersionedRootSignature(&rsDesc, &signature, nullptr);
     if (FAILED(hr)) {
         qWarning("Failed to serialize root signature: %s", qPrintable(QSystemError::windowsComString(hr)));
         return {};
diff -urN b/src/gui/text/windows/qwindowsfontdatabasebase.cpp a/src/gui/text/windows/qwindowsfontdatabasebase.cpp
--- b/src/gui/text/windows/qwindowsfontdatabasebase.cpp	2023-09-13 19:02:48.000000000 +0300
+++ a/src/gui/text/windows/qwindowsfontdatabasebase.cpp	2025-01-07 15:33:44.259416700 +0200
@@ -685,7 +685,16 @@
     // 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 (WINAPI *SystemParametersInfoForDpiFunc) (UINT, UINT, PVOID, UINT, UINT);
+    static SystemParametersInfoForDpiFunc mySystemParametersInfoForDpi = 
+        (SystemParametersInfoForDpiFunc)::GetProcAddress(::GetModuleHandle(L"user32"), "SystemParametersInfoForDpi");
+
+    if (mySystemParametersInfoForDpi)
+        mySystemParametersInfoForDpi(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 -urN b/src/network/kernel/qdnslookup_win.cpp a/src/network/kernel/qdnslookup_win.cpp
--- b/src/network/kernel/qdnslookup_win.cpp	2023-09-13 19:02:48.000000000 +0300
+++ a/src/network/kernel/qdnslookup_win.cpp	2025-01-07 15:33:44.259416700 +0200
@@ -65,35 +65,101 @@
 
 void QDnsLookupRunnable::query(QDnsLookupReply *reply)
 {
-    // Perform DNS query.
-    alignas(DNS_ADDR_ARRAY) uchar dnsAddresses[sizeof(DNS_ADDR_ARRAY) + sizeof(DNS_ADDR)];
-    DNS_QUERY_REQUEST request = {};
-    request.Version = 1;
-    request.QueryName = reinterpret_cast<const wchar_t *>(requestName.constData());
-    request.QueryType = requestType;
-    request.QueryOptions = DNS_QUERY_STANDARD | DNS_QUERY_TREAT_AS_FQDN;
-
-    if (!nameserver.isNull()) {
-        memset(dnsAddresses, 0, sizeof(dnsAddresses));
-        request.pDnsServerList = new (dnsAddresses) DNS_ADDR_ARRAY;
-        auto addr = new (request.pDnsServerList->AddrArray) DNS_ADDR[1];
-        auto sa = new (addr[0].MaxSa) sockaddr;
-        request.pDnsServerList->MaxCount = sizeof(dnsAddresses);
-        request.pDnsServerList->AddrCount = 1;
-        // ### setting port 53 seems to cause some systems to fail
-        setSockaddr(sa, nameserver, port == DnsPort ? 0 : port);
-        request.pDnsServerList->Family = sa->sa_family;
+    typedef BOOL (WINAPI *DnsQueryExFunc) (PDNS_QUERY_REQUEST, PDNS_QUERY_RESULT, PDNS_QUERY_CANCEL);
+    static DnsQueryExFunc myDnsQueryEx = 
+        (DnsQueryExFunc)::GetProcAddress(::GetModuleHandle(L"Dnsapi"), "DnsQueryEx");
+
+    PDNS_RECORD ptrStart = nullptr;
+
+    if (myDnsQueryEx)
+    {
+        // Perform DNS query.
+        alignas(DNS_ADDR_ARRAY) uchar dnsAddresses[sizeof(DNS_ADDR_ARRAY) + sizeof(DNS_ADDR)];
+        DNS_QUERY_REQUEST request = {};
+        request.Version = 1;
+        request.QueryName = reinterpret_cast<const wchar_t *>(requestName.constData());
+        request.QueryType = requestType;
+        request.QueryOptions = DNS_QUERY_STANDARD | DNS_QUERY_TREAT_AS_FQDN;
+
+        if (!nameserver.isNull()) {
+            memset(dnsAddresses, 0, sizeof(dnsAddresses));
+            request.pDnsServerList = new (dnsAddresses) DNS_ADDR_ARRAY;
+            auto addr = new (request.pDnsServerList->AddrArray) DNS_ADDR[1];
+            auto sa = new (addr[0].MaxSa) sockaddr;
+            request.pDnsServerList->MaxCount = sizeof(dnsAddresses);
+            request.pDnsServerList->AddrCount = 1;
+            // ### setting port 53 seems to cause some systems to fail
+            setSockaddr(sa, nameserver, port == DnsPort ? 0 : port);
+            request.pDnsServerList->Family = sa->sa_family;
+        }
+
+        DNS_QUERY_RESULT results = {};
+        results.Version = 1;
+        const DNS_STATUS status = myDnsQueryEx(&request, &results, nullptr);
+        if (status >= DNS_ERROR_RCODE_FORMAT_ERROR && status <= DNS_ERROR_RCODE_LAST)
+            return reply->makeDnsRcodeError(status - DNS_ERROR_RCODE_FORMAT_ERROR + 1);
+        else if (status == ERROR_TIMEOUT)
+            return reply->makeTimeoutError();
+        else if (status != ERROR_SUCCESS)
+            return reply->makeResolverSystemError(status);
+
+        ptrStart = results.pQueryRecords;
+    }
+    else
+    {
+        // Perform DNS query.
+        PDNS_RECORD dns_records = 0;
+        QByteArray requestNameUTF8 = requestName.toUtf8();
+        const QString requestNameUtf16 = QString::fromUtf8(requestNameUTF8.data(), requestNameUTF8.size());
+        IP4_ARRAY srvList;
+        memset(&srvList, 0, sizeof(IP4_ARRAY));
+        if (!nameserver.isNull()) {
+            if (nameserver.protocol() == QAbstractSocket::IPv4Protocol) {
+                // The below code is referenced from: http://support.microsoft.com/kb/831226
+                srvList.AddrCount = 1;
+                srvList.AddrArray[0] = htonl(nameserver.toIPv4Address());
+            } else if (nameserver.protocol() == QAbstractSocket::IPv6Protocol) {
+                // For supporting IPv6 nameserver addresses, we'll need to switch
+                // from DnsQuey() to DnsQueryEx() as it supports passing an IPv6
+                // address in the nameserver list
+                qWarning("%s", "IPv6 addresses for nameservers are currently not supported");
+                reply->error = QDnsLookup::ResolverError;
+                reply->errorString = tr("IPv6 addresses for nameservers are currently not supported");
+                return;
+            }
+        }
+        const DNS_STATUS status = DnsQuery_W(reinterpret_cast<const wchar_t*>(requestNameUtf16.utf16()), requestType, DNS_QUERY_STANDARD, &srvList, &dns_records, NULL);
+        switch (status) {
+        case ERROR_SUCCESS:
+            break;
+        case DNS_ERROR_RCODE_FORMAT_ERROR:
+            reply->error = QDnsLookup::InvalidRequestError;
+            reply->errorString = tr("Server could not process query");
+            return;
+        case DNS_ERROR_RCODE_SERVER_FAILURE:
+        case DNS_ERROR_RCODE_NOT_IMPLEMENTED:
+            reply->error = QDnsLookup::ServerFailureError;
+            reply->errorString = tr("Server failure");
+            return;
+        case DNS_ERROR_RCODE_NAME_ERROR:
+            reply->error = QDnsLookup::NotFoundError;
+            reply->errorString = tr("Non existent domain");
+            return;
+        case DNS_ERROR_RCODE_REFUSED:
+            reply->error = QDnsLookup::ServerRefusedError;
+            reply->errorString = tr("Server refused to answer");
+            return;
+        default:
+            reply->error = QDnsLookup::InvalidReplyError;
+            reply->errorString = QSystemError(status, QSystemError::NativeError).toString();
+            return;
+        }
+
+        ptrStart = dns_records;
     }
 
-    DNS_QUERY_RESULT results = {};
-    results.Version = 1;
-    const DNS_STATUS status = DnsQueryEx(&request, &results, nullptr);
-    if (status >= DNS_ERROR_RCODE_FORMAT_ERROR && status <= DNS_ERROR_RCODE_LAST)
-        return reply->makeDnsRcodeError(status - DNS_ERROR_RCODE_FORMAT_ERROR + 1);
-    else if (status == ERROR_TIMEOUT)
-        return reply->makeTimeoutError();
-    else if (status != ERROR_SUCCESS)
-        return reply->makeResolverSystemError(status);
+    if (!ptrStart)
+        return;
 
     QStringView lastEncodedName;
     QString cachedDecodedName;
@@ -105,9 +171,9 @@
     auto extractMaybeCachedHost = [&](QStringView name) -> const QString & {
         return lastEncodedName == name ? cachedDecodedName : extractAndCacheHost(name);
     };
-
+    
     // Extract results.
-    for (PDNS_RECORD ptr = results.pQueryRecords; ptr != NULL; ptr = ptr->pNext) {
+    for (PDNS_RECORD ptr = ptrStart; ptr != NULL; ptr = ptr->pNext) {
         // warning: always assign name to the record before calling extractXxxHost() again
         const QString &name = extractMaybeCachedHost(ptr->pName);
         if (ptr->wType == QDnsLookup::A) {
@@ -170,7 +236,7 @@
         }
     }
 
-    DnsRecordListFree(results.pQueryRecords, DnsFreeRecordList);
+    DnsRecordListFree(ptrStart, DnsFreeRecordList);
 }
 
 QT_END_NAMESPACE
diff -urN b/src/plugins/platforms/windows/qwin10helpers.cpp a/src/plugins/platforms/windows/qwin10helpers.cpp
--- b/src/plugins/platforms/windows/qwin10helpers.cpp	2023-09-13 19:02:48.000000000 +0300
+++ a/src/plugins/platforms/windows/qwin10helpers.cpp	2025-01-07 15:33:44.259916700 +0200
@@ -58,43 +58,73 @@
 } // namespace ABI
 #endif // HAS_UI_VIEW_SETTINGS
 
+// based on SDL approach
+// see SDL_windows_gaming_input.c, SDL_windows.c
+
+void * WIN_LoadComBaseFunction(const char *name)
+{
+    static bool s_bLoaded = false;
+    static HMODULE s_hComBase = NULL;
+   
+    if (!s_bLoaded) {
+       s_hComBase = ::LoadLibraryEx(L"combase.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
+       s_bLoaded = true;
+    }
+    if (s_hComBase) {
+        return ::GetProcAddress(s_hComBase, name);
+    } else {
+        return NULL;
+    }
+}
+
 QT_BEGIN_NAMESPACE
 
 // Return tablet mode, note: Does not work for GetDesktopWindow().
 bool qt_windowsIsTabletMode(HWND hwnd)
 {
-    bool result = false;
+    typedef HRESULT (WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING* string);
+    typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory);
 
-    const wchar_t uiViewSettingsId[] = L"Windows.UI.ViewManagement.UIViewSettings";
-    HSTRING_HEADER uiViewSettingsIdRefHeader;
-    HSTRING uiViewSettingsIdHs = nullptr;
-    const auto uiViewSettingsIdLen = UINT32(sizeof(uiViewSettingsId) / sizeof(uiViewSettingsId[0]) - 1);
-    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,
-                                                   reinterpret_cast<void **>(&uiViewSettingsInterop));
-    if (FAILED(hr))
-        return false;
-
-    //  __uuidof(ABI::Windows::UI::ViewManagement::IUIViewSettings);
-    const GUID uiViewSettingsRefId = {0xc63657f6, 0x8850, 0x470d,{0x88, 0xf8, 0x45, 0x5e, 0x16, 0xea, 0x2c, 0x26}};
-    ABI::Windows::UI::ViewManagement::IUIViewSettings *viewSettings = nullptr;
-    hr = uiViewSettingsInterop->GetForWindow(hwnd, uiViewSettingsRefId,
-                                             reinterpret_cast<void **>(&viewSettings));
-    if (SUCCEEDED(hr)) {
-        ABI::Windows::UI::ViewManagement::UserInteractionMode currentMode;
-        hr = viewSettings->get_UserInteractionMode(&currentMode);
-        if (SUCCEEDED(hr))
-            result = currentMode == 1; // Touch, 1
-        viewSettings->Release();
+    WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference");
+    RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory");
+
+    if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc)
+    {
+        bool result = false;
+
+        const wchar_t uiViewSettingsId[] = L"Windows.UI.ViewManagement.UIViewSettings";
+        HSTRING_HEADER uiViewSettingsIdRefHeader;
+        HSTRING uiViewSettingsIdHs = nullptr;
+        const auto uiViewSettingsIdLen = UINT32(sizeof(uiViewSettingsId) / sizeof(uiViewSettingsId[0]) - 1);
+        if (FAILED(WindowsCreateStringReferenceFunc(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 = RoGetActivationFactoryFunc(uiViewSettingsIdHs, uiViewSettingsInteropRefId,
+                                                       reinterpret_cast<void **>(&uiViewSettingsInterop));
+        if (FAILED(hr))
+            return false;
+
+        //  __uuidof(ABI::Windows::UI::ViewManagement::IUIViewSettings);
+        const GUID uiViewSettingsRefId = {0xc63657f6, 0x8850, 0x470d,{0x88, 0xf8, 0x45, 0x5e, 0x16, 0xea, 0x2c, 0x26}};
+        ABI::Windows::UI::ViewManagement::IUIViewSettings *viewSettings = nullptr;
+        hr = uiViewSettingsInterop->GetForWindow(hwnd, uiViewSettingsRefId,
+                                                 reinterpret_cast<void **>(&viewSettings));
+        if (SUCCEEDED(hr)) {
+            ABI::Windows::UI::ViewManagement::UserInteractionMode currentMode;
+            hr = viewSettings->get_UserInteractionMode(&currentMode);
+            if (SUCCEEDED(hr))
+                result = currentMode == 1; // Touch, 1
+            viewSettings->Release();
+        }
+        uiViewSettingsInterop->Release();
+        return result;
     }
-    uiViewSettingsInterop->Release();
-    return result;
+
+    return false;
 }
 
-QT_END_NAMESPACE
+QT_END_NAMESPACE
\ No newline at end of file
diff -urN b/src/plugins/platforms/windows/qwindowscontext.cpp a/src/plugins/platforms/windows/qwindowscontext.cpp
--- b/src/plugins/platforms/windows/qwindowscontext.cpp	2023-09-13 19:02:48.000000000 +0300
+++ a/src/plugins/platforms/windows/qwindowscontext.cpp	2025-01-07 15:33:50.977269700 +0200
@@ -44,6 +44,7 @@
 #include <QtCore/qsysinfo.h>
 #include <QtCore/qscopedpointer.h>
 #include <QtCore/quuid.h>
+#include <QtCore/private/qsystemlibrary_p.h>
 #include <QtCore/private/qwinregistry_p.h>
 #include <QtCore/private/qfactorycacheregistration_p.h>
 #include <QtCore/private/qsystemerror_p.h>
@@ -118,6 +119,77 @@
 static inline bool sessionManagerInteractionBlocked() { return false; }
 #endif
 
+/*!
+    \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");
+    isValidDpiAwarenessContext = (IsValidDpiAwarenessContext)library.resolve("IsValidDpiAwarenessContext");
+    areDpiAwarenessContextsEqual = (AreDpiAwarenessContextsEqual)library.resolve("AreDpiAwarenessContextsEqual");
+
+    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)) {
+        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;
 
 /*!
@@ -161,6 +233,9 @@
 QWindowsContextPrivate::QWindowsContextPrivate()
     : m_oleInitializeResult(OleInitialize(nullptr))
 {
+    QWindowsContext::user32dll.init();
+    QWindowsContext::shcoredll.init();
+    
     if (m_pointerHandler.touchDevice() || m_mouseHandler.touchDevice())
         m_systemInfo |= QWindowsContext::SI_SupportsTouch;
     m_displayContext = GetDC(nullptr);
@@ -279,6 +354,12 @@
     if (integrationOptions & QWindowsIntegration::DontUseWMPointer)
         return false;
 
+    if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8)
+        return false;
+
+    if (!QWindowsContext::user32dll.supportsPointerApi())
+        return false;
+
     d->m_systemInfo |= QWindowsContext::SI_SupportsPointer;
     return true;
 }
@@ -349,41 +430,58 @@
 [[nodiscard]] static inline QtWindows::DpiAwareness
     dpiAwarenessContextToQtDpiAwareness(DPI_AWARENESS_CONTEXT context)
 {
-    // IsValidDpiAwarenessContext() will handle the NULL pointer case.
-    if (!IsValidDpiAwarenessContext(context))
+    if (QWindowsContext::user32dll.isValidDpiAwarenessContext && QWindowsContext::user32dll.areDpiAwarenessContextsEqual)
+    {
+        // IsValidDpiAwarenessContext() will handle the NULL pointer case.
+        if (!QWindowsContext::user32dll.isValidDpiAwarenessContext(context))
+            return QtWindows::DpiAwareness::Invalid;
+        if (QWindowsContext::user32dll.areDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED))
+            return QtWindows::DpiAwareness::Unaware_GdiScaled;
+        if (QWindowsContext::user32dll.areDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2))
+            return QtWindows::DpiAwareness::PerMonitorVersion2;
+        if (QWindowsContext::user32dll.areDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE))
+            return QtWindows::DpiAwareness::PerMonitor;
+        if (QWindowsContext::user32dll.areDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_SYSTEM_AWARE))
+            return QtWindows::DpiAwareness::System;
+        if (QWindowsContext::user32dll.areDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_UNAWARE))
+            return QtWindows::DpiAwareness::Unaware;
+
         return QtWindows::DpiAwareness::Invalid;
-    if (AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED))
-        return QtWindows::DpiAwareness::Unaware_GdiScaled;
-    if (AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2))
-        return QtWindows::DpiAwareness::PerMonitorVersion2;
-    if (AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE))
-        return QtWindows::DpiAwareness::PerMonitor;
-    if (AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_SYSTEM_AWARE))
-        return QtWindows::DpiAwareness::System;
-    if (AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_UNAWARE))
-        return QtWindows::DpiAwareness::Unaware;
-    return QtWindows::DpiAwareness::Invalid;
+    }
+    
+    return QtWindows::DpiAwareness::Unaware; // Windows 7
 }
 
 QtWindows::DpiAwareness QWindowsContext::windowDpiAwareness(HWND hwnd)
 {
     if (!hwnd)
         return QtWindows::DpiAwareness::Invalid;
-    const auto context = GetWindowDpiAwarenessContext(hwnd);
-    return dpiAwarenessContextToQtDpiAwareness(context);
+
+    if (QWindowsContext::user32dll.getWindowDpiAwarenessContext)
+    {
+        const auto context = QWindowsContext::user32dll.getWindowDpiAwarenessContext(hwnd);
+        return dpiAwarenessContextToQtDpiAwareness(context);
+    }
+
+    return dpiAwarenessContextToQtDpiAwareness(DPI_AWARENESS_CONTEXT_UNAWARE);
 }
 
 QtWindows::DpiAwareness QWindowsContext::processDpiAwareness()
 {
-    // Although we have GetDpiAwarenessContextForProcess(), however,
-    // it's only available on Win10 1903+, which is a little higher
-    // than Qt's minimum supported version (1809), so we can't use it.
-    // Luckily, MS docs said GetThreadDpiAwarenessContext() will also
-    // 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();
-    return dpiAwarenessContextToQtDpiAwareness(context);
+    if (QWindowsContext::user32dll.getThreadDpiAwarenessContext)
+    {
+        // Although we have GetDpiAwarenessContextForProcess(), however,
+        // it's only available on Win10 1903+, which is a little higher
+        // than Qt's minimum supported version (1809), so we can't use it.
+        // Luckily, MS docs said GetThreadDpiAwarenessContext() will also
+        // 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 = QWindowsContext::user32dll.getThreadDpiAwarenessContext();
+        return dpiAwarenessContextToQtDpiAwareness(context);
+    }
+
+    return dpiAwarenessContextToQtDpiAwareness(DPI_AWARENESS_CONTEXT_UNAWARE);
 }
 
 [[nodiscard]] static inline DPI_AWARENESS_CONTEXT
@@ -442,23 +540,29 @@
     if (processDpiAwareness() == dpiAwareness)
         return true;
     const auto context = qtDpiAwarenessToDpiAwarenessContext(dpiAwareness);
-    if (!IsValidDpiAwarenessContext(context)) {
-        qCWarning(lcQpaWindow) << dpiAwareness << "is not supported by current system.";
-        return false;
-    }
-    if (!SetProcessDpiAwarenessContext(context)) {
-        qCWarning(lcQpaWindow).noquote().nospace()
-            << "SetProcessDpiAwarenessContext() failed: "
-            << QSystemError::windowsString()
-            << "\nQt's default DPI awareness context is "
-            << "DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2. If you know what you "
-            << "are doing, you can overwrite this default using qt.conf "
-            << "(https://doc.qt.io/qt-6/highdpi.html#configuring-windows).";
-        return false;
+
+    if (QWindowsContext::user32dll.isValidDpiAwarenessContext && QWindowsContext::user32dll.setProcessDpiAwarenessContext)
+    {
+        if (!QWindowsContext::user32dll.isValidDpiAwarenessContext(context)) {
+            qCWarning(lcQpaWindow) << dpiAwareness << "is not supported by current system.";
+            return false;
+        }
+        if (!QWindowsContext::user32dll.setProcessDpiAwarenessContext(context)) {
+            qCWarning(lcQpaWindow).noquote().nospace()
+                << "SetProcessDpiAwarenessContext() failed: "
+                << QSystemError::windowsString()
+                << "\nQt's default DPI awareness context is "
+                << "DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2. If you know what you "
+                << "are doing, you can overwrite this default using qt.conf "
+                << "(https://doc.qt.io/qt-6/highdpi.html#configuring-windows).";
+            return false;
+        }
+        QWindowsContextPrivate::m_v2DpiAware
+            = processDpiAwareness() == QtWindows::DpiAwareness::PerMonitorVersion2;
+        return true;
     }
-    QWindowsContextPrivate::m_v2DpiAware
-        = processDpiAwareness() == QtWindows::DpiAwareness::PerMonitorVersion2;
-    return true;
+
+    return false; // Windows 7
 }
 
 bool QWindowsContext::isDarkMode()
@@ -886,8 +990,8 @@
 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;
 }
@@ -974,8 +1078,8 @@
 static bool enableNonClientDpiScaling(HWND hwnd)
 {
     bool result = false;
-    if (QWindowsContext::windowDpiAwareness(hwnd) == QtWindows::DpiAwareness::PerMonitor) {
-        result = EnableNonClientDpiScaling(hwnd) != FALSE;
+    if (QWindowsContext::user32dll.enableNonClientDpiScaling && QWindowsContext::windowDpiAwareness(hwnd) == QtWindows::DpiAwareness::PerMonitor) {
+        result = QWindowsContext::user32dll.enableNonClientDpiScaling(hwnd) != FALSE;
         if (!result) {
             const DWORD errorCode = GetLastError();
             qErrnoWarning(int(errorCode), "EnableNonClientDpiScaling() failed for HWND %p (%lu)",
diff -urN b/src/plugins/platforms/windows/qwindowscontext.h a/src/plugins/platforms/windows/qwindowscontext.h
--- b/src/plugins/platforms/windows/qwindowscontext.h	2023-09-13 19:02:48.000000000 +0300
+++ a/src/plugins/platforms/windows/qwindowscontext.h	2025-01-07 15:33:50.977269700 +0200
@@ -14,6 +14,7 @@
 #define STRICT_TYPED_ITEMIDS
 #include <shlobj.h>
 #include <shlwapi.h>
+#include <shellscalingapi.h>
 
 QT_BEGIN_NAMESPACE
 
@@ -44,6 +45,94 @@
 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)(HANDLE);
+    typedef BOOL (WINAPI *AddClipboardFormatListener)(HWND);
+    typedef BOOL (WINAPI *RemoveClipboardFormatListener)(HWND);
+    typedef BOOL (WINAPI *GetDisplayAutoRotationPreferences)(DWORD *);
+    typedef BOOL (WINAPI *SetDisplayAutoRotationPreferences)(DWORD);
+    typedef BOOL (WINAPI *AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
+    typedef BOOL (WINAPI *EnableNonClientDpiScaling)(HWND);
+    typedef DPI_AWARENESS_CONTEXT (WINAPI *GetWindowDpiAwarenessContext)(HWND);
+    typedef DPI_AWARENESS (WINAPI *GetAwarenessFromDpiAwarenessContext)(int);
+    typedef BOOL (WINAPI *SystemParametersInfoForDpi)(UINT, UINT, PVOID, UINT, UINT);
+    typedef int  (WINAPI *GetDpiForWindow)(HWND);
+    typedef BOOL (WINAPI *GetSystemMetricsForDpi)(INT, UINT);
+    typedef BOOL (WINAPI *AreDpiAwarenessContextsEqual)(DPI_AWARENESS_CONTEXT, DPI_AWARENESS_CONTEXT);
+    typedef DPI_AWARENESS_CONTEXT (WINAPI *GetThreadDpiAwarenessContext)();
+    typedef BOOL (WINAPI *IsValidDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
+    
+    // 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;
+    IsValidDpiAwarenessContext isValidDpiAwarenessContext = nullptr;
+
+    // Windows 10 version 1703 onwards
+    SetProcessDpiAwarenessContext setProcessDpiAwarenessContext = nullptr;
+    AreDpiAwarenessContextsEqual areDpiAwarenessContextsEqual = 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;
+
+    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,PROCESS_DPI_AWARENESS *);
+    typedef HRESULT (WINAPI *SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
+    typedef HRESULT (WINAPI *GetDpiForMonitor)(HMONITOR,int,UINT *,UINT *);
+
+    GetProcessDpiAwareness getProcessDpiAwareness = nullptr;
+    SetProcessDpiAwareness setProcessDpiAwareness = nullptr;
+    GetDpiForMonitor getDpiForMonitor = nullptr;
+};
+
 class QWindowsContext
 {
     Q_DISABLE_COPY_MOVE(QWindowsContext)
@@ -138,6 +227,9 @@
     QWindowsScreenManager &screenManager();
     QWindowsTabletSupport *tabletSupport() const;
 
+    static QWindowsUser32DLL user32dll;
+    static QWindowsShcoreDLL shcoredll;
+
     bool asyncExpose() const;
     void setAsyncExpose(bool value);
 
diff -urN b/src/plugins/platforms/windows/qwindowsdrag.cpp a/src/plugins/platforms/windows/qwindowsdrag.cpp
--- b/src/plugins/platforms/windows/qwindowsdrag.cpp	2023-09-13 19:02:48.000000000 +0300
+++ a/src/plugins/platforms/windows/qwindowsdrag.cpp	2025-01-07 15:33:44.260916900 +0200
@@ -670,7 +670,7 @@
                 const quint32 pointerId = GET_POINTERID_WPARAM(msg.wParam);
 
                 POINTER_INFO pointerInfo{};
-                if (!GetPointerInfo(pointerId, &pointerInfo))
+                if (!QWindowsContext::user32dll.getPointerInfo || !QWindowsContext::user32dll.getPointerInfo(pointerId, &pointerInfo))
                     return E_FAIL;
 
                 if (pointerInfo.pointerFlags & POINTER_FLAG_PRIMARY) {
diff -urN b/src/plugins/platforms/windows/qwindowskeymapper.cpp a/src/plugins/platforms/windows/qwindowskeymapper.cpp
--- b/src/plugins/platforms/windows/qwindowskeymapper.cpp	2023-09-13 19:02:48.000000000 +0300
+++ a/src/plugins/platforms/windows/qwindowskeymapper.cpp	2025-01-07 15:33:44.261416900 +0200
@@ -751,15 +751,28 @@
 
 [[nodiscard]] static inline int getTitleBarHeight(const HWND hwnd)
 {
-    const UINT dpi = GetDpiForWindow(hwnd);
-    const int captionHeight = GetSystemMetricsForDpi(SM_CYCAPTION, dpi);
-    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);
-    return captionHeight + frameHeight;
+    if (QWindowsContext::user32dll.getDpiForWindow && QWindowsContext::user32dll.getSystemMetricsForDpi)
+    {
+        const UINT dpi = QWindowsContext::user32dll.getDpiForWindow(hwnd);
+        const int captionHeight = QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CYCAPTION, dpi);
+        if (IsZoomed(hwnd))
+            return captionHeight;
+        // The frame height should also be taken into account if the window
+        // is not maximized.
+        const int frameHeight = QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CYSIZEFRAME, dpi)
+                                + QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
+        return captionHeight + frameHeight;    
+    }
+    else
+    {
+        const int captionHeight = 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 = GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
+        return captionHeight + frameHeight;    
+    }
 }
 
 [[nodiscard]] static inline bool isSystemMenuOffsetNeeded(const Qt::WindowFlags flags)
diff -urN b/src/plugins/platforms/windows/qwindowspointerhandler.cpp a/src/plugins/platforms/windows/qwindowspointerhandler.cpp
--- b/src/plugins/platforms/windows/qwindowspointerhandler.cpp	2023-09-13 19:02:48.000000000 +0300
+++ a/src/plugins/platforms/windows/qwindowspointerhandler.cpp	2025-01-07 15:33:44.261917000 +0200
@@ -48,7 +48,7 @@
     *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;
     }
@@ -62,12 +62,12 @@
     }
     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;
         }
@@ -80,10 +80,10 @@
         // 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,
-                                                 &historyCount,
-                                                 &pointerCount,
-                                                 touchInfo.data())) {
+            if (!QWindowsContext::user32dll.getPointerFrameTouchInfoHistory(pointerId,
+                                                                            &historyCount,
+                                                                            &pointerCount,
+                                                                            touchInfo.data())) {
                 qWarning() << "GetPointerFrameTouchInfoHistory() failed:" << qt_error_string();
                 return false;
             }
@@ -101,7 +101,7 @@
     }
     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;
         }
@@ -113,7 +113,7 @@
                 || !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;
             }
@@ -519,7 +519,7 @@
         inputIds.insert(touchPoint.id);
 
         // Avoid getting repeated messages for this frame if there are multiple pointerIds
-        SkipPointerFrameMessages(touchInfo[i].pointerInfo.pointerId);
+        QWindowsContext::user32dll.skipPointerFrameMessages(touchInfo[i].pointerInfo.pointerId);
     }
 
     // Some devices send touches for each finger in a different message/frame, instead of consolidating
@@ -565,7 +565,7 @@
     auto *penInfo = static_cast<POINTER_PEN_INFO *>(vPenInfo);
 
     RECT pRect, dRect;
-    if (!GetPointerDeviceRects(penInfo->pointerInfo.sourceDevice, &pRect, &dRect))
+    if (!QWindowsContext::user32dll.getPointerDeviceRects(penInfo->pointerInfo.sourceDevice, &pRect, &dRect))
         return false;
 
     const auto systemId = (qint64)penInfo->pointerInfo.sourceDevice;
diff -urN b/src/plugins/platforms/windows/qwindowsscreen.cpp a/src/plugins/platforms/windows/qwindowsscreen.cpp
--- b/src/plugins/platforms/windows/qwindowsscreen.cpp	2023-09-13 19:02:48.000000000 +0300
+++ a/src/plugins/platforms/windows/qwindowsscreen.cpp	2025-01-07 15:33:44.262417000 +0200
@@ -42,10 +42,12 @@
 
 static inline QDpi monitorDPI(HMONITOR hMonitor)
 {
-    UINT dpiX;
-    UINT dpiY;
-    if (SUCCEEDED(GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY)))
-        return QDpi(dpiX, dpiY);
+    if (QWindowsContext::shcoredll.isValid()) {
+        UINT dpiX;
+        UINT dpiY;
+        if (SUCCEEDED(QWindowsContext::shcoredll.getDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY)))
+            return QDpi(dpiX, dpiY);
+    }
     return {0, 0};
 }
 
@@ -564,47 +566,51 @@
 bool QWindowsScreen::setOrientationPreference(Qt::ScreenOrientation o)
 {
     bool result = false;
-    ORIENTATION_PREFERENCE orientationPreference = ORIENTATION_PREFERENCE_NONE;
-    switch (o) {
-    case Qt::PrimaryOrientation:
-        break;
-    case Qt::PortraitOrientation:
-        orientationPreference = ORIENTATION_PREFERENCE_PORTRAIT;
-        break;
-    case Qt::LandscapeOrientation:
-        orientationPreference = ORIENTATION_PREFERENCE_LANDSCAPE;
-        break;
-    case Qt::InvertedPortraitOrientation:
-        orientationPreference = ORIENTATION_PREFERENCE_PORTRAIT_FLIPPED;
-        break;
-    case Qt::InvertedLandscapeOrientation:
-        orientationPreference = ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED;
-        break;
+    if (QWindowsContext::user32dll.setDisplayAutoRotationPreferences) {
+        ORIENTATION_PREFERENCE orientationPreference = ORIENTATION_PREFERENCE_NONE;
+        switch (o) {
+        case Qt::PrimaryOrientation:
+            break;
+        case Qt::PortraitOrientation:
+            orientationPreference = ORIENTATION_PREFERENCE_PORTRAIT;
+            break;
+        case Qt::LandscapeOrientation:
+            orientationPreference = ORIENTATION_PREFERENCE_LANDSCAPE;
+            break;
+        case Qt::InvertedPortraitOrientation:
+            orientationPreference = ORIENTATION_PREFERENCE_PORTRAIT_FLIPPED;
+            break;
+        case Qt::InvertedLandscapeOrientation:
+            orientationPreference = ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED;
+            break;
+        }
+        result = QWindowsContext::user32dll.setDisplayAutoRotationPreferences(orientationPreference);
     }
-    result = SetDisplayAutoRotationPreferences(orientationPreference);
     return result;
 }
 
 Qt::ScreenOrientation QWindowsScreen::orientationPreference()
 {
     Qt::ScreenOrientation result = Qt::PrimaryOrientation;
-    ORIENTATION_PREFERENCE orientationPreference = ORIENTATION_PREFERENCE_NONE;
-    if (GetDisplayAutoRotationPreferences(&orientationPreference)) {
-        switch (orientationPreference) {
-        case ORIENTATION_PREFERENCE_NONE:
-            break;
-        case ORIENTATION_PREFERENCE_LANDSCAPE:
-            result = Qt::LandscapeOrientation;
-            break;
-        case ORIENTATION_PREFERENCE_PORTRAIT:
-            result = Qt::PortraitOrientation;
-            break;
-        case ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED:
-            result = Qt::InvertedLandscapeOrientation;
-            break;
-        case ORIENTATION_PREFERENCE_PORTRAIT_FLIPPED:
-            result = Qt::InvertedPortraitOrientation;
-            break;
+    if (QWindowsContext::user32dll.getDisplayAutoRotationPreferences) {
+        DWORD orientationPreference = ORIENTATION_PREFERENCE_NONE;
+        if (QWindowsContext::user32dll.getDisplayAutoRotationPreferences(&orientationPreference)) {
+            switch (orientationPreference) {
+            case ORIENTATION_PREFERENCE_NONE:
+                break;
+            case ORIENTATION_PREFERENCE_LANDSCAPE:
+                result = Qt::LandscapeOrientation;
+                break;
+            case ORIENTATION_PREFERENCE_PORTRAIT:
+                result = Qt::PortraitOrientation;
+                break;
+            case ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED:
+                result = Qt::InvertedLandscapeOrientation;
+                break;
+            case ORIENTATION_PREFERENCE_PORTRAIT_FLIPPED:
+                result = Qt::InvertedPortraitOrientation;
+                break;
+            }
         }
     }
     return result;
diff -urN b/src/plugins/platforms/windows/qwindowstheme.cpp a/src/plugins/platforms/windows/qwindowstheme.cpp
--- b/src/plugins/platforms/windows/qwindowstheme.cpp	2023-09-13 19:02:48.000000000 +0300
+++ a/src/plugins/platforms/windows/qwindowstheme.cpp	2025-01-07 15:33:44.262917100 +0200
@@ -42,6 +42,8 @@
 
 #include <algorithm>
 
+#include <VersionHelpers.h>
+
 #if QT_CONFIG(cpp_winrt)
 #   include <QtCore/private/qt_winrtbase_p.h>
 
@@ -243,19 +245,21 @@
 */
 static void populateLightSystemBasePalette(QPalette &result)
 {
-    const QColor background = getSysColor(COLOR_BTNFACE);
-    const QColor textColor = getSysColor(COLOR_WINDOWTEXT);
+    QColor background = getSysColor(COLOR_BTNFACE);
+    QColor textColor = getSysColor(COLOR_WINDOWTEXT);
+    QColor accent = qt_accentColor();
+    QColor accentDarkest = accent.darker(120 * 120 * 120);
 
 #if QT_CONFIG(cpp_winrt)
-    // respect the Windows 11 accent color
-    using namespace winrt::Windows::UI::ViewManagement;
-    const auto settings = UISettings();
-
-    const QColor accent = getSysColor(settings.GetColorValue(UIColorType::Accent));
-    const QColor accentDarkest = getSysColor(settings.GetColorValue(UIColorType::AccentDark3));
-#else
-    const QColor accent = qt_accentColor();
-    const QColor accentDarkest = accent.darker(120 * 120 * 120);
+    if (IsWindows10OrGreater())
+    {
+        // respect the Windows 11 accent color
+        using namespace winrt::Windows::UI::ViewManagement;
+        const auto settings = UISettings();
+
+        accent = getSysColor(settings.GetColorValue(UIColorType::Accent));
+        accentDarkest = getSysColor(settings.GetColorValue(UIColorType::AccentDark3));    
+    }
 #endif
 
     const QColor linkColor = accent;
@@ -292,39 +296,43 @@
 
 static void populateDarkSystemBasePalette(QPalette &result)
 {
+    QColor foreground = Qt::white;
+    QColor background = QColor(0x1E, 0x1E, 0x1E);
+    QColor accent = qt_accentColor();
+    QColor accentDark = accent.darker(120);
+    QColor accentDarker = accentDark.darker(120);
+    QColor accentDarkest = accentDarker.darker(120);
+    QColor accentLight = accent.lighter(120);
+    QColor accentLighter = accentLight.lighter(120);
+    QColor accentLightest = accentLighter.lighter(120);
+
 #if QT_CONFIG(cpp_winrt)
-    using namespace winrt::Windows::UI::ViewManagement;
-    const auto settings = UISettings();
+    if (IsWindows10OrGreater())
+    {
+        using namespace winrt::Windows::UI::ViewManagement;
+        const auto settings = UISettings();
 
-    // We have to craft a palette from these colors. The settings.UIElementColor(UIElementType) API
-    // returns the old system colors, not the dark mode colors. If the background is black (which it
-    // usually), then override it with a dark gray instead so that we can go up and down the lightness.
-    const QColor foreground = getSysColor(settings.GetColorValue(UIColorType::Foreground));
-    const QColor background = [&settings]() -> QColor {
-        auto systemBackground = getSysColor(settings.GetColorValue(UIColorType::Background));
-        if (systemBackground == Qt::black)
-            systemBackground = QColor(0x1E, 0x1E, 0x1E);
-        return systemBackground;
-    }();
-
-    const QColor accent = getSysColor(settings.GetColorValue(UIColorType::Accent));
-    const QColor accentDark = getSysColor(settings.GetColorValue(UIColorType::AccentDark1));
-    const QColor accentDarker = getSysColor(settings.GetColorValue(UIColorType::AccentDark2));
-    const QColor accentDarkest = getSysColor(settings.GetColorValue(UIColorType::AccentDark3));
-    const QColor accentLight = getSysColor(settings.GetColorValue(UIColorType::AccentLight1));
-    const QColor accentLighter = getSysColor(settings.GetColorValue(UIColorType::AccentLight2));
-    const QColor accentLightest = getSysColor(settings.GetColorValue(UIColorType::AccentLight3));
-#else
-    const QColor foreground = Qt::white;
-    const QColor background = QColor(0x1E, 0x1E, 0x1E);
-    const QColor accent = qt_accentColor();
-    const QColor accentDark = accent.darker(120);
-    const QColor accentDarker = accentDark.darker(120);
-    const QColor accentDarkest = accentDarker.darker(120);
-    const QColor accentLight = accent.lighter(120);
-    const QColor accentLighter = accentLight.lighter(120);
-    const QColor accentLightest = accentLighter.lighter(120);
+        // We have to craft a palette from these colors. The settings.UIElementColor(UIElementType) API
+        // returns the old system colors, not the dark mode colors. If the background is black (which it
+        // usually), then override it with a dark gray instead so that we can go up and down the lightness.
+        foreground = getSysColor(settings.GetColorValue(UIColorType::Foreground));
+        background = [&settings]() -> QColor {
+            auto systemBackground = getSysColor(settings.GetColorValue(UIColorType::Background));
+            if (systemBackground == Qt::black)
+                systemBackground = QColor(0x1E, 0x1E, 0x1E);
+            return systemBackground;
+        }();
+
+        accent = getSysColor(settings.GetColorValue(UIColorType::Accent));
+        accentDark = getSysColor(settings.GetColorValue(UIColorType::AccentDark1));
+        accentDarker = getSysColor(settings.GetColorValue(UIColorType::AccentDark2));
+        accentDarkest = getSysColor(settings.GetColorValue(UIColorType::AccentDark3));
+        accentLight = getSysColor(settings.GetColorValue(UIColorType::AccentLight1));
+        accentLighter = getSysColor(settings.GetColorValue(UIColorType::AccentLight2));
+        accentLightest = getSysColor(settings.GetColorValue(UIColorType::AccentLight3));
+    }
 #endif
+
     const QColor linkColor = accent;
     const QColor buttonColor = background.lighter(200);
 
@@ -551,16 +559,19 @@
     m_palettes[MenuPalette] = new QPalette(menuPalette(*m_palettes[SystemPalette], light));
     m_palettes[MenuBarPalette] = menuBarPalette(*m_palettes[MenuPalette], light);
     if (!light) {
+        QColor accent = qt_accentColor();
+        QColor accentLight = accent.lighter(120);
+        QColor accentDarkest = accent.darker(120 * 120 * 120);
+
 #if QT_CONFIG(cpp_winrt)
-        using namespace winrt::Windows::UI::ViewManagement;
-        const auto settings = UISettings();
-        const QColor accent = getSysColor(settings.GetColorValue(UIColorType::Accent));
-        const QColor accentLight = getSysColor(settings.GetColorValue(UIColorType::AccentLight1));
-        const QColor accentDarkest = getSysColor(settings.GetColorValue(UIColorType::AccentDark3));
-#else
-        const QColor accent = qt_accentColor();
-        const QColor accentLight = accent.lighter(120);
-        const QColor accentDarkest = accent.darker(120 * 120 * 120);
+        if (IsWindows10OrGreater())
+        {
+            using namespace winrt::Windows::UI::ViewManagement;
+            const auto settings = UISettings();
+            accent = getSysColor(settings.GetColorValue(UIColorType::Accent));
+            accentLight = getSysColor(settings.GetColorValue(UIColorType::AccentLight1));
+            accentDarkest = getSysColor(settings.GetColorValue(UIColorType::AccentDark3));    
+        }    
 #endif
         m_palettes[CheckBoxPalette] = new QPalette(*m_palettes[SystemPalette]);
         m_palettes[CheckBoxPalette]->setColor(QPalette::Active, QPalette::Base, accent);
@@ -664,8 +675,14 @@
     fixedFont.setStyleHint(QFont::TypeWriter);
 
     LOGFONT lfIconTitleFont;
-    SystemParametersInfoForDpi(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0, dpi);
-    const QFont iconTitleFont = QWindowsFontDatabase::LOGFONT_to_QFont(lfIconTitleFont, dpi);
+    QFont iconTitleFont;
+    if (QWindowsContext::user32dll.systemParametersInfoForDpi) {
+        QWindowsContext::user32dll.systemParametersInfoForDpi(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0, dpi);
+        iconTitleFont = QWindowsFontDatabase::LOGFONT_to_QFont(lfIconTitleFont, dpi);
+    } else {
+        SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0);
+        iconTitleFont = QWindowsFontDatabase::LOGFONT_to_QFont(lfIconTitleFont);
+    }
 
     m_fonts[SystemFont] = new QFont(QWindowsFontDatabase::systemDefaultFont());
     m_fonts[MenuFont] = new QFont(menuFont);
diff -urN b/src/plugins/platforms/windows/qwindowswindow.cpp a/src/plugins/platforms/windows/qwindowswindow.cpp
--- b/src/plugins/platforms/windows/qwindowswindow.cpp	2023-09-13 19:02:48.000000000 +0300
+++ a/src/plugins/platforms/windows/qwindowswindow.cpp	2025-01-07 15:33:44.263417200 +0200
@@ -523,11 +523,15 @@
 
 [[nodiscard]] static inline int getResizeBorderThickness(const UINT dpi)
 {
-    // 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) {
+        // 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 QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CXSIZEFRAME, dpi)
+               + QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
+    }
+    
+    return GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
 }
 
 /*!
@@ -537,13 +541,17 @@
 
 static QMargins invisibleMargins(QPoint screenPoint)
 {
-    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))) {
-            const int gap = getResizeBorderThickness(dpiX);
-            return QMargins(gap, 0, gap, gap);
+    if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10) {
+        POINT pt = {screenPoint.x(), screenPoint.y()};
+        if (HMONITOR hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL)) {
+            if (QWindowsContext::shcoredll.isValid()) {
+                UINT dpiX;
+                UINT dpiY;
+                if (SUCCEEDED(QWindowsContext::shcoredll.getDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) {
+                    const int gap = getResizeBorderThickness(dpiX);
+                    return QMargins(gap, 0, gap, gap);
+                }
+            }
         }
     }
     return QMargins();
@@ -551,9 +559,12 @@
 
 [[nodiscard]] static inline QMargins invisibleMargins(const HWND hwnd)
 {
-    const UINT dpi = GetDpiForWindow(hwnd);
-    const int gap = getResizeBorderThickness(dpi);
-    return QMargins(gap, 0, gap, gap);
+    if (QWindowsContext::user32dll.getDpiForWindow) {
+        const UINT dpi = QWindowsContext::user32dll.getDpiForWindow(hwnd);
+        const int gap = getResizeBorderThickness(dpi);
+        return QMargins(gap, 0, gap, gap);
+    }
+    return QMargins();
 }
 
 /*!
@@ -1055,7 +1066,8 @@
         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) {
+    if (QWindowsContext::user32dll.adjustWindowRectExForDpi &&
+        QWindowsContext::user32dll.adjustWindowRectExForDpi(&rect, style, FALSE, exStyle, unsigned(qRound(dpi))) == FALSE) {
         qErrnoWarning("%s: AdjustWindowRectExForDpi failed", __FUNCTION__);
     }
     const QMargins result(qAbs(rect.left), qAbs(rect.top),
@@ -1549,7 +1561,8 @@
             QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(w, obtainedGeometry);
         }
     }
-    QWindowsWindow::setSavedDpi(GetDpiForWindow(handle()));
+    QWindowsWindow::setSavedDpi(QWindowsContext::user32dll.getDpiForWindow ?
+        QWindowsContext::user32dll.getDpiForWindow(handle()) : 96);
 }
 
 QSurfaceFormat QWindowsWindow::format() const
@@ -2041,17 +2054,20 @@
 
 void QWindowsWindow::handleDpiChangedAfterParent(HWND hwnd)
 {
-    const UINT dpi = GetDpiForWindow(hwnd);
-    const qreal scale = dpiRelativeScale(dpi);
-    setSavedDpi(dpi);
-
-    checkForScreenChanged(QWindowsWindow::FromDpiChange);
-
-    // Child windows do not get WM_GETDPISCALEDSIZE messages to inform
-    // Windows about the new size, so we need to manually scale them.
-    QRect currentGeometry = geometry();
-    QRect scaledGeometry = QRect(currentGeometry.topLeft() * scale, currentGeometry.size() * scale);
-    setGeometry(scaledGeometry);
+    if (QWindowsContext::user32dll.getDpiForWindow)
+    {
+        const UINT dpi = QWindowsContext::user32dll.getDpiForWindow(hwnd);
+        const qreal scale = dpiRelativeScale(dpi);
+        setSavedDpi(dpi);
+
+        checkForScreenChanged(QWindowsWindow::FromDpiChange);
+
+        // Child windows do not get WM_GETDPISCALEDSIZE messages to inform
+        // Windows about the new size, so we need to manually scale them.
+        QRect currentGeometry = geometry();
+        QRect scaledGeometry = QRect(currentGeometry.topLeft() * scale, currentGeometry.size() * scale);
+        setGeometry(scaledGeometry);
+    }    
 }
 
 static QRect normalFrameGeometry(HWND hwnd)
