From: <sv...@op...> - 2024-11-11 19:07:17
|
Author: sagamusix Date: Mon Nov 11 20:07:05 2024 New Revision: 22159 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22159 Log: [Fix] GetWindowPlacement/SetWindowPlacement is also broken on mixed-DPI setups. Use the same workaround that is apparently good enough for Microsoft's own code by temporarily switching to a DPI-unaware context (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/). Modified: trunk/OpenMPT/mptrack/HighDPISupport.cpp trunk/OpenMPT/mptrack/HighDPISupport.h trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/TrackerSettings.cpp Modified: trunk/OpenMPT/mptrack/HighDPISupport.cpp ============================================================================== --- trunk/OpenMPT/mptrack/HighDPISupport.cpp Mon Nov 11 19:57:12 2024 (r22158) +++ trunk/OpenMPT/mptrack/HighDPISupport.cpp Mon Nov 11 20:07:05 2024 (r22159) @@ -43,7 +43,7 @@ }; -enum MPT_DPI_AWARENESS_CONTEXT +enum MPT_DPI_AWARENESS_CONTEXT : intptr_t { MPT_DPI_AWARENESS_CONTEXT_UNAWARE = -1, MPT_DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = -2, @@ -164,10 +164,29 @@ } -HighDPISupport::DPIAwarenessBypass::DPIAwarenessBypass() +bool HighDPISupport::SetWindowPlacement(HWND hwnd, const WINDOWPLACEMENT &wpl) +{ + // 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/ + // What is not mentioned there: The first SetWindowPlacement call will restore the window to the wrong dimensions if it's not on the main screen... + HighDPISupport::DPIAwarenessBypass bypass{HighDPISupport::Mode::LowDpi}; + ::SetWindowPlacement(hwnd, &wpl); + return ::SetWindowPlacement(hwnd, &wpl) != FALSE; +} + + +bool HighDPISupport::GetWindowPlacement(HWND hwnd, WINDOWPLACEMENT &wpl) +{ + // 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{HighDPISupport::Mode::LowDpi}; + wpl.length = sizeof(WINDOWPLACEMENT); + return ::GetWindowPlacement(hwnd, &wpl) != FALSE; +} + + +HighDPISupport::DPIAwarenessBypass::DPIAwarenessBypass(Mode forceMode) { if(auto instance = GetHighDPISupportData(); instance->m_SetThreadDpiAwarenessContext) - m_previous = instance->m_SetThreadDpiAwarenessContext(HANDLE(MPT_DPI_AWARENESS_CONTEXT_SYSTEM_AWARE)); + m_previous = instance->m_SetThreadDpiAwarenessContext(HANDLE((forceMode == Mode::HighDpi) ? MPT_DPI_AWARENESS_CONTEXT_SYSTEM_AWARE : MPT_DPI_AWARENESS_CONTEXT_UNAWARE)); } Modified: trunk/OpenMPT/mptrack/HighDPISupport.h ============================================================================== --- trunk/OpenMPT/mptrack/HighDPISupport.h Mon Nov 11 19:57:12 2024 (r22158) +++ trunk/OpenMPT/mptrack/HighDPISupport.h Mon Nov 11 20:07:05 2024 (r22159) @@ -43,6 +43,11 @@ void CreateGUIFont(CFont &font, HWND hwnd); + // Normalized to 96 DPI to avoid issues in mixed-DPI contexts + bool SetWindowPlacement(HWND hwnd, const WINDOWPLACEMENT &wpl); + // Normalized to 96 DPI to avoid issues in mixed-DPI contexts + bool GetWindowPlacement(HWND hwnd, WINDOWPLACEMENT &wpl); + // Applies DPI scaling factor to some given size MPT_FORCEINLINE int ScalePixels(int pixels, HWND hwnd) { @@ -58,7 +63,7 @@ class DPIAwarenessBypass { public: - DPIAwarenessBypass(); + DPIAwarenessBypass(Mode forceMode = Mode::HighDpi); ~DPIAwarenessBypass(); private: Modified: trunk/OpenMPT/mptrack/MainFrm.cpp ============================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp Mon Nov 11 19:57:12 2024 (r22158) +++ trunk/OpenMPT/mptrack/MainFrm.cpp Mon Nov 11 20:07:05 2024 (r22159) @@ -2725,13 +2725,13 @@ void CMainFrame::OnShowWindow(BOOL bShow, UINT /*nStatus*/) { static bool firstShow = true; - if (bShow && !IsWindowVisible() && firstShow) + if(bShow && !IsWindowVisible() && firstShow) { firstShow = false; WINDOWPLACEMENT wpl; GetWindowPlacement(&wpl); wpl = theApp.GetSettings().Read<WINDOWPLACEMENT>(U_("Display"), U_("WindowPlacement"), wpl); - SetWindowPlacement(&wpl); + HighDPISupport::SetWindowPlacement(m_hWnd, wpl); } } Modified: trunk/OpenMPT/mptrack/TrackerSettings.cpp ============================================================================== --- trunk/OpenMPT/mptrack/TrackerSettings.cpp Mon Nov 11 19:57:12 2024 (r22158) +++ trunk/OpenMPT/mptrack/TrackerSettings.cpp Mon Nov 11 20:07:05 2024 (r22159) @@ -12,6 +12,7 @@ #include "stdafx.h" #include "TrackerSettings.h" #include "ExceptionHandler.h" +#include "HighDPISupport.h" #include "Mainfrm.h" #include "Moddoc.h" #include "Mpdlgs.h" @@ -1304,10 +1305,8 @@ void TrackerSettings::SaveSettings() { - WINDOWPLACEMENT wpl; - wpl.length = sizeof(WINDOWPLACEMENT); - CMainFrame::GetMainFrame()->GetWindowPlacement(&wpl); + HighDPISupport::GetWindowPlacement(*CMainFrame::GetMainFrame(), wpl); conf.Write<WINDOWPLACEMENT>(UL_("Display"), UL_("WindowPlacement"), wpl); conf.Write<int32>(UL_("Pattern Editor"), UL_("NumClipboards"), mpt::saturate_cast<int32>(PatternClipboard::GetClipboardSize())); |