[*] Restore Windows 7 support [pt 2]
Change-Id: Iae61503a4aa2f788fe76b9e9b7a7c1ad1abfae36
This commit is contained in:
parent
21ed922bf6
commit
30fa00045e
@ -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(¤tMode);
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
result = currentMode == 1; // Touch, 1
|
|
||||||
viewSettings->Release();
|
|
||||||
}
|
|
||||||
uiViewSettingsInterop->Release();
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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()
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user