From 6fe190576ec9fd93bd0f1eb35539077bce864309 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 21 Dec 2000 02:12:22 +0000 Subject: [PATCH] wxSpinCtrl now sens TEXT_UPDATED events as in wxGTK git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8976 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/spinctrl.h | 21 ++++++++++-- src/msw/fontdlg.cpp | 2 +- src/msw/spinctrl.cpp | 69 ++++++++++++++++++++++++++++++++------- src/msw/window.cpp | 15 +++++++++ 4 files changed, 92 insertions(+), 15 deletions(-) diff --git a/include/wx/msw/spinctrl.h b/include/wx/msw/spinctrl.h index 243e7b6833..61a03e25ef 100644 --- a/include/wx/msw/spinctrl.h +++ b/include/wx/msw/spinctrl.h @@ -18,6 +18,10 @@ #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 @@ -70,7 +74,16 @@ public: // 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; @@ -83,7 +96,11 @@ protected: // 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) diff --git a/src/msw/fontdlg.cpp b/src/msw/fontdlg.cpp index 75acaeeea3..c9eed41aee 100644 --- a/src/msw/fontdlg.cpp +++ b/src/msw/fontdlg.cpp @@ -52,7 +52,7 @@ // wxWin macros // ---------------------------------------------------------------------------- - IMPLEMENT_DYNAMIC_CLASS(wxFontDialog, wxDialog) +IMPLEMENT_DYNAMIC_CLASS(wxFontDialog, wxDialog) // ============================================================================ // implementation diff --git a/src/msw/spinctrl.cpp b/src/msw/spinctrl.cpp index 9f2928f82a..d6e9aebcad 100644 --- a/src/msw/spinctrl.cpp +++ b/src/msw/spinctrl.cpp @@ -56,6 +56,8 @@ BEGIN_EVENT_TABLE(wxSpinCtrl, wxSpinButton) EVT_SPIN(-1, wxSpinCtrl::OnSpinChange) END_EVENT_TABLE() +#define GetBuddyHwnd() (HWND)(m_hwndBuddy) + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -69,6 +71,8 @@ static const int MARGIN_BETWEEN = 1; // implementation // ============================================================================ +wxArraySpins wxSpinCtrl::ms_allSpins; + // ---------------------------------------------------------------------------- // wnd proc for the buddy text ctrl // ---------------------------------------------------------------------------- @@ -95,6 +99,41 @@ LRESULT APIENTRY _EXPORT wxBuddyTextWndProc(HWND hwnd, 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 // ---------------------------------------------------------------------------- @@ -165,9 +204,9 @@ bool wxSpinCtrl::Create(wxWindow *parent, } // 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()); @@ -185,7 +224,7 @@ bool wxSpinCtrl::Create(wxWindow *parent, 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); @@ -195,14 +234,20 @@ bool wxSpinCtrl::Create(wxWindow *parent, 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()); } // ---------------------------------------------------------------------------- @@ -211,7 +256,7 @@ wxSpinCtrl::~wxSpinCtrl() void wxSpinCtrl::SetValue(const wxString& text) { - if ( !::SetWindowText((HWND)m_hwndBuddy, text.c_str()) ) + if ( !::SetWindowText(GetBuddyHwnd(), text.c_str()) ) { wxLogLastError(wxT("SetWindowText(buddy)")); } @@ -241,7 +286,7 @@ bool wxSpinCtrl::SetFont(const wxFont& font) } WXHANDLE hFont = GetFont().GetResourceHandle(); - (void)::SendMessage((HWND)m_hwndBuddy, WM_SETFONT, (WPARAM)hFont, TRUE); + (void)::SendMessage(GetBuddyHwnd(), WM_SETFONT, (WPARAM)hFont, TRUE); return TRUE; } @@ -253,7 +298,7 @@ bool wxSpinCtrl::Show(bool show) return FALSE; } - ::ShowWindow((HWND)m_hwndBuddy, show ? SW_SHOW : SW_HIDE); + ::ShowWindow(GetBuddyHwnd(), show ? SW_SHOW : SW_HIDE); return TRUE; } @@ -265,14 +310,14 @@ bool wxSpinCtrl::Enable(bool enable) return FALSE; } - ::EnableWindow((HWND)m_hwndBuddy, enable); + ::EnableWindow(GetBuddyHwnd(), enable); return TRUE; } void wxSpinCtrl::SetFocus() { - ::SetFocus((HWND)m_hwndBuddy); + ::SetFocus(GetBuddyHwnd()); } // ---------------------------------------------------------------------------- @@ -324,7 +369,7 @@ void wxSpinCtrl::DoMoveWindow(int x, int y, int width, int height) 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)")); } @@ -341,7 +386,7 @@ void wxSpinCtrl::DoGetSize(int *x, int *y) const { RECT spinrect, textrect, ctrlrect; GetWindowRect(GetHwnd(), &spinrect); - GetWindowRect((HWND)m_hwndBuddy, &textrect); + GetWindowRect(GetBuddyHwnd(), &textrect); UnionRect(&ctrlrect,&textrect, &spinrect); if ( x ) diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 2f317e1a91..84dc12f4b7 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -71,6 +71,10 @@ #include "wx/caret.h" #endif // wxUSE_CARET +#if wxUSE_SPINCTRL + #include "wx/spinctrl.h" +#endif // wxUSE_SPINCTRL + #include "wx/intl.h" #include "wx/log.h" @@ -3227,6 +3231,17 @@ bool wxWindow::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control) return GetEventHandler()->ProcessEvent(event); } +#if wxUSE_SPINCTRL + else + { + // the text ctrl which is logically part of wxSpinCtrl sends WM_COMMAND + // notifications to its parent which we want to reflect back to + // wxSpinCtrl + wxSpinCtrl *spin = wxSpinCtrl::GetSpinForTextCtrl(control); + if ( spin && spin->ProcessTextCommand(cmd, id) ) + return TRUE; + } +#endif // wxUSE_SPINCTRL return FALSE; } -- 2.45.2