+wxArraySpins wxSpinCtrl::ms_allSpins;
+
+// ----------------------------------------------------------------------------
+// wnd proc for the buddy text ctrl
+// ----------------------------------------------------------------------------
+
+LRESULT APIENTRY _EXPORT wxBuddyTextWndProc(HWND hwnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ wxSpinCtrl *spin = (wxSpinCtrl *)::GetWindowLong(hwnd, GWL_USERDATA);
+
+ // forward some messages (the key ones only so far) to the spin ctrl
+ switch ( message )
+ {
+ case WM_CHAR:
+ case WM_DEADCHAR:
+ case WM_KEYUP:
+ case WM_KEYDOWN:
+ spin->MSWWindowProc(message, wParam, lParam);
+ break;
+ }
+
+ return ::CallWindowProc(CASTWNDPROC spin->GetBuddyWndProc(),
+ hwnd, message, wParam, lParam);
+}
+
+/* static */
+wxSpinCtrl *wxSpinCtrl::GetSpinForTextCtrl(WXHWND hwndBuddy)
+{
+ wxSpinCtrl *spin = (wxSpinCtrl *)::GetWindowLong((HWND)hwndBuddy,
+ GWL_USERDATA);
+
+ int i = ms_allSpins.Index(spin);
+
+ if ( i == wxNOT_FOUND )
+ return NULL;
+
+ // sanity check
+ wxASSERT_MSG( spin->m_hwndBuddy == hwndBuddy,
+ _T("wxSpinCtrl has incorrect buddy HWND!") );
+
+ return spin;
+}
+
+// process a WM_COMMAND generated by the buddy text control
+bool wxSpinCtrl::ProcessTextCommand(WXWORD cmd, WXWORD WXUNUSED(id))
+{
+ if ( cmd == EN_CHANGE )
+ {
+ wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId());
+ event.SetEventObject(this);
+ event.SetInt(GetValue());
+ GetEventHandler()->ProcessEvent(event);
+
+ return TRUE;
+ }
+
+ // not processed
+ return FALSE;
+}
+