+void wxSpinCtrlGenericBase::SetSnapToTicks(bool snap_to_ticks)
+{
+ m_snap_to_ticks = snap_to_ticks;
+ DoSetValue(m_value);
+}
+
+void wxSpinCtrlGenericBase::SetSelection(long from, long to)
+{
+ wxCHECK_RET( m_textCtrl, wxT("invalid call to wxSpinCtrl::SetSelection") );
+
+ m_textCtrl->SetSelection(from, to);
+}
+
+#ifndef wxHAS_NATIVE_SPINCTRL
+
+//-----------------------------------------------------------------------------
+// wxSpinCtrl
+//-----------------------------------------------------------------------------
+
+bool wxSpinCtrl::SetBase(int base)
+{
+ // Currently we only support base 10 and 16. We could add support for base
+ // 8 quite easily but wxMSW doesn't support it natively so don't bother.
+ if ( base != 10 && base != 16 )
+ return false;
+
+ if ( base == m_base )
+ return true;
+
+ // Update the current control contents to show in the new base: be careful
+ // to call DoTextToValue() before changing the base...
+ double val;
+ const bool hasValidVal = DoTextToValue(m_textCtrl->GetValue(), &val);
+
+ m_base = base;
+
+ // ... but DoValueToText() after doing it.
+ if ( hasValidVal )
+ m_textCtrl->SetValue(DoValueToText(val));
+
+ return true;
+}
+
+void wxSpinCtrl::DoSendEvent()
+{
+ wxSpinEvent event( wxEVT_SPINCTRL, GetId());
+ event.SetEventObject( this );
+ event.SetPosition((int)(m_value + 0.5)); // FIXME should be SetValue
+ event.SetString(m_textCtrl->GetValue());
+ GetEventHandler()->ProcessEvent( event );
+}
+
+bool wxSpinCtrl::DoTextToValue(const wxString& text, double *val)
+{
+ long lval;
+ if ( !text.ToLong(&lval, GetBase()) )
+ return false;
+
+ *val = static_cast<double>(lval);
+
+ return true;
+}
+
+wxString wxSpinCtrl::DoValueToText(double val)
+{
+ switch ( GetBase() )