win: refactor

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2022-12-13 11:36:41 +08:00
parent c849217d43
commit d4293e0a55
5 changed files with 776 additions and 635 deletions

View File

@ -52,7 +52,9 @@
# define NOMINMAX # define NOMINMAX
#endif #endif
#include <sdkddkver.h> #if __has_include(<sdkddkver.h>)
# include <sdkddkver.h>
#endif
#ifndef _WIN32_WINNT_WIN10 #ifndef _WIN32_WINNT_WIN10
# define _WIN32_WINNT_WIN10 0x0A00 # define _WIN32_WINNT_WIN10 0x0A00
@ -79,6 +81,8 @@
#include <shellapi.h> #include <shellapi.h>
#include <dwmapi.h> #include <dwmapi.h>
#include <framelesshelpercore_global.h>
#ifndef WM_NCUAHDRAWCAPTION #ifndef WM_NCUAHDRAWCAPTION
# define WM_NCUAHDRAWCAPTION (0x00AE) # define WM_NCUAHDRAWCAPTION (0x00AE)
#endif #endif
@ -437,6 +441,265 @@ using ShouldSystemUseDarkModePtr = BOOL(WINAPI *)(VOID); // Ordinal 138
using SetPreferredAppModePtr = PREFERRED_APP_MODE(WINAPI *)(PREFERRED_APP_MODE); // Ordinal 135 using SetPreferredAppModePtr = PREFERRED_APP_MODE(WINAPI *)(PREFERRED_APP_MODE); // Ordinal 135
using IsDarkModeAllowedForAppPtr = BOOL(WINAPI *)(VOID); // Ordinal 139 using IsDarkModeAllowedForAppPtr = BOOL(WINAPI *)(VOID); // Ordinal 139
EXTERN_C_START
///////////////////////////////////////////////
// Function prototypes
_MMRESULT WINAPI
_timeGetDevCaps(
_PTIMECAPS ptc,
UINT cbtc
);
_MMRESULT WINAPI
_timeBeginPeriod(
UINT uPeriod
);
_MMRESULT WINAPI
_timeEndPeriod(
UINT uPeriod
);
HRESULT WINAPI
_SetProcessDpiAwareness(
_PROCESS_DPI_AWARENESS value
);
HRESULT WINAPI
_GetProcessDpiAwareness(
HANDLE hProcess,
_PROCESS_DPI_AWARENESS *value
);
HRESULT WINAPI
_GetDpiForMonitor(
HMONITOR hMonitor,
_MONITOR_DPI_TYPE dpiType,
UINT *dpiX,
UINT *dpiY
);
int WINAPI
_GetSystemMetricsForDpi(
int nIndex,
UINT dpi
);
UINT WINAPI
_GetWindowDPI(
HWND hWnd
);
UINT WINAPI
_GetDpiForWindow(
HWND hWnd
);
UINT WINAPI
_GetDpiForSystem(
VOID
);
UINT WINAPI
_GetSystemDpiForProcess(
HANDLE hProcess
);
BOOL WINAPI
_SetProcessDpiAwarenessContext(
_DPI_AWARENESS_CONTEXT value
);
BOOL WINAPI
_SetProcessDPIAware(
VOID
);
HRESULT WINAPI
_GetScaleFactorForMonitor(
HMONITOR hMon,
_DEVICE_SCALE_FACTOR *pScale
);
BOOL WINAPI
_EnableNonClientDpiScaling(
HWND hWnd
);
_DPI_AWARENESS_CONTEXT WINAPI
_GetThreadDpiAwarenessContext(
VOID
);
_DPI_AWARENESS_CONTEXT WINAPI
_GetWindowDpiAwarenessContext(
HWND hWnd
);
_DPI_AWARENESS WINAPI
_GetAwarenessFromDpiAwarenessContext(
_DPI_AWARENESS_CONTEXT value
);
_DPI_AWARENESS_CONTEXT WINAPI
_GetDpiAwarenessContextForProcess(
HANDLE hProcess
);
BOOL WINAPI
_AreDpiAwarenessContextsEqual(
_DPI_AWARENESS_CONTEXT dpiContextA,
_DPI_AWARENESS_CONTEXT dpiContextB
);
BOOL WINAPI
_EnableChildWindowDpiMessage(
HWND hWnd,
BOOL fEnable
);
BOOL WINAPI
_EnablePerMonitorDialogScaling(
VOID
);
int WINAPI
_GetDpiMetrics(
int nIndex,
UINT dpi
);
BOOL WINAPI
_AdjustWindowRectExForDpi(
LPRECT lpRect,
DWORD dwStyle,
BOOL bMenu,
DWORD dwExStyle,
UINT dpi
);
///////////////////////////////////////////////
// API thunks
FRAMELESSHELPER_CORE_API BOOL WINAPI
_GetWindowCompositionAttribute(
const HWND hWnd,
PWINDOWCOMPOSITIONATTRIBDATA pvData
);
FRAMELESSHELPER_CORE_API BOOL WINAPI
_SetWindowCompositionAttribute(
const HWND hWnd,
PWINDOWCOMPOSITIONATTRIBDATA pvData
);
FRAMELESSHELPER_CORE_API HRESULT WINAPI
_SetWindowThemeAttribute(
const HWND hWnd,
const _WINDOWTHEMEATTRIBUTETYPE attrib,
PVOID pvData,
const DWORD cbData
);
FRAMELESSHELPER_CORE_API HRESULT WINAPI
_SetWindowThemeNonClientAttributes(
const HWND hWnd,
const DWORD dwMask,
const DWORD dwAttributes
);
FRAMELESSHELPER_CORE_API BOOL WINAPI
_ShouldAppsUseDarkMode(
VOID
);
FRAMELESSHELPER_CORE_API BOOL WINAPI
_AllowDarkModeForWindow(
const HWND hWnd,
const BOOL bAllow
);
FRAMELESSHELPER_CORE_API BOOL WINAPI
_AllowDarkModeForApp(
const BOOL bAllow
);
FRAMELESSHELPER_CORE_API VOID WINAPI
_FlushMenuThemes(
VOID
);
FRAMELESSHELPER_CORE_API VOID WINAPI
_RefreshImmersiveColorPolicyState(
VOID
);
FRAMELESSHELPER_CORE_API BOOL WINAPI
_IsDarkModeAllowedForWindow(
const HWND hWnd
);
FRAMELESSHELPER_CORE_API BOOL WINAPI
_GetIsImmersiveColorUsingHighContrast(
const IMMERSIVE_HC_CACHE_MODE mode
);
FRAMELESSHELPER_CORE_API HTHEME WINAPI
_OpenNcThemeData(
const HWND hWnd,
LPCWSTR pszClassList
);
FRAMELESSHELPER_CORE_API BOOL WINAPI
_ShouldSystemUseDarkMode(
VOID
);
FRAMELESSHELPER_CORE_API PREFERRED_APP_MODE WINAPI
_SetPreferredAppMode(
const PREFERRED_APP_MODE mode
);
FRAMELESSHELPER_CORE_API BOOL WINAPI
_IsDarkModeAllowedForApp(
VOID
);
FRAMELESSHELPER_CORE_API BOOL WINAPI
_EnableChildWindowDpiMessage2(
const HWND hWnd,
const BOOL fEnable
);
FRAMELESSHELPER_CORE_API BOOL WINAPI
_EnablePerMonitorDialogScaling2(
VOID
);
FRAMELESSHELPER_CORE_API UINT WINAPI
_GetDpiForWindow2(
const HWND hWnd
);
FRAMELESSHELPER_CORE_API int WINAPI
_GetSystemMetricsForDpi2(
const int nIndex,
const UINT dpi
);
FRAMELESSHELPER_CORE_API BOOL WINAPI
_AdjustWindowRectExForDpi2(
LPRECT lpRect,
const DWORD dwStyle,
const BOOL bMenu,
const DWORD dwExStyle,
const UINT dpi
);
EXTERN_C_END
[[maybe_unused]] inline constexpr const int kAutoHideTaskBarThickness = 2; // The thickness of an auto-hide taskbar in pixels. [[maybe_unused]] inline constexpr const int kAutoHideTaskBarThickness = 2; // The thickness of an auto-hide taskbar in pixels.
[[maybe_unused]] inline constexpr const wchar_t kDwmRegistryKey[] = LR"(Software\Microsoft\Windows\DWM)"; [[maybe_unused]] inline constexpr const wchar_t kDwmRegistryKey[] = LR"(Software\Microsoft\Windows\DWM)";
[[maybe_unused]] inline constexpr const wchar_t kPersonalizeRegistryKey[] = LR"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)"; [[maybe_unused]] inline constexpr const wchar_t kPersonalizeRegistryKey[] = LR"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)";

