#include "wx/spinbutt.h" // the base class
+#include "wx/dynarray.h"
+class WXDLLEXPORT wxSpinCtrl;
+WX_DEFINE_EXPORTED_ARRAY(wxSpinCtrl *, wxArraySpins);
+
// ----------------------------------------------------------------------------
// Under Win32, wxSpinCtrl is a wxSpinButton with a buddy (as MSDN docs call
// it) text window whose contents is automatically updated when the spin
// wxSpinButton doesn't accept focus, but we do
virtual bool AcceptsFocus() const { return wxWindow::AcceptsFocus(); }
- WXFARPROC GetBuddyWndProc() const { return m_oldBuddyWndProc; }
+ // for internal use only
+
+ // get the subclassed window proc of the buddy text
+ WXFARPROC GetBuddyWndProc() const { return m_wndProcBuddy; }
+
+ // return the spinctrl object whose buddy is the given window or NULL
+ static wxSpinCtrl *GetSpinForTextCtrl(WXHWND hwndBuddy);
+
+ // process a WM_COMMAND generated by the buddy text control
+ bool ProcessTextCommand(WXWORD cmd, WXWORD id);
protected:
virtual void DoGetPosition(int *x, int *y) const;
// the data for the "buddy" text ctrl
WXHWND m_hwndBuddy;
- WXFARPROC m_oldBuddyWndProc;
+ WXFARPROC m_wndProcBuddy;
+
+ // all existing wxSpinCtrls - this allows to find the one corresponding to
+ // the given buddy window in GetSpinForTextCtrl()
+ static wxArraySpins ms_allSpins;
private:
DECLARE_DYNAMIC_CLASS(wxSpinCtrl)
EVT_SPIN(-1, wxSpinCtrl::OnSpinChange)
END_EVENT_TABLE()
+#define GetBuddyHwnd() (HWND)(m_hwndBuddy)
+
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
// implementation
// ============================================================================
+wxArraySpins wxSpinCtrl::ms_allSpins;
+
// ----------------------------------------------------------------------------
// wnd proc for the buddy text ctrl
// ----------------------------------------------------------------------------
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;
+}
+
// ----------------------------------------------------------------------------
// construction
// ----------------------------------------------------------------------------
}
// subclass the text ctrl to be able to intercept some events
- m_oldBuddyWndProc = (WXFARPROC)::GetWindowLong((HWND)m_hwndBuddy, GWL_WNDPROC);
- ::SetWindowLong((HWND)m_hwndBuddy, GWL_USERDATA, (LONG)this);
- ::SetWindowLong((HWND)m_hwndBuddy, GWL_WNDPROC, (LONG)wxBuddyTextWndProc);
+ m_wndProcBuddy = (WXFARPROC)::GetWindowLong(GetBuddyHwnd(), GWL_WNDPROC);
+ ::SetWindowLong(GetBuddyHwnd(), GWL_USERDATA, (LONG)this);
+ ::SetWindowLong(GetBuddyHwnd(), GWL_WNDPROC, (LONG)wxBuddyTextWndProc);
// should have the same font as the other controls
SetFont(GetParent()->GetFont());
DoMoveWindow(pos.x, pos.y,
sizeText.x + sizeBtn.x + MARGIN_BETWEEN, sizeText.y);
- (void)::ShowWindow((HWND)m_hwndBuddy, SW_SHOW);
+ (void)::ShowWindow(GetBuddyHwnd(), SW_SHOW);
// associate the text window with the spin button
(void)::SendMessage(GetHwnd(), UDM_SETBUDDY, (WPARAM)m_hwndBuddy, 0);
SetValue(value);
}
+ // do it after finishing with m_hwndBuddy creation to avoid generating
+ // initial wxEVT_COMMAND_TEXT_UPDATED message
+ ms_allSpins.Add(this);
+
return TRUE;
}
wxSpinCtrl::~wxSpinCtrl()
{
+ ms_allSpins.Remove(this);
+
// destroy the buddy window because this pointer which wxBuddyTextWndProc
// uses will not soon be valid any more
- ::DestroyWindow((HWND)m_hwndBuddy);
+ ::DestroyWindow(GetBuddyHwnd());
}
// ----------------------------------------------------------------------------
void wxSpinCtrl::SetValue(const wxString& text)
{
- if ( !::SetWindowText((HWND)m_hwndBuddy, text.c_str()) )
+ if ( !::SetWindowText(GetBuddyHwnd(), text.c_str()) )
{
wxLogLastError(wxT("SetWindowText(buddy)"));
}
}
WXHANDLE hFont = GetFont().GetResourceHandle();
- (void)::SendMessage((HWND)m_hwndBuddy, WM_SETFONT, (WPARAM)hFont, TRUE);
+ (void)::SendMessage(GetBuddyHwnd(), WM_SETFONT, (WPARAM)hFont, TRUE);
return TRUE;
}
return FALSE;
}
- ::ShowWindow((HWND)m_hwndBuddy, show ? SW_SHOW : SW_HIDE);
+ ::ShowWindow(GetBuddyHwnd(), show ? SW_SHOW : SW_HIDE);
return TRUE;
}
return FALSE;
}
- ::EnableWindow((HWND)m_hwndBuddy, enable);
+ ::EnableWindow(GetBuddyHwnd(), enable);
return TRUE;
}
void wxSpinCtrl::SetFocus()
{
- ::SetFocus((HWND)m_hwndBuddy);
+ ::SetFocus(GetBuddyHwnd());
}
// ----------------------------------------------------------------------------
wxLogDebug(_T("not enough space for wxSpinCtrl!"));
}
- if ( !::MoveWindow((HWND)m_hwndBuddy, x, y, widthText, height, TRUE) )
+ if ( !::MoveWindow(GetBuddyHwnd(), x, y, widthText, height, TRUE) )
{
wxLogLastError(wxT("MoveWindow(buddy)"));
}
{
RECT spinrect, textrect, ctrlrect;
GetWindowRect(GetHwnd(), &spinrect);
- GetWindowRect((HWND)m_hwndBuddy, &textrect);
+ GetWindowRect(GetBuddyHwnd(), &textrect);
UnionRect(&ctrlrect,&textrect, &spinrect);
if ( x )