Improve calculating wxButton best size under wxMSW

We can use BCM_GETIDEALSIZE message to get the size of the button that
best fits its text and image (if present).
It gives better results for text wxButton with wxBU_EXACTFIT style.
This commit is contained in:
Artur Wieczorek
2021-04-08 19:16:38 +02:00
parent a02690f957
commit de10f054c4
2 changed files with 49 additions and 20 deletions

View File

@@ -59,6 +59,7 @@ protected:
// Should only be called if we do have a button, i.e. if m_imageData is // Should only be called if we do have a button, i.e. if m_imageData is
// non-NULL. // non-NULL.
void AdjustForBitmapSize(wxSize& size) const; void AdjustForBitmapSize(wxSize& size) const;
void AdjustForBitmapMargins(wxSize& size) const;
class wxButtonImageData *m_imageData; class wxButtonImageData *m_imageData;

View File

@@ -75,6 +75,11 @@ using namespace wxMSWImpl;
#endif #endif
#endif // wxUSE_UXTHEME #endif // wxUSE_UXTHEME
// BCM_GETIDEALSIZE is defined since XP
#ifndef BCM_GETIDEALSIZE
#define BCM_GETIDEALSIZE 0x1601
#endif // BCM_GETIDEALSIZE
#ifndef ODS_NOACCEL #ifndef ODS_NOACCEL
#define ODS_NOACCEL 0x0100 #define ODS_NOACCEL 0x0100
#endif #endif
@@ -516,6 +521,16 @@ void wxAnyButton::AdjustForBitmapSize(wxSize &size) const
size.x = sizeBmp.x; size.x = sizeBmp.x;
} }
// and also for the margins we always add internally (unless we have no
// border at all in which case the button has exactly the same size as
// bitmap and so no margins should be used)
AdjustForBitmapMargins(size);
}
void wxAnyButton::AdjustForBitmapMargins(wxSize& size) const
{
wxCHECK_RET(m_imageData, wxT("shouldn't be called if no image"));
// and also for the margins we always add internally (unless we have no // and also for the margins we always add internally (unless we have no
// border at all in which case the button has exactly the same size as // border at all in which case the button has exactly the same size as
// bitmap and so no margins should be used) // bitmap and so no margins should be used)
@@ -565,6 +580,18 @@ wxSize wxAnyButton::DoGetBestSize() const
wxSize size; wxSize size;
// BCM_GETIDEALSIZE works properly only it there is a text label in the button.
if ( !IsOwnerDrawn() && ShowsLabel() )
{
SIZE idealSize = { 0, 0 };
::SendMessage(GetHwnd(), BCM_GETIDEALSIZE, 0, (LPARAM)&idealSize);
size.Set(idealSize.cx, idealSize.cy);
if ( m_imageData )
AdjustForBitmapMargins(size);
}
else
{
// Account for the text part if we have it. // Account for the text part if we have it.
if ( ShowsLabel() ) if ( ShowsLabel() )
{ {
@@ -591,6 +618,7 @@ wxSize wxAnyButton::DoGetBestSize() const
if ( m_imageData ) if ( m_imageData )
AdjustForBitmapSize(size); AdjustForBitmapSize(size);
}
return wxMSWButton::IncreaseToStdSizeAndCache(self, size); return wxMSWButton::IncreaseToStdSizeAndCache(self, size);
} }