1 /////////////////////////////////////////////////////////////////////////////
2 // Name: msw/spinctrl.cpp
3 // Purpose: wxSpinCtrl class implementation for Win32
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
18 #pragma implementation "spinctrlbase.h"
19 #pragma implementation "spinctrl.h"
22 // ----------------------------------------------------------------------------
24 // ----------------------------------------------------------------------------
26 // for compilers that support precompilation, includes "wx.h".
27 #include "wx/wxprec.h"
36 #include "wx/spinctrl.h"
37 #include "wx/os2/private.h"
39 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
43 extern void wxAssociateWinWithHandle( HWND hWnd
46 static WXFARPROC fnWndProcSpinCtrl
= (WXFARPROC
)NULL
;
47 wxArraySpins
wxSpinCtrl::m_svAllSpins
;
49 IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl
, wxControl
)
51 BEGIN_EVENT_TABLE(wxSpinCtrl
, wxSpinButton
)
52 EVT_SPIN(-1, wxSpinCtrl::OnSpinChange
)
54 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
58 // the margin between the up-down control and its buddy
59 static const int MARGIN_BETWEEN
= 5;
61 // ============================================================================
63 // ============================================================================
64 MRESULT EXPENTRY
wxSpinCtrlWndProc(
71 wxSpinCtrl
* pSpin
= (wxSpinCtrl
*)::WinQueryWindowULong( hWnd
74 bool bProccesed
= FALSE
;
75 MRESULT rc
= (MRESULT
)0;
77 // Forward some messages (the key ones only so far) to the spin ctrl
82 pSpin
->OS2WindowProc( uMessage
88 // The control may have been deleted at this point, so check.
90 if (!(::WinIsWindow(vHabmain
, hWnd
) && ((wxSpinCtrl
*)::WinQueryWindowULong( hWnd
98 return (fnWndProcSpinCtrl( hWnd
104 } // end of wxSpinCtrlWndProc
106 wxSpinCtrl::~wxSpinCtrl()
108 m_svAllSpins
.Remove(this);
110 // This removes spurious memory leak reporting
111 if (m_svAllSpins
.GetCount() == 0)
112 m_svAllSpins
.Clear();
113 } // end of wxSpinCtrl::~wxSpinCtrl
115 // ----------------------------------------------------------------------------
117 // ----------------------------------------------------------------------------
119 bool wxSpinCtrl::Create(
122 , const wxString
& rsValue
123 , const wxPoint
& rPos
124 , const wxSize
& rSize
129 , const wxString
& rsName
135 m_windowId
= NewControlId();
138 m_backgroundColour
= pParent
->GetBackgroundColour();
139 m_foregroundColour
= pParent
->GetForegroundColour();
142 m_windowStyle
= lStyle
;
146 lSstyle
= WS_VISIBLE
|
148 SPBS_MASTER
| // We use only single field spin buttons
149 SPBS_NUMERICONLY
; // We default to numeric data
151 if (m_windowStyle
& wxCLIP_SIBLINGS
)
152 lSstyle
|= WS_CLIPSIBLINGS
;
155 // If the parent is a scrolled window the controls must
156 // have this style or they will overlap the scrollbars
159 if (pParent
->IsKindOf(CLASSINFO(wxScrolledWindow
)) ||
160 pParent
->IsKindOf(CLASSINFO(wxGenericScrolledWindow
)))
161 lSstyle
|= WS_CLIPSIBLINGS
;
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
;
172 m_hWnd
= (WXHWND
)::WinCreateWindow( GetWinHwnd(pParent
)
187 m_hWndBuddy
= m_hWnd
; // One in the same for OS/2
189 pParent
->AddChild((wxSpinButton
*)this);
190 SetFont(*wxSMALL_FONT
);
191 ::WinQueryWindowPos(m_hWnd
, &vSwp
);
200 SetRange(nMin
, nMax
);
204 // For OS/2 we'll just set our handle into our long data
206 wxAssociateWinWithHandle( m_hWnd
209 ::WinSetWindowULong(GetHwnd(), QWL_USER
, (LONG
)this);
210 fnWndProcSpinCtrl
= (WXFARPROC
)::WinSubclassWindow(m_hWnd
, (PFNWP
)wxSpinCtrlWndProc
);
211 m_svAllSpins
.Add(this);
213 } // end of wxSpinCtrl::Create
215 wxSize
wxSpinCtrl::DoGetBestSize() const
217 wxSize vSizeBtn
= wxSpinButton::DoGetBestSize();
220 vSizeBtn
.x
+= DEFAULT_ITEM_WIDTH
+ MARGIN_BETWEEN
;
222 wxGetCharSize( GetHWND()
227 nHeight
= EDIT_HEIGHT_FROM_CHAR_HEIGHT(nHeight
);
229 if (vSizeBtn
.y
< nHeight
)
232 // Make the text tall enough
234 vSizeBtn
.y
= nHeight
;
237 } // end of wxSpinCtrl::DoGetBestSize
239 void wxSpinCtrl::DoGetPosition(
244 WXHWND hWnd
= GetHWND();
246 wxConstCast(this, wxSpinCtrl
)->m_hWnd
= m_hWndBuddy
;
247 wxSpinButton::DoGetPosition( pnX
250 wxConstCast(this, wxSpinCtrl
)->m_hWnd
= hWnd
;
251 } // end of wxpinCtrl::DoGetPosition
253 void wxSpinCtrl::DoGetSize(
260 ::WinQueryWindowRect(GetHwnd(), &vSpinrect
);
263 *pnWidth
= vSpinrect
.xRight
- vSpinrect
.xLeft
;
265 *pnHeight
= vSpinrect
.yTop
- vSpinrect
.yBottom
;
266 } // end of wxSpinCtrl::DoGetSize
268 void wxSpinCtrl::DoMoveWindow(
275 wxWindowOS2
* pParent
= (wxWindowOS2
*)GetParent();
279 int nOS2Height
= GetOS2ParentHeight(pParent
);
281 nY
= nOS2Height
- (nY
+ nHeight
);
287 ::WinQueryWindowRect(HWND_DESKTOP
, &vRect
);
288 nY
= vRect
.yTop
- (nY
+ nHeight
);
290 ::WinSetWindowPos( GetHwnd()
296 ,SWP_SIZE
| SWP_MOVE
| SWP_ZORDER
| SWP_SHOW
298 } // end of wxSpinCtrl::DoMoveWindow
300 bool wxSpinCtrl::Enable(
304 if (!wxControl::Enable(bEnable
))
308 ::WinEnableWindow(GetHwnd(), bEnable
);
310 } // end of wxSpinCtrl::Enable
312 wxSpinCtrl
* wxSpinCtrl::GetSpinForTextCtrl(
316 wxSpinCtrl
* pSpin
= (wxSpinCtrl
*)::WinQueryWindowULong( (HWND
)hWndBuddy
319 int i
= m_svAllSpins
.Index(pSpin
);
321 if (i
== wxNOT_FOUND
)
325 wxASSERT_MSG( pSpin
->m_hWndBuddy
== hWndBuddy
,
326 _T("wxSpinCtrl has incorrect buddy HWND!") );
329 } // end of wxSpinCtrl::GetSpinForTextCtrl
331 int wxSpinCtrl::GetValue() const
336 ::WinSendMsg( GetHwnd()
339 ,MPFROM2SHORT( (USHORT
)10
345 } // end of wxSpinCtrl::GetValue
347 void wxSpinCtrl::OnChar (
351 switch (rEvent
.KeyCode())
355 wxCommandEvent
vEvent( wxEVT_COMMAND_TEXT_ENTER
358 wxString sVal
= wxGetWindowText(m_hWndBuddy
);
360 InitCommandEvent(vEvent
);
361 vEvent
.SetString((char*)sVal
.c_str());
362 vEvent
.SetInt(GetValue());
363 if (GetEventHandler()->ProcessEvent(vEvent
))
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.
376 wxNavigationKeyEvent vEventNav
;
378 vEventNav
.SetDirection(!rEvent
.ShiftDown());
379 vEventNav
.SetWindowChange(rEvent
.ControlDown());
380 vEventNav
.SetEventObject(this);
381 if (GetParent()->GetEventHandler()->ProcessEvent(vEventNav
))
388 // No, we didn't process it
391 } // end of wxSpinCtrl::OnChar
393 void wxSpinCtrl::OnSpinChange(
394 wxSpinEvent
& rEventSpin
397 wxCommandEvent
vEvent( wxEVT_COMMAND_SPINCTRL_UPDATED
401 vEvent
.SetEventObject(this);
402 vEvent
.SetInt(rEventSpin
.GetPosition());
403 (void)GetEventHandler()->ProcessEvent(vEvent
);
404 if (rEventSpin
.GetSkipped())
408 } // end of wxSpinCtrl::OnSpinChange
410 bool wxSpinCtrl::ProcessTextCommand(
419 wxCommandEvent
vEvent( wxEVT_COMMAND_TEXT_UPDATED
422 vEvent
.SetEventObject(this);
424 wxString sVal
= wxGetWindowText(m_hWndBuddy
);
426 vEvent
.SetString((char*)sVal
.c_str());
427 vEvent
.SetInt(GetValue());
428 return (GetEventHandler()->ProcessEvent(vEvent
));
434 wxFocusEvent
vEvent( wCmd
== EN_KILLFOCUS
? wxEVT_KILL_FOCUS
: wxEVT_SET_FOCUS
438 vEvent
.SetEventObject(this);
439 return(GetEventHandler()->ProcessEvent(vEvent
));
449 } // end of wxSpinCtrl::ProcessTextCommand
451 void wxSpinCtrl::SetFocus()
453 ::WinSetFocus(HWND_DESKTOP
, GetHwnd());
454 } // end of wxSpinCtrl::SetFocus
456 bool wxSpinCtrl::SetFont(
460 if (!wxWindowBase::SetFont(rFont
))
466 WXHANDLE hFont
= GetFont().GetResourceHandle();
471 } // end of wxSpinCtrl::SetFont
473 void wxSpinCtrl::SetValue(
474 const wxString
& rsText
479 lVal
= atol(rsText
.c_str());
480 wxSpinButton::SetValue(lVal
);
481 } // end of wxSpinCtrl::SetValue
483 bool wxSpinCtrl::Show(
487 if (!wxControl::Show(bShow
))
492 } // end of wxSpinCtrl::Show
494 #endif //wxUSE_SPINBTN