Skip to content

Commit

Permalink
[Fix] GetWindowPlacement/SetWindowPlacement is also broken on mixed-D…
Browse files Browse the repository at this point in the history
…PI 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/).

git-svn-id: https://source.openmpt.org/svn/openmpt/trunk/OpenMPT@22159 56274372-70c3-4bfc-bfc3-4c3a0b034d27
  • Loading branch information
sagamusix committed Nov 11, 2024
1 parent 4a93c7f commit d7cafce
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 9 deletions.
25 changes: 22 additions & 3 deletions mptrack/HighDPISupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ struct HighDPISupportData
};


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,
Expand Down Expand Up @@ -164,10 +164,29 @@ void HighDPISupport::CreateGUIFont(CFont &font, HWND hwnd)
}


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));
}


Expand Down
7 changes: 6 additions & 1 deletion mptrack/HighDPISupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ namespace HighDPISupport

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)
{
Expand All @@ -58,7 +63,7 @@ namespace HighDPISupport
class DPIAwarenessBypass
{
public:
DPIAwarenessBypass();
DPIAwarenessBypass(Mode forceMode = Mode::HighDpi);
~DPIAwarenessBypass();

private:
Expand Down
4 changes: 2 additions & 2 deletions mptrack/MainFrm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2725,13 +2725,13 @@ bool CMainFrame::UpdateEffectKeys(const CModDoc *modDoc)
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);
}
}

Expand Down
5 changes: 2 additions & 3 deletions mptrack/TrackerSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -1304,10 +1305,8 @@ void TrackerSettings::FixupEQ(EQPreset &eqSettings)

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()));
Expand Down

0 comments on commit d7cafce

Please sign in to comment.