]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/os2/spinctrl.cpp
toplevel code transferred to wxTopLevelWindow
[wxWidgets.git] / src / os2 / spinctrl.cpp
... / ...
CommitLineData
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
17#ifdef __GNUG__
18 #pragma implementation "spinctrlbase.h"
19 #pragma implementation "spinctrl.h"
20#endif
21
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
34#if wxUSE_SPINBTN
35
36#include "wx/spinctrl.h"
37#include "wx/os2/private.h"
38
39// ----------------------------------------------------------------------------
40// macros
41// ----------------------------------------------------------------------------
42
43extern void wxAssociateWinWithHandle( HWND hWnd
44 ,wxWindowOS2* pWin
45 );
46static WXFARPROC fnWndProcSpinCtrl = (WXFARPROC)NULL;
47wxArraySpins wxSpinCtrl::m_svAllSpins;
48
49IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl)
50
51BEGIN_EVENT_TABLE(wxSpinCtrl, wxSpinButton)
52 EVT_SPIN(-1, wxSpinCtrl::OnSpinChange)
53END_EVENT_TABLE()
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// ============================================================================
64MRESULT EXPENTRY wxSpinCtrlWndProc(
65 HWND hWnd
66, UINT uMessage
67, MPARAM wParam
68, MPARAM lParam
69)
70{
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 )
80 {
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;
96
97 }
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);
109
110 // This removes spurious memory leak reporting
111 if (m_svAllSpins.GetCount() == 0)
112 m_svAllSpins.Clear();
113} // end of wxSpinCtrl::~wxSpinCtrl
114
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)
173 {
174 return FALSE;
175 }
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
200
201wxSize wxSpinCtrl::DoGetBestSize() const
202{
203 wxSize vSizeBtn = wxSpinButton::DoGetBestSize();
204 int nHeight;
205
206 vSizeBtn.x += DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN;
207
208 wxGetCharSize( GetHWND()
209 ,NULL
210 ,&nHeight
211 ,(wxFont*)&GetFont()
212 );
213 nHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nHeight);
214
215 if (vSizeBtn.y < nHeight)
216 {
217 //
218 // Make the text tall enough
219 //
220 vSizeBtn.y = nHeight;
221 }
222 return vSizeBtn;
223} // end of wxSpinCtrl::DoGetBestSize
224
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();
262
263 if (pParent)
264 {
265 if (pParent->IsKindOf(CLASSINFO(wxFrame)))
266 {
267 nY = pParent->GetClientSize().y - (nY + nHeight);
268 }
269 else
270 nY = pParent->GetSize().y - (nY + nHeight);
271 }
272 else
273 {
274 RECTL vRect;
275
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)
292{
293 if (!wxControl::Enable(bEnable))
294 {
295 return FALSE;
296 }
297 ::WinEnableWindow(GetHwnd(), bEnable);
298 return TRUE;
299} // end of wxSpinCtrl::Enable
300
301wxSpinCtrl* wxSpinCtrl::GetSpinForTextCtrl(
302 WXHWND hWndBuddy
303)
304{
305 wxSpinCtrl* pSpin = (wxSpinCtrl *)::WinQueryWindowULong( (HWND)hWndBuddy
306 ,QWL_USER
307 );
308 int i = m_svAllSpins.Index(pSpin);
309
310 if (i == wxNOT_FOUND)
311 return NULL;
312
313 // sanity check
314 wxASSERT_MSG( pSpin->m_hWndBuddy == hWndBuddy,
315 _T("wxSpinCtrl has incorrect buddy HWND!") );
316
317 return pSpin;
318} // end of wxSpinCtrl::GetSpinForTextCtrl
319
320int wxSpinCtrl::GetValue() const
321{
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())
341 {
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;
374 }
375
376 //
377 // No, we didn't process it
378 //
379 rEvent.Skip();
380} // end of wxSpinCtrl::OnChar
381
382void wxSpinCtrl::OnSpinChange(
383 wxSpinEvent& rEventSpin
384)
385{
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())
394 {
395 vEvent.Skip();
396 }
397} // end of wxSpinCtrl::OnSpinChange
398
399bool wxSpinCtrl::ProcessTextCommand(
400 WXWORD wCmd
401, WXWORD wId
402)
403{
404 switch (wCmd)
405 {
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;
432 }
433
434 //
435 // Not processed
436 //
437 return FALSE;
438} // end of wxSpinCtrl::ProcessTextCommand
439
440void wxSpinCtrl::SetFocus()
441{
442 ::WinSetFocus(HWND_DESKTOP, GetHwnd());
443} // end of wxSpinCtrl::SetFocus
444
445bool wxSpinCtrl::SetFont(
446 const wxFont& rFont
447)
448{
449 if (!wxWindowBase::SetFont(rFont))
450 {
451 // nothing to do
452 return FALSE;
453 }
454
455 WXHANDLE hFont = GetFont().GetResourceHandle();
456 wxOS2SetFont( m_hWnd
457 ,rFont
458 );
459 return TRUE;
460} // end of wxSpinCtrl::SetFont
461
462void wxSpinCtrl::SetValue(
463 const wxString& rsText
464)
465{
466 long lVal;
467
468 lVal = atol(rsText.c_str());
469 wxSpinButton::SetValue(lVal);
470} // end of wxSpinCtrl::SetValue
471
472bool wxSpinCtrl::Show(
473 bool bShow
474)
475{
476 if (!wxControl::Show(bShow))
477 {
478 return FALSE;
479 }
480 return TRUE;
481} // end of wxSpinCtrl::Show
482
483#endif //wxUSE_SPINBTN