View File

@ -58,7 +58,8 @@ win32 {
$$CORE_SRC_DIR/framelesshelper_win.cpp \ $$CORE_SRC_DIR/framelesshelper_win.cpp \
$$CORE_SRC_DIR/utils_win.cpp \ $$CORE_SRC_DIR/utils_win.cpp \
$$CORE_SRC_DIR/registrykey.cpp \ $$CORE_SRC_DIR/registrykey.cpp \
$$CORE_SRC_DIR/winverhelper.cpp $$CORE_SRC_DIR/winverhelper.cpp \
$$CORE_SRC_DIR/platformsupport_win.cpp
LIBS += -luser32 -lgdi32 -lshell32 LIBS += -luser32 -lgdi32 -lshell32
} }

View File

@ -97,6 +97,7 @@ if(WIN32)
utils_win.cpp utils_win.cpp
framelesshelper_win.cpp framelesshelper_win.cpp
winverhelper.cpp winverhelper.cpp
platformsupport_win.cpp
) )
elseif(APPLE) elseif(APPLE)
list(APPEND SOURCES utils_mac.mm) list(APPEND SOURCES utils_mac.mm)

View File

@ -0,0 +1,501 @@
/*
* MIT License
*
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "sysapiloader_p.h"
#include "winverhelper_p.h"
#include "framelesshelper_windows.h"
FRAMELESSHELPER_STRING_CONSTANT(user32)
FRAMELESSHELPER_STRING_CONSTANT(uxtheme)
FRAMELESSHELPER_STRING_CONSTANT(win32u)
FRAMELESSHELPER_STRING_CONSTANT(GetWindowCompositionAttribute)
FRAMELESSHELPER_STRING_CONSTANT(SetWindowCompositionAttribute)
FRAMELESSHELPER_STRING_CONSTANT(SetWindowThemeAttribute)
FRAMELESSHELPER_STRING_CONSTANT(NtUserEnableChildWindowDpiMessage)
FRAMELESSHELPER_STRING_CONSTANT(EnableChildWindowDpiMessage)
FRAMELESSHELPER_STRING_CONSTANT(EnablePerMonitorDialogScaling)
FRAMELESSHELPER_STRING_CONSTANT(GetDpiForWindow)
FRAMELESSHELPER_STRING_CONSTANT(GetWindowDPI)
FRAMELESSHELPER_STRING_CONSTANT(GetSystemMetricsForDpi)
FRAMELESSHELPER_STRING_CONSTANT(GetDpiMetrics)
FRAMELESSHELPER_STRING_CONSTANT(AdjustWindowRectExForDpi)
EXTERN_C BOOL WINAPI
_GetWindowCompositionAttribute(const HWND hWnd, PWINDOWCOMPOSITIONATTRIBDATA pvData)
{
Q_ASSERT(hWnd);
Q_ASSERT(pvData);
if (!hWnd || !pvData) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (!API_USER_AVAILABLE(GetWindowCompositionAttribute)) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return API_CALL_FUNCTION4(GetWindowCompositionAttribute, hWnd, pvData);
}
EXTERN_C BOOL WINAPI
_SetWindowCompositionAttribute(const HWND hWnd, PWINDOWCOMPOSITIONATTRIBDATA pvData)
{
Q_ASSERT(hWnd);
Q_ASSERT(pvData);
if (!hWnd || !pvData) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (!API_USER_AVAILABLE(SetWindowCompositionAttribute)) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return API_CALL_FUNCTION4(SetWindowCompositionAttribute, hWnd, pvData);
}
EXTERN_C HRESULT WINAPI
_SetWindowThemeAttribute(const HWND hWnd, const _WINDOWTHEMEATTRIBUTETYPE attrib,
PVOID pvData, const DWORD cbData
)
{
Q_ASSERT(hWnd);
Q_ASSERT(pvData);
Q_ASSERT(cbData != 0);
if (!hWnd || !pvData || (cbData == 0)) {
return E_INVALIDARG;
}
if (!API_THEME_AVAILABLE(SetWindowThemeAttribute)) {
return E_NOTIMPL;
}
return API_CALL_FUNCTION4(SetWindowThemeAttribute, hWnd, attrib, pvData, cbData);
}
EXTERN_C HRESULT WINAPI
_SetWindowThemeNonClientAttributes(const HWND hWnd, const DWORD dwMask, const DWORD dwAttributes)
{
Q_ASSERT(hWnd);
if (!hWnd) {
return E_INVALIDARG;
}
WTA_OPTIONS2 options = {};
options.dwFlags = dwAttributes;
options.dwMask = dwMask;
return _SetWindowThemeAttribute(hWnd, _WTA_NONCLIENT, &options, sizeof(options));
}
EXTERN_C BOOL WINAPI
_ShouldAppsUseDarkMode(VOID)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
static const auto pShouldAppsUseDarkMode
= reinterpret_cast<ShouldAppsUseDarkModePtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(132)));
if (!pShouldAppsUseDarkMode) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pShouldAppsUseDarkMode();
}
EXTERN_C BOOL WINAPI
_AllowDarkModeForWindow(const HWND hWnd, const BOOL bAllow)
{
Q_ASSERT(hWnd);
if (!hWnd) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
static const auto pAllowDarkModeForWindow
= reinterpret_cast<AllowDarkModeForWindowPtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(133)));
if (!pAllowDarkModeForWindow) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pAllowDarkModeForWindow(hWnd, bAllow);
}
EXTERN_C BOOL WINAPI
_AllowDarkModeForApp(const BOOL bAllow)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
static const auto pAllowDarkModeForApp
= reinterpret_cast<AllowDarkModeForAppPtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(135)));
if (!pAllowDarkModeForApp) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pAllowDarkModeForApp(bAllow);
}
EXTERN_C VOID WINAPI
_FlushMenuThemes(VOID)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return;
}
static const auto pFlushMenuThemes
= reinterpret_cast<FlushMenuThemesPtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(136)));
if (!pFlushMenuThemes) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return;
}
pFlushMenuThemes();
}
EXTERN_C VOID WINAPI
_RefreshImmersiveColorPolicyState(VOID)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return;
}
static const auto pRefreshImmersiveColorPolicyState
= reinterpret_cast<RefreshImmersiveColorPolicyStatePtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(104)));
if (!pRefreshImmersiveColorPolicyState) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return;
}
pRefreshImmersiveColorPolicyState();
}
EXTERN_C BOOL WINAPI
_IsDarkModeAllowedForWindow(const HWND hWnd)
{
Q_ASSERT(hWnd);
if (!hWnd) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
static const auto pIsDarkModeAllowedForWindow
= reinterpret_cast<IsDarkModeAllowedForWindowPtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(137)));
if (!pIsDarkModeAllowedForWindow) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pIsDarkModeAllowedForWindow(hWnd);
}
EXTERN_C BOOL WINAPI
_GetIsImmersiveColorUsingHighContrast(const IMMERSIVE_HC_CACHE_MODE mode)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
static const auto pGetIsImmersiveColorUsingHighContrast
= reinterpret_cast<GetIsImmersiveColorUsingHighContrastPtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(106)));
if (!pGetIsImmersiveColorUsingHighContrast) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pGetIsImmersiveColorUsingHighContrast(mode);
}
EXTERN_C HTHEME WINAPI
_OpenNcThemeData(const HWND hWnd, LPCWSTR pszClassList)
{
Q_ASSERT(hWnd);
Q_ASSERT(pszClassList);
if (!hWnd || !pszClassList) {
SetLastError(ERROR_INVALID_PARAMETER);
return nullptr;
}
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return nullptr;
}
static const auto pOpenNcThemeData
= reinterpret_cast<OpenNcThemeDataPtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(49)));
if (!pOpenNcThemeData) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return nullptr;
}
return pOpenNcThemeData(hWnd, pszClassList);
}
EXTERN_C BOOL WINAPI
_ShouldSystemUseDarkMode(VOID)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
static const auto pShouldSystemUseDarkMode
= reinterpret_cast<ShouldSystemUseDarkModePtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(138)));
if (!pShouldSystemUseDarkMode) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pShouldSystemUseDarkMode();
}
EXTERN_C PREFERRED_APP_MODE WINAPI
_SetPreferredAppMode(const PREFERRED_APP_MODE mode)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return PAM_MAX;
}
static const auto pSetPreferredAppMode
= reinterpret_cast<SetPreferredAppModePtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(135)));
if (!pSetPreferredAppMode) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return PAM_MAX;
}
return pSetPreferredAppMode(mode);
}
EXTERN_C BOOL WINAPI
_IsDarkModeAllowedForApp(VOID)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
static const auto pIsDarkModeAllowedForApp
= reinterpret_cast<IsDarkModeAllowedForAppPtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(139)));
if (!pIsDarkModeAllowedForApp) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pIsDarkModeAllowedForApp();
}
EXTERN_C BOOL WINAPI
_EnableChildWindowDpiMessage2(const HWND hWnd, const BOOL fEnable)
{
Q_ASSERT(hWnd);
if (!hWnd) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
using EnableChildWindowDpiMessagePtr = decltype(&::_EnableChildWindowDpiMessage);
static const auto pEnableChildWindowDpiMessage = []() -> EnableChildWindowDpiMessagePtr {
// EnableChildWindowDpiMessage() was moved to "win32u.dll" and renamed to
// "NtUserEnableChildWindowDpiMessage" since Win10 1607.
if (const auto pFunc = reinterpret_cast<EnableChildWindowDpiMessagePtr>(
SysApiLoader::resolve(kwin32u, kNtUserEnableChildWindowDpiMessage))) {
return pFunc;
}
// EnableChildWindowDpiMessage() was once a public API, so we can load it by name,
// but it got removed in Win10 1607, so we can't link to it directly.
if (const auto pFunc = reinterpret_cast<EnableChildWindowDpiMessagePtr>(
SysApiLoader::resolve(kuser32, kEnableChildWindowDpiMessage))) {
return pFunc;
}
// EnableChildWindowDpiMessage() was made private since Win10 1607.
if (const auto pFunc = reinterpret_cast<EnableChildWindowDpiMessagePtr>(
SysApiLoader::resolve(kuser32, MAKEINTRESOURCEA(2704)))) {
return pFunc;
}
return nullptr;
}();
if (!pEnableChildWindowDpiMessage) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pEnableChildWindowDpiMessage(hWnd, fEnable);
}
EXTERN_C BOOL WINAPI
_EnablePerMonitorDialogScaling2(VOID)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
using EnablePerMonitorDialogScalingPtr = decltype(&::_EnablePerMonitorDialogScaling);
static const auto pEnablePerMonitorDialogScaling = []() -> EnablePerMonitorDialogScalingPtr {
// EnablePerMonitorDialogScaling() was once a public API, so we can load it by name,
// but it got removed in Win10 1607, so we can't link to it directly.
if (const auto pFunc = reinterpret_cast<EnablePerMonitorDialogScalingPtr>(
SysApiLoader::resolve(kuser32, kEnablePerMonitorDialogScaling))) {
return pFunc;
}
// EnablePerMonitorDialogScaling() was made private since Win10 1607.
if (const auto pFunc = reinterpret_cast<EnablePerMonitorDialogScalingPtr>(
SysApiLoader::resolve(kuser32, MAKEINTRESOURCEA(2577)))) {
return pFunc;
}
return nullptr;
}();
if (!pEnablePerMonitorDialogScaling) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pEnablePerMonitorDialogScaling();
}
EXTERN_C UINT WINAPI
_GetDpiForWindow2(const HWND hWnd)
{
Q_ASSERT(hWnd);
if (!hWnd) {
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
using GetDpiForWindowPtr = decltype(&::_GetDpiForWindow);
static const auto pGetDpiForWindow = []() -> GetDpiForWindowPtr {
// GetDpiForWindow() was made public since Win10 1607.
if (const auto pFunc = reinterpret_cast<GetDpiForWindowPtr>(
SysApiLoader::resolve(kuser32, kGetDpiForWindow))) {
return pFunc;
}
// GetDpiForWindow() was named "GetWindowDPI" before made public.
if (const auto pFunc = reinterpret_cast<GetDpiForWindowPtr>(
SysApiLoader::resolve(kuser32, kGetWindowDPI))) {
return pFunc;
}
// GetWindowDPI() was made private since Win10 1607.
if (const auto pFunc = reinterpret_cast<GetDpiForWindowPtr>(
SysApiLoader::resolve(kuser32, MAKEINTRESOURCEA(2707)))) {
return pFunc;
}
return nullptr;
}();
if (!pGetDpiForWindow) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
return pGetDpiForWindow(hWnd);
}
EXTERN_C int WINAPI
_GetSystemMetricsForDpi2(const int nIndex, const UINT dpi)
{
Q_ASSERT(nIndex >= 0);
Q_ASSERT(dpi != 0);
if ((nIndex < 0) || (dpi == 0)) {
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
using GetSystemMetricsForDpiPtr = decltype(&::_GetSystemMetricsForDpi);
static const auto pGetSystemMetricsForDpi = []() -> GetSystemMetricsForDpiPtr {
// GetSystemMetricsForDpi() was made public since Win10 1607.
if (const auto pFunc = reinterpret_cast<GetSystemMetricsForDpiPtr>(
SysApiLoader::resolve(kuser32, kGetSystemMetricsForDpi))) {
return pFunc;
}
// GetSystemMetricsForDpi() was named "GetDpiMetrics" before made public,
// that is, when in Win10 1507 & 1511.
if (const auto pFunc = reinterpret_cast<GetSystemMetricsForDpiPtr>(
SysApiLoader::resolve(kuser32, kGetDpiMetrics))) {
return pFunc;
}
return nullptr;
}();
if (!pGetSystemMetricsForDpi) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
return pGetSystemMetricsForDpi(nIndex, dpi);
}
EXTERN_C BOOL WINAPI
_AdjustWindowRectExForDpi2(LPRECT lpRect, const DWORD dwStyle,
const BOOL bMenu, const DWORD dwExStyle, const UINT dpi)
{
Q_ASSERT(lpRect);
Q_ASSERT(dpi != 0);
if (!lpRect || (dpi == 0)) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
using AdjustWindowRectExForDpiPtr = decltype(&::_AdjustWindowRectExForDpi);
static const auto pAdjustWindowRectExForDpi = []() -> AdjustWindowRectExForDpiPtr {
// AdjustWindowRectExForDpi() was made public since Win10 1607.
if (const auto pFunc = reinterpret_cast<AdjustWindowRectExForDpiPtr>(
SysApiLoader::resolve(kuser32, kAdjustWindowRectExForDpi))) {
return pFunc;
}
// AdjustWindowRectExForDpi() was made private in Win10 1507 & 1511.
if (const auto pFunc = reinterpret_cast<AdjustWindowRectExForDpiPtr>(
SysApiLoader::resolve(kuser32, MAKEINTRESOURCEA(2580)))) {
return pFunc;
}
return nullptr;
}();
if (!pAdjustWindowRectExForDpi) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pAdjustWindowRectExForDpi(lpRect, dwStyle, bMenu, dwExStyle, dpi);
}

View File

@ -23,6 +23,12 @@
*/ */
#include "utils.h" #include "utils.h"
#include "framelesshelper_windows.h"
#include "framelessmanager.h"
#include "framelessconfig_p.h"
#include "sysapiloader_p.h"
#include "registrykey_p.h"
#include "winverhelper_p.h"
#include <QtCore/qmutex.h> #include <QtCore/qmutex.h>
#include <QtCore/qhash.h> #include <QtCore/qhash.h>
#include <QtGui/qwindow.h> #include <QtGui/qwindow.h>
@ -39,641 +45,8 @@
# include <QtGui/qpa/qplatformwindow_p.h> # include <QtGui/qpa/qplatformwindow_p.h>
# endif // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) # endif // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
#endif // FRAMELESSHELPER_CORE_NO_PRIVATE #endif // FRAMELESSHELPER_CORE_NO_PRIVATE
#include "framelessmanager.h"
#include "framelesshelper_windows.h"
#include "framelessconfig_p.h"
#include "sysapiloader_p.h"
#include "registrykey_p.h"
#include "winverhelper_p.h"
#include <d2d1.h> #include <d2d1.h>
EXTERN_C_START
_MMRESULT WINAPI
_timeGetDevCaps(
_Out_writes_bytes_(cbtc) _PTIMECAPS ptc,
_In_ UINT cbtc
);
_MMRESULT WINAPI
_timeBeginPeriod(
_In_ UINT uPeriod
);
_MMRESULT WINAPI
_timeEndPeriod(
_In_ UINT uPeriod
);
HRESULT WINAPI
_SetProcessDpiAwareness(
_In_ _PROCESS_DPI_AWARENESS value
);
HRESULT WINAPI
_GetProcessDpiAwareness(
_In_opt_ HANDLE hProcess,
_Out_ _PROCESS_DPI_AWARENESS *value
);
HRESULT WINAPI
_GetDpiForMonitor(
_In_ HMONITOR hMonitor,
_In_ _MONITOR_DPI_TYPE dpiType,
_Out_ UINT *dpiX,
_Out_ UINT *dpiY
);
int WINAPI
_GetSystemMetricsForDpi(
_In_ int nIndex,
_In_ UINT dpi
);
UINT WINAPI
_GetWindowDPI(
_In_ HWND hWnd
);
UINT WINAPI
_GetDpiForWindow(
_In_ HWND hWnd
);
UINT WINAPI
_GetDpiForSystem(
VOID
);
UINT WINAPI
_GetSystemDpiForProcess(
_In_ HANDLE hProcess
);
BOOL WINAPI
_SetProcessDpiAwarenessContext(
_In_ _DPI_AWARENESS_CONTEXT value
);
BOOL WINAPI
_SetProcessDPIAware(
VOID
);
HRESULT WINAPI
_GetScaleFactorForMonitor(
_In_ HMONITOR hMon,
_Out_ _DEVICE_SCALE_FACTOR *pScale
);
BOOL WINAPI
_EnableNonClientDpiScaling(
_In_ HWND hWnd
);
_DPI_AWARENESS_CONTEXT WINAPI
_GetThreadDpiAwarenessContext(
VOID
);
_DPI_AWARENESS_CONTEXT WINAPI
_GetWindowDpiAwarenessContext(
_In_ HWND hWnd
);
_DPI_AWARENESS WINAPI
_GetAwarenessFromDpiAwarenessContext(
_In_ _DPI_AWARENESS_CONTEXT value
);
_DPI_AWARENESS_CONTEXT WINAPI
_GetDpiAwarenessContextForProcess(
_In_ HANDLE hProcess
);
BOOL WINAPI
_AreDpiAwarenessContextsEqual(
_In_ _DPI_AWARENESS_CONTEXT dpiContextA,
_In_ _DPI_AWARENESS_CONTEXT dpiContextB
);
BOOL WINAPI
_EnableChildWindowDpiMessage(
_In_ HWND hWnd,
_In_ BOOL fEnable
);
BOOL WINAPI
_EnablePerMonitorDialogScaling(
VOID
);
int WINAPI
_GetDpiMetrics(
_In_ int nIndex,
_In_ UINT dpi
);
BOOL WINAPI
_AdjustWindowRectExForDpi(
_Inout_ LPRECT lpRect,
_In_ DWORD dwStyle,
_In_ BOOL bMenu,
_In_ DWORD dwExStyle,
_In_ UINT dpi
);
EXTERN_C_END
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API BOOL WINAPI
_GetWindowCompositionAttribute(const HWND hWnd, PWINDOWCOMPOSITIONATTRIBDATA pvData)
{
Q_ASSERT(hWnd);
Q_ASSERT(pvData);
if (!hWnd || !pvData) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
FRAMELESSHELPER_STRING_CONSTANT(user32)
FRAMELESSHELPER_STRING_CONSTANT(GetWindowCompositionAttribute)
if (!API_USER_AVAILABLE(GetWindowCompositionAttribute)) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return API_CALL_FUNCTION4(GetWindowCompositionAttribute, hWnd, pvData);
}
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API BOOL WINAPI
_SetWindowCompositionAttribute(const HWND hWnd, PWINDOWCOMPOSITIONATTRIBDATA pvData)
{
Q_ASSERT(hWnd);
Q_ASSERT(pvData);
if (!hWnd || !pvData) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
FRAMELESSHELPER_STRING_CONSTANT(user32)
FRAMELESSHELPER_STRING_CONSTANT(SetWindowCompositionAttribute)
if (!API_USER_AVAILABLE(SetWindowCompositionAttribute)) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return API_CALL_FUNCTION4(SetWindowCompositionAttribute, hWnd, pvData);
}
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API HRESULT WINAPI
_SetWindowThemeAttribute(const HWND hWnd, const _WINDOWTHEMEATTRIBUTETYPE attrib,
PVOID pvData, const DWORD cbData
)
{
Q_ASSERT(hWnd);
Q_ASSERT(pvData);
Q_ASSERT(cbData != 0);
if (!hWnd || !pvData || (cbData == 0)) {
return E_INVALIDARG;
}
FRAMELESSHELPER_STRING_CONSTANT(uxtheme)
FRAMELESSHELPER_STRING_CONSTANT(SetWindowThemeAttribute)
if (!API_THEME_AVAILABLE(SetWindowThemeAttribute)) {
return E_NOTIMPL;
}
return API_CALL_FUNCTION4(SetWindowThemeAttribute, hWnd, attrib, pvData, cbData);
}
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API HRESULT WINAPI
_SetWindowThemeNonClientAttributes(const HWND hWnd, const DWORD dwMask, const DWORD dwAttributes)
{
Q_ASSERT(hWnd);
if (!hWnd) {
return E_INVALIDARG;
}
WTA_OPTIONS2 options = {};
options.dwFlags = dwAttributes;
options.dwMask = dwMask;
return _SetWindowThemeAttribute(hWnd, _WTA_NONCLIENT, &options, sizeof(options));
}
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API BOOL WINAPI
_ShouldAppsUseDarkMode(VOID)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
FRAMELESSHELPER_STRING_CONSTANT(uxtheme)
static const auto pShouldAppsUseDarkMode
= reinterpret_cast<ShouldAppsUseDarkModePtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(132)));
if (!pShouldAppsUseDarkMode) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pShouldAppsUseDarkMode();
}
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API BOOL WINAPI
_AllowDarkModeForWindow(const HWND hWnd, const BOOL bAllow)
{
Q_ASSERT(hWnd);
if (!hWnd) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
FRAMELESSHELPER_STRING_CONSTANT(uxtheme)
static const auto pAllowDarkModeForWindow
= reinterpret_cast<AllowDarkModeForWindowPtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(133)));
if (!pAllowDarkModeForWindow) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pAllowDarkModeForWindow(hWnd, bAllow);
}
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API BOOL WINAPI
_AllowDarkModeForApp(const BOOL bAllow)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
FRAMELESSHELPER_STRING_CONSTANT(uxtheme)
static const auto pAllowDarkModeForApp
= reinterpret_cast<AllowDarkModeForAppPtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(135)));
if (!pAllowDarkModeForApp) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pAllowDarkModeForApp(bAllow);
}
EXTERN_C FRAMELESSHELPER_CORE_API VOID WINAPI
_FlushMenuThemes(VOID)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return;
}
FRAMELESSHELPER_STRING_CONSTANT(uxtheme)
static const auto pFlushMenuThemes
= reinterpret_cast<FlushMenuThemesPtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(136)));
if (!pFlushMenuThemes) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return;
}
pFlushMenuThemes();
}
EXTERN_C FRAMELESSHELPER_CORE_API VOID WINAPI
_RefreshImmersiveColorPolicyState(VOID)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return;
}
FRAMELESSHELPER_STRING_CONSTANT(uxtheme)
static const auto pRefreshImmersiveColorPolicyState
= reinterpret_cast<RefreshImmersiveColorPolicyStatePtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(104)));
if (!pRefreshImmersiveColorPolicyState) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return;
}
pRefreshImmersiveColorPolicyState();
}
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API BOOL WINAPI
_IsDarkModeAllowedForWindow(const HWND hWnd)
{
Q_ASSERT(hWnd);
if (!hWnd) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
FRAMELESSHELPER_STRING_CONSTANT(uxtheme)
static const auto pIsDarkModeAllowedForWindow
= reinterpret_cast<IsDarkModeAllowedForWindowPtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(137)));
if (!pIsDarkModeAllowedForWindow) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pIsDarkModeAllowedForWindow(hWnd);
}
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API BOOL WINAPI
_GetIsImmersiveColorUsingHighContrast(const IMMERSIVE_HC_CACHE_MODE mode)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
FRAMELESSHELPER_STRING_CONSTANT(uxtheme)
static const auto pGetIsImmersiveColorUsingHighContrast
= reinterpret_cast<GetIsImmersiveColorUsingHighContrastPtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(106)));
if (!pGetIsImmersiveColorUsingHighContrast) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pGetIsImmersiveColorUsingHighContrast(mode);
}
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API HTHEME WINAPI
_OpenNcThemeData(const HWND hWnd, LPCWSTR pszClassList)
{
Q_ASSERT(hWnd);
Q_ASSERT(pszClassList);
if (!hWnd || !pszClassList) {
SetLastError(ERROR_INVALID_PARAMETER);
return nullptr;
}
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return nullptr;
}
FRAMELESSHELPER_STRING_CONSTANT(uxtheme)
static const auto pOpenNcThemeData
= reinterpret_cast<OpenNcThemeDataPtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(49)));
if (!pOpenNcThemeData) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return nullptr;
}
return pOpenNcThemeData(hWnd, pszClassList);
}
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API BOOL WINAPI
_ShouldSystemUseDarkMode(VOID)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
FRAMELESSHELPER_STRING_CONSTANT(uxtheme)
static const auto pShouldSystemUseDarkMode
= reinterpret_cast<ShouldSystemUseDarkModePtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(138)));
if (!pShouldSystemUseDarkMode) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pShouldSystemUseDarkMode();
}
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API PREFERRED_APP_MODE WINAPI
_SetPreferredAppMode(const PREFERRED_APP_MODE mode)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return PAM_MAX;
}
FRAMELESSHELPER_STRING_CONSTANT(uxtheme)
static const auto pSetPreferredAppMode
= reinterpret_cast<SetPreferredAppModePtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(135)));
if (!pSetPreferredAppMode) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return PAM_MAX;
}
return pSetPreferredAppMode(mode);
}
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API BOOL WINAPI
_IsDarkModeAllowedForApp(VOID)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
FRAMELESSHELPER_STRING_CONSTANT(uxtheme)
static const auto pIsDarkModeAllowedForApp
= reinterpret_cast<IsDarkModeAllowedForAppPtr>(
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(139)));
if (!pIsDarkModeAllowedForApp) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pIsDarkModeAllowedForApp();
}
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API BOOL WINAPI
_EnableChildWindowDpiMessage2(const HWND hWnd, const BOOL fEnable)
{
Q_ASSERT(hWnd);
if (!hWnd) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
using EnableChildWindowDpiMessagePtr = decltype(&::_EnableChildWindowDpiMessage);
static const auto pEnableChildWindowDpiMessage = []() -> EnableChildWindowDpiMessagePtr {
FRAMELESSHELPER_STRING_CONSTANT(win32u)
FRAMELESSHELPER_STRING_CONSTANT(NtUserEnableChildWindowDpiMessage)
// EnableChildWindowDpiMessage() was moved to "win32u.dll" and renamed to
// "NtUserEnableChildWindowDpiMessage" since Win10 1607.
if (const auto pFunc = reinterpret_cast<EnableChildWindowDpiMessagePtr>(
SysApiLoader::resolve(kwin32u, kNtUserEnableChildWindowDpiMessage))) {
return pFunc;
}
FRAMELESSHELPER_STRING_CONSTANT(user32)
FRAMELESSHELPER_STRING_CONSTANT(EnableChildWindowDpiMessage)
// EnableChildWindowDpiMessage() was once a public API, so we can load it by name,
// but it got removed in Win10 1607, so we can't link to it directly.
if (const auto pFunc = reinterpret_cast<EnableChildWindowDpiMessagePtr>(
SysApiLoader::resolve(kuser32, kEnableChildWindowDpiMessage))) {
return pFunc;
}
// EnableChildWindowDpiMessage() was made private since Win10 1607.
if (const auto pFunc = reinterpret_cast<EnableChildWindowDpiMessagePtr>(
SysApiLoader::resolve(kuser32, MAKEINTRESOURCEA(2704)))) {
return pFunc;
}
return nullptr;
}();
if (!pEnableChildWindowDpiMessage) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pEnableChildWindowDpiMessage(hWnd, fEnable);
}
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API BOOL WINAPI
_EnablePerMonitorDialogScaling2(VOID)
{
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
using EnablePerMonitorDialogScalingPtr = decltype(&::_EnablePerMonitorDialogScaling);
static const auto pEnablePerMonitorDialogScaling = []() -> EnablePerMonitorDialogScalingPtr {
FRAMELESSHELPER_STRING_CONSTANT(user32)
FRAMELESSHELPER_STRING_CONSTANT(EnablePerMonitorDialogScaling)
// EnablePerMonitorDialogScaling() was once a public API, so we can load it by name,
// but it got removed in Win10 1607, so we can't link to it directly.
if (const auto pFunc = reinterpret_cast<EnablePerMonitorDialogScalingPtr>(
SysApiLoader::resolve(kuser32, kEnablePerMonitorDialogScaling))) {
return pFunc;
}
// EnablePerMonitorDialogScaling() was made private since Win10 1607.
if (const auto pFunc = reinterpret_cast<EnablePerMonitorDialogScalingPtr>(
SysApiLoader::resolve(kuser32, MAKEINTRESOURCEA(2577)))) {
return pFunc;
}
return nullptr;
}();
if (!pEnablePerMonitorDialogScaling) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pEnablePerMonitorDialogScaling();
}
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API UINT WINAPI
_GetDpiForWindow2(const HWND hWnd)
{
Q_ASSERT(hWnd);
if (!hWnd) {
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
using GetDpiForWindowPtr = decltype(&::_GetDpiForWindow);
static const auto pGetDpiForWindow = []() -> GetDpiForWindowPtr {
FRAMELESSHELPER_STRING_CONSTANT(user32)
FRAMELESSHELPER_STRING_CONSTANT(GetDpiForWindow)
// GetDpiForWindow() was made public since Win10 1607.
if (const auto pFunc = reinterpret_cast<GetDpiForWindowPtr>(
SysApiLoader::resolve(kuser32, kGetDpiForWindow))) {
return pFunc;
}
// GetDpiForWindow() was named "GetWindowDPI" before made public.
FRAMELESSHELPER_STRING_CONSTANT(GetWindowDPI)
if (const auto pFunc = reinterpret_cast<GetDpiForWindowPtr>(
SysApiLoader::resolve(kuser32, kGetWindowDPI))) {
return pFunc;
}
// GetWindowDPI() was made private since Win10 1607.
if (const auto pFunc = reinterpret_cast<GetDpiForWindowPtr>(
SysApiLoader::resolve(kuser32, MAKEINTRESOURCEA(2707)))) {
return pFunc;
}
return nullptr;
}();
if (!pGetDpiForWindow) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
return pGetDpiForWindow(hWnd);
}
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API int WINAPI
_GetSystemMetricsForDpi2(const int nIndex, const UINT dpi)
{
Q_ASSERT(nIndex >= 0);
Q_ASSERT(dpi != 0);
if ((nIndex < 0) || (dpi == 0)) {
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
using GetSystemMetricsForDpiPtr = decltype(&::_GetSystemMetricsForDpi);
static const auto pGetSystemMetricsForDpi = []() -> GetSystemMetricsForDpiPtr {
FRAMELESSHELPER_STRING_CONSTANT(user32)
FRAMELESSHELPER_STRING_CONSTANT(GetSystemMetricsForDpi)
// GetSystemMetricsForDpi() was made public since Win10 1607.
if (const auto pFunc = reinterpret_cast<GetSystemMetricsForDpiPtr>(
SysApiLoader::resolve(kuser32, kGetSystemMetricsForDpi))) {
return pFunc;
}
// GetSystemMetricsForDpi() was named "GetDpiMetrics" before made public,
// that is, when in Win10 1507 & 1511.
FRAMELESSHELPER_STRING_CONSTANT(GetDpiMetrics)
if (const auto pFunc = reinterpret_cast<GetSystemMetricsForDpiPtr>(
SysApiLoader::resolve(kuser32, kGetDpiMetrics))) {
return pFunc;
}
return nullptr;
}();
if (!pGetSystemMetricsForDpi) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
return pGetSystemMetricsForDpi(nIndex, dpi);
}
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API BOOL WINAPI
_AdjustWindowRectExForDpi2(LPRECT lpRect, const DWORD dwStyle,
const BOOL bMenu, const DWORD dwExStyle, const UINT dpi)
{
Q_ASSERT(lpRect);
Q_ASSERT(dpi != 0);
if (!lpRect || (dpi == 0)) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
FRAMELESSHELPER_USE_NAMESPACE
if (!WindowsVersionHelper::isWin10OrGreater()) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
using AdjustWindowRectExForDpiPtr = decltype(&::_AdjustWindowRectExForDpi);
static const auto pAdjustWindowRectExForDpi = []() -> AdjustWindowRectExForDpiPtr {
FRAMELESSHELPER_STRING_CONSTANT(user32)
FRAMELESSHELPER_STRING_CONSTANT(AdjustWindowRectExForDpi)
// AdjustWindowRectExForDpi() was made public since Win10 1607.
if (const auto pFunc = reinterpret_cast<AdjustWindowRectExForDpiPtr>(
SysApiLoader::resolve(kuser32, kAdjustWindowRectExForDpi))) {
return pFunc;
}
// AdjustWindowRectExForDpi() was made private in Win10 1507 & 1511.
if (const auto pFunc = reinterpret_cast<AdjustWindowRectExForDpiPtr>(
SysApiLoader::resolve(kuser32, MAKEINTRESOURCEA(2580)))) {
return pFunc;
}
return nullptr;
}();
if (!pAdjustWindowRectExForDpi) {
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return pAdjustWindowRectExForDpi(lpRect, dwStyle, bMenu, dwExStyle, dpi);
}
Q_DECLARE_METATYPE(QMargins) Q_DECLARE_METATYPE(QMargins)
FRAMELESSHELPER_BEGIN_NAMESPACE FRAMELESSHELPER_BEGIN_NAMESPACE
@ -1630,6 +1003,8 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
HRESULT hr = pD2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory), HRESULT hr = pD2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory),
nullptr, reinterpret_cast<void **>(&d2dFactory)); nullptr, reinterpret_cast<void **>(&d2dFactory));
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
// We want to get the newest system DPI, so refresh the system metrics
// manually to ensure that.
hr = d2dFactory->ReloadSystemMetrics(); hr = d2dFactory->ReloadSystemMetrics();
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
FLOAT dpiX = 0.0f, dpiY = 0.0f; FLOAT dpiX = 0.0f, dpiY = 0.0f;