From ae1e93cbae496ec292d1e425fdc1c98307960180 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Thu, 9 Jul 2020 22:53:07 +0200 Subject: [PATCH] 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. --- include/wx/private/spinctrl.h | 2 ++ interface/wx/spinctrl.h | 9 ++++++++- src/common/spinctrlcmn.cpp | 6 ++++++ src/msw/spinctrl.cpp | 10 ++++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/include/wx/private/spinctrl.h b/include/wx/private/spinctrl.h index af2ae47270..e0a59db1cc 100644 --- a/include/wx/private/spinctrl.h +++ b/include/wx/private/spinctrl.h @@ -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_ diff --git a/interface/wx/spinctrl.h b/interface/wx/spinctrl.h index 3bef883df2..edb2ac83b6 100644 --- a/interface/wx/spinctrl.h +++ b/interface/wx/spinctrl.h @@ -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); diff --git a/src/common/spinctrlcmn.cpp b/src/common/spinctrlcmn.cpp index 42e571dfac..2d5bba4b43 100644 --- a/src/common/spinctrlcmn.cpp +++ b/src/common/spinctrlcmn.cpp @@ -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 diff --git a/src/msw/spinctrl.cpp b/src/msw/spinctrl.cpp index 01cc251835..b297f3922e 100644 --- a/src/msw/spinctrl.cpp +++ b/src/msw/spinctrl.cpp @@ -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.