Add framework for Per-Monitor DPI Awareness on Windows

React to the WM_DPICHANGED event and update the size of the  child windows and
the top-level window. Scale the minimum and maximum window size to the new DPI.

Only react to WM_DPICHANGED when DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 is
used.
This commit is contained in:
Maarten Bent
2016-10-05 21:04:13 +02:00
parent 70f8bf4c86
commit 137713e0c8
6 changed files with 141 additions and 1 deletions

View File

@@ -4837,6 +4837,47 @@ wxSize wxWindowMSW::GetDPI() const
return dpi;
}
// Helper function to update the given coordinate by the scaling factor if it
// is set, i.e. different from wxDefaultCoord.
static void ScaleCoordIfSet(int& coord, float scaleFactor)
{
if ( coord != wxDefaultCoord )
{
const float coordScaled = coord * scaleFactor;
coord = scaleFactor > 1.0 ? ceil(coordScaled) : floor(coordScaled);
}
}
void
wxWindowMSW::MSWUpdateOnDPIChange(const wxSize& oldDPI, const wxSize& newDPI)
{
// update min and max size if necessary
const float scaleFactor = (float)newDPI.y / oldDPI.y;
ScaleCoordIfSet(m_minHeight, scaleFactor);
ScaleCoordIfSet(m_minWidth, scaleFactor);
ScaleCoordIfSet(m_maxHeight, scaleFactor);
ScaleCoordIfSet(m_maxWidth, scaleFactor);
InvalidateBestSize();
// update children
wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
while ( current )
{
wxWindow *childWin = current->GetData();
// Update all children, except other top-level windows.
// These could be on a different monitor and will get their own
// dpi-changed event.
if ( childWin && !childWin->IsTopLevel() )
{
childWin->MSWUpdateOnDPIChange(oldDPI, newDPI);
}
current = current->GetNext();
}
}
// ---------------------------------------------------------------------------
// colours and palettes
// ---------------------------------------------------------------------------