1 /////////////////////////////////////////////////////////////////////////////
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
25 #include "wx/slider.h"
26 #include "wx/os2/private.h"
28 IMPLEMENT_DYNAMIC_CLASS(wxSlider
, wxControl
)
40 } // end of wxSlider::wxSlider
45 ::WinDestroyWindow((HWND
)m_hStaticMin
);
47 ::WinDestroyWindow((HWND
)m_hStaticMax
);
49 ::WinDestroyWindow((HWND
)m_hStaticValue
);
50 } // end of wxSlider::~wxSlider
52 void wxSlider::ClearSel()
54 } // end of wxSlider::ClearSel
56 void wxSlider::ClearTicks()
58 } // end of wxSlider::ClearTicks
60 void wxSlider::Command (
61 wxCommandEvent
& rEvent
64 SetValue(rEvent
.GetInt());
65 ProcessCommand(rEvent
);
66 } // end of wxSlider::Command
68 bool wxSlider::ContainsHWND(
72 return ( hWnd
== GetStaticMin() ||
73 hWnd
== GetStaticMax() ||
74 hWnd
== GetEditValue()
76 } // end of wxSlider::ContainsHWND
78 bool wxSlider::Create(
88 , const wxValidator
& rValidator
90 , const wxString
& rsName
96 int nHeight
= rSize
.y
;
102 SetValidator(rValidator
);
105 pParent
->AddChild(this);
106 SetBackgroundColour(pParent
->GetBackgroundColour()) ;
107 SetForegroundColour(pParent
->GetForegroundColour()) ;
114 m_windowStyle
= lStyle
;
118 m_windowId
= (int)NewControlId();
122 if (m_windowStyle
& wxCLIP_SIBLINGS
)
123 lMsStyle
|= WS_CLIPSIBLINGS
;
125 if (m_windowStyle
& wxSL_LABELS
)
127 lMsStyle
|= WS_VISIBLE
| SS_TEXT
| DT_VCENTER
;
129 m_hStaticValue
= (WXHWND
)::WinCreateWindow( (HWND
)GetHwndOf(pParent
) // Parent window handle
130 ,WC_STATIC
// Window class
131 ,(PSZ
)NULL
// Initial Text
132 ,(ULONG
)lMsStyle
// Style flags
133 ,0L, 0L, 0L, 0L // Origin -- 0 size
134 ,(HWND
)GetHwndOf(pParent
) // owner window handle (same as parent
135 ,HWND_TOP
// initial z position
136 ,(ULONG
)NewControlId() // Window identifier
137 ,NULL
// no control data
138 ,NULL
// no Presentation parameters
142 // Now create min static control
144 sprintf(wxBuffer
, "%d", nMinValue
);
145 lWstyle
= SS_TEXT
|DT_LEFT
|WS_VISIBLE
;
146 if (m_windowStyle
& wxCLIP_SIBLINGS
)
147 lWstyle
|= WS_CLIPSIBLINGS
;
148 m_hStaticMin
= (WXHWND
)::WinCreateWindow( (HWND
)GetHwndOf(pParent
) // Parent window handle
149 ,WC_STATIC
// Window class
150 ,(PSZ
)wxBuffer
// Initial Text
151 ,(ULONG
)lWstyle
// Style flags
152 ,0L, 0L, 0L, 0L // Origin -- 0 size
153 ,(HWND
)GetHwndOf(pParent
) // owner window handle (same as parent
154 ,HWND_TOP
// initial z position
155 ,(ULONG
)NewControlId() // Window identifier
156 ,NULL
// no control data
157 ,NULL
// no Presentation parameters
164 vSlData
.cbSize
= sizeof(SLDCDATA
);
165 if (m_windowStyle
& wxSL_VERTICAL
)
166 lMsStyle
= SLS_VERTICAL
| WS_VISIBLE
| WS_TABSTOP
;
168 lMsStyle
= SLS_HORIZONTAL
| WS_VISIBLE
| WS_TABSTOP
;
170 if (m_windowStyle
& wxCLIP_SIBLINGS
)
171 lMsStyle
|= WS_CLIPSIBLINGS
;
173 if (m_windowStyle
& wxSL_AUTOTICKS
)
175 vSlData
.usScale1Spacing
= 0;
176 vSlData
.usScale2Spacing
= 0;
179 if (m_windowStyle
& wxSL_LEFT
)
180 lMsStyle
|= SLS_PRIMARYSCALE2
; // if SLS_VERTICAL then SCALE2 is to the left
181 else if (m_windowStyle
& wxSL_RIGHT
)
182 lMsStyle
|= SLS_PRIMARYSCALE1
; // if SLS_VERTICAL then SCALE2 is to the right
183 else if (m_windowStyle
& wxSL_TOP
)
184 lMsStyle
|= SLS_PRIMARYSCALE1
; // if SLS_HORIZONTAL then SCALE1 is to the top
185 else if (m_windowStyle
& wxSL_BOTTOM
)
186 lMsStyle
|= SLS_PRIMARYSCALE2
; // if SLS_HORIZONTAL then SCALE1 is to the bottom
187 else if ( m_windowStyle
& wxSL_BOTH
)
188 lMsStyle
|= SLS_PRIMARYSCALE1
| SLS_PRIMARYSCALE2
;
190 lMsStyle
|= SLS_PRIMARYSCALE2
;
192 m_nPageSize
= ((nMaxValue
- nMinValue
)/10);
193 vSlData
.usScale1Increments
= m_nPageSize
;
194 vSlData
.usScale2Increments
= m_nPageSize
;
196 HWND hScrollBar
= ::WinCreateWindow( (HWND
)GetHwndOf(pParent
) // Parent window handle
197 ,WC_SLIDER
// Window class
198 ,(PSZ
)wxBuffer
// Initial Text
199 ,(ULONG
)lMsStyle
// Style flags
200 ,0L, 0L, 0L, 0L // Origin -- 0 size
201 ,(HWND
)GetHwndOf(pParent
) // owner window handle (same as parent
202 ,HWND_TOP
// initial z position
203 ,(HMENU
)m_windowId
// Window identifier
204 ,&vSlData
// Slider control data
205 ,NULL
// no Presentation parameters
207 m_nRangeMax
= nMaxValue
;
208 m_nRangeMin
= nMinValue
;
211 // Set the size of the ticks ... default to 6 pixels
213 ::WinSendMsg( hScrollBar
215 ,MPFROM2SHORT(SMA_SETALLTICKS
, 6)
219 // Set the position to the initial value
221 ::WinSendMsg( hScrollBar
223 ,MPFROM2SHORT(SMA_SLIDERARMPOSITION
, SMA_RANGEVALUE
)
227 m_hWnd
= (WXHWND
)hScrollBar
;
228 SubclassWin(GetHWND());
229 ::WinSetWindowText((HWND
)m_hWnd
, "");
230 SetFont(pParent
->GetFont());
231 if (m_windowStyle
& wxSL_LABELS
)
234 // Finally, create max value static item
236 sprintf(wxBuffer
, "%d", nMaxValue
);
237 lWstyle
= SS_TEXT
|DT_LEFT
|WS_VISIBLE
;
238 if (m_windowStyle
& wxCLIP_SIBLINGS
)
239 lMsStyle
|= WS_CLIPSIBLINGS
;
240 m_hStaticMax
= (WXHWND
)::WinCreateWindow( (HWND
)GetHwndOf(pParent
) // Parent window handle
241 ,WC_STATIC
// Window class
242 ,(PSZ
)wxBuffer
// Initial Text
243 ,(ULONG
)lWstyle
// Style flags
244 ,0L, 0L, 0L, 0L // Origin -- 0 size
245 ,(HWND
)GetHwndOf(pParent
) // owner window handle (same as parent
246 ,HWND_TOP
// initial z position
247 ,(ULONG
)NewControlId() // Window identifier
248 ,NULL
// no control data
249 ,NULL
// no Presentation parameters
253 if (GetFont().GetResourceHandle())
256 wxOS2SetFont( m_hStaticMin
260 wxOS2SetFont( m_hStaticMax
264 wxOS2SetFont( m_hStaticValue
276 m_nThumbLength
= SHORT1FROMMR(::WinSendMsg( GetHwnd()
278 ,MPFROM2SHORT( SMA_SLIDERARMDIMENSIONS
283 ) + 4; // for bordersizes
287 vColour
.Set(wxString("BLACK"));
289 LONG lColor
= (LONG
)vColour
.GetPixel();
291 ::WinSetPresParam( m_hStaticMin
296 ::WinSetPresParam( m_hStaticMax
301 ::WinSetPresParam( m_hStaticValue
306 ::WinSetPresParam( m_hWnd
313 } // end of wxSlider::Create
315 void wxSlider::DoSetSize(
325 int nWidth1
= nWidth
;
326 int nHeight1
= nHeight
;
329 int nCx
; // slider,min,max sizes
337 // Adjust for OS/2's reverse coordinate system
339 wxWindowOS2
* pParent
= (wxWindowOS2
*)GetParent();
341 int nOS2Height
= nHeight
;
349 // Under OS/2, where a frame window is the parent, most child windows
350 // that are not specific frame clients are actually children of the
351 // frame's client, not the frame itself, and so position themselves
352 // with regards to the client origin, not the frame.
354 if (pParent
->IsKindOf(CLASSINFO(wxFrame
)))
356 nYOffset
= pParent
->GetClientSize().y
- (nYOffset
+ nOS2Height
);
358 nY1
= pParent
->GetClientSize().y
- (nY1
+ nOS2Height
);
362 nYOffset
= pParent
->GetSize().y
- (nYOffset
+ nOS2Height
);
364 nY1
= pParent
->GetSize().y
- (nY1
+ nOS2Height
);
371 ::WinQueryWindowRect(HWND_DESKTOP
, &vRect
);
372 nYOffset
= vRect
.yTop
- (nYOffset
+ nOS2Height
);
374 nY1
= vRect
.yTop
- (nY1
+ nOS2Height
);
377 GetPosition( &nCurrentX
380 if (nX
== -1 && !(nSizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
382 if (nY
== -1 && !(nSizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
385 AdjustForParentClientOrigin( nX1
389 wxGetCharSize( GetHWND()
395 if ((m_windowStyle
& wxSL_VERTICAL
) != wxSL_VERTICAL
)
397 if (m_windowStyle
& wxSL_LABELS
)
402 ::WinQueryWindowText((HWND
)m_hStaticMin
, 300, zBuf
);
403 GetTextExtent(zBuf
, &nMinLen
, &nCyf
, NULL
, NULL
, &this->GetFont());
404 ::WinQueryWindowText((HWND
)m_hStaticMax
, 300, zBuf
);
405 GetTextExtent(zBuf
, &nMaxLen
, &nCyf
, NULL
, NULL
, &this->GetFont());
409 int nNewWidth
= (wxMax(nMinLen
, nMaxLen
));
410 int nValueHeight
= nCyf
;
412 ::WinSetWindowPos( (HWND
)m_hStaticValue
415 ,(LONG
)nYOffset
- (nCyf
* 1.2)
418 ,SWP_ZORDER
| SWP_SIZE
| SWP_MOVE
| SWP_SHOW
420 nXOffset
+= nNewWidth
+ nCx
;
422 ::WinSetWindowPos( (HWND
)m_hStaticMin
425 ,(LONG
)nYOffset
- nCyf
428 ,SWP_ZORDER
| SWP_SIZE
| SWP_MOVE
| SWP_SHOW
430 nXOffset
+= nMinLen
+ nCx
;
432 int nSliderLength
= nWidth1
- nXOffset
- nMaxLen
- nCx
;
433 int nSliderHeight
= nHeight1
;
435 if (nSliderHeight
< 0)
439 // Slider must have a minimum/default length/height
441 if (nSliderLength
< 100)
444 ::WinSetWindowPos( GetHwnd()
450 ,SWP_ZORDER
| SWP_SIZE
| SWP_MOVE
| SWP_SHOW
452 nXOffset
+= nSliderLength
+ nCx
;
454 ::WinSetWindowPos( (HWND
)m_hStaticMax
457 ,(LONG
)nYOffset
- nCyf
460 ,SWP_ZORDER
| SWP_SIZE
| SWP_MOVE
| SWP_SHOW
467 // If we're prepared to use the existing size, then...
469 if (nWidth
== -1 && nHeight
== -1 &&
470 ((nSizeFlags
& wxSIZE_AUTO
) != wxSIZE_AUTO
))
480 ::WinSetWindowPos( GetHwnd()
486 ,SWP_ZORDER
| SWP_SIZE
| SWP_MOVE
| SWP_SHOW
492 // Now deal with a vertical slider
496 if (m_windowStyle
& wxSL_LABELS
)
501 ::WinQueryWindowText((HWND
)m_hStaticMin
, 300, zBuf
);
502 GetTextExtent(zBuf
, &nMinLen
, &nCyf
, NULL
, NULL
, &this->GetFont());
503 ::WinQueryWindowText((HWND
)m_hStaticMax
, 300, zBuf
);
504 GetTextExtent(zBuf
, &nMaxLen
, &nCyf
, NULL
, NULL
, &this->GetFont());
507 int nNewWidth
= wxMax(nMinLen
, nMaxLen
);
508 int nValueHeight
= nCyf
;
513 // The height needs to be a bit bigger under Win95 if using native
516 nValueHeight
= (int)(nValueHeight
* 1.5);
517 ::WinSetWindowPos( (HWND
)m_hStaticValue
523 ,SWP_ZORDER
| SWP_SIZE
| SWP_MOVE
| SWP_SHOW
525 nYOffset
-= nValueHeight
;
526 nUsedHeight
+= nValueHeight
;
528 ::WinSetWindowPos( (HWND
)m_hStaticMin
534 ,SWP_ZORDER
| SWP_SIZE
| SWP_MOVE
| SWP_SHOW
539 int nSliderLength
= nHeight1
- (nUsedHeight
+ (2 * nCy
));
540 int nSliderWidth
= nWidth1
;
542 if (nSliderWidth
< 0)
546 // Slider must have a minimum/default length
548 if (nSliderLength
< 100)
551 ::WinSetWindowPos( (HWND
)m_hStaticMin
557 ,SWP_ZORDER
| SWP_SIZE
| SWP_MOVE
| SWP_SHOW
559 nYOffset
-= nSliderLength
;
560 nUsedHeight
+= nSliderLength
;
561 ::WinSetWindowPos( (HWND
)m_hStaticMax
567 ,SWP_ZORDER
| SWP_SIZE
| SWP_MOVE
| SWP_SHOW
574 // If we're prepared to use the existing size, then...
576 if (nWidth
== -1 && nHeight
== -1 &&
577 ((nSizeFlags
& wxSIZE_AUTO
) != wxSIZE_AUTO
))
587 ::WinSetWindowPos( GetHwnd()
593 ,SWP_ZORDER
| SWP_SIZE
| SWP_MOVE
| SWP_SHOW
597 } // end of void wxSlider::DoSetSize
599 int wxSlider::GetLineSize() const
602 } // end of wxSlider::GetLineSize
604 int wxSlider::GetPageSize() const
607 } // end of wxSlider::GetPageSize
609 void wxSlider::GetPosition(
614 wxWindowOS2
* pParent
= GetParent();
621 wxFindMaxSize( GetHWND()
626 wxFindMaxSize( m_hStaticMin
630 wxFindMaxSize( m_hStaticMax
634 wxFindMaxSize( m_hStaticValue
639 // Since we now have the absolute screen coords,
640 // if there's a parent we must subtract its top left corner
644 vPoint
.x
= vRect
.xLeft
;
645 vPoint
.y
= vRect
.yTop
;
651 ::WinQueryWindowPos((HWND
)pParent
->GetHWND(), &vSwp
);
657 // We may be faking the client origin.
658 // So a window that's really at (0, 30) may appear
659 // (to wxWin apps) to be at (0, 0).
663 wxPoint
vPt(GetParent()->GetClientAreaOrigin());
670 } // end of wxSlider::GetPosition
672 int wxSlider::GetSelEnd() const
675 } // end of wxSlider::GetSelEnd
677 int wxSlider::GetSelStart() const
680 } // end of wxSlider::GetSelStart
682 void wxSlider::GetSize(
694 wxFindMaxSize( GetHWND()
699 wxFindMaxSize( m_hStaticMin
703 wxFindMaxSize( m_hStaticMax
707 wxFindMaxSize( m_hStaticValue
710 *pnWidth
= vRect
.xRight
- vRect
.xLeft
;
711 *pnHeight
= vRect
.yBottom
- vRect
.yTop
;
712 } // end of wxSlider::GetSize
714 int wxSlider::GetThumbLength() const
716 return m_nThumbLength
;
717 } // end of wxSlider::GetThumbLength
719 int wxSlider::GetValue() const
721 int nPixelRange
= SHORT1FROMMR(::WinSendMsg( GetHwnd()
723 ,MPFROM2SHORT( SMA_SHAFTDIMENSIONS
729 double dPixelToRange
= (double)(nPixelRange
- m_nThumbLength
)/(double)(m_nRangeMax
- m_nRangeMin
);
731 int nPixelPos
= SHORT1FROMMR(::WinSendMsg( GetHwnd()
733 ,MPFROM2SHORT( SMA_SLIDERARMPOSITION
739 nNewPos
= (int)(nPixelPos
/dPixelToRange
);
740 if (nNewPos
> (m_nRangeMax
- m_nRangeMin
)/2)
743 } // end of wxSlider::GetValue
745 WXHBRUSH
wxSlider::OnCtlColor(
754 return (wxControl::OnCtlColor( hDC
762 } // end of wxSlider::OnCtlColor
764 bool wxSlider::OS2OnScroll(
765 int WXUNUSED(nOrientation
)
771 wxEventType eScrollEvent
= wxEVT_NULL
;
776 if (m_windowStyle
& wxSL_TOP
)
777 eScrollEvent
= wxEVT_SCROLL_TOP
;
778 else if (m_windowStyle
& wxSL_BOTTOM
)
779 eScrollEvent
= wxEVT_SCROLL_BOTTOM
;
782 case SLN_SLIDERTRACK
:
783 eScrollEvent
= wxEVT_SCROLL_THUMBTRACK
;
790 int nPixelRange
= SHORT1FROMMR(::WinSendMsg( GetHwnd()
792 ,MPFROM2SHORT( SMA_SHAFTDIMENSIONS
798 m_dPixelToRange
= (double)(nPixelRange
- m_nThumbLength
)/(double)(m_nRangeMax
- m_nRangeMin
);
800 int nPixelPos
= SHORT1FROMMR(::WinSendMsg( GetHwnd()
802 ,MPFROM2SHORT( SMA_SLIDERARMPOSITION
808 nNewPos
= (nPixelPos
/m_dPixelToRange
);
809 if (nNewPos
> (m_nRangeMax
- m_nRangeMin
)/2)
811 if ((nNewPos
< GetMin()) || (nNewPos
> GetMax()))
814 // Out of range - but we did process it
820 wxScrollEvent
vEvent( eScrollEvent
824 vEvent
.SetPosition(nNewPos
);
825 vEvent
.SetEventObject(this);
826 GetEventHandler()->ProcessEvent(vEvent
);
828 wxCommandEvent
vCevent( wxEVT_COMMAND_SLIDER_UPDATED
832 vCevent
.SetInt(nNewPos
);
833 vCevent
.SetEventObject(this);
834 return (GetEventHandler()->ProcessEvent(vCevent
));
835 } // end of wxSlider::OS2OnScroll
837 void wxSlider::SetLineSize(
841 m_nLineSize
= nLineSize
;
842 } // end of wxSlider::SetLineSize
845 void wxSlider::SetPageSize(
849 m_nPageSize
= nPageSize
;
850 } // end of wxSlider::SetPageSize
852 void wxSlider::SetRange(
859 m_nRangeMin
= nMinValue
;
860 m_nRangeMax
= nMaxValue
;
862 int nPixelRange
= SHORT1FROMMR(::WinSendMsg( GetHwnd()
864 ,MPFROM2SHORT( SMA_SHAFTDIMENSIONS
870 m_dPixelToRange
= (double)(nPixelRange
- m_nThumbLength
)/(double)(m_nRangeMax
- m_nRangeMin
);
873 wxSprintf(zBuf
, wxT("%d"), m_nRangeMin
);
874 ::WinSetWindowText((HWND
)m_hStaticMin
, zBuf
);
879 wxSprintf(zBuf
, wxT("%d"), m_nRangeMax
);
880 ::WinSetWindowText((HWND
)m_hStaticMax
, zBuf
);
882 } // end of wxSlider::SetRange
884 void wxSlider::SetSelection(
885 int WXUNUSED(nMinPos
)
886 , int WXUNUSED(nMaxPos
)
889 } // end of wxSlider::SetSelection
891 void wxSlider::SetThumbLength(
897 m_nThumbLength
= SHORT1FROMMR(::WinSendMsg( GetHwnd()
899 ,MPFROM2SHORT( SMA_SLIDERARMDIMENSIONS
904 ) + 4; // for bordersizes
905 nBreadth
= SHORT2FROMMR(::WinSendMsg( GetHwnd()
907 ,MPFROM2SHORT( SMA_SLIDERARMDIMENSIONS
913 ::WinSendMsg( GetHwnd()
915 ,MPFROM2SHORT( SMA_SLIDERARMDIMENSIONS
918 ,MPFROM2SHORT(nLen
, nBreadth
)
920 m_nThumbLength
= nLen
+ 4; // Borders
921 } // end of wxSlider::SetThumbLength
923 void wxSlider::SetTick(
927 nTickPos
*= m_dPixelToRange
;
928 ::WinSendMsg( GetHwnd()
930 ,MPFROMSHORT(nTickPos
)
933 } // end of wxSlider::SetTick
935 // For trackbars only
936 void wxSlider::SetTickFreq(
942 WNDPARAMS vWndParams
;
946 vSlData
.cbSize
= sizeof(SLDCDATA
);
947 if (m_windowStyle
& wxSL_AUTOTICKS
)
949 vSlData
.usScale1Spacing
= 0;
950 vSlData
.usScale2Spacing
= 0;
952 vSlData
.usScale1Increments
= (m_nRangeMax
- m_nRangeMin
)/n
;
953 vSlData
.usScale2Increments
= (m_nRangeMax
- m_nRangeMin
)/n
;
955 vWndParams
.fsStatus
= WPM_CTLDATA
;
956 vWndParams
.cchText
= 0L;
957 vWndParams
.pszText
= NULL
;
958 vWndParams
.cbPresParams
= 0L;
959 vWndParams
.pPresParams
= NULL
;
960 vWndParams
.cbCtlData
= vSlData
.cbSize
;
961 vWndParams
.pCtlData
= (PVOID
)&vSlData
;
962 ::WinSendMsg(GetHwnd(), WM_SETWINDOWPARAMS
, (MPARAM
)&vWndParams
, (MPARAM
)0);
963 for (i
= 1; i
< (m_nRangeMax
- m_nRangeMin
)/n
; i
++)
965 nPixelPos
= i
* n
* m_dPixelToRange
;
966 ::WinSendMsg( GetHwnd()
968 ,MPFROMSHORT(nPixelPos
)
972 } // end of wxSlider::SetTickFreq
974 void wxSlider::SetValue(
978 int nPixelPos
= SHORT1FROMMR(::WinSendMsg( GetHwnd()
980 ,MPFROM2SHORT( SMA_SLIDERARMPOSITION
986 int nPixelRange
= SHORT1FROMMR(::WinSendMsg( GetHwnd()
988 ,MPFROM2SHORT( SMA_SHAFTDIMENSIONS
994 m_dPixelToRange
= (double)(nPixelRange
- m_nThumbLength
)/(double)(m_nRangeMax
- m_nRangeMin
);
995 int nNewPos
= (int)(nValue
* m_dPixelToRange
);
997 ::WinSendMsg( GetHwnd()
999 ,MPFROM2SHORT( SMA_SLIDERARMPOSITION
1006 wxSprintf(wxBuffer
, wxT("%d"), nValue
);
1007 ::WinSetWindowText((HWND
)m_hStaticValue
, wxBuffer
);
1009 } // end of wxSlider::SetValue
1011 bool wxSlider::Show(
1015 wxWindowOS2::Show(bShow
);
1017 ::WinShowWindow((HWND
)m_hStaticValue
, bShow
);
1019 ::WinShowWindow((HWND
)m_hStaticMin
, bShow
);
1021 ::WinShowWindow((HWND
)m_hStaticMax
, bShow
);
1023 } // end of wxSlider::Show