Don't allow wxSpinCtrl range to include negative values if base != 10 (wxMSW)

In a native up-down control hexadecimal numbers are always unsigned (see
UDM_SETBASE message documentation) so we need to prevent:
- Setting a range including negative values if base == 16.
- Setting base != 10 if current range includes negative values.

See #18805.
This commit is contained in:
Artur Wieczorek
2020-07-09 22:53:07 +02:00
parent b2d4a9dedc
commit ae1e93cbae
4 changed files with 26 additions and 1 deletions

View File

@@ -26,6 +26,8 @@ extern int GetMaxValueLength(int minVal, int maxVal, int base);
// of wxSpinCtrl is derived from wxSpinButton but uses the same algorithm.
extern wxSize GetBestSize(const wxControl* spin, int minVal, int maxVal, int base);
// Helper function to check if given combination of range and base is valid.
extern bool IsBaseCompatibleWithRange(int minVal, int maxVal, int base);
} // namespace wxSpinCtrlImpl
#endif // _WX_PRIVATE_SPINCTRL_H_

View File

@@ -149,11 +149,15 @@ public:
the numbers in the specified base when they are changed using the spin
control arrows.
@note Under wxMSW setting a base to 16 is allowed only if current range
does not include negative values.
@param base
Numeric base, currently only 10 and 16 are supported.
@return
@true if the base was successfully changed or @false if it failed,
usually meaning that either the base is not 10 or 16.
usually meaning that either the base is not 10 or 16 or that
the base is not supported for values in the current range.
@since 2.9.5
*/
@@ -166,6 +170,9 @@ public:
it's not inside the new valid range, e.g. it will become @a minVal if
it is less than it now. However no @c wxEVT_SPINCTRL
event is generated, even if it the value does change.
@note Under wxMSW setting a range including negative values is silently
ignored if current base is set to 16.
*/
void SetRange(int minVal, int maxVal);

View File

@@ -137,4 +137,10 @@ wxSize wxSpinCtrlImpl::GetBestSize(const wxControl* spin,
return spin->GetSizeFromText(largestString);
}
bool wxSpinCtrlImpl::IsBaseCompatibleWithRange(int minVal, int maxVal, int base)
{
// Negative values in the range are allowed only if base == 10
return base == 10 || (minVal >= 0 && maxVal >= 0);
}
#endif // wxUSE_SPINCTRL

View File

@@ -421,6 +421,10 @@ int wxSpinCtrl::GetBase() const
bool wxSpinCtrl::SetBase(int base)
{
// For negative values in the range only base == 10 is allowed
if ( !wxSpinCtrlImpl::IsBaseCompatibleWithRange(m_min, m_max, base) )
return false;
if ( !::SendMessage(GetHwnd(), UDM_SETBASE, base, 0) )
return false;
@@ -537,6 +541,12 @@ WXHWND wxSpinCtrl::MSWGetFocusHWND() const
void wxSpinCtrl::SetRange(int minVal, int maxVal)
{
// Negative values in the range are allowed only if base == 10
if ( !wxSpinCtrlImpl::IsBaseCompatibleWithRange(minVal, maxVal, GetBase()) )
{
return;
}
// Manually adjust the old value to avoid an event being sent from
// NormalizeValue() called from inside the base class SetRange() as we're
// not supposed to generate any events from here.