1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        msw/spinctrl.cpp 
   3 // Purpose:     wxSpinCtrl class implementation for Win32 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  18     #pragma implementation "spinctrlbase.h" 
  19     #pragma implementation "spinctrl.h" 
  22 // ---------------------------------------------------------------------------- 
  24 // ---------------------------------------------------------------------------- 
  26 // for compilers that support precompilation, includes "wx.h". 
  27 #include "wx/wxprec.h" 
  36 #include "wx/spinctrl.h" 
  37 #include "wx/os2/private.h" 
  39 // ---------------------------------------------------------------------------- 
  41 // ---------------------------------------------------------------------------- 
  43 IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl
, wxControl
) 
  45 BEGIN_EVENT_TABLE(wxSpinCtrl
, wxSpinButton
) 
  46     EVT_SPIN(-1, wxSpinCtrl::OnSpinChange
) 
  48 // ---------------------------------------------------------------------------- 
  50 // ---------------------------------------------------------------------------- 
  52 // the margin between the up-down control and its buddy 
  53 static const int MARGIN_BETWEEN 
= 5; 
  55 // ============================================================================ 
  57 // ============================================================================ 
  59 // ---------------------------------------------------------------------------- 
  61 // ---------------------------------------------------------------------------- 
  63 bool wxSpinCtrl::Create(wxWindow 
*parent
, 
  65                         const wxString
& value
, 
  69                         int min
, int max
, int initial
, 
  74     // before using DoGetBestSize(), have to set style to let the base class 
  75     // know whether this is a horizontal or vertical control (we're always 
  77     style |= wxSP_VERTICAL; 
  78     SetWindowStyle(style); 
  80     // calculate the sizes: the size given is the toal size for both controls 
  81     // and we need to fit them both in the given width (height is the same) 
  82     wxSize sizeText(size), sizeBtn(size); 
  83     sizeBtn.x = wxSpinButton::DoGetBestSize().x; 
  84     if ( sizeText.x <= 0 ) 
  86         // DEFAULT_ITEM_WIDTH is the default width for the text control 
  87         sizeText.x = DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN + sizeBtn.x; 
  90     sizeText.x -= sizeBtn.x + MARGIN_BETWEEN; 
  91     if ( sizeText.x <= 0 ) 
  93         wxLogDebug(_T("not enough space for wxSpinCtrl!")); 
  97     posBtn.x += sizeText.x + MARGIN_BETWEEN; 
  99     // create the spin button 
 100     if ( !wxSpinButton::Create(parent, id, posBtn, sizeBtn, style, name) ) 
 108     // create the text window 
 109     m_hwndBuddy = (WXHWND)::CreateWindowEx 
 111                      WS_EX_CLIENTEDGE,       // sunken border 
 112                      _T("EDIT"),             // window class 
 113                      NULL,                   // no window title 
 114                      WS_CHILD | WS_BORDER,   // style (will be shown later) 
 115                      pos.x, pos.y,           // position 
 116                      0, 0,                   // size (will be set later) 
 117                      GetHwndOf(parent),      // parent 
 118                      (HMENU)-1,              // control id 
 119                      wxGetInstance(),        // app instance 
 120                      NULL                    // unused client data 
 125         wxLogLastError("CreateWindow(buddy text window)"); 
 130     // should have the same font as the other controls 
 131     SetFont(GetParent()->GetFont()); 
 133     // set the size of the text window - can do it only now, because we 
 134     // couldn't call DoGetBestSize() before as font wasn't set 
 135     if ( sizeText.y <= 0 ) 
 138         wxGetCharSize(GetHWND(), &cx, &cy, &GetFont()); 
 140         sizeText.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy); 
 143     DoMoveWindow(pos.x, pos.y, 
 144                  sizeText.x + sizeBtn.x + MARGIN_BETWEEN, sizeText.y); 
 146     (void)::ShowWindow((HWND)m_hwndBuddy, SW_SHOW); 
 148     // associate the text window with the spin button 
 149     (void)::SendMessage(GetHwnd(), UDM_SETBUDDY, (WPARAM)m_hwndBuddy, 0); 
 151     if ( !value.IsEmpty() ) 
 159 // ---------------------------------------------------------------------------- 
 160 // wxTextCtrl-like methods 
 161 // ---------------------------------------------------------------------------- 
 163 void wxSpinCtrl::SetValue(const wxString
& text
) 
 167     if ( !::SetWindowText((HWND)m_hwndBuddy, text.c_str()) ) 
 169         wxLogLastError("SetWindowText(buddy)"); 
 174 int wxSpinCtrl::GetValue() const 
 176     wxString val 
= wxGetWindowText(m_hwndBuddy
); 
 179     if ( (wxSscanf(val
, wxT("%lu"), &n
) != 1) ) 
 185 // ---------------------------------------------------------------------------- 
 186 // forward some methods to subcontrols 
 187 // ---------------------------------------------------------------------------- 
 189 bool wxSpinCtrl::SetFont(const wxFont
& font
) 
 191     if ( !wxWindowBase::SetFont(font
) ) 
 197     WXHANDLE hFont 
= GetFont().GetResourceHandle(); 
 200     (void)::SendMessage((HWND)m_hwndBuddy, WM_SETFONT, (WPARAM)hFont, TRUE); 
 205 bool wxSpinCtrl::Show(bool show
) 
 207     if ( !wxControl::Show(show
) ) 
 214     ::ShowWindow((HWND)m_hwndBuddy, show ? SW_SHOW : SW_HIDE); 
 219 bool wxSpinCtrl::Enable(bool enable
) 
 221     if ( !wxControl::Enable(enable
) ) 
 228     ::EnableWindow((HWND)m_hwndBuddy, enable); 
 233 // ---------------------------------------------------------------------------- 
 235 // ---------------------------------------------------------------------------- 
 237 void wxSpinCtrl::OnSpinChange(wxSpinEvent
& eventSpin
) 
 239     wxCommandEvent 
event(wxEVT_COMMAND_SPINCTRL_UPDATED
, GetId()); 
 240     event
.SetEventObject(this); 
 241     event
.SetInt(eventSpin
.GetPosition()); 
 243     (void)GetEventHandler()->ProcessEvent(event
); 
 245     if ( eventSpin
.GetSkipped() ) 
 251 // ---------------------------------------------------------------------------- 
 253 // ---------------------------------------------------------------------------- 
 255 wxSize 
wxSpinCtrl::DoGetBestSize() const 
 257     wxSize sizeBtn 
= wxSpinButton::DoGetBestSize(); 
 260     sizeBtn.x += DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN; 
 263     wxGetCharSize(GetHWND(), NULL, &y, &GetFont()); 
 264     y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(y); 
 268         // make the text tall enough 
 275 void wxSpinCtrl::DoMoveWindow(int x
, int y
, int width
, int height
) 
 277     int widthBtn 
= DoGetBestSize().x
; 
 278     int widthText 
= width 
- widthBtn 
- MARGIN_BETWEEN
; 
 279     if ( widthText 
<= 0 ) 
 281         wxLogDebug(_T("not enough space for wxSpinCtrl!")); 
 285     if ( !::MoveWindow((HWND)m_hwndBuddy, x, y, widthText, height, TRUE) ) 
 287         wxLogLastError("MoveWindow(buddy)"); 
 290     x += widthText + MARGIN_BETWEEN; 
 291     if ( !::MoveWindow(GetHwnd(), x, y, widthBtn, height, TRUE) ) 
 293         wxLogLastError("MoveWindow"); 
 298 #endif //wxUSE_SPINBTN