X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6fe190576ec9fd93bd0f1eb35539077bce864309..2d956b58023a4955313a1c1531bc70a0deb0b831:/src/msw/spinctrl.cpp?ds=sidebyside diff --git a/src/msw/spinctrl.cpp b/src/msw/spinctrl.cpp index d6e9aebcad..22ee0816c9 100644 --- a/src/msw/spinctrl.cpp +++ b/src/msw/spinctrl.cpp @@ -40,7 +40,7 @@ #include "wx/spinctrl.h" #include "wx/msw/private.h" -#if defined(__WIN95__) && !(defined(__GNUWIN32_OLD__) || defined(__TWIN32__)) +#if defined(__WIN95__) && !((defined(__GNUWIN32_OLD__) || defined(__TWIN32__)) && !defined(__CYGWIN10__)) #include #endif @@ -53,6 +53,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl) BEGIN_EVENT_TABLE(wxSpinCtrl, wxSpinButton) + EVT_CHAR(wxSpinCtrl::OnChar) EVT_SPIN(-1, wxSpinCtrl::OnSpinChange) END_EVENT_TABLE() @@ -92,7 +93,15 @@ LRESULT APIENTRY _EXPORT wxBuddyTextWndProc(HWND hwnd, case WM_KEYUP: case WM_KEYDOWN: spin->MSWWindowProc(message, wParam, lParam); + + // The control may have been deleted at this point, so check. + if (!(::IsWindow(hwnd) && ((wxSpinCtrl *)::GetWindowLong(hwnd, GWL_USERDATA)) == spin)) + return 0; break; + + case WM_GETDLGCODE: + // we want to get WXK_RETURN in order to generate the event for it + return DLGC_WANTCHARS; } return ::CallWindowProc(CASTWNDPROC spin->GetBuddyWndProc(), @@ -120,20 +129,71 @@ 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 ) + switch (cmd) { - wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId()); - event.SetEventObject(this); - event.SetInt(GetValue()); - GetEventHandler()->ProcessEvent(event); - - return TRUE; + case EN_CHANGE: + { + wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId()); + event.SetEventObject(this); + wxString val = wxGetWindowText(m_hwndBuddy); + event.SetString(val); + event.SetInt(GetValue()); + return GetEventHandler()->ProcessEvent(event); + } + case EN_SETFOCUS: + case EN_KILLFOCUS: + { + wxFocusEvent event(cmd == EN_KILLFOCUS ? wxEVT_KILL_FOCUS + : wxEVT_SET_FOCUS, + m_windowId); + event.SetEventObject( this ); + return GetEventHandler()->ProcessEvent(event); + } + default: + break; } // not processed return FALSE; } +void wxSpinCtrl::OnChar(wxKeyEvent& event) +{ + switch ( event.KeyCode() ) + { + case WXK_RETURN: + { + wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId); + InitCommandEvent(event); + wxString val = wxGetWindowText(m_hwndBuddy); + event.SetString(val); + event.SetInt(GetValue()); + if ( GetEventHandler()->ProcessEvent(event) ) + return; + break; + } + + case WXK_TAB: + // always produce navigation event - even if we process TAB + // ourselves the fact that we got here means that the user code + // decided to skip processing of this TAB - probably to let it + // do its default job. + { + wxNavigationKeyEvent eventNav; + eventNav.SetDirection(!event.ShiftDown()); + eventNav.SetWindowChange(event.ControlDown()); + eventNav.SetEventObject(this); + + if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav) ) + return; + } + break; + } + + // no, we didn't process it + event.Skip(); +} + // ---------------------------------------------------------------------------- // construction // ---------------------------------------------------------------------------- @@ -181,13 +241,25 @@ bool wxSpinCtrl::Create(wxWindow *parent, SetRange(min, max); SetValue(initial); + bool want3D; + WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D); + int msStyle = WS_CHILD; + + // Even with extended styles, need to combine with WS_BORDER for them to + // look right. + if ( want3D || wxStyleHasBorder(style) ) + msStyle |= WS_BORDER; + + if ( style & wxCLIP_SIBLINGS ) + msStyle |= WS_CLIPSIBLINGS; + // create the text window m_hwndBuddy = (WXHWND)::CreateWindowEx ( - WS_EX_CLIENTEDGE, // sunken border + exStyle, // sunken border _T("EDIT"), // window class NULL, // no window title - WS_CHILD | WS_BORDER /* | WS_CLIPSIBLINGS */, // style (will be shown later) + msStyle /* | WS_CLIPSIBLINGS */, // style (will be shown later) pos.x, pos.y, // position 0, 0, // size (will be set later) GetHwndOf(parent), // parent @@ -245,6 +317,10 @@ wxSpinCtrl::~wxSpinCtrl() { ms_allSpins.Remove(this); + // This removes spurious memory leak reporting + if (ms_allSpins.GetCount() == 0) + ms_allSpins.Clear(); + // destroy the buddy window because this pointer which wxBuddyTextWndProc // uses will not soon be valid any more ::DestroyWindow(GetBuddyHwnd());