1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/spinctrl.cpp
3 // Purpose: wxSpinCtrl class implementation for OS/2
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // for compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
30 #include "wx/spinctrl.h"
31 #include "wx/os2/private.h"
33 // ----------------------------------------------------------------------------
35 // ----------------------------------------------------------------------------
37 extern void wxAssociateWinWithHandle( HWND hWnd
40 static WXFARPROC fnWndProcSpinCtrl
= (WXFARPROC
)NULL
;
41 wxArraySpins
wxSpinCtrl::m_svAllSpins
;
43 IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl
, wxControl
)
45 BEGIN_EVENT_TABLE(wxSpinCtrl
, wxSpinButton
)
46 EVT_CHAR(wxSpinCtrl::OnChar
)
47 EVT_SPIN(wxID_ANY
, wxSpinCtrl::OnSpinChange
)
48 EVT_SET_FOCUS(wxSpinCtrl::OnSetFocus
)
50 // ----------------------------------------------------------------------------
52 // ----------------------------------------------------------------------------
54 // the margin between the up-down control and its buddy
55 static const int MARGIN_BETWEEN
= 5;
57 // ============================================================================
59 // ============================================================================
60 MRESULT EXPENTRY
wxSpinCtrlWndProc(
67 wxSpinCtrl
* pSpin
= (wxSpinCtrl
*)::WinQueryWindowULong( hWnd
72 // Forward some messages (the key ones only so far) to the spin ctrl
77 pSpin
->OS2WindowProc( uMessage
83 // The control may have been deleted at this point, so check.
85 if (!(::WinIsWindow(vHabmain
, hWnd
) && ((wxSpinCtrl
*)::WinQueryWindowULong( hWnd
93 return (fnWndProcSpinCtrl( hWnd
99 } // end of wxSpinCtrlWndProc
101 wxSpinCtrl::~wxSpinCtrl()
103 m_svAllSpins
.Remove(this);
105 // This removes spurious memory leak reporting
106 if (m_svAllSpins
.GetCount() == 0)
107 m_svAllSpins
.Clear();
108 } // end of wxSpinCtrl::~wxSpinCtrl
110 // ----------------------------------------------------------------------------
112 // ----------------------------------------------------------------------------
114 bool wxSpinCtrl::Create( wxWindow
* pParent
,
116 const wxString
& WXUNUSED(rsValue
),
123 const wxString
& rsName
)
126 m_windowId
= NewControlId();
129 m_backgroundColour
= pParent
->GetBackgroundColour();
130 m_foregroundColour
= pParent
->GetForegroundColour();
133 m_windowStyle
= lStyle
;
137 lSstyle
= WS_VISIBLE
|
139 SPBS_MASTER
| // We use only single field spin buttons
140 SPBS_NUMERICONLY
; // We default to numeric data
142 if (m_windowStyle
& wxCLIP_SIBLINGS
)
143 lSstyle
|= WS_CLIPSIBLINGS
;
147 vCtrlData
.cbSize
= sizeof(SPBCDATA
);
148 vCtrlData
.ulTextLimit
= 10L;
149 vCtrlData
.lLowerLimit
= 0L;
150 vCtrlData
.lUpperLimit
= 100L;
151 vCtrlData
.idMasterSpb
= vId
;
152 vCtrlData
.pHWXCtlData
= NULL
;
154 m_hWnd
= (WXHWND
)::WinCreateWindow( GetWinHwnd(pParent
)
169 m_hWndBuddy
= m_hWnd
; // One in the same for OS/2
171 pParent
->AddChild((wxSpinButton
*)this);
173 SetFont(*wxSMALL_FONT
);
176 SetSize( rPos
.x
, rPos
.y
, rSize
.x
, rSize
.y
);
178 SetRange(nMin
, nMax
);
182 // For OS/2 we'll just set our handle into our long data
184 wxAssociateWinWithHandle( m_hWnd
187 ::WinSetWindowULong(GetHwnd(), QWL_USER
, (LONG
)this);
188 fnWndProcSpinCtrl
= (WXFARPROC
)::WinSubclassWindow(m_hWnd
, (PFNWP
)wxSpinCtrlWndProc
);
189 m_svAllSpins
.Add(this);
191 } // end of wxSpinCtrl::Create
193 wxSize
wxSpinCtrl::DoGetBestSize() const
195 wxSize vSizeBtn
= wxSpinButton::DoGetBestSize();
197 wxFont vFont
= (wxFont
)GetFont();
199 vSizeBtn
.x
+= DEFAULT_ITEM_WIDTH
+ MARGIN_BETWEEN
;
201 wxGetCharSize( GetHWND()
206 nHeight
= EDIT_HEIGHT_FROM_CHAR_HEIGHT(nHeight
)+4;
208 if (vSizeBtn
.y
< nHeight
)
211 // Make the text tall enough
213 vSizeBtn
.y
= nHeight
;
216 } // end of wxSpinCtrl::DoGetBestSize
218 void wxSpinCtrl::DoGetPosition(
223 wxSpinButton::DoGetPosition( pnX
,pnY
);
224 } // end of wxpinCtrl::DoGetPosition
226 void wxSpinCtrl::DoGetSize(
233 ::WinQueryWindowRect(GetHwnd(), &vSpinrect
);
236 *pnWidth
= vSpinrect
.xRight
- vSpinrect
.xLeft
;
238 *pnHeight
= vSpinrect
.yTop
- vSpinrect
.yBottom
;
239 } // end of wxSpinCtrl::DoGetSize
241 void wxSpinCtrl::DoMoveWindow(
248 wxWindowOS2
* pParent
= (wxWindowOS2
*)GetParent();
252 int nOS2Height
= GetOS2ParentHeight(pParent
);
254 nY
= nOS2Height
- (nY
+ nHeight
);
260 ::WinQueryWindowRect(HWND_DESKTOP
, &vRect
);
261 nY
= vRect
.yTop
- (nY
+ nHeight
);
263 ::WinSetWindowPos( GetHwnd()
269 ,SWP_SIZE
| SWP_MOVE
| SWP_ZORDER
| SWP_SHOW
271 } // end of wxSpinCtrl::DoMoveWindow
273 bool wxSpinCtrl::Enable(
277 if (!wxControl::Enable(bEnable
))
281 ::WinEnableWindow(GetHwnd(), bEnable
);
283 } // end of wxSpinCtrl::Enable
285 wxSpinCtrl
* wxSpinCtrl::GetSpinForTextCtrl(
289 wxSpinCtrl
* pSpin
= (wxSpinCtrl
*)::WinQueryWindowULong( (HWND
)hWndBuddy
292 int i
= m_svAllSpins
.Index(pSpin
);
294 if (i
== wxNOT_FOUND
)
298 wxASSERT_MSG( pSpin
->m_hWndBuddy
== hWndBuddy
,
299 _T("wxSpinCtrl has incorrect buddy HWND!") );
302 } // end of wxSpinCtrl::GetSpinForTextCtrl
304 int wxSpinCtrl::GetValue() const
309 ::WinSendMsg( GetHwnd()
312 ,MPFROM2SHORT( (USHORT
)10
318 } // end of wxSpinCtrl::GetValue
320 void wxSpinCtrl::OnChar (
324 switch (rEvent
.GetKeyCode())
328 wxCommandEvent
vEvent( wxEVT_COMMAND_TEXT_ENTER
331 wxString sVal
= wxGetWindowText(m_hWndBuddy
);
333 InitCommandEvent(vEvent
);
334 vEvent
.SetString(sVal
);
335 vEvent
.SetInt(GetValue());
336 if (GetEventHandler()->ProcessEvent(vEvent
))
343 // Always produce navigation event - even if we process TAB
344 // ourselves the fact that we got here means that the user code
345 // decided to skip processing of this TAB - probably to let it
346 // do its default job.
349 wxNavigationKeyEvent vEventNav
;
351 vEventNav
.SetDirection(!rEvent
.ShiftDown());
352 vEventNav
.SetWindowChange(rEvent
.ControlDown());
353 vEventNav
.SetEventObject(this);
354 if (GetParent()->GetEventHandler()->ProcessEvent(vEventNav
))
361 // No, we didn't process it
364 } // end of wxSpinCtrl::OnChar
366 void wxSpinCtrl::OnSpinChange(
367 wxSpinEvent
& rEventSpin
370 wxCommandEvent
vEvent( wxEVT_COMMAND_SPINCTRL_UPDATED
374 vEvent
.SetEventObject(this);
375 vEvent
.SetInt(rEventSpin
.GetPosition());
376 (void)GetEventHandler()->ProcessEvent(vEvent
);
377 if (rEventSpin
.GetSkipped())
381 } // end of wxSpinCtrl::OnSpinChange
383 void wxSpinCtrl::OnSetFocus (
388 // When we get focus, give it to our buddy window as it needs it more than
391 ::WinSetFocus(HWND_DESKTOP
, (HWND
)m_hWndBuddy
);
393 } // end of wxSpinCtrl::OnSetFocus
395 bool wxSpinCtrl::ProcessTextCommand( WXWORD wCmd
,
396 WXWORD
WXUNUSED(wId
) )
402 wxCommandEvent
vEvent( wxEVT_COMMAND_TEXT_UPDATED
, GetId() );
403 vEvent
.SetEventObject(this);
405 wxString sVal
= wxGetWindowText(m_hWndBuddy
);
407 vEvent
.SetString(sVal
);
408 vEvent
.SetInt(GetValue());
409 return (GetEventHandler()->ProcessEvent(vEvent
));
415 wxFocusEvent
vEvent( wCmd
== EN_KILLFOCUS
? wxEVT_KILL_FOCUS
: wxEVT_SET_FOCUS
419 vEvent
.SetEventObject(this);
420 return(GetEventHandler()->ProcessEvent(vEvent
));
430 } // end of wxSpinCtrl::ProcessTextCommand
432 void wxSpinCtrl::SetFocus()
434 ::WinSetFocus(HWND_DESKTOP
, GetHwnd());
435 } // end of wxSpinCtrl::SetFocus
437 bool wxSpinCtrl::SetFont(
441 if (!wxWindowBase::SetFont(rFont
))
451 } // end of wxSpinCtrl::SetFont
453 void wxSpinCtrl::SetValue(
454 const wxString
& rsText
459 lVal
= atol((char*)rsText
.c_str());
460 wxSpinButton::SetValue(lVal
);
461 } // end of wxSpinCtrl::SetValue
463 bool wxSpinCtrl::Show(
467 if (!wxControl::Show(bShow
))
472 } // end of wxSpinCtrl::Show
474 void wxSpinCtrl::SetSelection (
480 // If from and to are both -1, it means (in wxWidgets) that all text should
481 // be selected - translate into Windows convention
483 if ((lFrom
== -1) && (lTo
== -1))
487 ::WinSendMsg(m_hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), (MPARAM
)0);
488 } // end of wxSpinCtrl::SetSelection
490 #endif //wxUSE_SPINCTRL