1. corrected some owner-drawn buttons bugs
[wxWidgets.git] / src / msw / spinbutt.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: spinbutt.cpp
3 // Purpose: wxSpinButton
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "spinbutt.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/wx.h"
33 #endif
34
35 // Can't resolve reference to CreateUpDownControl in
36 // TWIN32, but could probably use normal CreateWindow instead.
37
38 #if wxUSE_SPINBTN
39
40 #if defined(__WIN95__) && !defined(__TWIN32__)
41
42 #include "wx/spinbutt.h"
43 #include "wx/msw/private.h"
44
45 #if !defined(__GNUWIN32__) || defined(__TWIN32__) || defined(wxUSE_NORLANDER_HEADERS)
46 #include <commctrl.h>
47 #endif
48
49 // ============================================================================
50 // implementation
51 // ============================================================================
52
53 // ----------------------------------------------------------------------------
54 // wxWin macros
55 // ----------------------------------------------------------------------------
56
57 IMPLEMENT_DYNAMIC_CLASS(wxSpinButton, wxControl)
58 IMPLEMENT_DYNAMIC_CLASS(wxSpinEvent, wxScrollEvent);
59
60 // ----------------------------------------------------------------------------
61 // wxSpinButton
62 // ----------------------------------------------------------------------------
63
64 bool wxSpinButton::Create(wxWindow *parent,
65 wxWindowID id,
66 const wxPoint& pos,
67 const wxSize& size,
68 long style,
69 const wxString& name)
70 {
71 // basic initialization
72 InitBase();
73
74 m_windowId = (id == -1) ? NewControlId() : id;
75
76 m_backgroundColour = parent->GetBackgroundColour() ;
77 m_foregroundColour = parent->GetForegroundColour() ;
78
79 SetName(name);
80
81 int x = pos.x;
82 int y = pos.y;
83 int width = size.x;
84 int height = size.y;
85
86 m_windowStyle = style;
87
88 SetParent(parent);
89
90 // get the right size for the control
91 if ( width <= 0 || height <= 0 )
92 {
93 wxSize size = DoGetBestSize();
94 if ( width <= 0 )
95 width = size.x;
96 if ( height <= 0 )
97 height = size.y;
98 }
99
100 if ( x < 0 )
101 x = 0;
102 if ( y < 0 )
103 y = 0;
104
105 // translate the styles
106 DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP |
107 UDS_SETBUDDYINT; // it doesn't harm if we don't have buddy
108
109 if ( m_windowStyle & wxSP_HORIZONTAL )
110 wstyle |= UDS_HORZ;
111 if ( m_windowStyle & wxSP_ARROW_KEYS )
112 wstyle |= UDS_ARROWKEYS;
113 if ( m_windowStyle & wxSP_WRAP )
114 wstyle |= UDS_WRAP;
115
116 // create the UpDown control.
117 m_hWnd = (WXHWND)CreateUpDownControl
118 (
119 wstyle,
120 x, y, width, height,
121 GetHwndOf(parent),
122 m_windowId,
123 wxGetInstance(),
124 NULL, // no buddy
125 m_max, m_min,
126 m_min // initial position
127 );
128
129 if ( !m_hWnd )
130 {
131 wxLogLastError("CreateUpDownControl");
132
133 return FALSE;
134 }
135
136 if ( parent )
137 {
138 parent->AddChild(this);
139 }
140
141 SubclassWin(m_hWnd);
142
143 return TRUE;
144 }
145
146 wxSpinButton::~wxSpinButton()
147 {
148 }
149
150 // ----------------------------------------------------------------------------
151 // size calculation
152 // ----------------------------------------------------------------------------
153
154 wxSize wxSpinButton::DoGetBestSize() const
155 {
156 if ( (GetWindowStyle() & wxSP_VERTICAL) != 0 )
157 {
158 // vertical control
159 return wxSize(GetSystemMetrics(SM_CXVSCROLL),
160 2*GetSystemMetrics(SM_CYVSCROLL));
161 }
162 else
163 {
164 // horizontal control
165 return wxSize(2*GetSystemMetrics(SM_CXHSCROLL),
166 GetSystemMetrics(SM_CYHSCROLL));
167 }
168 }
169
170 // ----------------------------------------------------------------------------
171 // Attributes
172 // ----------------------------------------------------------------------------
173
174 int wxSpinButton::GetValue() const
175 {
176 return (short)LOWORD(::SendMessage(GetHwnd(), UDM_GETPOS, 0, 0));
177 }
178
179 void wxSpinButton::SetValue(int val)
180 {
181 ::SendMessage(GetHwnd(), UDM_SETPOS, 0, (LPARAM) MAKELONG((short) val, 0));
182 }
183
184 void wxSpinButton::SetRange(int minVal, int maxVal)
185 {
186 wxSpinButtonBase::SetRange(minVal, maxVal);
187 ::SendMessage(GetHwnd(), UDM_SETRANGE, 0,
188 (LPARAM) MAKELONG((short)maxVal, (short)minVal));
189 }
190
191 bool wxSpinButton::MSWOnScroll(int orientation, WXWORD wParam,
192 WXWORD pos, WXHWND control)
193 {
194 wxCHECK_MSG( control, FALSE, wxT("scrolling what?") )
195
196 if ( wParam != SB_THUMBPOSITION )
197 {
198 // probable SB_ENDSCROLL - we don't react to it
199 return FALSE;
200 }
201
202 wxSpinEvent event(wxEVT_SCROLL_THUMBTRACK, m_windowId);
203 event.SetPosition((short)pos); // cast is important for negative values!
204 event.SetEventObject(this);
205
206 return GetEventHandler()->ProcessEvent(event);
207 }
208
209 bool wxSpinButton::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
210 {
211 #ifndef __GNUWIN32__
212 #if defined(__BORLANDC__) || defined(__WATCOMC__)
213 LPNM_UPDOWN lpnmud = (LPNM_UPDOWN)lParam;
214 #elif defined(__VISUALC__) && (__VISUALC__ >= 1000) && (__VISUALC__ < 1020)
215 LPNM_UPDOWN lpnmud = (LPNM_UPDOWN)lParam;
216 #else
217 LPNMUPDOWN lpnmud = (LPNMUPDOWN)lParam;
218 #endif
219
220 wxSpinEvent event(lpnmud->iDelta > 0 ? wxEVT_SCROLL_LINEUP
221 : wxEVT_SCROLL_LINEDOWN,
222 m_windowId);
223 event.SetPosition(lpnmud->iPos + lpnmud->iDelta);
224 event.SetEventObject(this);
225
226 bool processed = GetEventHandler()->ProcessEvent(event);
227
228 *result = event.IsAllowed() ? 0 : 1;
229
230 return processed;
231 #else // GnuWin32
232 return FALSE;
233 #endif
234 }
235
236 bool wxSpinButton::MSWCommand(WXUINT cmd, WXWORD id)
237 {
238 // No command messages
239 return FALSE;
240 }
241
242 #endif // __WIN95__
243
244 #endif
245 // wxUSE_SPINCTN
246