forked from github_mirror/framelesshelper
parent
b789c050cc
commit
4e1d324100
|
@ -54,9 +54,12 @@ FramelessHelper::FramelessHelper(QObject *parent) : QObject(parent) {
|
||||||
connect(this, &FramelessHelper::framelessWindowsChanged,
|
connect(this, &FramelessHelper::framelessWindowsChanged,
|
||||||
[this]() { updateQtFrame_internal(m_titlebarHeight); });
|
[this]() { updateQtFrame_internal(m_titlebarHeight); });
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
m_borderWidth = WinNativeEventFilter::borderWidth(nullptr);
|
m_borderWidth = WinNativeEventFilter::getSystemMetric(
|
||||||
m_borderHeight = WinNativeEventFilter::borderHeight(nullptr);
|
nullptr, WinNativeEventFilter::SystemMetric::BorderWidth, false);
|
||||||
m_titlebarHeight = WinNativeEventFilter::titlebarHeight(nullptr);
|
m_borderHeight = WinNativeEventFilter::getSystemMetric(
|
||||||
|
nullptr, WinNativeEventFilter::SystemMetric::BorderHeight, false);
|
||||||
|
m_titlebarHeight = WinNativeEventFilter::getSystemMetric(
|
||||||
|
nullptr, WinNativeEventFilter::SystemMetric::TitleBarHeight, false);
|
||||||
#else
|
#else
|
||||||
// TODO: The default border width and height on Windows is 8 pixels if DPI
|
// TODO: The default border width and height on Windows is 8 pixels if DPI
|
||||||
// is 96. Don't know how to acquire these values on UNIX platforms.
|
// is 96. Don't know how to acquire these values on UNIX platforms.
|
||||||
|
|
3
main.cpp
3
main.cpp
|
@ -18,14 +18,11 @@ int main(int argc, char *argv[]) {
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
|
|
||||||
|
|
||||||
QApplication application(argc, argv);
|
QApplication application(argc, argv);
|
||||||
|
|
||||||
FramelessHelper helper;
|
FramelessHelper helper;
|
||||||
|
|
||||||
QWidget widget;
|
QWidget widget;
|
||||||
widget.setAttribute(Qt::WA_DontCreateNativeAncestors);
|
|
||||||
helper.setFramelessWindows({&widget});
|
helper.setFramelessWindows({&widget});
|
||||||
widget.show();
|
widget.show();
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
</compatibility>
|
</compatibility>
|
||||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
<windowsSettings>
|
<windowsSettings>
|
||||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
|
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
|
||||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
|
||||||
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
|
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
|
||||||
</windowsSettings>
|
</windowsSettings>
|
||||||
</application>
|
</application>
|
||||||
|
|
|
@ -25,11 +25,7 @@
|
||||||
#include "winnativeeventfilter.h"
|
#include "winnativeeventfilter.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#else
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#endif
|
|
||||||
#include <QLibrary>
|
#include <QLibrary>
|
||||||
#include <QOperatingSystemVersion>
|
#include <QOperatingSystemVersion>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
@ -105,12 +101,12 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef WM_DPICHANGED
|
#ifndef WM_DPICHANGED
|
||||||
// Only available since Windows 7
|
// Only available since Windows 8.1
|
||||||
#define WM_DPICHANGED 0x02E0
|
#define WM_DPICHANGED 0x02E0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ABM_GETAUTOHIDEBAREX
|
#ifndef ABM_GETAUTOHIDEBAREX
|
||||||
// Only available since Windows 8
|
// Only available since Windows 8.1
|
||||||
#define ABM_GETAUTOHIDEBAREX 0x0000000b
|
#define ABM_GETAUTOHIDEBAREX 0x0000000b
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -174,6 +170,12 @@ using APPBARDATA = struct _APPBARDATA {
|
||||||
LPARAM lParam;
|
LPARAM lParam;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using PROCESS_DPI_AWARENESS = enum _PROCESS_DPI_AWARENESS {
|
||||||
|
PROCESS_DPI_UNAWARE = 0,
|
||||||
|
PROCESS_SYSTEM_DPI_AWARE = 1,
|
||||||
|
PROCESS_PER_MONITOR_DPI_AWARE = 2
|
||||||
|
};
|
||||||
|
|
||||||
WNEF_GENERATE_WINAPI(GetSystemDpiForProcess, UINT, HANDLE)
|
WNEF_GENERATE_WINAPI(GetSystemDpiForProcess, UINT, HANDLE)
|
||||||
WNEF_GENERATE_WINAPI(GetDpiForWindow, UINT, HWND)
|
WNEF_GENERATE_WINAPI(GetDpiForWindow, UINT, HWND)
|
||||||
WNEF_GENERATE_WINAPI(GetDpiForSystem, UINT)
|
WNEF_GENERATE_WINAPI(GetDpiForSystem, UINT)
|
||||||
|
@ -232,6 +234,10 @@ WNEF_GENERATE_WINAPI(DeleteObject, BOOL, HGDIOBJ)
|
||||||
WNEF_GENERATE_WINAPI(IsThemeActive, BOOL)
|
WNEF_GENERATE_WINAPI(IsThemeActive, BOOL)
|
||||||
WNEF_GENERATE_WINAPI(BeginPaint, HDC, HWND, LPPAINTSTRUCT)
|
WNEF_GENERATE_WINAPI(BeginPaint, HDC, HWND, LPPAINTSTRUCT)
|
||||||
WNEF_GENERATE_WINAPI(EndPaint, BOOL, HWND, CONST LPPAINTSTRUCT)
|
WNEF_GENERATE_WINAPI(EndPaint, BOOL, HWND, CONST LPPAINTSTRUCT)
|
||||||
|
WNEF_GENERATE_WINAPI(GetCurrentProcess, HANDLE)
|
||||||
|
WNEF_GENERATE_WINAPI(GetProcessDpiAwareness, HRESULT, HANDLE,
|
||||||
|
PROCESS_DPI_AWARENESS *)
|
||||||
|
WNEF_GENERATE_WINAPI(IsProcessDPIAware, BOOL)
|
||||||
|
|
||||||
BOOL IsDwmCompositionEnabled() {
|
BOOL IsDwmCompositionEnabled() {
|
||||||
// Since Win8, DWM composition is always enabled and can't be disabled.
|
// Since Win8, DWM composition is always enabled and can't be disabled.
|
||||||
|
@ -347,18 +353,6 @@ void WinNativeEventFilter::clearFramelessWindows() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int WinNativeEventFilter::borderWidth(HWND handle) {
|
|
||||||
return getBorderWidthForWindow(handle, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int WinNativeEventFilter::borderHeight(HWND handle) {
|
|
||||||
return getBorderHeightForWindow(handle, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int WinNativeEventFilter::titlebarHeight(HWND handle) {
|
|
||||||
return getTitlebarHeightForWindow(handle, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||||
bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
|
bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
|
||||||
void *message, qintptr *result)
|
void *message, qintptr *result)
|
||||||
|
@ -391,12 +385,15 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
|
||||||
if (!data->initialized) {
|
if (!data->initialized) {
|
||||||
// Avoid initializing a same window twice.
|
// Avoid initializing a same window twice.
|
||||||
data->initialized = TRUE;
|
data->initialized = TRUE;
|
||||||
|
// Restore default window style.
|
||||||
|
m_lpSetWindowLongPtrW(msg->hwnd, GWL_STYLE,
|
||||||
|
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN |
|
||||||
|
WS_CLIPSIBLINGS);
|
||||||
// The following two lines can help us get rid of the three system
|
// The following two lines can help us get rid of the three system
|
||||||
// buttons (minimize, maximize and close). But they also break the
|
// buttons (minimize, maximize and close). But they also break the
|
||||||
// Arcylic effect (introduced in Win10 1709), don't know why.
|
// Arcylic effect (introduced in Win10 1709), don't know why.
|
||||||
m_lpSetWindowLongPtrW(msg->hwnd, GWL_EXSTYLE,
|
m_lpSetWindowLongPtrW(msg->hwnd, GWL_EXSTYLE,
|
||||||
m_lpGetWindowLongPtrW(msg->hwnd, GWL_EXSTYLE) |
|
WS_EX_APPWINDOW | WS_EX_LAYERED);
|
||||||
WS_EX_LAYERED);
|
|
||||||
m_lpSetLayeredWindowAttributes(msg->hwnd, RGB(255, 0, 255), 0,
|
m_lpSetLayeredWindowAttributes(msg->hwnd, RGB(255, 0, 255), 0,
|
||||||
LWA_COLORKEY);
|
LWA_COLORKEY);
|
||||||
// Make sure our window have it's frame shadow.
|
// Make sure our window have it's frame shadow.
|
||||||
|
@ -412,10 +409,13 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
|
||||||
<< getDotsPerInchForWindow(msg->hwnd)
|
<< getDotsPerInchForWindow(msg->hwnd)
|
||||||
<< "Window DPR:"
|
<< "Window DPR:"
|
||||||
<< getDevicePixelRatioForWindow(msg->hwnd);
|
<< getDevicePixelRatioForWindow(msg->hwnd);
|
||||||
qDebug().noquote() << "Window border width:" << borderWidth(msg->hwnd)
|
qDebug().noquote()
|
||||||
<< "Window border height:" << borderHeight(msg->hwnd)
|
<< "Window border width:"
|
||||||
<< "Window titlebar height:"
|
<< getSystemMetric(msg->hwnd, SystemMetric::BorderWidth, false)
|
||||||
<< titlebarHeight(msg->hwnd);
|
<< "Window border height:"
|
||||||
|
<< getSystemMetric(msg->hwnd, SystemMetric::BorderHeight, false)
|
||||||
|
<< "Window titlebar height:"
|
||||||
|
<< getSystemMetric(msg->hwnd, SystemMetric::TitleBarHeight, false);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
switch (msg->message) {
|
switch (msg->message) {
|
||||||
|
@ -434,8 +434,10 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
|
||||||
if (IsMaximized(_hWnd) || IsFullScreened(_hWnd)) {
|
if (IsMaximized(_hWnd) || IsFullScreened(_hWnd)) {
|
||||||
// Windows automatically adds a standard width border to all
|
// Windows automatically adds a standard width border to all
|
||||||
// sides when a window is maximized.
|
// sides when a window is maximized.
|
||||||
int frameThickness_x = getBorderWidthForWindow(_hWnd);
|
int frameThickness_x =
|
||||||
int frameThickness_y = getBorderHeightForWindow(_hWnd);
|
getSystemMetric(_hWnd, SystemMetric::BorderWidth);
|
||||||
|
int frameThickness_y =
|
||||||
|
getSystemMetric(_hWnd, SystemMetric::BorderHeight);
|
||||||
// The following two lines are two seperate functions in
|
// The following two lines are two seperate functions in
|
||||||
// Chromium, it uses them to judge whether the window
|
// Chromium, it uses them to judge whether the window
|
||||||
// should draw it's own frame or not. But here we will always
|
// should draw it's own frame or not. But here we will always
|
||||||
|
@ -478,30 +480,56 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
|
||||||
abd.cbSize = sizeof(abd);
|
abd.cbSize = sizeof(abd);
|
||||||
const UINT taskbarState = m_lpSHAppBarMessage(ABM_GETSTATE, &abd);
|
const UINT taskbarState = m_lpSHAppBarMessage(ABM_GETSTATE, &abd);
|
||||||
if (taskbarState & ABS_AUTOHIDE) {
|
if (taskbarState & ABS_AUTOHIDE) {
|
||||||
const HMONITOR hMonitor =
|
const HMONITOR windowMonitor =
|
||||||
m_lpMonitorFromWindow(msg->hwnd, MONITOR_DEFAULTTONEAREST);
|
m_lpMonitorFromWindow(msg->hwnd, MONITOR_DEFAULTTONEAREST);
|
||||||
MONITORINFO monitorInfo;
|
bool top = false, bottom = false, left = false, right = false;
|
||||||
SecureZeroMemory(&monitorInfo, sizeof(monitorInfo));
|
if (QOperatingSystemVersion::current() >=
|
||||||
monitorInfo.cbSize = sizeof(monitorInfo);
|
QOperatingSystemVersion::Windows8_1) {
|
||||||
m_lpGetMonitorInfoW(hMonitor, &monitorInfo);
|
MONITORINFO monitorInfo;
|
||||||
const auto hasAutohideTaskbar =
|
SecureZeroMemory(&monitorInfo, sizeof(monitorInfo));
|
||||||
[&monitorInfo](const UINT edge) -> bool {
|
monitorInfo.cbSize = sizeof(monitorInfo);
|
||||||
|
m_lpGetMonitorInfoW(windowMonitor, &monitorInfo);
|
||||||
|
const auto hasAutohideTaskbar =
|
||||||
|
[&monitorInfo](const UINT edge) -> bool {
|
||||||
|
APPBARDATA _abd;
|
||||||
|
SecureZeroMemory(&_abd, sizeof(_abd));
|
||||||
|
_abd.cbSize = sizeof(_abd);
|
||||||
|
_abd.uEdge = edge;
|
||||||
|
_abd.rc = monitorInfo.rcMonitor;
|
||||||
|
const auto hTaskbar = reinterpret_cast<HWND>(
|
||||||
|
m_lpSHAppBarMessage(ABM_GETAUTOHIDEBAREX, &_abd));
|
||||||
|
return hTaskbar != nullptr;
|
||||||
|
};
|
||||||
|
top = hasAutohideTaskbar(ABE_TOP);
|
||||||
|
bottom = hasAutohideTaskbar(ABE_BOTTOM);
|
||||||
|
left = hasAutohideTaskbar(ABE_LEFT);
|
||||||
|
right = hasAutohideTaskbar(ABE_RIGHT);
|
||||||
|
} else {
|
||||||
|
int edge = -1;
|
||||||
APPBARDATA _abd;
|
APPBARDATA _abd;
|
||||||
SecureZeroMemory(&_abd, sizeof(_abd));
|
SecureZeroMemory(&_abd, sizeof(_abd));
|
||||||
_abd.cbSize = sizeof(_abd);
|
_abd.cbSize = sizeof(_abd);
|
||||||
_abd.uEdge = edge;
|
_abd.hWnd = m_lpFindWindowW(L"Shell_TrayWnd", nullptr);
|
||||||
_abd.rc = monitorInfo.rcMonitor;
|
if (_abd.hWnd) {
|
||||||
const auto hTaskbar = reinterpret_cast<HWND>(
|
const HMONITOR taskbarMonitor = m_lpMonitorFromWindow(
|
||||||
m_lpSHAppBarMessage(ABM_GETAUTOHIDEBAREX, &_abd));
|
_abd.hWnd, MONITOR_DEFAULTTOPRIMARY);
|
||||||
return hTaskbar != nullptr;
|
if (taskbarMonitor == windowMonitor) {
|
||||||
};
|
m_lpSHAppBarMessage(ABM_GETTASKBARPOS, &_abd);
|
||||||
if (hasAutohideTaskbar(ABE_TOP)) {
|
edge = _abd.uEdge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
top = edge == ABE_TOP;
|
||||||
|
bottom = edge == ABE_BOTTOM;
|
||||||
|
left = edge == ABE_LEFT;
|
||||||
|
right = edge == ABE_RIGHT;
|
||||||
|
}
|
||||||
|
if (top) {
|
||||||
clientRect->top += kAutoHideTaskbarThicknessPy;
|
clientRect->top += kAutoHideTaskbarThicknessPy;
|
||||||
} else if (hasAutohideTaskbar(ABE_BOTTOM)) {
|
} else if (bottom) {
|
||||||
clientRect->bottom -= kAutoHideTaskbarThicknessPy;
|
clientRect->bottom -= kAutoHideTaskbarThicknessPy;
|
||||||
} else if (hasAutohideTaskbar(ABE_LEFT)) {
|
} else if (left) {
|
||||||
clientRect->left += kAutoHideTaskbarThicknessPx;
|
clientRect->left += kAutoHideTaskbarThicknessPx;
|
||||||
} else if (hasAutohideTaskbar(ABE_RIGHT)) {
|
} else if (right) {
|
||||||
clientRect->right -= kAutoHideTaskbarThicknessPx;
|
clientRect->right -= kAutoHideTaskbarThicknessPx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -578,9 +606,10 @@ bool WinNativeEventFilter::nativeEventFilter(const QByteArray &eventType,
|
||||||
mouse.y = GET_Y_LPARAM(_lParam);
|
mouse.y = GET_Y_LPARAM(_lParam);
|
||||||
m_lpScreenToClient(_hWnd, &mouse);
|
m_lpScreenToClient(_hWnd, &mouse);
|
||||||
// These values are DPI-aware.
|
// These values are DPI-aware.
|
||||||
const LONG bw = getBorderWidthForWindow(_hWnd);
|
const LONG bw = getSystemMetric(_hWnd, SystemMetric::BorderWidth);
|
||||||
const LONG bh = getBorderHeightForWindow(_hWnd);
|
const LONG bh = getSystemMetric(_hWnd, SystemMetric::BorderHeight);
|
||||||
const LONG tbh = getTitlebarHeightForWindow(_hWnd);
|
const LONG tbh =
|
||||||
|
getSystemMetric(_hWnd, SystemMetric::TitleBarHeight);
|
||||||
const qreal dpr = getDevicePixelRatioForWindow(_hWnd);
|
const qreal dpr = getDevicePixelRatioForWindow(_hWnd);
|
||||||
const bool isTitlebar = (mouse.y < tbh) &&
|
const bool isTitlebar = (mouse.y < tbh) &&
|
||||||
!isInSpecificAreas(mouse.x, mouse.y,
|
!isInSpecificAreas(mouse.x, mouse.y,
|
||||||
|
@ -765,14 +794,25 @@ UINT WinNativeEventFilter::getDotsPerInchForWindow(HWND handle) {
|
||||||
}
|
}
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
};
|
};
|
||||||
|
bool dpiEnabled = false;
|
||||||
|
if (m_lpGetProcessDpiAwareness) {
|
||||||
|
PROCESS_DPI_AWARENESS awareness = PROCESS_DPI_UNAWARE;
|
||||||
|
m_lpGetProcessDpiAwareness(m_lpGetCurrentProcess(), &awareness);
|
||||||
|
dpiEnabled = awareness != PROCESS_DPI_UNAWARE;
|
||||||
|
} else if (m_lpIsProcessDPIAware) {
|
||||||
|
dpiEnabled = m_lpIsProcessDPIAware();
|
||||||
|
}
|
||||||
|
if (!dpiEnabled) {
|
||||||
|
// Return hard-coded DPI if DPI scaling is disabled.
|
||||||
|
return m_defaultDotsPerInch;
|
||||||
|
}
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
if (m_lpGetSystemDpiForProcess) {
|
if (m_lpGetSystemDpiForProcess) {
|
||||||
return m_lpGetSystemDpiForProcess(GetCurrentProcess());
|
return m_lpGetSystemDpiForProcess(m_lpGetCurrentProcess());
|
||||||
} else if (m_lpGetDpiForSystem) {
|
} else if (m_lpGetDpiForSystem) {
|
||||||
return m_lpGetDpiForSystem();
|
return m_lpGetDpiForSystem();
|
||||||
} else {
|
|
||||||
return getScreenDpi(m_defaultDotsPerInch);
|
|
||||||
}
|
}
|
||||||
|
return getScreenDpi(m_defaultDotsPerInch);
|
||||||
}
|
}
|
||||||
if (m_lpGetDpiForWindow) {
|
if (m_lpGetDpiForWindow) {
|
||||||
return m_lpGetDpiForWindow(handle);
|
return m_lpGetDpiForWindow(handle);
|
||||||
|
@ -896,16 +936,20 @@ void WinNativeEventFilter::initWin32Api() {
|
||||||
WNEF_RESOLVE_WINAPI(Gdi32, DeleteObject)
|
WNEF_RESOLVE_WINAPI(Gdi32, DeleteObject)
|
||||||
// Available since Windows XP.
|
// Available since Windows XP.
|
||||||
WNEF_RESOLVE_WINAPI(Shell32, SHAppBarMessage)
|
WNEF_RESOLVE_WINAPI(Shell32, SHAppBarMessage)
|
||||||
|
WNEF_RESOLVE_WINAPI(Kernel32, GetCurrentProcess)
|
||||||
// Available since Windows Vista.
|
// Available since Windows Vista.
|
||||||
|
WNEF_RESOLVE_WINAPI(User32, IsProcessDPIAware)
|
||||||
WNEF_RESOLVE_WINAPI(Dwmapi, DwmIsCompositionEnabled)
|
WNEF_RESOLVE_WINAPI(Dwmapi, DwmIsCompositionEnabled)
|
||||||
WNEF_RESOLVE_WINAPI(Dwmapi, DwmExtendFrameIntoClientArea)
|
WNEF_RESOLVE_WINAPI(Dwmapi, DwmExtendFrameIntoClientArea)
|
||||||
WNEF_RESOLVE_WINAPI(Dwmapi, DwmSetWindowAttribute)
|
WNEF_RESOLVE_WINAPI(Dwmapi, DwmSetWindowAttribute)
|
||||||
WNEF_RESOLVE_WINAPI(UxTheme, IsThemeActive)
|
WNEF_RESOLVE_WINAPI(UxTheme, IsThemeActive)
|
||||||
|
// Available since Windows 8.1
|
||||||
if (QOperatingSystemVersion::current() >=
|
if (QOperatingSystemVersion::current() >=
|
||||||
QOperatingSystemVersion::Windows8_1) {
|
QOperatingSystemVersion::Windows8_1) {
|
||||||
WNEF_RESOLVE_WINAPI(SHCore, GetDpiForMonitor)
|
WNEF_RESOLVE_WINAPI(SHCore, GetDpiForMonitor)
|
||||||
|
WNEF_RESOLVE_WINAPI(SHCore, GetProcessDpiAwareness)
|
||||||
}
|
}
|
||||||
// Windows 10, version 1607 (10.0.14393)
|
// Available since Windows 10, version 1607 (10.0.14393)
|
||||||
if (QOperatingSystemVersion::current() >=
|
if (QOperatingSystemVersion::current() >=
|
||||||
QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0,
|
QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0,
|
||||||
14393)) {
|
14393)) {
|
||||||
|
@ -913,7 +957,7 @@ void WinNativeEventFilter::initWin32Api() {
|
||||||
WNEF_RESOLVE_WINAPI(User32, GetDpiForSystem)
|
WNEF_RESOLVE_WINAPI(User32, GetDpiForSystem)
|
||||||
WNEF_RESOLVE_WINAPI(User32, GetSystemMetricsForDpi)
|
WNEF_RESOLVE_WINAPI(User32, GetSystemMetricsForDpi)
|
||||||
}
|
}
|
||||||
// Windows 10, version 1803 (10.0.17134)
|
// Available since Windows 10, version 1803 (10.0.17134)
|
||||||
if (QOperatingSystemVersion::current() >=
|
if (QOperatingSystemVersion::current() >=
|
||||||
QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0,
|
QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0,
|
||||||
17134)) {
|
17134)) {
|
||||||
|
@ -1005,7 +1049,8 @@ void WinNativeEventFilter::updateWindow(HWND handle, bool triggerFrameChange) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int WinNativeEventFilter::getBorderWidthForWindow(HWND handle, bool dpiAware) {
|
int WinNativeEventFilter::getSystemMetric(HWND handle, SystemMetric metric,
|
||||||
|
bool dpiAware) {
|
||||||
initWin32Api();
|
initWin32Api();
|
||||||
const qreal dpr = dpiAware ? getDevicePixelRatioForWindow(handle)
|
const qreal dpr = dpiAware ? getDevicePixelRatioForWindow(handle)
|
||||||
: m_defaultDevicePixelRatio;
|
: m_defaultDevicePixelRatio;
|
||||||
|
@ -1013,64 +1058,69 @@ int WinNativeEventFilter::getBorderWidthForWindow(HWND handle, bool dpiAware) {
|
||||||
createUserData(handle);
|
createUserData(handle);
|
||||||
const auto userData = reinterpret_cast<WINDOW *>(
|
const auto userData = reinterpret_cast<WINDOW *>(
|
||||||
m_lpGetWindowLongPtrW(handle, GWLP_USERDATA));
|
m_lpGetWindowLongPtrW(handle, GWLP_USERDATA));
|
||||||
const int bw = userData->windowData.borderWidth;
|
switch (metric) {
|
||||||
if (bw > 0) {
|
case SystemMetric::BorderWidth: {
|
||||||
return std::round(bw * dpr);
|
const int bw = userData->windowData.borderWidth;
|
||||||
|
if (bw > 0) {
|
||||||
|
return std::round(bw * dpr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SystemMetric::BorderHeight: {
|
||||||
|
const int bh = userData->windowData.borderHeight;
|
||||||
|
if (bh > 0) {
|
||||||
|
return std::round(bh * dpr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SystemMetric::TitleBarHeight: {
|
||||||
|
const int tbh = userData->windowData.titlebarHeight;
|
||||||
|
if (tbh > 0) {
|
||||||
|
return std::round(tbh * dpr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_borderWidth > 0) {
|
switch (metric) {
|
||||||
return std::round(m_borderWidth * dpr);
|
case SystemMetric::BorderWidth: {
|
||||||
}
|
if (m_borderWidth > 0) {
|
||||||
const int result = m_lpGetSystemMetrics(SM_CXSIZEFRAME) +
|
return std::round(m_borderWidth * dpr);
|
||||||
m_lpGetSystemMetrics(SM_CXPADDEDBORDER);
|
} else {
|
||||||
const int result_dpi = getSystemMetricsForWindow(handle, SM_CXSIZEFRAME) +
|
const int result = m_lpGetSystemMetrics(SM_CXSIZEFRAME) +
|
||||||
getSystemMetricsForWindow(handle, SM_CXPADDEDBORDER);
|
m_lpGetSystemMetrics(SM_CXPADDEDBORDER);
|
||||||
return dpiAware ? result_dpi : result;
|
const int result_dpi =
|
||||||
}
|
getSystemMetricsForWindow(handle, SM_CXSIZEFRAME) +
|
||||||
|
getSystemMetricsForWindow(handle, SM_CXPADDEDBORDER);
|
||||||
int WinNativeEventFilter::getBorderHeightForWindow(HWND handle, bool dpiAware) {
|
return dpiAware ? result_dpi : result;
|
||||||
initWin32Api();
|
|
||||||
const qreal dpr = dpiAware ? getDevicePixelRatioForWindow(handle)
|
|
||||||
: m_defaultDevicePixelRatio;
|
|
||||||
if (handle && m_lpIsWindow(handle)) {
|
|
||||||
createUserData(handle);
|
|
||||||
const auto userData = reinterpret_cast<WINDOW *>(
|
|
||||||
m_lpGetWindowLongPtrW(handle, GWLP_USERDATA));
|
|
||||||
const int bh = userData->windowData.borderHeight;
|
|
||||||
if (bh > 0) {
|
|
||||||
return std::round(bh * dpr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_borderHeight > 0) {
|
case SystemMetric::BorderHeight: {
|
||||||
return std::round(m_borderHeight * dpr);
|
if (m_borderHeight > 0) {
|
||||||
}
|
return std::round(m_borderHeight * dpr);
|
||||||
const int result = m_lpGetSystemMetrics(SM_CYSIZEFRAME) +
|
} else {
|
||||||
m_lpGetSystemMetrics(SM_CXPADDEDBORDER);
|
const int result = m_lpGetSystemMetrics(SM_CYSIZEFRAME) +
|
||||||
const int result_dpi = getSystemMetricsForWindow(handle, SM_CYSIZEFRAME) +
|
m_lpGetSystemMetrics(SM_CXPADDEDBORDER);
|
||||||
getSystemMetricsForWindow(handle, SM_CXPADDEDBORDER);
|
const int result_dpi =
|
||||||
return dpiAware ? result_dpi : result;
|
getSystemMetricsForWindow(handle, SM_CYSIZEFRAME) +
|
||||||
}
|
getSystemMetricsForWindow(handle, SM_CXPADDEDBORDER);
|
||||||
|
return dpiAware ? result_dpi : result;
|
||||||
int WinNativeEventFilter::getTitlebarHeightForWindow(HWND handle,
|
|
||||||
bool dpiAware) {
|
|
||||||
initWin32Api();
|
|
||||||
const qreal dpr = dpiAware ? getDevicePixelRatioForWindow(handle)
|
|
||||||
: m_defaultDevicePixelRatio;
|
|
||||||
if (handle && m_lpIsWindow(handle)) {
|
|
||||||
createUserData(handle);
|
|
||||||
const auto userData = reinterpret_cast<WINDOW *>(
|
|
||||||
m_lpGetWindowLongPtrW(handle, GWLP_USERDATA));
|
|
||||||
const int tbh = userData->windowData.titlebarHeight;
|
|
||||||
if (tbh > 0) {
|
|
||||||
return std::round(tbh * dpr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_titlebarHeight > 0) {
|
case SystemMetric::TitleBarHeight: {
|
||||||
return std::round(m_titlebarHeight * dpr);
|
if (m_titlebarHeight > 0) {
|
||||||
|
return std::round(m_titlebarHeight * dpr);
|
||||||
|
} else {
|
||||||
|
const int result = m_lpGetSystemMetrics(SM_CYSIZEFRAME) +
|
||||||
|
m_lpGetSystemMetrics(SM_CXPADDEDBORDER) +
|
||||||
|
m_lpGetSystemMetrics(SM_CYCAPTION);
|
||||||
|
const int result_dpi =
|
||||||
|
getSystemMetricsForWindow(handle, SM_CYSIZEFRAME) +
|
||||||
|
getSystemMetricsForWindow(handle, SM_CXPADDEDBORDER) +
|
||||||
|
getSystemMetricsForWindow(handle, SM_CYCAPTION);
|
||||||
|
return dpiAware ? result_dpi : result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const int result = getBorderHeightForWindow(handle, false) +
|
}
|
||||||
m_lpGetSystemMetrics(SM_CYCAPTION);
|
return -1;
|
||||||
const int result_dpi = getBorderHeightForWindow(handle) +
|
|
||||||
getSystemMetricsForWindow(handle, SM_CYCAPTION);
|
|
||||||
return dpiAware ? result_dpi : result;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,8 @@ public:
|
||||||
WINDOWDATA windowData;
|
WINDOWDATA windowData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class SystemMetric { BorderWidth, BorderHeight, TitleBarHeight };
|
||||||
|
|
||||||
explicit WinNativeEventFilter();
|
explicit WinNativeEventFilter();
|
||||||
~WinNativeEventFilter() override;
|
~WinNativeEventFilter() override;
|
||||||
|
|
||||||
|
@ -84,15 +86,10 @@ public:
|
||||||
static void setBorderHeight(int bh);
|
static void setBorderHeight(int bh);
|
||||||
static void setTitlebarHeight(int tbh);
|
static void setTitlebarHeight(int tbh);
|
||||||
|
|
||||||
// DPI-unaware border width of the given window (if the pointer is null,
|
// System metric value of the given window (if the pointer is null,
|
||||||
// return the system's standard value).
|
// return the system's standard value).
|
||||||
static int borderWidth(HWND handle);
|
static int getSystemMetric(HWND handle, SystemMetric metric,
|
||||||
// DPI-unaware border height of the given window (if the pointer is null,
|
bool dpiAware = true);
|
||||||
// return the system's standard value).
|
|
||||||
static int borderHeight(HWND handle);
|
|
||||||
// DPI-unaware titlebar height (including the border height) of the given
|
|
||||||
// window (if the pointer is null, return the system's standard value).
|
|
||||||
static int titlebarHeight(HWND handle);
|
|
||||||
|
|
||||||
static void updateWindow(HWND handle, bool triggerFrameChange = true);
|
static void updateWindow(HWND handle, bool triggerFrameChange = true);
|
||||||
|
|
||||||
|
@ -112,7 +109,4 @@ private:
|
||||||
static UINT getDotsPerInchForWindow(HWND handle);
|
static UINT getDotsPerInchForWindow(HWND handle);
|
||||||
static qreal getDevicePixelRatioForWindow(HWND handle);
|
static qreal getDevicePixelRatioForWindow(HWND handle);
|
||||||
static int getSystemMetricsForWindow(HWND handle, int index);
|
static int getSystemMetricsForWindow(HWND handle, int index);
|
||||||
static int getBorderWidthForWindow(HWND handle, bool dpiAware = true);
|
|
||||||
static int getBorderHeightForWindow(HWND handle, bool dpiAware = true);
|
|
||||||
static int getTitlebarHeightForWindow(HWND handle, bool dpiAware = true);
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue