Fix unwanted refreshes when setting size of wxChoice in wxMSW

The window was still resized even if its size didn't really change,
which, in particular, unexpectedly resulted in closing its drop down if
it was shown.

Fix this by moving the code dealing with the different interpretation of
the control height between wxMSW and MSW (for the former, it's just the
height of the visible part, while for the latter it includes drop down
as well), from wxChoice::DoSetSize() to DoMoveWindow(). This allows the
base class DoSetSize() to correctly filter out calls not really changing
the size, while still setting the height correctly when it does change.

See #17075.

See https://github.com/wxWidgets/wxWidgets/pull/389
This commit is contained in:
Steve Browne 2017-01-07 08:42:54 -05:00 committed by Vadim Zeitlin
parent 0bae199ffe
commit 1525e84e56

View file

@ -478,7 +478,37 @@ void wxChoice::DoMoveWindow(int x, int y, int width, int height)
if ( width < 0 )
return;
wxControl::DoMoveWindow(x, y, width, height);
// the height which we must pass to Windows should be the total height of
// the control including the drop down list while the height given to us
// is, of course, just the height of the permanently visible part of it so
// add the drop down height to it
// don't make the drop down list too tall, arbitrarily limit it to 30
// items max and also don't make it too small if it's currently empty
size_t nItems = GetCount();
if (!HasFlag(wxCB_SIMPLE))
{
if (!nItems)
nItems = 9;
else if (nItems > 30)
nItems = 30;
}
int heightWithItems = 0;
if (!HasFlag(wxCB_SIMPLE))
{
// The extra item (" + 1") is required to prevent a vertical
// scrollbar from appearing with comctl32.dll versions earlier
// than 6.0 (such as found in Win2k).
const int hItem = SendMessage(GetHwnd(), CB_GETITEMHEIGHT, 0, 0);
heightWithItems = height + hItem*(nItems + 1);
}
else
{
heightWithItems = SetHeightSimpleComboBox(nItems);
}
wxControl::DoMoveWindow(x, y, width, heightWithItems);
}
void wxChoice::DoGetSize(int *w, int *h) const
@ -497,22 +527,13 @@ void wxChoice::DoSetSize(int x, int y,
int width, int height,
int sizeFlags)
{
// The height of the control itself, i.e. of its visible part.
int heightVisible = height;
// we need the real height below so get the current one if it's not given
if ( height == wxDefaultCoord )
{
// height not specified, use the same as before
DoGetSize(NULL, &heightVisible);
}
else if ( height == GetBestSize().y )
if ( height == GetBestSize().y )
{
// we don't need to manually manage our height, let the system use the
// default one
m_heightOwn = wxDefaultCoord;
}
else // non-default height specified
else if ( height != wxDefaultCoord ) // non-default height specified
{
// set our new own height but be careful not to make it too big: the
// native control apparently stores it as a single byte and so setting
@ -527,36 +548,8 @@ void wxChoice::DoSetSize(int x, int y,
m_heightOwn = COMBO_HEIGHT_ADJ;
}
// the height which we must pass to Windows should be the total height of
// the control including the drop down list while the height given to us
// is, of course, just the height of the permanently visible part of it so
// add the drop down height to it
// don't make the drop down list too tall, arbitrarily limit it to 30
// items max and also don't make it too small if it's currently empty
size_t nItems = GetCount();
if (!HasFlag(wxCB_SIMPLE))
{
if ( !nItems )
nItems = 9;
else if ( nItems > 30 )
nItems = 30;
}
const int hItem = SendMessage(GetHwnd(), CB_GETITEMHEIGHT, 0, 0);
int heightWithItems = 0;
if (!HasFlag(wxCB_SIMPLE))
// The extra item (" + 1") is required to prevent a vertical
// scrollbar from appearing with comctl32.dll versions earlier
// than 6.0 (such as found in Win2k).
heightWithItems = heightVisible + hItem*(nItems + 1);
else
heightWithItems = SetHeightSimpleComboBox(nItems);
// do resize the native control
wxControl::DoSetSize(x, y, width, heightWithItems, sizeFlags);
wxControl::DoSetSize(x, y, width, height, sizeFlags);
// make the control itself of the requested height: notice that this