diff --git a/src/msw/slider.cpp b/src/msw/slider.cpp index 4d08687349..ffa5d3919a 100644 --- a/src/msw/slider.cpp +++ b/src/msw/slider.cpp @@ -712,6 +712,11 @@ void wxSlider::SetValue(int value) void wxSlider::SetRange(int minValue, int maxValue) { + // Remember the old logical value if we need to update the physical control + // value after changing its range in wxSL_INVERSE case (and avoid an + // unnecessary call to GetValue() otherwise as it's just not needed). + const int valueOld = HasFlag(wxSL_INVERSE) ? GetValue() : 0; + m_rangeMin = minValue; m_rangeMax = maxValue; @@ -725,6 +730,14 @@ void wxSlider::SetRange(int minValue, int maxValue) ::SetWindowText((*m_labels)[SliderLabel_Max], Format(ValueInvertOrNot(m_rangeMax)).wx_str()); } + + // When emulating wxSL_INVERSE style in wxWidgets, we need to update the + // value after changing the range to ensure that the value seen by the user + // code, i.e. the one returned by GetValue(), does not change. + if ( HasFlag(wxSL_INVERSE) ) + { + ::SendMessage(GetHwnd(), TBM_SETPOS, TRUE, ValueInvertOrNot(valueOld)); + } } void wxSlider::SetTickFreq(int n, int pos) diff --git a/tests/controls/slidertest.cpp b/tests/controls/slidertest.cpp index 536166c8fc..2712d4424a 100644 --- a/tests/controls/slidertest.cpp +++ b/tests/controls/slidertest.cpp @@ -39,6 +39,9 @@ private: CPPUNIT_TEST( Value ); CPPUNIT_TEST( Range ); WXUISIM_TEST( Thumb ); + CPPUNIT_TEST( PseudoTest_Inversed ); + CPPUNIT_TEST( Value ); + CPPUNIT_TEST( Range ); CPPUNIT_TEST_SUITE_END(); void PageUpDown(); @@ -47,12 +50,17 @@ private: void Value(); void Range(); void Thumb(); + void PseudoTest_Inversed() { ms_inversed = true; } + + static bool ms_inversed; wxSlider* m_slider; DECLARE_NO_COPY_CLASS(SliderTestCase) }; +bool SliderTestCase::ms_inversed = false; + // register in the unnamed registry so that these tests are run by default CPPUNIT_TEST_SUITE_REGISTRATION( SliderTestCase ); @@ -61,7 +69,14 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SliderTestCase, "SliderTestCase" ); void SliderTestCase::setUp() { - m_slider = new wxSlider(wxTheApp->GetTopWindow(), wxID_ANY, 50, 0, 100); + long style = wxSL_HORIZONTAL; + + if ( ms_inversed ) + style |= wxSL_INVERSE; + + m_slider = new wxSlider(wxTheApp->GetTopWindow(), wxID_ANY, 50, 0, 100, + wxDefaultPosition, wxDefaultSize, + style); } void SliderTestCase::tearDown() @@ -163,6 +178,11 @@ void SliderTestCase::Range() CPPUNIT_ASSERT_EQUAL(0, m_slider->GetMin()); CPPUNIT_ASSERT_EQUAL(100, m_slider->GetMax()); + // Changing range shouldn't change the value. + m_slider->SetValue(17); + m_slider->SetRange(0, 200); + CPPUNIT_ASSERT_EQUAL(17, m_slider->GetValue()); + //Test negative ranges m_slider->SetRange(-50, 0);