Merge branch 'msw-button-getdefaultsize'

Fix wxButton::GetDefaultSize() in high DPI under MSW.

See #24285.

Closes #24285.
This commit is contained in:
Vadim Zeitlin 2024-02-09 17:23:06 +01:00
commit 308815bafd
2 changed files with 13 additions and 34 deletions

View file

@ -546,17 +546,7 @@ wxSize wxMSWButton::IncreaseToStdSizeAndCache(wxControl *btn, const wxSize& size
// By default all buttons have at least the standard size.
if ( !btn->HasFlag(wxBU_EXACTFIT) )
{
// The "Recommended sizing and spacing" section of MSDN layout article
// documents the default button size as being 50*14 dialog units or
// 75*23 relative pixels (what we call DIPs). As dialog units don't
// scale well in high DPI because of rounding errors, just DIPs here.
//
// Moreover, it looks like the extra 2px borders around the visible
// part of the button are not scaled correctly in higher than normal
// DPI, so add them without scaling.
const wxSize sizeDef = btn->FromDIP(wxSize(73, 21)) + wxSize(2, 2);
sizeBtn.IncTo(sizeDef);
sizeBtn.IncTo(wxButton::GetDefaultSize(btn));
}
// wxBU_EXACTFIT is typically used alongside a text control or similar,

View file

@ -163,30 +163,19 @@ wxSize wxButtonBase::GetDefaultSize(wxWindow* win)
if ( s_sizeBtn.HasChanged(win) )
{
wxSize base;
if ( win )
{
wxClientDC dc(win);
dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
base = wxPrivate::GetAverageASCIILetterSize(dc);
}
else
{
wxScreenDC dc;
dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
base = wxPrivate::GetAverageASCIILetterSize(dc);
}
// The size of a standard button in the dialog units is 50x14,
// translate this to pixels.
// The "Recommended sizing and spacing" section of MSDN layout article
// documents the default button size as being 50*14 dialog units or
// 75*23 relative pixels (what we call DIPs). But dialog units don't
// work well in high DPI (and not just because of rounding errors, i.e.
// the values differ from the actual default button size used by
// Windows itself in high DPI by too much), so just use DIPs directly.
//
// Windows' computes dialog units using average character width over
// upper- and lower-case ASCII alphabet and not using the average
// character width metadata stored in the font; see
// http://support.microsoft.com/default.aspx/kb/145994 for detailed
// discussion.
s_sizeBtn.SetAtNewDPI(wxRescaleCoord(50, 14).From(4, 8).To(base));
// Moreover, it looks like the extra 2px borders around the visible
// part of the button are not scaled correctly in higher than normal
// DPI, so add them without scaling.
s_sizeBtn.SetAtNewDPI(
wxWindow::FromDIP(wxSize(73, 21), win) + wxSize(2, 2)
);
}
return s_sizeBtn.Get();