X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/937013e0fd914d4c42f9f5ec98da665986b93dfa..af27647706cb7ca50cf04814ff867532919a252c:/src/msw/spinctrl.cpp diff --git a/src/msw/spinctrl.cpp b/src/msw/spinctrl.cpp index ff3afaf8c8..05965d0c3d 100644 --- a/src/msw/spinctrl.cpp +++ b/src/msw/spinctrl.cpp @@ -114,10 +114,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl) BEGIN_EVENT_TABLE(wxSpinCtrl, wxSpinButton) EVT_CHAR(wxSpinCtrl::OnChar) - EVT_SET_FOCUS(wxSpinCtrl::OnSetFocus) EVT_KILL_FOCUS(wxSpinCtrl::OnKillFocus) - EVT_SPIN(wxID_ANY, wxSpinCtrl::OnSpinChange) END_EVENT_TABLE() #define GetBuddyHwnd() (HWND)(m_hwndBuddy) @@ -148,8 +146,7 @@ LRESULT APIENTRY _EXPORT wxBuddyTextWndProc(HWND hwnd, { wxSpinCtrl *spin = (wxSpinCtrl *)wxGetWindowUserData(hwnd); - // forward some messages (the key and focus ones only so far) to - // the spin ctrl + // forward some messages (mostly the key and focus ones) to the spin ctrl switch ( message ) { case WM_SETFOCUS: @@ -164,6 +161,12 @@ LRESULT APIENTRY _EXPORT wxBuddyTextWndProc(HWND hwnd, case WM_DEADCHAR: case WM_KEYUP: case WM_KEYDOWN: +#ifdef WM_HELP + // we need to forward WM_HELP too to ensure that the context help + // associated with wxSpinCtrl is shown when the text control part of it + // is clicked with the "?" cursor + case WM_HELP: +#endif spin->MSWWindowProc(message, wParam, lParam); // The control may have been deleted at this point, so check. @@ -172,8 +175,20 @@ LRESULT APIENTRY _EXPORT wxBuddyTextWndProc(HWND hwnd, break; case WM_GETDLGCODE: - // we want to get WXK_RETURN in order to generate the event for it - return DLGC_WANTCHARS; + if ( spin->HasFlag(wxTE_PROCESS_ENTER) ) + { + long dlgCode = ::CallWindowProc + ( + CASTWNDPROC spin->GetBuddyWndProc(), + hwnd, + message, + wParam, + lParam + ); + dlgCode |= DLGC_WANTMESSAGE; + return dlgCode; + } + break; } return ::CallWindowProc(CASTWNDPROC spin->GetBuddyWndProc(), @@ -200,7 +215,7 @@ wxSpinCtrl *wxSpinCtrl::GetSpinForTextCtrl(WXHWND hwndBuddy) // process a WM_COMMAND generated by the buddy text control bool wxSpinCtrl::ProcessTextCommand(WXWORD cmd, WXWORD WXUNUSED(id)) { - if ( cmd == EN_CHANGE ) + if ( (cmd == EN_CHANGE) && (!m_blockEvent )) { wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId()); event.SetEventObject(this); @@ -296,6 +311,8 @@ bool wxSpinCtrl::Create(wxWindow *parent, int min, int max, int initial, const wxString& name) { + m_blockEvent = false; + // this should be in ctor/init function but I don't want to add one to 2.8 // to avoid problems with default ctor which can be inlined in the user // code and so might not get this fix without recompilation @@ -457,6 +474,8 @@ void wxSpinCtrl::SetValue(const wxString& text) void wxSpinCtrl::SetValue(int val) { + m_blockEvent = true; + wxSpinButton::SetValue(val); // normally setting the value of the spin button is enough as it updates @@ -472,6 +491,8 @@ void wxSpinCtrl::SetValue(int val) } m_oldValue = GetValue(); + + m_blockEvent = false; } int wxSpinCtrl::GetValue() const @@ -532,6 +553,46 @@ bool wxSpinCtrl::Show(bool show) return true; } +bool wxSpinCtrl::Reparent(wxWindowBase *newParent) +{ + // Reparenting both the updown control and its buddy does not seem to work: + // they continue to be connected somehow, but visually there is no feedback + // on the buddy edit control. To avoid this problem, we reparent the buddy + // window normally, but we recreate the updown control and reassign its + // buddy. + + if ( !wxWindowBase::Reparent(newParent) ) + return false; + + newParent->GetChildren().DeleteObject(this); + + // preserve the old values + const wxSize size = GetSize(); + int value = GetValue(); + const wxRect btnRect = wxRectFromRECT(wxGetWindowRect(GetHwnd())); + + // destroy the old spin button + UnsubclassWin(); + if ( !::DestroyWindow(GetHwnd()) ) + wxLogLastError(wxT("DestroyWindow")); + + // create and initialize the new one + if ( !wxSpinButton::Create(GetParent(), GetId(), + btnRect.GetPosition(), btnRect.GetSize(), + GetWindowStyle(), GetName()) ) + return false; + + SetValue(value); + SetRange(m_min, m_max); + SetInitialSize(size); + + // associate it with the buddy control again + ::SetParent(GetBuddyHwnd(), GetHwndOf(GetParent())); + (void)::SendMessage(GetHwnd(), UDM_SETBUDDY, (WPARAM)GetBuddyHwnd(), 0); + + return true; +} + bool wxSpinCtrl::Enable(bool enable) { if ( !wxControl::Enable(enable) ) @@ -576,15 +637,37 @@ void wxSpinCtrl::SendSpinUpdate(int value) m_oldValue = value; } -void wxSpinCtrl::OnSpinChange(wxSpinEvent& eventSpin) +bool wxSpinCtrl::MSWOnScroll(int WXUNUSED(orientation), WXWORD wParam, + WXWORD pos, WXHWND control) { - const int value = eventSpin.GetPosition(); - if ( value != m_oldValue ) + wxCHECK_MSG( control, false, wxT("scrolling what?") ); + + if ( wParam != SB_THUMBPOSITION ) { - SendSpinUpdate(value); + // probable SB_ENDSCROLL - we don't react to it + return false; } + + int new_value = (short) pos; + if (m_oldValue != new_value) + SendSpinUpdate( new_value ); + + return TRUE; +} + +bool wxSpinCtrl::MSWOnNotify(int WXUNUSED(idCtrl), WXLPARAM lParam, WXLPARAM *result) +{ + NM_UPDOWN *lpnmud = (NM_UPDOWN *)lParam; + + if (lpnmud->hdr.hwndFrom != GetHwnd()) // make sure it is the right control + return false; + + *result = 0; // never reject UP and DOWN events + + return TRUE; } + // ---------------------------------------------------------------------------- // size calculations // ---------------------------------------------------------------------------- @@ -643,6 +726,19 @@ void wxSpinCtrl::DoGetSize(int *x, int *y) const *y = ctrlrect.bottom - ctrlrect.top; } +void wxSpinCtrl::DoGetClientSize(int *x, int *y) const +{ + RECT spinrect = wxGetClientRect(GetHwnd()); + RECT textrect = wxGetClientRect(GetBuddyHwnd()); + RECT ctrlrect; + UnionRect(&ctrlrect,&textrect, &spinrect); + + if ( x ) + *x = ctrlrect.right - ctrlrect.left; + if ( y ) + *y = ctrlrect.bottom - ctrlrect.top; +} + void wxSpinCtrl::DoGetPosition(int *x, int *y) const { // hack: pretend that our HWND is the text control just for a moment