]> git.saurik.com Git - wxWidgets.git/blame - src/msw/spinctrl.cpp
bitmap and image updates
[wxWidgets.git] / src / msw / spinctrl.cpp
CommitLineData
b782f2e0
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: msw/spinctrl.cpp
3// Purpose: wxSpinCtrl class implementation for Win32
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 22.07.99
7// RCS-ID: $Id$
8// Copyright: (c) Vadim Zeitlin
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16#ifdef __GNUG__
17 #pragma implementation "spinctrlbase.h"
18 #pragma implementation "spinctrl.h"
19#endif
20
21// ----------------------------------------------------------------------------
22// headers
23// ----------------------------------------------------------------------------
24
25// for compilers that support precompilation, includes "wx.h".
26#include "wx/wxprec.h"
27
28#ifdef __BORLANDC__
29 #pragma hdrstop
30#endif
31
32#ifndef WX_PRECOMP
33 #include "wx/wx.h"
34#endif
35
0e528b99
JS
36#if wxUSE_SPINCTRL
37
b782f2e0
VZ
38#if defined(__WIN95__)
39
40#include "wx/spinctrl.h"
41#include "wx/msw/private.h"
42
4c0a2c5c
JS
43#if (defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__) || defined(wxUSE_NORLANDER_HEADERS)
44 #include <commctrl.h>
45#endif
b782f2e0 46
678cd6de
VZ
47#include <limits.h> // for INT_MIN
48
b782f2e0
VZ
49// ----------------------------------------------------------------------------
50// macros
51// ----------------------------------------------------------------------------
52
53#if !USE_SHARED_LIBRARY
54 IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl)
55#endif
56
57// ----------------------------------------------------------------------------
58// constants
59// ----------------------------------------------------------------------------
60
baccb514
VZ
61// the margin between the up-down control and its buddy (can be arbitrary,
62// choose what you like - or may be decide during run-time depending on the
63// font size?)
64static const int MARGIN_BETWEEN = 1;
b782f2e0
VZ
65
66// ============================================================================
67// implementation
68// ============================================================================
69
70// ----------------------------------------------------------------------------
71// construction
72// ----------------------------------------------------------------------------
73
74bool wxSpinCtrl::Create(wxWindow *parent,
75 wxWindowID id,
678cd6de 76 const wxString& value,
b782f2e0
VZ
77 const wxPoint& pos,
78 const wxSize& size,
79 long style,
80 int min, int max, int initial,
81 const wxString& name)
82{
83 // before using DoGetBestSize(), have to set style to let the base class
84 // know whether this is a horizontal or vertical control (we're always
85 // vertical)
86 SetWindowStyle(style | wxSP_VERTICAL);
87
88 // calculate the sizes: the size given is the toal size for both controls
89 // and we need to fit them both in the given width (height is the same)
90 wxSize sizeText(size), sizeBtn(size);
91 sizeBtn.x = wxSpinButton::DoGetBestSize().x;
baccb514
VZ
92 if ( sizeText.x <= 0 )
93 {
94 // DEFAULT_ITEM_WIDTH is the default width for the text control
95 sizeText.x = DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN + sizeBtn.x;
96 }
97
b782f2e0
VZ
98 sizeText.x -= sizeBtn.x + MARGIN_BETWEEN;
99 if ( sizeText.x <= 0 )
100 {
101 wxLogDebug(_T("not enough space for wxSpinCtrl!"));
102 }
103
104 wxPoint posBtn(pos);
105 posBtn.x += sizeText.x + MARGIN_BETWEEN;
106
107 // create the spin button
108 if ( !wxSpinButton::Create(parent, id, posBtn, sizeBtn, style, name) )
109 {
110 return FALSE;
111 }
112
113 SetRange(min, max);
114 SetValue(initial);
115
116 // create the text window
b782f2e0
VZ
117 m_hwndBuddy = (WXHWND)::CreateWindowEx
118 (
baccb514
VZ
119 WS_EX_CLIENTEDGE, // sunken border
120 _T("EDIT"), // window class
121 NULL, // no window title
122 WS_CHILD | WS_BORDER, // style (will be shown later)
123 pos.x, pos.y, // position
124 0, 0, // size (will be set later)
125 GetHwndOf(parent), // parent
126 (HMENU)-1, // control id
127 wxGetInstance(), // app instance
128 NULL // unused client data
b782f2e0
VZ
129 );
130
131 if ( !m_hwndBuddy )
132 {
133 wxLogLastError("CreateWindow(buddy text window)");
134
135 return FALSE;
136 }
137
138 // should have the same font as the other controls
baccb514
VZ
139 SetFont(GetParent()->GetFont());
140
141 // set the size of the text window - can do it only now, because we
142 // couldn't call DoGetBestSize() before as font wasn't set
143 if ( sizeText.y <= 0 )
144 {
145 // make it the same height as the button then
146 sizeText.y = DoGetBestSize().y;
147 }
148
149 DoMoveWindow(pos.x, pos.y,
150 sizeText.x + sizeBtn.x + MARGIN_BETWEEN, sizeText.y);
151
152 (void)::ShowWindow((HWND)m_hwndBuddy, SW_SHOW);
b782f2e0
VZ
153
154 // associate the text window with the spin button
baccb514
VZ
155 (void)::SendMessage(GetHwnd(), UDM_SETBUDDY, (WPARAM)m_hwndBuddy, 0);
156
678cd6de
VZ
157 if ( !value.IsEmpty() )
158 {
159 SetValue(value);
160 }
161
baccb514
VZ
162 return TRUE;
163}
164
678cd6de
VZ
165// ----------------------------------------------------------------------------
166// wxTextCtrl-like methods
167// ----------------------------------------------------------------------------
168
169void wxSpinCtrl::SetValue(const wxString& text)
170{
171 if ( ::SetWindowText((HWND)m_hwndBuddy, text.c_str()) )
172 {
173 wxLogLastError("SetWindowText(buddy)");
174 }
175}
176
177int wxSpinCtrl::GetValue() const
178{
179 wxString val = wxGetWindowText(m_hwndBuddy);
180
181 long n;
182 if ( (wxSscanf(val, wxT("%lu"), &n) != 1) )
183 n = INT_MIN;
184
185 return n;
186}
187
baccb514
VZ
188// ----------------------------------------------------------------------------
189// when setting font, we need to do it for both controls
190// ----------------------------------------------------------------------------
191
192bool wxSpinCtrl::SetFont(const wxFont& font)
193{
194 if ( !wxWindowBase::SetFont(font) )
195 {
196 // nothing to do
197 return FALSE;
198 }
199
200 WXHANDLE hFont = GetFont().GetResourceHandle();
201 (void)::SendMessage((HWND)m_hwndBuddy, WM_SETFONT, (WPARAM)hFont, TRUE);
b782f2e0
VZ
202
203 return TRUE;
204}
205
206// ----------------------------------------------------------------------------
207// size calculations
208// ----------------------------------------------------------------------------
209
f68586e5 210wxSize wxSpinCtrl::DoGetBestSize() const
baccb514
VZ
211{
212 wxSize sizeBtn = wxSpinButton::DoGetBestSize();
213 sizeBtn.x += DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN;
214
215 int y;
216 wxGetCharSize(GetHWND(), NULL, &y, &GetFont());
217 y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(y);
218
219 if ( sizeBtn.y < y )
220 {
221 // make the text tall enough
222 sizeBtn.y = y;
223 }
224
225 return sizeBtn;
226}
227
b782f2e0
VZ
228void wxSpinCtrl::DoMoveWindow(int x, int y, int width, int height)
229{
baccb514 230 int widthBtn = wxSpinButton::DoGetBestSize().x;
b782f2e0
VZ
231 int widthText = width - widthBtn - MARGIN_BETWEEN;
232 if ( widthText <= 0 )
233 {
234 wxLogDebug(_T("not enough space for wxSpinCtrl!"));
235 }
236
237 if ( !::MoveWindow((HWND)m_hwndBuddy, x, y, widthText, height, TRUE) )
238 {
239 wxLogLastError("MoveWindow(buddy)");
240 }
241
242 x += widthText + MARGIN_BETWEEN;
243 if ( !::MoveWindow(GetHwnd(), x, y, widthBtn, height, TRUE) )
244 {
245 wxLogLastError("MoveWindow");
246 }
247}
248
249#endif // __WIN95__
0e528b99
JS
250
251#endif
252 // wxUSE_SPINCTRL
253