]> git.saurik.com Git - wxWidgets.git/blame - src/os2/spinctrl.cpp
Adaptions for new redrawing
[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{
132 if (vId == -1)
133 m_windowId = NewControlId();
134 else
135 m_windowId = vId;
136 m_backgroundColour = pParent->GetBackgroundColour();
137 m_foregroundColour = pParent->GetForegroundColour();
138 SetName(rsName);
139 SetParent(pParent);
140 m_windowStyle = lStyle;
141
142 int lSstyle = 0L;
143
144 lSstyle = WS_VISIBLE |
145 WS_TABSTOP |
146 SPBS_MASTER | // We use only single field spin buttons
147 SPBS_NUMERICONLY; // We default to numeric data
148
149 if (m_windowStyle & wxCLIP_SIBLINGS )
150 lSstyle |= WS_CLIPSIBLINGS;
151
152 SPBCDATA vCtrlData;
153
154 vCtrlData.cbSize = sizeof(SPBCDATA);
155 vCtrlData.ulTextLimit = 10L;
156 vCtrlData.lLowerLimit = 0L;
157 vCtrlData.lUpperLimit = 100L;
158 vCtrlData.idMasterSpb = vId;
159 vCtrlData.pHWXCtlData = NULL;
160
161 m_hWnd = (WXHWND)::WinCreateWindow( GetWinHwnd(pParent)
162 ,WC_SPINBUTTON
163 ,(PSZ)NULL
164 ,lSstyle
165 ,0L, 0L, 0L, 0L
166 ,GetWinHwnd(pParent)
167 ,HWND_TOP
168 ,(HMENU)vId
169 ,(PVOID)&vCtrlData
170 ,NULL
171 );
172 if (m_hWnd == 0)
409c9842
DW
173 {
174 return FALSE;
175 }
3c299c3a
DW
176 m_hWndBuddy = m_hWnd; // One in the same for OS/2
177 if(pParent)
178 pParent->AddChild((wxSpinButton *)this);
179 SetFont(pParent->GetFont());
180 SetSize( rPos.x
181 ,rPos.y
182 ,rSize.x
183 ,rSize.y
184 );
185
186 SetRange(nMin, nMax);
187 SetValue(nInitial);
188
189 //
190 // For OS/2 we'll just set our handle into our long data
191 //
192 wxAssociateWinWithHandle( m_hWnd
193 ,(wxWindowOS2*)this
194 );
195 ::WinSetWindowULong(GetHwnd(), QWL_USER, (LONG)this);
196 fnWndProcSpinCtrl = (WXFARPROC)::WinSubclassWindow(m_hWnd, (PFNWP)wxSpinCtrlWndProc);
197 m_svAllSpins.Add(this);
198 return TRUE;
199} // end of wxSpinCtrl::Create
409c9842 200
3c299c3a
DW
201wxSize wxSpinCtrl::DoGetBestSize() const
202{
203 wxSize vSizeBtn = wxSpinButton::DoGetBestSize();
204 int nHeight;
409c9842 205
3c299c3a 206 vSizeBtn.x += DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN;
409c9842 207
3c299c3a
DW
208 wxGetCharSize( GetHWND()
209 ,NULL
210 ,&nHeight
211 ,(wxFont*)&GetFont()
212 );
213 nHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nHeight);
3d62dcb6 214
3c299c3a 215 if (vSizeBtn.y < nHeight)
3d62dcb6 216 {
3c299c3a
DW
217 //
218 // Make the text tall enough
219 //
220 vSizeBtn.y = nHeight;
3d62dcb6 221 }
3c299c3a
DW
222 return vSizeBtn;
223} // end of wxSpinCtrl::DoGetBestSize
3d62dcb6 224
3c299c3a
DW
225void wxSpinCtrl::DoGetPosition(
226 int* pnX
227, int* pnY
228) const
229{
230 WXHWND hWnd = GetHWND();
231
232 wxConstCast(this, wxSpinCtrl)->m_hWnd = m_hWndBuddy;
233 wxSpinButton::DoGetPosition( pnX
234 ,pnY
235 );
236 wxConstCast(this, wxSpinCtrl)->m_hWnd = hWnd;
237} // end of wxpinCtrl::DoGetPosition
238
239void wxSpinCtrl::DoGetSize(
240 int* pnWidth
241, int* pnHeight
242) const
243{
244 RECTL vSpinrect;
245
246 ::WinQueryWindowRect(GetHwnd(), &vSpinrect);
247
248 if (pnWidth)
249 *pnWidth = vSpinrect.xRight - vSpinrect.xLeft;
250 if (pnHeight)
251 *pnHeight = vSpinrect.yTop - vSpinrect.yBottom;
252} // end of wxSpinCtrl::DoGetSize
253
254void wxSpinCtrl::DoMoveWindow(
255 int nX
256, int nY
257, int nWidth
258, int nHeight
259)
260{
261 wxWindowOS2* pParent = (wxWindowOS2*)GetParent();
3d62dcb6 262
3c299c3a 263 if (pParent)
3d62dcb6 264 {
3c299c3a
DW
265 if (pParent->IsKindOf(CLASSINFO(wxFrame)))
266 {
267 nY = pParent->GetClientSize().y - (nY + nHeight);
268 }
269 else
270 nY = pParent->GetSize().y - (nY + nHeight);
3d62dcb6 271 }
3c299c3a
DW
272 else
273 {
274 RECTL vRect;
3d62dcb6 275
3c299c3a
DW
276 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
277 nY = vRect.yTop - (nY + nHeight);
278 }
279 ::WinSetWindowPos( GetHwnd()
280 ,HWND_TOP
281 ,nX
282 ,nY
283 ,nWidth
284 ,nHeight
285 ,SWP_SIZE | SWP_MOVE | SWP_ZORDER | SWP_SHOW
286 );
287} // end of wxSpinCtrl::DoMoveWindow
288
289bool wxSpinCtrl::Enable(
290 bool bEnable
291)
3d62dcb6 292{
3c299c3a 293 if (!wxControl::Enable(bEnable))
3d62dcb6 294 {
3c299c3a 295 return FALSE;
3d62dcb6 296 }
3c299c3a
DW
297 ::WinEnableWindow(GetHwnd(), bEnable);
298 return TRUE;
299} // end of wxSpinCtrl::Enable
3d62dcb6 300
3c299c3a
DW
301wxSpinCtrl* wxSpinCtrl::GetSpinForTextCtrl(
302 WXHWND hWndBuddy
303)
3d62dcb6 304{
3c299c3a
DW
305 wxSpinCtrl* pSpin = (wxSpinCtrl *)::WinQueryWindowULong( (HWND)hWndBuddy
306 ,QWL_USER
307 );
308 int i = m_svAllSpins.Index(pSpin);
3d62dcb6 309
3c299c3a
DW
310 if (i == wxNOT_FOUND)
311 return NULL;
3d62dcb6 312
3c299c3a
DW
313 // sanity check
314 wxASSERT_MSG( pSpin->m_hWndBuddy == hWndBuddy,
315 _T("wxSpinCtrl has incorrect buddy HWND!") );
3d62dcb6 316
3c299c3a
DW
317 return pSpin;
318} // end of wxSpinCtrl::GetSpinForTextCtrl
3d62dcb6 319
3c299c3a 320int wxSpinCtrl::GetValue() const
3d62dcb6 321{
3c299c3a
DW
322 long lVal = 0L;
323 char zVal[10];
324
325 ::WinSendMsg( GetHwnd()
326 ,SPBM_QUERYVALUE
327 ,MPFROMP(zVal)
328 ,MPFROM2SHORT( (USHORT)10
329 ,SPBQ_UPDATEIFVALID
330 )
331 );
332 lVal - atol(zVal);
333 return lVal;
334} // end of wxSpinCtrl::GetValue
335
336void wxSpinCtrl::OnChar (
337 wxKeyEvent& rEvent
338)
339{
340 switch (rEvent.KeyCode())
3d62dcb6 341 {
3c299c3a
DW
342 case WXK_RETURN:
343 {
344 wxCommandEvent vEvent( wxEVT_COMMAND_TEXT_ENTER
345 ,m_windowId
346 );
347 wxString sVal = wxGetWindowText(m_hWndBuddy);
348
349 InitCommandEvent(vEvent);
350 vEvent.SetString((char*)sVal.c_str());
351 vEvent.SetInt(GetValue());
352 if (GetEventHandler()->ProcessEvent(vEvent))
353 return;
354 break;
355 }
356
357 case WXK_TAB:
358 //
359 // Always produce navigation event - even if we process TAB
360 // ourselves the fact that we got here means that the user code
361 // decided to skip processing of this TAB - probably to let it
362 // do its default job.
363 //
364 {
365 wxNavigationKeyEvent vEventNav;
366
367 vEventNav.SetDirection(!rEvent.ShiftDown());
368 vEventNav.SetWindowChange(rEvent.ControlDown());
369 vEventNav.SetEventObject(this);
370 if (GetParent()->GetEventHandler()->ProcessEvent(vEventNav))
371 return;
372 }
373 break;
3d62dcb6
DW
374 }
375
3c299c3a
DW
376 //
377 // No, we didn't process it
378 //
379 rEvent.Skip();
380} // end of wxSpinCtrl::OnChar
3d62dcb6 381
3c299c3a
DW
382void wxSpinCtrl::OnSpinChange(
383 wxSpinEvent& rEventSpin
384)
3d62dcb6 385{
3c299c3a
DW
386 wxCommandEvent vEvent( wxEVT_COMMAND_SPINCTRL_UPDATED
387 ,GetId()
388 );
389
390 vEvent.SetEventObject(this);
391 vEvent.SetInt(rEventSpin.GetPosition());
392 (void)GetEventHandler()->ProcessEvent(vEvent);
393 if (rEventSpin.GetSkipped())
3d62dcb6 394 {
3c299c3a 395 vEvent.Skip();
3d62dcb6 396 }
3c299c3a 397} // end of wxSpinCtrl::OnSpinChange
3d62dcb6 398
3c299c3a
DW
399bool wxSpinCtrl::ProcessTextCommand(
400 WXWORD wCmd
401, WXWORD wId
402)
3d62dcb6 403{
3c299c3a 404 switch (wCmd)
3d62dcb6 405 {
3c299c3a
DW
406 case SPBN_CHANGE:
407 {
408 wxCommandEvent vEvent( wxEVT_COMMAND_TEXT_UPDATED
409 ,GetId()
410 );
411 vEvent.SetEventObject(this);
412
413 wxString sVal = wxGetWindowText(m_hWndBuddy);
414
415 vEvent.SetString((char*)sVal.c_str());
416 vEvent.SetInt(GetValue());
417 return (GetEventHandler()->ProcessEvent(vEvent));
418 }
419
420 case SPBN_SETFOCUS:
421 case SPBN_KILLFOCUS:
422 {
423 wxFocusEvent vEvent( wCmd == EN_KILLFOCUS ? wxEVT_KILL_FOCUS : wxEVT_SET_FOCUS
424 ,m_windowId
425 );
426
427 vEvent.SetEventObject(this);
428 return(GetEventHandler()->ProcessEvent(vEvent));
429 }
430 default:
431 break;
3d62dcb6
DW
432 }
433
3c299c3a
DW
434 //
435 // Not processed
436 //
437 return FALSE;
438} // end of wxSpinCtrl::ProcessTextCommand
3d62dcb6 439
3c299c3a 440void wxSpinCtrl::SetFocus()
3d62dcb6 441{
3c299c3a
DW
442 ::WinSetFocus(HWND_DESKTOP, GetHwnd());
443} // end of wxSpinCtrl::SetFocus
3d62dcb6 444
3c299c3a
DW
445bool wxSpinCtrl::SetFont(
446 const wxFont& rFont
447)
448{
449 if (!wxWindowBase::SetFont(rFont))
3d62dcb6 450 {
3c299c3a
DW
451 // nothing to do
452 return FALSE;
3d62dcb6 453 }
3d62dcb6 454
3c299c3a
DW
455 WXHANDLE hFont = GetFont().GetResourceHandle();
456 wxOS2SetFont( m_hWnd
457 ,rFont
458 );
459 return TRUE;
460} // end of wxSpinCtrl::SetFont
409c9842 461
3c299c3a
DW
462void wxSpinCtrl::SetValue(
463 const wxString& rsText
464)
3d62dcb6 465{
3c299c3a 466 long lVal;
3d62dcb6 467
3c299c3a
DW
468 lVal = atol(rsText.c_str());
469 wxSpinButton::SetValue(lVal);
470} // end of wxSpinCtrl::SetValue
3d62dcb6 471
3c299c3a
DW
472bool wxSpinCtrl::Show(
473 bool bShow
474)
409c9842 475{
3c299c3a 476 if (!wxControl::Show(bShow))
409c9842 477 {
3c299c3a 478 return FALSE;
409c9842 479 }
3c299c3a
DW
480 return TRUE;
481} // end of wxSpinCtrl::Show
7e99520b
DW
482
483#endif //wxUSE_SPINBTN