Skip to content

Commit 1c663bd

Browse files
RealGetDpiForSystemDownlevel解决在8.1或者更高平台中主屏Dpi变化导致系统真实Dpi获取不准问题。
1 parent e31a686 commit 1c663bd

File tree

3 files changed

+77
-5
lines changed

3 files changed

+77
-5
lines changed

ThunksList.md

+2
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,8 @@
780780
| GetPointerDeviceRects | 报告错误 ERROR_INVALID_PARAMETER。
781781
| PhysicalToLogicalPoint | 假装成功。
782782
| LogicalToPhysicalPoint | 假装成功。
783+
| PhysicalToLogicalPointForPerMonitorDPI | 调用 PhysicalToLogicalPoint。
784+
| LogicalToPhysicalPointForPerMonitorDPI | 调用 LogicalToPhysicalPoint。
783785

784786
## userenv.dll
785787
| 函数 | Fallback

src/Thunks/ext-ms-win-ntuser-window.hpp

+48-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#if (YY_Thunks_Target < __WindowsNT6_2)
1+
#if (YY_Thunks_Target < __WindowsNT6_3)
22
#include <winuser.h>
33
#endif
44

@@ -76,4 +76,51 @@ namespace YY::Thunks
7676
return TRUE;
7777
}
7878
#endif
79+
80+
#if (YY_Thunks_Target < __WindowsNT6_3)
81+
82+
// 最低受支持的客户端 Windows 8.1 [仅限桌面应用]
83+
// 最低受支持的服务器 Windows Server 2012 R2[仅限桌面应用]
84+
__DEFINE_THUNK(
85+
user32,
86+
8,
87+
BOOL,
88+
WINAPI,
89+
PhysicalToLogicalPointForPerMonitorDPI,
90+
_In_ HWND _hWnd,
91+
_Inout_ LPPOINT _pPoint
92+
)
93+
{
94+
if (auto const _pfnPhysicalToLogicalPointForPerMonitorDPI = try_get_PhysicalToLogicalPointForPerMonitorDPI())
95+
{
96+
return _pfnPhysicalToLogicalPointForPerMonitorDPI(_hWnd, _pPoint);
97+
}
98+
99+
return PhysicalToLogicalPoint(_hWnd, _pPoint);
100+
}
101+
#endif
102+
103+
104+
#if (YY_Thunks_Target < __WindowsNT6_3)
105+
106+
// 最低受支持的客户端 Windows 8.1 [仅限桌面应用]
107+
// 最低受支持的服务器 Windows Server 2012 R2[仅限桌面应用]
108+
__DEFINE_THUNK(
109+
user32,
110+
8,
111+
BOOL,
112+
WINAPI,
113+
LogicalToPhysicalPointForPerMonitorDPI,
114+
_In_ HWND _hWnd,
115+
_Inout_ LPPOINT _pPoint
116+
)
117+
{
118+
if (auto const _pfnLogicalToPhysicalPointForPerMonitorDPI = try_get_LogicalToPhysicalPointForPerMonitorDPI())
119+
{
120+
return _pfnLogicalToPhysicalPointForPerMonitorDPI(_hWnd, _pPoint);
121+
}
122+
123+
return LogicalToPhysicalPoint(_hWnd, _pPoint);
124+
}
125+
#endif
79126
}

src/Thunks/user32.hpp

+27-4
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ namespace YY::Thunks::internal
4949
/// 获取真实的系统DPI。
5050
/// </summary>
5151
/// <returns></returns>
52-
static UINT __fastcall RealGetDpiForSystemDownlevel() noexcept
52+
static UINT __fastcall RealGetDpiForSystemDownlevel(HWND _hSystemAwareWnd = nullptr) noexcept
5353
{
5454
static UINT s_uRealSystemDpi = 0;
5555
if (s_uRealSystemDpi)
@@ -58,7 +58,6 @@ namespace YY::Thunks::internal
5858
UINT _uDpi = GetDpiForSystemDownlevel();
5959
if (_uDpi == USER_DEFAULT_SCREEN_DPI && IsProcessDPIAware() == FALSE)
6060
{
61-
// 早期系统 主屏Dpi始终等于系统Dpi,因为修改主屏Dpi必须注销。
6261
HMONITOR _hMonitor = MonitorFromWindow(nullptr, MONITOR_DEFAULTTOPRIMARY);
6362
if (_hMonitor)
6463
{
@@ -67,7 +66,31 @@ namespace YY::Thunks::internal
6766
_oDevMode.dmSize = sizeof(_oDevMode);
6867
if (GetMonitorInfoW(_hMonitor, &_oMonitorInfo) && EnumDisplaySettingsW(_oMonitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &_oDevMode))
6968
{
70-
_uDpi = _oDevMode.dmPelsHeight * _uDpi / (_oMonitorInfo.rcMonitor.bottom - _oMonitorInfo.rcMonitor.top);
69+
// MonitorDpi
70+
_uDpi = _oDevMode.dmPelsHeight * USER_DEFAULT_SCREEN_DPI / (_oMonitorInfo.rcMonitor.bottom - _oMonitorInfo.rcMonitor.top);
71+
72+
// [6.3,) 这类系统屏幕Dpi随时可以改变,MonitorDpi并不一定与系统Dpi相同。
73+
if (internal::GetSystemVersion() >= __WindowsNT6_3)
74+
{
75+
_ASSERT(_hSystemAwareWnd);
76+
if (!_hSystemAwareWnd)
77+
return _uDpi;
78+
79+
#if (YY_Thunks_Target < __WindowsNT6_3)
80+
auto const LogicalToPhysicalPointForPerMonitorDPI = try_get_LogicalToPhysicalPointForPerMonitorDPI();
81+
#endif
82+
constexpr uint32_t kLogical = USER_DEFAULT_SCREEN_DPI;
83+
POINT _uPhysical = { kLogical ,kLogical };
84+
if (!LogicalToPhysicalPointForPerMonitorDPI(_hSystemAwareWnd, &_uPhysical))
85+
{
86+
return _uDpi;
87+
}
88+
89+
// LogicalToPhysicalPointForPerMonitorDPI存在以下转换关系:
90+
// Physical = Logical * MonitorDpi / SystemDpi;
91+
// 所以:SystemDpi = Logical * MonitorDpi / Physical;
92+
_uDpi /*SystemDpi*/ = kLogical * _uDpi / _uPhysical.x;
93+
}
7194
}
7295
}
7396
}
@@ -412,7 +435,7 @@ namespace YY::Thunks
412435
}
413436
else if (_eTargrtPocressDpiAwareness == PROCESS_DPI_AWARENESS::PROCESS_SYSTEM_DPI_AWARE)
414437
{
415-
return internal::RealGetDpiForSystemDownlevel();
438+
return internal::RealGetDpiForSystemDownlevel(_hWnd);
416439
}
417440
else
418441
{

0 commit comments

Comments
 (0)