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