[*] Restore Windows 7 support [pt 2]

Change-Id: Iae61503a4aa2f788fe76b9e9b7a7c1ad1abfae36
This commit is contained in:
Reece Wilson 2023-11-24 02:35:42 +00:00
parent 21ed922bf6
commit 30fa00045e
6 changed files with 238 additions and 59 deletions

View File

@ -63,38 +63,8 @@ QT_BEGIN_NAMESPACE
// Return tablet mode, note: Does not work for GetDesktopWindow(). // Return tablet mode, note: Does not work for GetDesktopWindow().
bool qt_windowsIsTabletMode(HWND hwnd) bool qt_windowsIsTabletMode(HWND hwnd)
{ {
bool result = false;
return 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(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();
}
uiViewSettingsInterop->Release();
return result;
} }
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -58,6 +58,13 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
typedef HRESULT(__stdcall * SetProcessDpiAwareness_f)(PROCESS_DPI_AWARENESS value);
typedef HRESULT(__stdcall * GetProcessDpiAwareness_f)(HANDLE hprocess, PROCESS_DPI_AWARENESS* value);
typedef BOOL(__stdcall * SetProcessDpiAwarenessContext_f)(DPI_AWARENESS_CONTEXT value);
typedef BOOL(__stdcall * EnableNonClientDpiScaling_f)(HWND hwnd);
typedef DPI_AWARENESS_CONTEXT (__stdcall * GetWindowDpiAwarenessContext_f)(HWND hwnd);
typedef DPI_AWARENESS (__stdcall * GetAwarenessFromDpiAwarenessContext_f)(DPI_AWARENESS_CONTEXT value);
using namespace Qt::StringLiterals; using namespace Qt::StringLiterals;
Q_LOGGING_CATEGORY(lcQpaWindows, "qt.qpa.windows") Q_LOGGING_CATEGORY(lcQpaWindows, "qt.qpa.windows")
@ -119,7 +126,17 @@ static inline bool sessionManagerInteractionBlocked() { return false; }
static inline int windowDpiAwareness(HWND hwnd) static inline int windowDpiAwareness(HWND hwnd)
{ {
return static_cast<int>(GetAwarenessFromDpiAwarenessContext(GetWindowDpiAwarenessContext(hwnd))); auto pGetAwarenessFromDpiAwarenessContext = reinterpret_cast<GetAwarenessFromDpiAwarenessContext_f>(GetProcAddress(LoadLibraryW(L"USER32.dll"), "GetAwarenessFromDpiAwarenessContext"));
if (!pGetAwarenessFromDpiAwarenessContext) {
return false;
}
auto pGetWindowDpiAwarenessContext = reinterpret_cast<GetWindowDpiAwarenessContext_f>(GetProcAddress(LoadLibraryW(L"USER32.dll"), "GetWindowDpiAwarenessContext"));
if (!pGetWindowDpiAwarenessContext) {
return false;
}
return static_cast<int>(pGetAwarenessFromDpiAwarenessContext(pGetWindowDpiAwarenessContext(hwnd)));
} }
// Note: This only works within WM_NCCREATE // Note: This only works within WM_NCCREATE
@ -127,7 +144,12 @@ static bool enableNonClientDpiScaling(HWND hwnd)
{ {
bool result = false; bool result = false;
if (windowDpiAwareness(hwnd) == 2) { if (windowDpiAwareness(hwnd) == 2) {
result = EnableNonClientDpiScaling(hwnd) != FALSE; auto pEnableNonClientDpiScaling = reinterpret_cast<EnableNonClientDpiScaling_f>(GetProcAddress(LoadLibraryW(L"USER32.dll"), "EnableNonClientDpiScaling"));
if (!pEnableNonClientDpiScaling) {
return false;
}
result = pEnableNonClientDpiScaling(hwnd) != FALSE;
if (!result) { if (!result) {
const DWORD errorCode = GetLastError(); const DWORD errorCode = GetLastError();
qErrnoWarning(int(errorCode), "EnableNonClientDpiScaling() failed for HWND %p (%lu)", qErrnoWarning(int(errorCode), "EnableNonClientDpiScaling() failed for HWND %p (%lu)",
@ -364,17 +386,32 @@ void QWindowsContext::setDetectAltGrModifier(bool a)
int QWindowsContext::processDpiAwareness() int QWindowsContext::processDpiAwareness()
{ {
PROCESS_DPI_AWARENESS result; PROCESS_DPI_AWARENESS result;
if (SUCCEEDED(GetProcessDpiAwareness(nullptr, &result))) {
auto pGetDPIAwareness = reinterpret_cast<GetProcessDpiAwareness_f>(GetProcAddress(LoadLibraryW(L"api-ms-win-shcore-scaling-l1-1-1.dll"), "GetProcessDpiAwareness"));
if (!pGetDPIAwareness) {
return 0;
}
if (SUCCEEDED(pGetDPIAwareness(nullptr, &result))) {
return static_cast<int>(result); return static_cast<int>(result);
} }
return -1; return -1;
} }
void QWindowsContext::setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiAwareness) void QWindowsContext::setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiAwareness)
{ {
PROCESS_DPI_AWARENESS result;
auto pSetProcessDpiAwareness = reinterpret_cast<SetProcessDpiAwareness_f>(GetProcAddress(LoadLibraryW(L"api-ms-win-shcore-scaling-l1-1-1.dll"), "SetProcessDpiAwareness"));
if (!pSetProcessDpiAwareness) {
return;
}
qCDebug(lcQpaWindows) << __FUNCTION__ << dpiAwareness; qCDebug(lcQpaWindows) << __FUNCTION__ << dpiAwareness;
const HRESULT hr = SetProcessDpiAwareness(static_cast<PROCESS_DPI_AWARENESS>(dpiAwareness)); const HRESULT hr = pSetProcessDpiAwareness(static_cast<PROCESS_DPI_AWARENESS>(dpiAwareness));
// E_ACCESSDENIED means set externally (MSVC manifest or external app loading Qt plugin). // E_ACCESSDENIED means set externally (MSVC manifest or external app loading Qt plugin).n
// Silence warning in that case unless debug is enabled. // Silence warning in that case unless debug is enabled.
if (FAILED(hr) && (hr != E_ACCESSDENIED || lcQpaWindows().isDebugEnabled())) { if (FAILED(hr) && (hr != E_ACCESSDENIED || lcQpaWindows().isDebugEnabled())) {
qWarning().noquote().nospace() << "SetProcessDpiAwareness(" qWarning().noquote().nospace() << "SetProcessDpiAwareness("
@ -384,9 +421,14 @@ void QWindowsContext::setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiA
} }
bool QWindowsContext::setProcessDpiV2Awareness() bool QWindowsContext::setProcessDpiV2Awareness()
{ {
auto pSetProcessDpiAwarenessContext = reinterpret_cast<SetProcessDpiAwarenessContext_f>(GetProcAddress(LoadLibraryW(L"USER32.dll"), "SetProcessDpiAwarenessContext"));
if (!pSetProcessDpiAwarenessContext) {
return false;
}
qCDebug(lcQpaWindows) << __FUNCTION__; qCDebug(lcQpaWindows) << __FUNCTION__;
const BOOL ok = SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); const BOOL ok = pSetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
if (!ok) { if (!ok) {
const HRESULT errorCode = GetLastError(); const HRESULT errorCode = GetLastError();
qCWarning(lcQpaWindows).noquote().nospace() << "setProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) failed: " qCWarning(lcQpaWindows).noquote().nospace() << "setProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) failed: "
@ -910,11 +952,21 @@ void QWindowsContext::forceNcCalcSize(HWND hwnd)
SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER); SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
} }
typedef BOOL (__stdcall *SystemParametersInfoForDpi_f)(
UINT uiAction,
UINT uiParam,
PVOID pvParam,
UINT fWinIni,
UINT dpi
);
bool QWindowsContext::systemParametersInfo(unsigned action, unsigned param, void *out, bool QWindowsContext::systemParametersInfo(unsigned action, unsigned param, void *out,
unsigned dpi) unsigned dpi)
{ {
const BOOL result = dpi != 0 auto pSystemParametersInfoForDpi = reinterpret_cast<SystemParametersInfoForDpi_f>(GetProcAddress(LoadLibraryW(L"USER32.dll"), "SystemParametersInfoForDpi"));
? SystemParametersInfoForDpi(action, param, out, 0, dpi)
const BOOL result = dpi != 0 && pSystemParametersInfoForDpi
? pSystemParametersInfoForDpi(action, param, out, 0, dpi)
: SystemParametersInfo(action, param, out, 0); : SystemParametersInfo(action, param, out, 0);
return result == TRUE; return result == TRUE;
} }

View File

@ -749,17 +749,40 @@ static inline QString messageKeyText(const MSG &msg)
return ch.isNull() ? QString() : QString(ch); return ch.isNull() ? QString() : QString(ch);
} }
UINT GetDpiForWindow2(HWND hwnd);
typedef int (__stdcall *GetSystemMetricsForDpi_f)(int, UINT);
typedef int (__stdcall *GetSystemMetrics_f)(int);
[[nodiscard]] static inline int getTitleBarHeight(const HWND hwnd) [[nodiscard]] static inline int getTitleBarHeight(const HWND hwnd)
{ {
const UINT dpi = GetDpiForWindow(hwnd); const UINT dpi = GetDpiForWindow2(hwnd);
const int captionHeight = GetSystemMetricsForDpi(SM_CYCAPTION, dpi);
if (IsZoomed(hwnd)) auto pGetSystemMetricsForDpi = reinterpret_cast<GetSystemMetricsForDpi_f>(GetProcAddress(LoadLibraryW(L"USER32.dll"), "GetSystemMetricsForDpi"));
return captionHeight; auto pGetSystemMetrics = reinterpret_cast<GetSystemMetrics_f>(GetProcAddress(LoadLibraryW(L"USER32.dll"), "GetSystemMetrics"));
// The frame height should also be taken into account if the window
// is not maximized. if (pGetSystemMetricsForDpi)
const int frameHeight = GetSystemMetricsForDpi(SM_CYSIZEFRAME, dpi) {
+ GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi); const int captionHeight = pGetSystemMetricsForDpi(SM_CYCAPTION, dpi);
return captionHeight + frameHeight; if (IsZoomed(hwnd))
return captionHeight;
// The frame height should also be taken into account if the window
// is not maximized.
const int frameHeight = pGetSystemMetricsForDpi(SM_CYSIZEFRAME, dpi)
+ pGetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
return captionHeight + frameHeight;
}
else
{
const int captionHeight = pGetSystemMetrics(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 = pGetSystemMetrics(SM_CYSIZEFRAME)
+ pGetSystemMetrics(SM_CXPADDEDBORDER);
return captionHeight + frameHeight;
}
} }
[[nodiscard]] static inline bool isSystemMenuOffsetNeeded(const Qt::WindowFlags flags) [[nodiscard]] static inline bool isSystemMenuOffsetNeeded(const Qt::WindowFlags flags)

View File

@ -49,6 +49,8 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
{ {
*result = 0; *result = 0;
const quint32 pointerId = GET_POINTERID_WPARAM(msg.wParam); const quint32 pointerId = GET_POINTERID_WPARAM(msg.wParam);
#if 0
if (!GetPointerType(pointerId, &m_pointerType)) { if (!GetPointerType(pointerId, &m_pointerType)) {
qWarning() << "GetPointerType() failed:" << qt_error_string(); qWarning() << "GetPointerType() failed:" << qt_error_string();
@ -131,6 +133,8 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
return translatePenEvent(window, hwnd, et, msg, &penInfo); return translatePenEvent(window, hwnd, et, msg, &penInfo);
} }
} }
#endif
return false; return false;
} }
@ -558,6 +562,7 @@ QWindowsPointerHandler::QPointingDevicePtr QWindowsPointerHandler::findTabletDev
bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et,
MSG msg, PVOID vPenInfo) MSG msg, PVOID vPenInfo)
{ {
#if 0
#if QT_CONFIG(tabletevent) #if QT_CONFIG(tabletevent)
if (et & QtWindows::NonClientEventFlag) if (et & QtWindows::NonClientEventFlag)
return false; // Let DefWindowProc() handle Non Client messages. return false; // Let DefWindowProc() handle Non Client messages.
@ -691,6 +696,8 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
Q_UNUSED(vPenInfo); Q_UNUSED(vPenInfo);
return false; return false;
#endif #endif
#endif
return false;
} }
static inline bool isMouseEventSynthesizedFromPenOrTouch() static inline bool isMouseEventSynthesizedFromPenOrTouch()

View File

@ -26,6 +26,11 @@ QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals; using namespace Qt::StringLiterals;
HRESULT GetDpiForMonitor2(HMONITOR hmonitor,
MONITOR_DPI_TYPE dpiType,
UINT *pDpiX,
UINT *pDpiY);
static inline QDpi deviceDPI(HDC hdc) static inline QDpi deviceDPI(HDC hdc)
{ {
return QDpi(GetDeviceCaps(hdc, LOGPIXELSX), GetDeviceCaps(hdc, LOGPIXELSY)); return QDpi(GetDeviceCaps(hdc, LOGPIXELSX), GetDeviceCaps(hdc, LOGPIXELSY));
@ -35,7 +40,7 @@ static inline QDpi monitorDPI(HMONITOR hMonitor)
{ {
UINT dpiX; UINT dpiX;
UINT dpiY; UINT dpiY;
if (SUCCEEDED(GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) if (SUCCEEDED(GetDpiForMonitor2(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY)))
return QDpi(dpiX, dpiY); return QDpi(dpiX, dpiY);
return {0, 0}; return {0, 0};
} }
@ -425,6 +430,10 @@ QRect QWindowsScreen::virtualGeometry(const QPlatformScreen *screen) // cf QScre
return result; return result;
} }
typedef BOOL (__stdcall *SetDisplayAutoRotationPreferences_f)(
ORIENTATION_PREFERENCE orientation
);
bool QWindowsScreen::setOrientationPreference(Qt::ScreenOrientation o) bool QWindowsScreen::setOrientationPreference(Qt::ScreenOrientation o)
{ {
bool result = false; bool result = false;
@ -444,8 +453,14 @@ bool QWindowsScreen::setOrientationPreference(Qt::ScreenOrientation o)
case Qt::InvertedLandscapeOrientation: case Qt::InvertedLandscapeOrientation:
orientationPreference = ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED; orientationPreference = ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED;
break; break;
} }
result = SetDisplayAutoRotationPreferences(orientationPreference);
auto pSetDisplayAutoRotationPreferences = reinterpret_cast<SetDisplayAutoRotationPreferences_f>(GetProcAddress(LoadLibraryW(L"user32.dll"), "SetDisplayAutoRotationPreferences"));
if (pSetDisplayAutoRotationPreferences) {
result = pSetDisplayAutoRotationPreferences(orientationPreference);
}
return result; return result;
} }

View File

@ -47,6 +47,14 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
typedef int (__stdcall *GetSystemMetricsForDpi_f)(int, UINT);
typedef int (__stdcall *GetSystemMetrics_f)(int);
typedef HRESULT(__stdcall *GetDpiForMonitor_f)(HMONITOR hmonitor,
MONITOR_DPI_TYPE dpiType,
UINT *pDpiX,
UINT *pDpiY);
typedef UINT(__stdcall *GetDpiForWindow_f)(HWND hwnd);
using QWindowCreationContextPtr = QSharedPointer<QWindowCreationContext>; using QWindowCreationContextPtr = QSharedPointer<QWindowCreationContext>;
enum { enum {
@ -518,17 +526,78 @@ static inline void updateGLWindowSettings(const QWindow *w, HWND hwnd, Qt::Windo
[[nodiscard]] static inline int getResizeBorderThickness(const UINT dpi) [[nodiscard]] static inline int getResizeBorderThickness(const UINT dpi)
{ {
auto pGetSystemMetricsForDpi = reinterpret_cast<GetSystemMetricsForDpi_f>(GetProcAddress(LoadLibraryW(L"USER32.dll"), "GetSystemMetricsForDpi"));
auto pGetSystemMetrics = reinterpret_cast<GetSystemMetrics_f>(GetProcAddress(LoadLibraryW(L"USER32.dll"), "GetSystemMetrics"));
// The width of the padded border will always be 0 if DWM composition is // 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, but since it will always be enabled and can't be programtically
// disabled from Windows 8, we are safe to go. // disabled from Windows 8, we are safe to go.
return GetSystemMetricsForDpi(SM_CXSIZEFRAME, dpi)
+ GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi); if (pGetSystemMetricsForDpi)
{
return pGetSystemMetricsForDpi(SM_CXSIZEFRAME, dpi)
+ pGetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
}
else if (pGetSystemMetrics)
{
return pGetSystemMetrics(SM_CXSIZEFRAME)
+ pGetSystemMetrics(SM_CXPADDEDBORDER);
} else {
return 0;
}
} }
/*! /*!
Calculates the dimensions of the invisible borders within the Calculates the dimensions of the invisible borders within the
window frames which only exist on Windows 10 and onwards. window frames which only exist on Windows 10 and onwards.
*/ */
HRESULT GetDpiForMonitor2(HMONITOR hmonitor,
MONITOR_DPI_TYPE dpiType,
UINT *pDpiX,
UINT *pDpiY)
{
auto pGetDpiForMonitor = reinterpret_cast<GetDpiForMonitor_f>(GetProcAddress(LoadLibraryW(L"api-ms-win-shcore-scaling-l1-1-1.dll"), "GetDpiForMonitor"));
if (pGetDpiForMonitor)
{
return pGetDpiForMonitor(hmonitor, dpiType, pDpiX, pDpiY);
}
auto hwnd = GetActiveWindow();
if (HDC hDC = GetDC(hwnd))
{
auto dpiX = GetDeviceCaps(hDC, LOGPIXELSX);
auto dpiY = GetDeviceCaps(hDC, LOGPIXELSY);
ReleaseDC(hwnd, hDC);
*pDpiX = dpiX;
*pDpiY = dpiY;
return S_OK;
}
else
{
*pDpiX = 97;
*pDpiY = 97;
return S_OK;
}
}
UINT GetDpiForWindow2(HWND hwnd)
{
auto pGetDpiForWindow = reinterpret_cast<GetDpiForWindow_f>(GetProcAddress(LoadLibraryW(L"USER32.dll"), "GetDpiForWindow"));
if (pGetDpiForWindow) {
return pGetDpiForWindow(hwnd);
}
if (HDC hDC = GetDC(hwnd))
{
return GetDeviceCaps(hDC, LOGPIXELSX);
}
else
{
return 97;
}
}
static QMargins invisibleMargins(QPoint screenPoint) static QMargins invisibleMargins(QPoint screenPoint)
{ {
@ -536,7 +605,7 @@ static QMargins invisibleMargins(QPoint screenPoint)
if (HMONITOR hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL)) { if (HMONITOR hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL)) {
UINT dpiX; UINT dpiX;
UINT dpiY; UINT dpiY;
if (SUCCEEDED(GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) { if (SUCCEEDED(GetDpiForMonitor2(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) {
const int gap = getResizeBorderThickness(dpiX); const int gap = getResizeBorderThickness(dpiX);
return QMargins(gap, 0, gap, gap); return QMargins(gap, 0, gap, gap);
} }
@ -546,7 +615,7 @@ static QMargins invisibleMargins(QPoint screenPoint)
[[nodiscard]] static inline QMargins invisibleMargins(const HWND hwnd) [[nodiscard]] static inline QMargins invisibleMargins(const HWND hwnd)
{ {
const UINT dpi = GetDpiForWindow(hwnd); const UINT dpi = GetDpiForWindow2(hwnd);
const int gap = getResizeBorderThickness(dpi); const int gap = getResizeBorderThickness(dpi);
return QMargins(gap, 0, gap, gap); return QMargins(gap, 0, gap, gap);
} }
@ -1024,6 +1093,49 @@ static QSize toNativeSizeConstrained(QSize dip, const QScreen *s)
\internal \internal
*/ */
typedef BOOL (__stdcall *AdjustWindowRectExForDpi_f)(
LPRECT lpRect,
DWORD dwStyle,
BOOL bMenu,
DWORD dwExStyle,
UINT dpi
);
typedef BOOL (__stdcall *AdjustWindowRectEx_f)(
LPRECT lpRect,
DWORD dwStyle,
BOOL bMenu,
DWORD dwExStyle
);
static BOOL AdjustWindowRectExForDpi2(LPRECT lpRect,
DWORD dwStyle,
BOOL bMenu,
DWORD dwExStyle,
UINT dpi
)
{
auto pAdjustWindowRectExForDpi = reinterpret_cast<AdjustWindowRectExForDpi_f>(GetProcAddress(LoadLibraryW(L"user32.dll"), "AdjustWindowRectExForDpi"));
if (pAdjustWindowRectExForDpi) {
return pAdjustWindowRectExForDpi(lpRect,
dwStyle,
bMenu,
dwExStyle,
dpi);
}
auto pAdjustWindowRectEx = reinterpret_cast<AdjustWindowRectEx_f>(GetProcAddress(LoadLibraryW(L"user32.dll"), "AdjustWindowRectEx"));
if (pAdjustWindowRectEx) {
return pAdjustWindowRectEx(lpRect,
dwStyle,
bMenu,
dwExStyle);
}
return 0;
}
QMargins QWindowsGeometryHint::frameOnPrimaryScreen(const QWindow *w, DWORD style, DWORD exStyle) QMargins QWindowsGeometryHint::frameOnPrimaryScreen(const QWindow *w, DWORD style, DWORD exStyle)
{ {
if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint)) if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint))
@ -1054,7 +1166,7 @@ QMargins QWindowsGeometryHint::frame(const QWindow *w, DWORD style, DWORD exStyl
return {}; return {};
RECT rect = {0,0,0,0}; RECT rect = {0,0,0,0};
style &= ~DWORD(WS_OVERLAPPED); // Not permitted, see docs. style &= ~DWORD(WS_OVERLAPPED); // Not permitted, see docs.
if (AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, unsigned(qRound(dpi))) == FALSE) { if (AdjustWindowRectExForDpi2(&rect, style, FALSE, exStyle, unsigned(qRound(dpi))) == FALSE) {
qErrnoWarning("%s: AdjustWindowRectExForDpi failed", __FUNCTION__); qErrnoWarning("%s: AdjustWindowRectExForDpi failed", __FUNCTION__);
} }
const QMargins result(qAbs(rect.left), qAbs(rect.top), const QMargins result(qAbs(rect.left), qAbs(rect.top),
@ -1545,7 +1657,7 @@ void QWindowsWindow::initialize()
QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(w, obtainedGeometry); QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(w, obtainedGeometry);
} }
} }
QWindowsWindow::setSavedDpi(GetDpiForWindow(handle())); QWindowsWindow::setSavedDpi(GetDpiForWindow2(handle()));
} }
QSurfaceFormat QWindowsWindow::format() const QSurfaceFormat QWindowsWindow::format() const
@ -2011,7 +2123,7 @@ void QWindowsWindow::handleDpiChanged(HWND hwnd, WPARAM wParam, LPARAM lParam)
void QWindowsWindow::handleDpiChangedAfterParent(HWND hwnd) void QWindowsWindow::handleDpiChangedAfterParent(HWND hwnd)
{ {
const UINT dpi = GetDpiForWindow(hwnd); const UINT dpi = GetDpiForWindow2(hwnd);
const qreal scale = qreal(dpi) / qreal(savedDpi()); const qreal scale = qreal(dpi) / qreal(savedDpi());
setSavedDpi(dpi); setSavedDpi(dpi);