From: <sv...@op...> - 2024-11-10 22:19:55
|
Author: sagamusix Date: Sun Nov 10 23:19:43 2024 New Revision: 22154 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22154 Log: [Fix] The Windows font selection dialog is not compatible with mixed-DPI setups. Temporarily disable mixed-DPI-awareness while this dialog is open. Modified: trunk/OpenMPT/mptrack/ColorConfigDlg.cpp trunk/OpenMPT/mptrack/HighDPISupport.cpp trunk/OpenMPT/mptrack/HighDPISupport.h Modified: trunk/OpenMPT/mptrack/ColorConfigDlg.cpp ============================================================================== --- trunk/OpenMPT/mptrack/ColorConfigDlg.cpp Sun Nov 10 22:35:58 2024 (r22153) +++ trunk/OpenMPT/mptrack/ColorConfigDlg.cpp Sun Nov 10 23:19:43 2024 (r22154) @@ -24,6 +24,26 @@ OPENMPT_NAMESPACE_BEGIN + +class CFontDialogEx : public CFontDialog +{ + using CFontDialog::CFontDialog; + +public: + INT_PTR DoModal() override + { + // CHOOSEFONT is not compatible with mixed-DPI. Temporarily disable mixed-DPI awareness just for this dialog. + // https://blogs.windows.com/windowsdeveloper/2016/10/24/high-dpi-scaling-improvements-for-desktop-applications-and-mixed-mode-dpi-scaling-in-the-windows-10-anniversary-update/ + HighDPISupport::DPIAwarenessBypass bypass; + HDC dc = ::GetDC(nullptr); + uint32 dpi = ::GetDeviceCaps(dc, LOGPIXELSX); + ::ReleaseDC(m_hWnd, dc); + m_cf.lpLogFont->lfHeight = -MulDiv(m_cf.lpLogFont->lfHeight, dpi, 720); + return CFontDialog::DoModal(); + } +}; + + static constexpr struct ColorDescriptions { const TCHAR *name; @@ -266,11 +286,11 @@ MemsetZero(lf); const int32 size = patternFont.size < 10 ? 120 : patternFont.size; // Point size to pixels - lf.lfHeight = -MulDiv(size, HighDPISupport::GetDpiForWindow(m_hWnd), 720); + lf.lfHeight = size; lf.lfWeight = patternFont.flags[FontSetting::Bold] ? FW_BOLD : FW_NORMAL; lf.lfItalic = patternFont.flags[FontSetting::Italic] ? TRUE : FALSE; mpt::String::WriteWinBuf(lf.lfFaceName) = mpt::ToWin(patternFont.name); - CFontDialog dlg(&lf); + CFontDialogEx dlg(&lf); dlg.m_cf.hwndOwner = m_hWnd; if(patternFont.name != PATTERNFONT_SMALL && patternFont.name != PATTERNFONT_LARGE) { @@ -301,11 +321,11 @@ LOGFONT lf; MemsetZero(lf); // Point size to pixels - lf.lfHeight = -MulDiv(commentFont.size, HighDPISupport::GetDpiForWindow(m_hWnd), 720); + lf.lfHeight = commentFont.size; lf.lfWeight = commentFont.flags[FontSetting::Bold] ? FW_BOLD : FW_NORMAL; lf.lfItalic = commentFont.flags[FontSetting::Italic] ? TRUE : FALSE; mpt::String::WriteWinBuf(lf.lfFaceName) = mpt::ToWin(commentFont.name); - CFontDialog dlg(&lf); + CFontDialogEx dlg(&lf); dlg.m_cf.hwndOwner = m_hWnd; dlg.m_cf.lpLogFont = &lf; dlg.m_cf.Flags &= ~CF_EFFECTS; Modified: trunk/OpenMPT/mptrack/HighDPISupport.cpp ============================================================================== --- trunk/OpenMPT/mptrack/HighDPISupport.cpp Sun Nov 10 22:35:58 2024 (r22153) +++ trunk/OpenMPT/mptrack/HighDPISupport.cpp Sun Nov 10 23:19:43 2024 (r22154) @@ -21,6 +21,7 @@ HighDPISupportData() : m_user32{mpt::LibraryPath::System(P_("user32"))} { + m_user32.Bind(m_SetThreadDpiAwarenessContext, "SetThreadDpiAwarenessContext"); m_user32.Bind(m_GetDpiForWindow, "GetDpiForWindow"); m_user32.Bind(m_GetSystemMetricsForDpi, "GetSystemMetricsForDpi"); m_user32.Bind(m_SystemParametersInfoForDpi, "SystemParametersInfoForDpi"); @@ -28,6 +29,9 @@ mpt::Library m_user32; + using PSETTHREADDPIAWARENESSCONTEXT = HANDLE(WINAPI *)(HANDLE); + PSETTHREADDPIAWARENESSCONTEXT m_SetThreadDpiAwarenessContext = nullptr; + using PGETDPIFORWINDOW = UINT(WINAPI *)(HWND); PGETDPIFORWINDOW m_GetDpiForWindow = nullptr; @@ -39,6 +43,16 @@ }; +enum MPT_DPI_AWARENESS_CONTEXT +{ + MPT_DPI_AWARENESS_CONTEXT_UNAWARE = -1, + MPT_DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = -2, + MPT_DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = -3, + MPT_DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = -4, // Windows 10 version 1703 and newer + MPT_DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED = -5, // Windows 10 version 1809 update and newer +}; + + static HighDPISupportData *GetHighDPISupportData() { static std::unique_ptr<HighDPISupportData> highDPISupportData; @@ -56,14 +70,6 @@ // For Windows 10, Creators Update (1703) and newer if(instance->m_user32.IsValid()) { - enum MPT_DPI_AWARENESS_CONTEXT - { - MPT_DPI_AWARENESS_CONTEXT_UNAWARE = -1, - MPT_DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = -2, - MPT_DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = -3, - MPT_DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = -4, // Windows 10 version 1703 and newer - MPT_DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED = -5, // Windows 10 version 1809 update and newer - }; using PSETPROCESSDPIAWARENESSCONTEXT = BOOL(WINAPI *)(HANDLE); PSETPROCESSDPIAWARENESSCONTEXT SetProcessDpiAwarenessContext = nullptr; if(instance->m_user32.Bind(SetProcessDpiAwarenessContext, "SetProcessDpiAwarenessContext")) @@ -158,4 +164,18 @@ } +HighDPISupport::DPIAwarenessBypass::DPIAwarenessBypass() +{ + if(auto instance = GetHighDPISupportData(); instance->m_SetThreadDpiAwarenessContext) + m_previous = instance->m_SetThreadDpiAwarenessContext(HANDLE(MPT_DPI_AWARENESS_CONTEXT_SYSTEM_AWARE)); +} + + +HighDPISupport::DPIAwarenessBypass::~DPIAwarenessBypass() +{ + if(auto instance = GetHighDPISupportData(); instance->m_SetThreadDpiAwarenessContext) + instance->m_SetThreadDpiAwarenessContext(m_previous); +} + + OPENMPT_NAMESPACE_END Modified: trunk/OpenMPT/mptrack/HighDPISupport.h ============================================================================== --- trunk/OpenMPT/mptrack/HighDPISupport.h Sun Nov 10 22:35:58 2024 (r22153) +++ trunk/OpenMPT/mptrack/HighDPISupport.h Sun Nov 10 23:19:43 2024 (r22154) @@ -54,6 +54,16 @@ { return MulDiv(pixels, 96, HighDPISupport::GetDpiForWindow(hwnd)); } + + class DPIAwarenessBypass + { + public: + DPIAwarenessBypass(); + ~DPIAwarenessBypass(); + + private: + HANDLE m_previous = {}; + }; }; OPENMPT_NAMESPACE_END |