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
;
48 IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl
, wxControl
)
50 BEGIN_EVENT_TABLE(wxSpinCtrl
, wxSpinButton
)
51 EVT_SPIN(-1, wxSpinCtrl::OnSpinChange
)
53 // ----------------------------------------------------------------------------
55 // ----------------------------------------------------------------------------
57 // the margin between the up-down control and its buddy
58 static const int MARGIN_BETWEEN
= 5;
60 // ============================================================================
62 // ============================================================================
63 MRESULT EXPENTRY
wxSpinCtrlWndProc(
70 wxSpinCtrl
* pSpin
= (wxSpinCtrl
*)::WinQueryWindowULong( hWnd
73 bool bProccesed
= FALSE
;
74 MRESULT rc
= (MRESULT
)0;
76 // Forward some messages (the key ones only so far) to the spin ctrl
81 pSpin
->OS2WindowProc( uMessage
87 // The control may have been deleted at this point, so check.
89 if (!(::WinIsWindow(vHabmain
, hWnd
) && ((wxSpinCtrl
*)::WinQueryWindowULong( hWnd
97 return (fnWndProcSpinCtrl( hWnd
103 } // end of wxSpinCtrlWndProc
105 wxSpinCtrl::~wxSpinCtrl()
107 m_svAllSpins
.Remove(this);
109 // This removes spurious memory leak reporting
110 if (m_svAllSpins
.GetCount() == 0)
111 m_svAllSpins
.Clear();
112 } // end of wxSpinCtrl::~wxSpinCtrl
114 // ----------------------------------------------------------------------------
116 // ----------------------------------------------------------------------------
118 bool wxSpinCtrl::Create(
121 , const wxString
& rsValue
122 , const wxPoint
& rPos
123 , const wxSize
& rSize
128 , const wxString
& rsName
132 m_windowId
= NewControlId();
135 m_backgroundColour
= pParent
->GetBackgroundColour();
136 m_foregroundColour
= pParent
->GetForegroundColour();
139 m_windowStyle
= lStyle
;
143 lSstyle
= WS_VISIBLE
|
145 SPBS_MASTER
| // We use only single field spin buttons
146 SPBS_NUMERICONLY
; // We default to numeric data
148 if (m_windowStyle
& wxCLIP_SIBLINGS
)
149 lSstyle
|= WS_CLIPSIBLINGS
;
153 vCtrlData
.cbSize
= sizeof(SPBCDATA
);
154 vCtrlData
.ulTextLimit
= 10L;
155 vCtrlData
.lLowerLimit
= 0L;
156 vCtrlData
.lUpperLimit
= 100L;
157 vCtrlData
.idMasterSpb
= vId
;
158 vCtrlData
.pHWXCtlData
= NULL
;
160 m_hWnd
= (WXHWND
)::WinCreateWindow( GetWinHwnd(pParent
)
175 m_hWndBuddy
= m_hWnd
; // One in the same for OS/2
177 pParent
->AddChild((wxSpinButton
*)this);
178 SetFont(pParent
->GetFont());
185 SetRange(nMin
, nMax
);
189 // For OS/2 we'll just set our handle into our long data
191 wxAssociateWinWithHandle( m_hWnd
194 ::WinSetWindowULong(GetHwnd(), QWL_USER
, (LONG
)this);
195 fnWndProcSpinCtrl
= (WXFARPROC
)::WinSubclassWindow(m_hWnd
, (PFNWP
)wxSpinCtrlWndProc
);
196 m_svAllSpins
.Add(this);
198 } // end of wxSpinCtrl::Create
200 wxSize
wxSpinCtrl::DoGetBestSize() const
202 wxSize vSizeBtn
= wxSpinButton::DoGetBestSize();
205 vSizeBtn
.x
+= DEFAULT_ITEM_WIDTH
+ MARGIN_BETWEEN
;
207 wxGetCharSize( GetHWND()
212 nHeight
= EDIT_HEIGHT_FROM_CHAR_HEIGHT(nHeight
);
214 if (vSizeBtn
.y
< nHeight
)
217 // Make the text tall enough
219 vSizeBtn
.y
= nHeight
;
222 } // end of wxSpinCtrl::DoGetBestSize
224 void wxSpinCtrl::DoGetPosition(
229 WXHWND hWnd
= GetHWND();
231 wxConstCast(this, wxSpinCtrl
)->m_hWnd
= m_hWndBuddy
;
232 wxSpinButton::DoGetPosition( pnX
235 wxConstCast(this, wxSpinCtrl
)->m_hWnd
= hWnd
;
236 } // end of wxpinCtrl::DoGetPosition
238 void wxSpinCtrl::DoGetSize(
245 ::WinQueryWindowRect(GetHwnd(), &vSpinrect
);
248 *pnWidth
= vSpinrect
.xRight
- vSpinrect
.xLeft
;
250 *pnHeight
= vSpinrect
.yTop
- vSpinrect
.yBottom
;
251 } // end of wxSpinCtrl::DoGetSize
253 void wxSpinCtrl::DoMoveWindow(
260 wxWindowOS2
* pParent
= (wxWindowOS2
*)GetParent();
264 if (pParent
->IsKindOf(CLASSINFO(wxFrame
)))
266 nY
= pParent
->GetClientSize().y
- (nY
+ nHeight
);
269 nY
= pParent
->GetSize().y
- (nY
+ nHeight
);
275 ::WinQueryWindowRect(HWND_DESKTOP
, &vRect
);
276 nY
= vRect
.yTop
- (nY
+ nHeight
);
278 ::WinSetWindowPos( GetHwnd()
284 ,SWP_SIZE
| SWP_MOVE
| SWP_ZORDER
| SWP_SHOW
286 } // end of wxSpinCtrl::DoMoveWindow
288 bool wxSpinCtrl::Enable(
292 if (!wxControl::Enable(bEnable
))
296 ::WinEnableWindow(GetHwnd(), bEnable
);
298 } // end of wxSpinCtrl::Enable
300 wxSpinCtrl
* wxSpinCtrl::GetSpinForTextCtrl(
304 wxSpinCtrl
* pSpin
= (wxSpinCtrl
*)::WinQueryWindowULong( (HWND
)hWndBuddy
307 int i
= m_svAllSpins
.Index(pSpin
);
309 if (i
== wxNOT_FOUND
)
313 wxASSERT_MSG( pSpin
->m_hWndBuddy
== hWndBuddy
,
314 _T("wxSpinCtrl has incorrect buddy HWND!") );
317 } // end of wxSpinCtrl::GetSpinForTextCtrl
319 int wxSpinCtrl::GetValue() const
324 ::WinSendMsg( GetHwnd()
327 ,MPFROM2SHORT( (USHORT
)10
333 } // end of wxSpinCtrl::GetValue
335 void wxSpinCtrl::OnChar (
339 switch (rEvent
.KeyCode())
343 wxCommandEvent
vEvent( wxEVT_COMMAND_TEXT_ENTER
346 wxString sVal
= wxGetWindowText(m_hWndBuddy
);
348 InitCommandEvent(vEvent
);
349 vEvent
.SetString((char*)sVal
.c_str());
350 vEvent
.SetInt(GetValue());
351 if (GetEventHandler()->ProcessEvent(vEvent
))
358 // Always produce navigation event - even if we process TAB
359 // ourselves the fact that we got here means that the user code
360 // decided to skip processing of this TAB - probably to let it
361 // do its default job.
364 wxNavigationKeyEvent vEventNav
;
366 vEventNav
.SetDirection(!rEvent
.ShiftDown());
367 vEventNav
.SetWindowChange(rEvent
.ControlDown());
368 vEventNav
.SetEventObject(this);
369 if (GetParent()->GetEventHandler()->ProcessEvent(vEventNav
))
376 // No, we didn't process it
379 } // end of wxSpinCtrl::OnChar
381 void wxSpinCtrl::OnSpinChange(
382 wxSpinEvent
& rEventSpin
385 wxCommandEvent
vEvent( wxEVT_COMMAND_SPINCTRL_UPDATED
389 vEvent
.SetEventObject(this);
390 vEvent
.SetInt(rEventSpin
.GetPosition());
391 (void)GetEventHandler()->ProcessEvent(vEvent
);
392 if (rEventSpin
.GetSkipped())
396 } // end of wxSpinCtrl::OnSpinChange
398 bool wxSpinCtrl::ProcessTextCommand(
407 wxCommandEvent
vEvent( wxEVT_COMMAND_TEXT_UPDATED
410 vEvent
.SetEventObject(this);
412 wxString sVal
= wxGetWindowText(m_hWndBuddy
);
414 vEvent
.SetString((char*)sVal
.c_str());
415 vEvent
.SetInt(GetValue());
416 return (GetEventHandler()->ProcessEvent(vEvent
));
422 wxFocusEvent
vEvent( wCmd
== EN_KILLFOCUS
? wxEVT_KILL_FOCUS
: wxEVT_SET_FOCUS
426 vEvent
.SetEventObject(this);
427 return(GetEventHandler()->ProcessEvent(vEvent
));
437 } // end of wxSpinCtrl::ProcessTextCommand
439 void wxSpinCtrl::SetFocus()
441 ::WinSetFocus(HWND_DESKTOP
, GetHwnd());
442 } // end of wxSpinCtrl::SetFocus
444 bool wxSpinCtrl::SetFont(
448 if (!wxWindowBase::SetFont(rFont
))
454 WXHANDLE hFont
= GetFont().GetResourceHandle();
459 } // end of wxSpinCtrl::SetFont
461 void wxSpinCtrl::SetValue(
462 const wxString
& rsText
467 lVal
= atol(rsText
.c_str());
468 wxSpinButton::SetValue(lVal
);
469 } // end of wxSpinCtrl::SetValue
471 bool wxSpinCtrl::Show(
475 if (!wxControl::Show(bShow
))
480 } // end of wxSpinCtrl::Show
482 #endif //wxUSE_SPINBTN