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"
34 #include "wx/spinctrl.h"
35 #include "wx/os2/private.h"
37 // ----------------------------------------------------------------------------
39 // ----------------------------------------------------------------------------
41 IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl
, wxControl
)
43 BEGIN_EVENT_TABLE(wxSpinCtrl
, wxSpinButton
)
44 EVT_SPIN(-1, wxSpinCtrl::OnSpinChange
)
46 // ----------------------------------------------------------------------------
48 // ----------------------------------------------------------------------------
50 // the margin between the up-down control and its buddy
51 static const int MARGIN_BETWEEN
= 5;
53 // ============================================================================
55 // ============================================================================
57 // ----------------------------------------------------------------------------
59 // ----------------------------------------------------------------------------
61 bool wxSpinCtrl::Create(wxWindow
*parent
,
63 const wxString
& value
,
67 int min
, int max
, int initial
,
72 // before using DoGetBestSize(), have to set style to let the base class
73 // know whether this is a horizontal or vertical control (we're always
75 style |= wxSP_VERTICAL;
76 SetWindowStyle(style);
78 // calculate the sizes: the size given is the toal size for both controls
79 // and we need to fit them both in the given width (height is the same)
80 wxSize sizeText(size), sizeBtn(size);
81 sizeBtn.x = wxSpinButton::DoGetBestSize().x;
82 if ( sizeText.x <= 0 )
84 // DEFAULT_ITEM_WIDTH is the default width for the text control
85 sizeText.x = DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN + sizeBtn.x;
88 sizeText.x -= sizeBtn.x + MARGIN_BETWEEN;
89 if ( sizeText.x <= 0 )
91 wxLogDebug(_T("not enough space for wxSpinCtrl!"));
95 posBtn.x += sizeText.x + MARGIN_BETWEEN;
97 // create the spin button
98 if ( !wxSpinButton::Create(parent, id, posBtn, sizeBtn, style, name) )
106 // create the text window
107 m_hwndBuddy = (WXHWND)::CreateWindowEx
109 WS_EX_CLIENTEDGE, // sunken border
110 _T("EDIT"), // window class
111 NULL, // no window title
112 WS_CHILD | WS_BORDER, // style (will be shown later)
113 pos.x, pos.y, // position
114 0, 0, // size (will be set later)
115 GetHwndOf(parent), // parent
116 (HMENU)-1, // control id
117 wxGetInstance(), // app instance
118 NULL // unused client data
123 wxLogLastError("CreateWindow(buddy text window)");
128 // should have the same font as the other controls
129 SetFont(GetParent()->GetFont());
131 // set the size of the text window - can do it only now, because we
132 // couldn't call DoGetBestSize() before as font wasn't set
133 if ( sizeText.y <= 0 )
136 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
138 sizeText.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
141 DoMoveWindow(pos.x, pos.y,
142 sizeText.x + sizeBtn.x + MARGIN_BETWEEN, sizeText.y);
144 (void)::ShowWindow((HWND)m_hwndBuddy, SW_SHOW);
146 // associate the text window with the spin button
147 (void)::SendMessage(GetHwnd(), UDM_SETBUDDY, (WPARAM)m_hwndBuddy, 0);
149 if ( !value.IsEmpty() )
157 // ----------------------------------------------------------------------------
158 // wxTextCtrl-like methods
159 // ----------------------------------------------------------------------------
161 void wxSpinCtrl::SetValue(const wxString
& text
)
165 if ( !::SetWindowText((HWND)m_hwndBuddy, text.c_str()) )
167 wxLogLastError("SetWindowText(buddy)");
172 int wxSpinCtrl::GetValue() const
174 wxString val
= wxGetWindowText(m_hwndBuddy
);
177 if ( (wxSscanf(val
, wxT("%lu"), &n
) != 1) )
183 // ----------------------------------------------------------------------------
184 // forward some methods to subcontrols
185 // ----------------------------------------------------------------------------
187 bool wxSpinCtrl::SetFont(const wxFont
& font
)
189 if ( !wxWindowBase::SetFont(font
) )
195 WXHANDLE hFont
= GetFont().GetResourceHandle();
198 (void)::SendMessage((HWND)m_hwndBuddy, WM_SETFONT, (WPARAM)hFont, TRUE);
203 bool wxSpinCtrl::Show(bool show
)
205 if ( !wxControl::Show(show
) )
212 ::ShowWindow((HWND)m_hwndBuddy, show ? SW_SHOW : SW_HIDE);
217 bool wxSpinCtrl::Enable(bool enable
)
219 if ( !wxControl::Enable(enable
) )
226 ::EnableWindow((HWND)m_hwndBuddy, enable);
231 // ----------------------------------------------------------------------------
233 // ----------------------------------------------------------------------------
235 void wxSpinCtrl::OnSpinChange(wxSpinEvent
& eventSpin
)
237 wxCommandEvent
event(wxEVT_COMMAND_SPINCTRL_UPDATED
, GetId());
238 event
.SetEventObject(this);
239 event
.SetInt(eventSpin
.GetPosition());
241 (void)GetEventHandler()->ProcessEvent(event
);
243 if ( eventSpin
.GetSkipped() )
249 // ----------------------------------------------------------------------------
251 // ----------------------------------------------------------------------------
253 wxSize
wxSpinCtrl::DoGetBestSize() const
255 wxSize sizeBtn
= wxSpinButton::DoGetBestSize();
258 sizeBtn.x += DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN;
261 wxGetCharSize(GetHWND(), NULL, &y, &GetFont());
262 y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(y);
266 // make the text tall enough
273 void wxSpinCtrl::DoMoveWindow(int x
, int y
, int width
, int height
)
275 int widthBtn
= DoGetBestSize().x
;
276 int widthText
= width
- widthBtn
- MARGIN_BETWEEN
;
277 if ( widthText
<= 0 )
279 wxLogDebug(_T("not enough space for wxSpinCtrl!"));
283 if ( !::MoveWindow((HWND)m_hwndBuddy, x, y, widthText, height, TRUE) )
285 wxLogLastError("MoveWindow(buddy)");
288 x += widthText + MARGIN_BETWEEN;
289 if ( !::MoveWindow(GetHwnd(), x, y, widthBtn, height, TRUE) )
291 wxLogLastError("MoveWindow");