]> git.saurik.com Git - wxWidgets.git/blame - src/os2/spinctrl.cpp
tried to make wxArrayString(bool autosort) ctor more explicit, e.g. prevent it from...
[wxWidgets.git] / src / os2 / spinctrl.cpp
CommitLineData
409c9842
DW
1/////////////////////////////////////////////////////////////////////////////
2// Name: msw/spinctrl.cpp
3// Purpose: wxSpinCtrl class implementation for Win32
4// Author: David Webster
5// Modified by:
6// Created: 10/15/99
7// RCS-ID: $Id$
8// Copyright: (c) David Webster
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16
1c85008f
SN
17#ifdef __GNUG__
18 #pragma implementation "spinctrlbase.h"
19 #pragma implementation "spinctrl.h"
20#endif
21
409c9842
DW
22// ----------------------------------------------------------------------------
23// headers
24// ----------------------------------------------------------------------------
25
26// for compilers that support precompilation, includes "wx.h".
27#include "wx/wxprec.h"
28
29
30#ifndef WX_PRECOMP
31 #include "wx/wx.h"
32#endif
33
7e99520b
DW
34#if wxUSE_SPINBTN
35
409c9842
DW
36#include "wx/spinctrl.h"
37#include "wx/os2/private.h"
38
39// ----------------------------------------------------------------------------
40// macros
41// ----------------------------------------------------------------------------
42
3c299c3a
DW
43extern void wxAssociateWinWithHandle( HWND hWnd
44 ,wxWindowOS2* pWin
45 );
46static WXFARPROC fnWndProcSpinCtrl = (WXFARPROC)NULL;
32334453 47wxArraySpins wxSpinCtrl::m_svAllSpins;
3c299c3a 48
3d62dcb6 49IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl)
409c9842 50
3d62dcb6
DW
51BEGIN_EVENT_TABLE(wxSpinCtrl, wxSpinButton)
52 EVT_SPIN(-1, wxSpinCtrl::OnSpinChange)
53END_EVENT_TABLE()
409c9842
DW
54// ----------------------------------------------------------------------------
55// constants
56// ----------------------------------------------------------------------------
57
58// the margin between the up-down control and its buddy
59static const int MARGIN_BETWEEN = 5;
60
61// ============================================================================
62// implementation
63// ============================================================================
3c299c3a
DW
64MRESULT EXPENTRY wxSpinCtrlWndProc(
65 HWND hWnd
66, UINT uMessage
67, MPARAM wParam
68, MPARAM lParam
69)
409c9842 70{
3c299c3a
DW
71 wxSpinCtrl* pSpin = (wxSpinCtrl *)::WinQueryWindowULong( hWnd
72 ,QWL_USER
73 );
74 bool bProccesed = FALSE;
75 MRESULT rc = (MRESULT)0;
76 //
77 // Forward some messages (the key ones only so far) to the spin ctrl
78 //
79 switch (uMessage )
3d62dcb6 80 {
3c299c3a
DW
81 case WM_CHAR:
82 pSpin->OS2WindowProc( uMessage
83 ,wParam
84 ,lParam
85 );
86
87 //
88 // The control may have been deleted at this point, so check.
89 //
90 if (!(::WinIsWindow(vHabmain, hWnd) && ((wxSpinCtrl *)::WinQueryWindowULong( hWnd
91 ,QWL_USER
92 )
93 ) == pSpin))
94 return 0;
95 break;
3d62dcb6 96
409c9842 97 }
3c299c3a
DW
98 return (fnWndProcSpinCtrl( hWnd
99 ,(ULONG)uMessage
100 ,(MPARAM)wParam
101 ,(MPARAM)lParam
102 )
103 );
104} // end of wxSpinCtrlWndProc
105
106wxSpinCtrl::~wxSpinCtrl()
107{
108 m_svAllSpins.Remove(this);
409c9842 109
3c299c3a
DW
110 // This removes spurious memory leak reporting
111 if (m_svAllSpins.GetCount() == 0)
112 m_svAllSpins.Clear();
113} // end of wxSpinCtrl::~wxSpinCtrl
409c9842 114
3c299c3a
DW
115// ----------------------------------------------------------------------------
116// construction
117// ----------------------------------------------------------------------------
118
119bool wxSpinCtrl::Create(
120 wxWindow* pParent
121, wxWindowID vId
122, const wxString& rsValue
123, const wxPoint& rPos
124, const wxSize& rSize
125, long lStyle
126, int nMin
127, int nMax
128, int nInitial
129, const wxString& rsName
130)
131{
d8a3f66c
DW
132 SWP vSwp;
133
3c299c3a
DW
134 if (vId == -1)
135 m_windowId = NewControlId();
136 else
137 m_windowId = vId;
138 m_backgroundColour = pParent->GetBackgroundColour();
139 m_foregroundColour = pParent->GetForegroundColour();
140 SetName(rsName);
141 SetParent(pParent);
142 m_windowStyle = lStyle;
143
144 int lSstyle = 0L;
145
146 lSstyle = WS_VISIBLE |
147 WS_TABSTOP |
148 SPBS_MASTER | // We use only single field spin buttons
149 SPBS_NUMERICONLY; // We default to numeric data
150
151 if (m_windowStyle & wxCLIP_SIBLINGS )
152 lSstyle |= WS_CLIPSIBLINGS;
153
5d44b24e
DW
154 //
155 // If the parent is a scrolled window the controls must
156 // have this style or they will overlap the scrollbars
157 //
158 if (pParent)
159 if (pParent->IsKindOf(CLASSINFO(wxScrolledWindow)) ||
160 pParent->IsKindOf(CLASSINFO(wxGenericScrolledWindow)))
161 lSstyle |= WS_CLIPSIBLINGS;
162
3c299c3a
DW
163 SPBCDATA vCtrlData;
164
165 vCtrlData.cbSize = sizeof(SPBCDATA);
166 vCtrlData.ulTextLimit = 10L;
167 vCtrlData.lLowerLimit = 0L;
168 vCtrlData.lUpperLimit = 100L;
169 vCtrlData.idMasterSpb = vId;
170 vCtrlData.pHWXCtlData = NULL;
171
172 m_hWnd = (WXHWND)::WinCreateWindow( GetWinHwnd(pParent)
173 ,WC_SPINBUTTON
174 ,(PSZ)NULL
175 ,lSstyle
176 ,0L, 0L, 0L, 0L
177 ,GetWinHwnd(pParent)
178 ,HWND_TOP
179 ,(HMENU)vId
180 ,(PVOID)&vCtrlData
181 ,NULL
182 );
183 if (m_hWnd == 0)
409c9842
DW
184 {
185 return FALSE;
186 }
3c299c3a
DW
187 m_hWndBuddy = m_hWnd; // One in the same for OS/2
188 if(pParent)
189 pParent->AddChild((wxSpinButton *)this);
190 SetFont(pParent->GetFont());
d8a3f66c
DW
191 ::WinQueryWindowPos(m_hWnd, &vSwp);
192 SetXComp(vSwp.x);
193 SetYComp(vSwp.y);
3c299c3a
DW
194 SetSize( rPos.x
195 ,rPos.y
196 ,rSize.x
197 ,rSize.y
198 );
199
200 SetRange(nMin, nMax);
201 SetValue(nInitial);
202
203 //
204 // For OS/2 we'll just set our handle into our long data
205 //
206 wxAssociateWinWithHandle( m_hWnd
207 ,(wxWindowOS2*)this
208 );
209 ::WinSetWindowULong(GetHwnd(), QWL_USER, (LONG)this);
210 fnWndProcSpinCtrl = (WXFARPROC)::WinSubclassWindow(m_hWnd, (PFNWP)wxSpinCtrlWndProc);
211 m_svAllSpins.Add(this);
212 return TRUE;
213} // end of wxSpinCtrl::Create
409c9842 214
3c299c3a
DW
215wxSize wxSpinCtrl::DoGetBestSize() const
216{
217 wxSize vSizeBtn = wxSpinButton::DoGetBestSize();
218 int nHeight;
409c9842 219
3c299c3a 220 vSizeBtn.x += DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN;
409c9842 221
3c299c3a
DW
222 wxGetCharSize( GetHWND()
223 ,NULL
224 ,&nHeight
225 ,(wxFont*)&GetFont()
226 );
227 nHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nHeight);
3d62dcb6 228
3c299c3a 229 if (vSizeBtn.y < nHeight)
3d62dcb6 230 {
3c299c3a
DW
231 //
232 // Make the text tall enough
233 //
234 vSizeBtn.y = nHeight;
3d62dcb6 235 }
3c299c3a
DW
236 return vSizeBtn;
237} // end of wxSpinCtrl::DoGetBestSize
3d62dcb6 238
3c299c3a
DW
239void wxSpinCtrl::DoGetPosition(
240 int* pnX
241, int* pnY
242) const
243{
244 WXHWND hWnd = GetHWND();
245
246 wxConstCast(this, wxSpinCtrl)->m_hWnd = m_hWndBuddy;
247 wxSpinButton::DoGetPosition( pnX
248 ,pnY
249 );
250 wxConstCast(this, wxSpinCtrl)->m_hWnd = hWnd;
251} // end of wxpinCtrl::DoGetPosition
252
253void wxSpinCtrl::DoGetSize(
254 int* pnWidth
255, int* pnHeight
256) const
257{
258 RECTL vSpinrect;
259
260 ::WinQueryWindowRect(GetHwnd(), &vSpinrect);
261
262 if (pnWidth)
263 *pnWidth = vSpinrect.xRight - vSpinrect.xLeft;
264 if (pnHeight)
265 *pnHeight = vSpinrect.yTop - vSpinrect.yBottom;
266} // end of wxSpinCtrl::DoGetSize
267
268void wxSpinCtrl::DoMoveWindow(
269 int nX
270, int nY
271, int nWidth
272, int nHeight
273)
274{
275 wxWindowOS2* pParent = (wxWindowOS2*)GetParent();
3d62dcb6 276
3c299c3a 277 if (pParent)
3d62dcb6 278 {
d8a3f66c
DW
279 int nOS2Height = GetOS2ParentHeight(pParent);
280
281 nY = nOS2Height - (nY + nHeight);
3d62dcb6 282 }
3c299c3a
DW
283 else
284 {
285 RECTL vRect;
3d62dcb6 286
3c299c3a
DW
287 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
288 nY = vRect.yTop - (nY + nHeight);
289 }
290 ::WinSetWindowPos( GetHwnd()
291 ,HWND_TOP
292 ,nX
293 ,nY
294 ,nWidth
295 ,nHeight
296 ,SWP_SIZE | SWP_MOVE | SWP_ZORDER | SWP_SHOW
297 );
298} // end of wxSpinCtrl::DoMoveWindow
299
300bool wxSpinCtrl::Enable(
301 bool bEnable
302)
3d62dcb6 303{
3c299c3a 304 if (!wxControl::Enable(bEnable))
3d62dcb6 305 {
3c299c3a 306 return FALSE;
3d62dcb6 307 }
3c299c3a
DW
308 ::WinEnableWindow(GetHwnd(), bEnable);
309 return TRUE;
310} // end of wxSpinCtrl::Enable
3d62dcb6 311
3c299c3a
DW
312wxSpinCtrl* wxSpinCtrl::GetSpinForTextCtrl(
313 WXHWND hWndBuddy
314)
3d62dcb6 315{
3c299c3a
DW
316 wxSpinCtrl* pSpin = (wxSpinCtrl *)::WinQueryWindowULong( (HWND)hWndBuddy
317 ,QWL_USER
318 );
319 int i = m_svAllSpins.Index(pSpin);
3d62dcb6 320
3c299c3a
DW
321 if (i == wxNOT_FOUND)
322 return NULL;
3d62dcb6 323
3c299c3a
DW
324 // sanity check
325 wxASSERT_MSG( pSpin->m_hWndBuddy == hWndBuddy,
326 _T("wxSpinCtrl has incorrect buddy HWND!") );
3d62dcb6 327
3c299c3a
DW
328 return pSpin;
329} // end of wxSpinCtrl::GetSpinForTextCtrl
3d62dcb6 330
3c299c3a 331int wxSpinCtrl::GetValue() const
3d62dcb6 332{
3c299c3a
DW
333 long lVal = 0L;
334 char zVal[10];
335
336 ::WinSendMsg( GetHwnd()
337 ,SPBM_QUERYVALUE
338 ,MPFROMP(zVal)
339 ,MPFROM2SHORT( (USHORT)10
340 ,SPBQ_UPDATEIFVALID
341 )
342 );
343 lVal - atol(zVal);
344 return lVal;
345} // end of wxSpinCtrl::GetValue
346
347void wxSpinCtrl::OnChar (
348 wxKeyEvent& rEvent
349)
350{
351 switch (rEvent.KeyCode())
3d62dcb6 352 {
3c299c3a
DW
353 case WXK_RETURN:
354 {
355 wxCommandEvent vEvent( wxEVT_COMMAND_TEXT_ENTER
356 ,m_windowId
357 );
358 wxString sVal = wxGetWindowText(m_hWndBuddy);
359
360 InitCommandEvent(vEvent);
361 vEvent.SetString((char*)sVal.c_str());
362 vEvent.SetInt(GetValue());
363 if (GetEventHandler()->ProcessEvent(vEvent))
364 return;
365 break;
366 }
367
368 case WXK_TAB:
369 //
370 // Always produce navigation event - even if we process TAB
371 // ourselves the fact that we got here means that the user code
372 // decided to skip processing of this TAB - probably to let it
373 // do its default job.
374 //
375 {
376 wxNavigationKeyEvent vEventNav;
377
378 vEventNav.SetDirection(!rEvent.ShiftDown());
379 vEventNav.SetWindowChange(rEvent.ControlDown());
380 vEventNav.SetEventObject(this);
381 if (GetParent()->GetEventHandler()->ProcessEvent(vEventNav))
382 return;
383 }
384 break;
3d62dcb6
DW
385 }
386
3c299c3a
DW
387 //
388 // No, we didn't process it
389 //
390 rEvent.Skip();
391} // end of wxSpinCtrl::OnChar
3d62dcb6 392
3c299c3a
DW
393void wxSpinCtrl::OnSpinChange(
394 wxSpinEvent& rEventSpin
395)
3d62dcb6 396{
3c299c3a
DW
397 wxCommandEvent vEvent( wxEVT_COMMAND_SPINCTRL_UPDATED
398 ,GetId()
399 );
400
401 vEvent.SetEventObject(this);
402 vEvent.SetInt(rEventSpin.GetPosition());
403 (void)GetEventHandler()->ProcessEvent(vEvent);
404 if (rEventSpin.GetSkipped())
3d62dcb6 405 {
3c299c3a 406 vEvent.Skip();
3d62dcb6 407 }
3c299c3a 408} // end of wxSpinCtrl::OnSpinChange
3d62dcb6 409
3c299c3a
DW
410bool wxSpinCtrl::ProcessTextCommand(
411 WXWORD wCmd
412, WXWORD wId
413)
3d62dcb6 414{
3c299c3a 415 switch (wCmd)
3d62dcb6 416 {
3c299c3a
DW
417 case SPBN_CHANGE:
418 {
419 wxCommandEvent vEvent( wxEVT_COMMAND_TEXT_UPDATED
420 ,GetId()
421 );
422 vEvent.SetEventObject(this);
423
424 wxString sVal = wxGetWindowText(m_hWndBuddy);
425
426 vEvent.SetString((char*)sVal.c_str());
427 vEvent.SetInt(GetValue());
428 return (GetEventHandler()->ProcessEvent(vEvent));
429 }
430
431 case SPBN_SETFOCUS:
432 case SPBN_KILLFOCUS:
433 {
434 wxFocusEvent vEvent( wCmd == EN_KILLFOCUS ? wxEVT_KILL_FOCUS : wxEVT_SET_FOCUS
435 ,m_windowId
436 );
437
438 vEvent.SetEventObject(this);
439 return(GetEventHandler()->ProcessEvent(vEvent));
440 }
441 default:
442 break;
3d62dcb6
DW
443 }
444
3c299c3a
DW
445 //
446 // Not processed
447 //
448 return FALSE;
449} // end of wxSpinCtrl::ProcessTextCommand
3d62dcb6 450
3c299c3a 451void wxSpinCtrl::SetFocus()
3d62dcb6 452{
3c299c3a
DW
453 ::WinSetFocus(HWND_DESKTOP, GetHwnd());
454} // end of wxSpinCtrl::SetFocus
3d62dcb6 455
3c299c3a
DW
456bool wxSpinCtrl::SetFont(
457 const wxFont& rFont
458)
459{
460 if (!wxWindowBase::SetFont(rFont))
3d62dcb6 461 {
3c299c3a
DW
462 // nothing to do
463 return FALSE;
3d62dcb6 464 }
3d62dcb6 465
3c299c3a
DW
466 WXHANDLE hFont = GetFont().GetResourceHandle();
467 wxOS2SetFont( m_hWnd
468 ,rFont
469 );
470 return TRUE;
471} // end of wxSpinCtrl::SetFont
409c9842 472
3c299c3a
DW
473void wxSpinCtrl::SetValue(
474 const wxString& rsText
475)
3d62dcb6 476{
3c299c3a 477 long lVal;
3d62dcb6 478
3c299c3a
DW
479 lVal = atol(rsText.c_str());
480 wxSpinButton::SetValue(lVal);
481} // end of wxSpinCtrl::SetValue
3d62dcb6 482
3c299c3a
DW
483bool wxSpinCtrl::Show(
484 bool bShow
485)
409c9842 486{
3c299c3a 487 if (!wxControl::Show(bShow))
409c9842 488 {
3c299c3a 489 return FALSE;
409c9842 490 }
3c299c3a
DW
491 return TRUE;
492} // end of wxSpinCtrl::Show
7e99520b
DW
493
494#endif //wxUSE_SPINBTN