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 // ============================================================================
17 // ----------------------------------------------------------------------------
19 // ----------------------------------------------------------------------------
21 // for compilers that support precompilation, includes "wx.h".
22 #include "wx/wxprec.h"
29 #include "wx/spinctrl.h"
30 #include "wx/os2/private.h"
32 // ----------------------------------------------------------------------------
34 // ----------------------------------------------------------------------------
36 IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl
, wxControl
)
38 BEGIN_EVENT_TABLE(wxSpinCtrl
, wxSpinButton
)
39 EVT_SPIN(-1, wxSpinCtrl::OnSpinChange
)
41 // ----------------------------------------------------------------------------
43 // ----------------------------------------------------------------------------
45 // the margin between the up-down control and its buddy
46 static const int MARGIN_BETWEEN
= 5;
48 // ============================================================================
50 // ============================================================================
52 // ----------------------------------------------------------------------------
54 // ----------------------------------------------------------------------------
56 bool wxSpinCtrl::Create(wxWindow
*parent
,
58 const wxString
& value
,
62 int min
, int max
, int initial
,
67 // before using DoGetBestSize(), have to set style to let the base class
68 // know whether this is a horizontal or vertical control (we're always
70 style |= wxSP_VERTICAL;
71 SetWindowStyle(style);
73 // calculate the sizes: the size given is the toal size for both controls
74 // and we need to fit them both in the given width (height is the same)
75 wxSize sizeText(size), sizeBtn(size);
76 sizeBtn.x = wxSpinButton::DoGetBestSize().x;
77 if ( sizeText.x <= 0 )
79 // DEFAULT_ITEM_WIDTH is the default width for the text control
80 sizeText.x = DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN + sizeBtn.x;
83 sizeText.x -= sizeBtn.x + MARGIN_BETWEEN;
84 if ( sizeText.x <= 0 )
86 wxLogDebug(_T("not enough space for wxSpinCtrl!"));
90 posBtn.x += sizeText.x + MARGIN_BETWEEN;
92 // create the spin button
93 if ( !wxSpinButton::Create(parent, id, posBtn, sizeBtn, style, name) )
101 // create the text window
102 m_hwndBuddy = (WXHWND)::CreateWindowEx
104 WS_EX_CLIENTEDGE, // sunken border
105 _T("EDIT"), // window class
106 NULL, // no window title
107 WS_CHILD | WS_BORDER, // style (will be shown later)
108 pos.x, pos.y, // position
109 0, 0, // size (will be set later)
110 GetHwndOf(parent), // parent
111 (HMENU)-1, // control id
112 wxGetInstance(), // app instance
113 NULL // unused client data
118 wxLogLastError("CreateWindow(buddy text window)");
123 // should have the same font as the other controls
124 SetFont(GetParent()->GetFont());
126 // set the size of the text window - can do it only now, because we
127 // couldn't call DoGetBestSize() before as font wasn't set
128 if ( sizeText.y <= 0 )
131 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
133 sizeText.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
136 DoMoveWindow(pos.x, pos.y,
137 sizeText.x + sizeBtn.x + MARGIN_BETWEEN, sizeText.y);
139 (void)::ShowWindow((HWND)m_hwndBuddy, SW_SHOW);
141 // associate the text window with the spin button
142 (void)::SendMessage(GetHwnd(), UDM_SETBUDDY, (WPARAM)m_hwndBuddy, 0);
144 if ( !value.IsEmpty() )
152 // ----------------------------------------------------------------------------
153 // wxTextCtrl-like methods
154 // ----------------------------------------------------------------------------
156 void wxSpinCtrl::SetValue(const wxString
& text
)
160 if ( !::SetWindowText((HWND)m_hwndBuddy, text.c_str()) )
162 wxLogLastError("SetWindowText(buddy)");
167 int wxSpinCtrl::GetValue() const
169 wxString val
= wxGetWindowText(m_hwndBuddy
);
172 if ( (wxSscanf(val
, wxT("%lu"), &n
) != 1) )
178 // ----------------------------------------------------------------------------
179 // forward some methods to subcontrols
180 // ----------------------------------------------------------------------------
182 bool wxSpinCtrl::SetFont(const wxFont
& font
)
184 if ( !wxWindowBase::SetFont(font
) )
190 WXHANDLE hFont
= GetFont().GetResourceHandle();
193 (void)::SendMessage((HWND)m_hwndBuddy, WM_SETFONT, (WPARAM)hFont, TRUE);
198 bool wxSpinCtrl::Show(bool show
)
200 if ( !wxControl::Show(show
) )
207 ::ShowWindow((HWND)m_hwndBuddy, show ? SW_SHOW : SW_HIDE);
212 bool wxSpinCtrl::Enable(bool enable
)
214 if ( !wxControl::Enable(enable
) )
221 ::EnableWindow((HWND)m_hwndBuddy, enable);
226 // ----------------------------------------------------------------------------
228 // ----------------------------------------------------------------------------
230 void wxSpinCtrl::OnSpinChange(wxSpinEvent
& eventSpin
)
232 wxCommandEvent
event(wxEVT_COMMAND_SPINCTRL_UPDATED
, GetId());
233 event
.SetEventObject(this);
234 event
.SetInt(eventSpin
.GetPosition());
236 (void)GetEventHandler()->ProcessEvent(event
);
238 if ( eventSpin
.GetSkipped() )
244 // ----------------------------------------------------------------------------
246 // ----------------------------------------------------------------------------
248 wxSize
wxSpinCtrl::DoGetBestSize() const
250 wxSize sizeBtn
= wxSpinButton::DoGetBestSize();
253 sizeBtn.x += DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN;
256 wxGetCharSize(GetHWND(), NULL, &y, &GetFont());
257 y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(y);
261 // make the text tall enough
268 void wxSpinCtrl::DoMoveWindow(int x
, int y
, int width
, int height
)
270 int widthBtn
= DoGetBestSize().x
;
271 int widthText
= width
- widthBtn
- MARGIN_BETWEEN
;
272 if ( widthText
<= 0 )
274 wxLogDebug(_T("not enough space for wxSpinCtrl!"));
278 if ( !::MoveWindow((HWND)m_hwndBuddy, x, y, widthText, height, TRUE) )
280 wxLogLastError("MoveWindow(buddy)");
283 x += widthText + MARGIN_BETWEEN;
284 if ( !::MoveWindow(GetHwnd(), x, y, widthBtn, height, TRUE) )
286 wxLogLastError("MoveWindow");