]> git.saurik.com Git - wxWidgets.git/blobdiff - src/os2/slider.cpp
corrected path splitting for mac relative paths
[wxWidgets.git] / src / os2 / slider.cpp
index c9952342a968bc6f464811f2f05a047ee51d4028..7819dca287ef0ef6af1bea376e76fcede34513ab 100644 (file)
 /////////////////////////////////////////////////////////////////////////////
 // Name:        slider.cpp
 // Purpose:     wxSlider
-// Author:      AUTHOR
+// Author:      David Webster
 // Modified by:
-// Created:     ??/??/98
+// Created:     10/15/99
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) David Webster
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "slider.h"
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include <stdio.h>
+#include <wx/utils.h>
+#include <wx/brush.h>
+#include <wx/scrolwin.h>
 #endif
 
 #include "wx/slider.h"
+#include "wx/os2/private.h"
 
-#if !USE_SHARED_LIBRARY
 IMPLEMENT_DYNAMIC_CLASS(wxSlider, wxControl)
 
-BEGIN_EVENT_TABLE(wxSlider, wxControl)
-END_EVENT_TABLE()
-#endif
+wxSlider::wxSlider()
+{
+    m_hStaticValue = 0L;
+    m_hStaticMin   = 0L;
+    m_hStaticMax   = 0L;
+    m_nPageSize    = 1;
+    m_nLineSize    = 1;
+    m_nRangeMax    = 0;
+    m_nRangeMin    = 0;
+    m_nTickFreq    = 0;
+} // end of wxSlider::wxSlider
+
+wxSlider::~wxSlider()
+{
+    if (m_hStaticMin)
+        ::WinDestroyWindow((HWND)m_hStaticMin);
+    if (m_hStaticMax)
+        ::WinDestroyWindow((HWND)m_hStaticMax);
+    if (m_hStaticValue)
+        ::WinDestroyWindow((HWND)m_hStaticValue);
+} // end of wxSlider::~wxSlider
+
+void wxSlider::AdjustSubControls(
+  int                               nX
+, int                               nY
+, int                               nWidth
+, int                               nHeight
+, int                               nSizeFlags
+)
+{
+    SWP                             vSwp;
+    int                             nXOffset = nX;
+    int                             nYOffset = nY;
+    int                             nCx;     // slider,min,max sizes
+    int                             nCy;
+    int                             nCyf;
+    char                            zBuf[300];
 
+    wxGetCharSize( GetHWND()
+                  ,&nCx
+                  ,&nCy
+                  ,&this->GetFont()
+                 );
 
+    if ((m_windowStyle & wxSL_VERTICAL) != wxSL_VERTICAL)
+    {
+        if (m_windowStyle & wxSL_LABELS )
+        {
+            int                     nMinLen = 0;
+            int                     nMaxLen = 0;
 
-// Slider
-wxSlider::wxSlider()
+            ::WinQueryWindowText((HWND)m_hStaticMin, 300, zBuf);
+            GetTextExtent(zBuf, &nMinLen, &nCyf, NULL, NULL, &this->GetFont());
+
+            ::WinQueryWindowText((HWND)m_hStaticMax, 300, zBuf);
+            GetTextExtent(zBuf, &nMaxLen, &nCyf, NULL, NULL, &this->GetFont());
+
+            if (m_hStaticValue)
+            {
+                int                 nNewWidth = wxMax(nMinLen, nMaxLen);
+                int                 nValueHeight = nCyf;
+
+                ::WinSetWindowPos( (HWND)m_hStaticValue
+                                  ,HWND_TOP
+                                  ,(LONG)nXOffset - (nNewWidth + nCx + nMinLen + nCx)
+                                  ,(LONG)nYOffset
+                                  ,(LONG)nNewWidth
+                                  ,(LONG)nValueHeight
+                                  ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+                                 );
+            }
+            ::WinSetWindowPos( (HWND)m_hStaticMin
+                              ,HWND_TOP
+                              ,(LONG)nXOffset - (nMinLen + nCx)
+                              ,(LONG)nYOffset
+                              ,(LONG)nMinLen
+                              ,(LONG)nCy
+                              ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+                             );
+            nXOffset += nWidth + nCx;
+
+            ::WinSetWindowPos( (HWND)m_hStaticMax
+                              ,HWND_TOP
+                              ,(LONG)nXOffset
+                              ,(LONG)nYOffset
+                              ,(LONG)nMaxLen
+                              ,(LONG)nCy
+                              ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+                             );
+        }
+    }
+    //
+    // Now deal with a vertical slider -- OS/2 doesn't have vertical sliders
+    //
+} // end of wxSlider::AdjustSubControls
+
+void wxSlider::ClearSel()
+{
+} // end of wxSlider::ClearSel
+
+void wxSlider::ClearTicks()
 {
-  m_pageSize = 1;
-  m_lineSize = 1;
-  m_rangeMax = 0;
-  m_rangeMin = 0;
-  m_tickFreq = 0;
-}
+} // end of wxSlider::ClearTicks
 
-bool wxSlider::Create(wxWindow *parent, wxWindowID id,
-           int value, int minValue, int maxValue,
-           const wxPoint& pos,
-           const wxSize& size, long style,
-           const wxValidator& validator,
-           const wxString& name)
+void wxSlider::Command (
+  wxCommandEvent&                   rEvent
+)
 {
-    SetName(name);
-    SetValidator(validator);
+    SetValue(rEvent.GetInt());
+    ProcessCommand(rEvent);
+} // end of wxSlider::Command
 
-    if (parent) parent->AddChild(this);
+bool wxSlider::ContainsHWND(
+  WXHWND                            hWnd
+) const
+{
+    return ( hWnd == GetStaticMin() ||
+             hWnd == GetStaticMax() ||
+             hWnd == GetEditValue()
+           );
+} // end of wxSlider::ContainsHWND
 
-    m_lineSize = 1;
-    m_windowStyle = style;
-    m_tickFreq = 0;
+bool wxSlider::Create(
+  wxWindow*                         pParent
+, wxWindowID                        vId
+, int                               nValue
+, int                               nMinValue
+, int                               nMaxValue
+, const wxPoint&                    rPos
+, const wxSize&                     rSize
+, long                              lStyle
+#if wxUSE_VALIDATORS
+, const wxValidator&                rValidator
+#endif
+, const wxString&                   rsName
+)
+{
+    int                             nX       = rPos.x;
+    int                             nY       = rPos.y;
+    int                             nWidth   = rSize.x;
+    int                             nHeight  = rSize.y;
+    long                            lMsStyle = 0L;
+    long                            lWstyle  = 0L;
 
-    if ( id == -1 )
-           m_windowId = (int)NewControlId();
+    SetName(rsName);
+#if wxUSE_VALIDATORS
+    SetValidator(rValidator);
+#endif
+    if (pParent)
+        pParent->AddChild(this);
+    SetBackgroundColour(pParent->GetBackgroundColour()) ;
+    SetForegroundColour(pParent->GetForegroundColour()) ;
+
+    m_hStaticValue = 0L;
+    m_hStaticMin   = 0L;
+    m_hStaticMax   = 0L;
+    m_nPageSize    = 1;
+    m_nLineSize    = 1;
+    m_windowStyle  = lStyle;
+    m_nTickFreq    = 0;
+
+    if (vId == -1)
+        m_windowId = (int)NewControlId();
     else
-           m_windowId = id;
+        m_windowId = vId;
 
-    m_rangeMax = maxValue;
-    m_rangeMin = minValue;
+    if (m_windowStyle & wxCLIP_SIBLINGS )
+        lMsStyle |= WS_CLIPSIBLINGS;
 
-    m_pageSize = (int)((maxValue-minValue)/10);
+    if (m_windowStyle & wxSL_LABELS)
+    {
+        lMsStyle |= WS_VISIBLE | SS_TEXT | DT_VCENTER;
 
-    // TODO create slider
+        //
+        // If the parent is a scrolled window the controls must
+        // have this style or they will overlap the scrollbars
+        //
+        if (pParent)
+            if (pParent->IsKindOf(CLASSINFO(wxScrolledWindow)) ||
+                pParent->IsKindOf(CLASSINFO(wxGenericScrolledWindow)))
+                lMsStyle |= WS_CLIPSIBLINGS;
 
-    return FALSE;
-}
+        m_hStaticValue = (WXHWND)::WinCreateWindow( (HWND)GetHwndOf(pParent) // Parent window handle
+                                                   ,WC_STATIC                // Window class
+                                                   ,(PSZ)NULL                // Initial Text
+                                                   ,(ULONG)lMsStyle          // Style flags
+                                                   ,0L, 0L, 0L, 0L           // Origin -- 0 size
+                                                   ,(HWND)GetHwndOf(pParent) // owner window handle (same as parent
+                                                   ,HWND_TOP                 // initial z position
+                                                   ,(ULONG)NewControlId()    // Window identifier
+                                                   ,NULL                     // no control data
+                                                   ,NULL                     // no Presentation parameters
+                                                  );
 
-wxSlider::~wxSlider()
+        //
+        // Now create min static control
+        //
+        sprintf(wxBuffer, "%d", nMinValue);
+        lWstyle = SS_TEXT|DT_LEFT|WS_VISIBLE;
+        if (m_windowStyle & wxCLIP_SIBLINGS)
+            lWstyle |= WS_CLIPSIBLINGS;
+        //
+        // If the parent is a scrolled window the controls must
+        // have this style or they will overlap the scrollbars
+        //
+        if (pParent)
+            if (pParent->IsKindOf(CLASSINFO(wxScrolledWindow)) ||
+                pParent->IsKindOf(CLASSINFO(wxGenericScrolledWindow)))
+                lWstyle |= WS_CLIPSIBLINGS;
+
+        m_hStaticMin = (WXHWND)::WinCreateWindow( (HWND)GetHwndOf(pParent) // Parent window handle
+                                                 ,WC_STATIC                // Window class
+                                                 ,(PSZ)wxBuffer            // Initial Text
+                                                 ,(ULONG)lWstyle           // Style flags
+                                                 ,0L, 0L, 0L, 0L           // Origin -- 0 size
+                                                 ,(HWND)GetHwndOf(pParent) // owner window handle (same as parent
+                                                 ,HWND_TOP                 // initial z position
+                                                 ,(ULONG)NewControlId()    // Window identifier
+                                                 ,NULL                     // no control data
+                                                 ,NULL                     // no Presentation parameters
+                                                );
+    }
+    lMsStyle = 0;
+
+    SLDCDATA                        vSlData;
+
+    vSlData.cbSize = sizeof(SLDCDATA);
+    if (m_windowStyle & wxSL_VERTICAL)
+        lMsStyle = SLS_VERTICAL | WS_VISIBLE | WS_TABSTOP;
+    else
+        lMsStyle = SLS_HORIZONTAL | WS_VISIBLE | WS_TABSTOP;
+
+    if (m_windowStyle & wxCLIP_SIBLINGS)
+        lMsStyle |= WS_CLIPSIBLINGS;
+
+    if (m_windowStyle & wxSL_AUTOTICKS)
+    {
+        vSlData.usScale1Spacing = 0;
+        vSlData.usScale2Spacing = 0;
+    }
+
+    if (m_windowStyle & wxSL_LEFT)
+        lMsStyle |= SLS_PRIMARYSCALE2; // if SLS_VERTICAL then SCALE2 is to the left
+    else if (m_windowStyle & wxSL_RIGHT)
+        lMsStyle |= SLS_PRIMARYSCALE1; // if SLS_VERTICAL then SCALE2 is to the right
+    else if (m_windowStyle & wxSL_TOP)
+        lMsStyle |= SLS_PRIMARYSCALE1; // if SLS_HORIZONTAL then SCALE1 is to the top
+    else if (m_windowStyle & wxSL_BOTTOM )
+        lMsStyle |= SLS_PRIMARYSCALE2; // if SLS_HORIZONTAL then SCALE1 is to the bottom
+    else if ( m_windowStyle & wxSL_BOTH )
+        lMsStyle |= SLS_PRIMARYSCALE1 | SLS_PRIMARYSCALE2;
+    else
+        lMsStyle |= SLS_PRIMARYSCALE2;
+
+    //
+    // If the parent is a scrolled window the controls must
+    // have this style or they will overlap the scrollbars
+    //
+    if (pParent)
+        if (pParent->IsKindOf(CLASSINFO(wxScrolledWindow)) ||
+            pParent->IsKindOf(CLASSINFO(wxGenericScrolledWindow)))
+            lMsStyle |= WS_CLIPSIBLINGS;
+
+    m_nPageSize = ((nMaxValue - nMinValue)/10);
+    vSlData.usScale1Increments = m_nPageSize;
+    vSlData.usScale2Increments = m_nPageSize;
+
+    HWND                            hScrollBar = ::WinCreateWindow( (HWND)GetHwndOf(pParent) // Parent window handle
+                                                                   ,WC_SLIDER                // Window class
+                                                                   ,(PSZ)wxBuffer            // Initial Text
+                                                                   ,(ULONG)lMsStyle          // Style flags
+                                                                   ,0L, 0L, 0L, 0L           // Origin -- 0 size
+                                                                   ,(HWND)GetHwndOf(pParent) // owner window handle (same as parent
+                                                                   ,HWND_TOP                 // initial z position
+                                                                   ,(HMENU)m_windowId       // Window identifier
+                                                                   ,&vSlData                 // Slider control data
+                                                                   ,NULL                     // no Presentation parameters
+                                                                  );
+    m_nRangeMax = nMaxValue;
+    m_nRangeMin = nMinValue;
+
+    //
+    // Set the size of the ticks ... default to 6 pixels
+    //
+    ::WinSendMsg( hScrollBar
+                 ,SLM_SETTICKSIZE
+                 ,MPFROM2SHORT(SMA_SETALLTICKS, 6)
+                 ,NULL
+                );
+    //
+    // Set the position to the initial value
+    //
+    ::WinSendMsg( hScrollBar
+                 ,SLM_SETSLIDERINFO
+                 ,MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_RANGEVALUE)
+                 ,(MPARAM)nValue
+                );
+
+    m_hWnd = (WXHWND)hScrollBar;
+    SubclassWin(GetHWND());
+    ::WinSetWindowText((HWND)m_hWnd, "");
+    SetFont(*wxSMALL_FONT);
+    if (m_windowStyle & wxSL_LABELS)
+    {
+        //
+        // Finally, create max value static item
+        //
+        sprintf(wxBuffer, "%d", nMaxValue);
+        lWstyle = SS_TEXT|DT_LEFT|WS_VISIBLE;
+        if (m_windowStyle & wxCLIP_SIBLINGS)
+            lMsStyle |= WS_CLIPSIBLINGS;
+        //
+        // If the parent is a scrolled window the controls must
+        // have this style or they will overlap the scrollbars
+        //
+        if (pParent)
+            if (pParent->IsKindOf(CLASSINFO(wxScrolledWindow)) ||
+                pParent->IsKindOf(CLASSINFO(wxGenericScrolledWindow)))
+                lWstyle |= WS_CLIPSIBLINGS;
+
+        m_hStaticMax = (WXHWND)::WinCreateWindow( (HWND)GetHwndOf(pParent) // Parent window handle
+                                                 ,WC_STATIC                // Window class
+                                                 ,(PSZ)wxBuffer            // Initial Text
+                                                 ,(ULONG)lWstyle           // Style flags
+                                                 ,0L, 0L, 0L, 0L           // Origin -- 0 size
+                                                 ,(HWND)GetHwndOf(pParent) // owner window handle (same as parent
+                                                 ,HWND_TOP                 // initial z position
+                                                 ,(ULONG)NewControlId()    // Window identifier
+                                                 ,NULL                     // no control data
+                                                 ,NULL                     // no Presentation parameters
+                                                );
+        if (GetFont().Ok())
+        {
+            if (GetFont().GetResourceHandle())
+            {
+                if (m_hStaticMin)
+                    wxOS2SetFont( m_hStaticMin
+                                 ,GetFont()
+                                );
+                if (m_hStaticMax)
+                    wxOS2SetFont( m_hStaticMax
+                                 ,GetFont()
+                                );
+                if (m_hStaticValue)
+                    wxOS2SetFont( m_hStaticValue
+                                 ,GetFont()
+                                );
+            }
+        }
+    }
+
+    SetSize( nX
+            ,nY
+            ,nWidth
+            ,nHeight
+           );
+    m_nThumbLength = SHORT1FROMMR(::WinSendMsg( GetHwnd()
+                                               ,SLM_QUERYSLIDERINFO
+                                               ,MPFROM2SHORT( SMA_SLIDERARMDIMENSIONS
+                                                             ,SMA_RANGEVALUE
+                                                            )
+                                               ,(MPARAM)0
+                                              )
+                                 ) + 4; // for bordersizes
+
+    wxColour                        vColour;
+
+    vColour.Set(wxString("BLACK"));
+
+    LONG                            lColor = (LONG)vColour.GetPixel();
+
+    ::WinSetPresParam( m_hStaticMin
+                      ,PP_FOREGROUNDCOLOR
+                      ,sizeof(LONG)
+                      ,(PVOID)&lColor
+                     );
+    ::WinSetPresParam( m_hStaticMax
+                      ,PP_FOREGROUNDCOLOR
+                      ,sizeof(LONG)
+                      ,(PVOID)&lColor
+                     );
+    ::WinSetPresParam( m_hStaticValue
+                      ,PP_FOREGROUNDCOLOR
+                      ,sizeof(LONG)
+                      ,(PVOID)&lColor
+                     );
+    ::WinSetPresParam( m_hWnd
+                      ,PP_FOREGROUNDCOLOR
+                      ,sizeof(LONG)
+                      ,(PVOID)&lColor
+                     );
+    lColor = (LONG)m_backgroundColour.GetPixel();
+    ::WinSetPresParam( m_hStaticMin
+                      ,PP_BACKGROUNDCOLOR
+                      ,sizeof(LONG)
+                      ,(PVOID)&lColor
+                     );
+    ::WinSetPresParam( m_hStaticMax
+                      ,PP_BACKGROUNDCOLOR
+                      ,sizeof(LONG)
+                      ,(PVOID)&lColor
+                     );
+    ::WinSetPresParam( m_hStaticValue
+                      ,PP_BACKGROUNDCOLOR
+                      ,sizeof(LONG)
+                      ,(PVOID)&lColor
+                     );
+    ::WinSetPresParam( m_hWnd
+                      ,PP_BACKGROUNDCOLOR
+                      ,sizeof(LONG)
+                      ,(PVOID)&lColor
+                     );
+    SetValue(nValue);
+    return TRUE;
+} // end of wxSlider::Create
+
+void wxSlider::DoSetSize(
+  int                               nX
+, int                               nY
+, int                               nWidth
+, int                               nHeight
+, int                               nSizeFlags
+)
 {
-}
+    int                             nX1      = nX;
+    int                             nY1      = nY;
+    int                             nWidth1  = nWidth;
+    int                             nHeight1 = nHeight;
+    int                             nXOffset = nX;
+    int                             nYOffset = nY;
+    int                             nCx;     // slider,min,max sizes
+    int                             nCy;
+    int                             nCyf;
+    int                             nCurrentX;
+    int                             nCurrentY;
+    char                            zBuf[300];
 
-int wxSlider::GetValue() const
+    //
+    // Adjust for OS/2's reverse coordinate system
+    //
+    wxWindowOS2*                    pParent = (wxWindowOS2*)GetParent();
+    int                             nUsedHeight = 0;
+    int                             nOS2Height = nHeight;
+
+    if (nOS2Height < 0)
+        nOS2Height = 20;
+
+    if (pParent)
+    {
+        int                         nOS2ParentHeight = GetOS2ParentHeight(pParent);
+
+        nYOffset = nOS2ParentHeight - (nYOffset + nOS2Height);
+        if (nY != -1)
+            nY1 = nOS2ParentHeight - (nY1 + nOS2Height);
+    }
+    else
+    {
+        RECTL                       vRect;
+
+        ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
+        nYOffset = vRect.yTop - (nYOffset + nOS2Height);
+        if (nY != -1)
+            nY1 = vRect.yTop - (nY1 + nOS2Height);
+    }
+    m_nSizeFlags = nSizeFlags;
+
+    GetPosition( &nCurrentX
+                ,&nCurrentY
+               );
+    if (nX == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+        nX1 = nCurrentX;
+    if (nY == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+        nY1 = nCurrentY;
+
+    AdjustForParentClientOrigin( nX1
+                                ,nY1
+                                ,nSizeFlags
+                               );
+    wxGetCharSize( GetHWND()
+                  ,&nCx
+                  ,&nCy
+                  ,&this->GetFont()
+                 );
+
+    if ((m_windowStyle & wxSL_VERTICAL) != wxSL_VERTICAL)
+    {
+        if (m_windowStyle & wxSL_LABELS )
+        {
+            int                  nMinLen = 0;
+            int                  nMaxLen = 0;
+
+            ::WinQueryWindowText((HWND)m_hStaticMin, 300, zBuf);
+            GetTextExtent(zBuf, &nMinLen, &nCyf, NULL, NULL, &this->GetFont());
+            ::WinQueryWindowText((HWND)m_hStaticMax, 300, zBuf);
+            GetTextExtent(zBuf, &nMaxLen, &nCyf, NULL, NULL, &this->GetFont());
+
+            if (m_hStaticValue)
+            {
+                int              nNewWidth = (wxMax(nMinLen, nMaxLen));
+                int              nValueHeight = nCyf;
+
+                ::WinSetWindowPos( (HWND)m_hStaticValue
+                                  ,HWND_TOP
+                                  ,(LONG)nXOffset
+                                  ,(LONG)nYOffset - (nCyf * 1.2)
+                                  ,(LONG)nNewWidth
+                                  ,(LONG)nValueHeight
+                                  ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+                                 );
+                nXOffset += nNewWidth + nCx;
+            }
+            ::WinSetWindowPos( (HWND)m_hStaticMin
+                              ,HWND_TOP
+                              ,(LONG)nXOffset
+                              ,(LONG)nYOffset - nCyf
+                              ,(LONG)nMinLen
+                              ,(LONG)nCy
+                              ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+                             );
+            nXOffset += nMinLen + nCx;
+
+            int                  nSliderLength = nWidth1 - nXOffset - nMaxLen - nCx;
+            int                  nSliderHeight = nHeight1;
+
+            if (nSliderHeight < 0)
+                nSliderHeight = 20;
+
+            //
+            // Slider must have a minimum/default length/height
+            //
+            if (nSliderLength < 100)
+                nSliderLength = 100;
+
+            ::WinSetWindowPos( GetHwnd()
+                              ,HWND_TOP
+                              ,(LONG)nXOffset
+                              ,(LONG)nYOffset
+                              ,(LONG)nSliderLength
+                              ,(LONG)nSliderHeight
+                              ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+                             );
+            nXOffset += nSliderLength + nCx;
+
+            ::WinSetWindowPos( (HWND)m_hStaticMax
+                              ,HWND_TOP
+                              ,(LONG)nXOffset
+                              ,(LONG)nYOffset - nCyf
+                              ,(LONG)nMaxLen
+                              ,(LONG)nCy
+                              ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+                             );
+        }
+        else
+        {
+            //
+            // No labels
+            // If we're prepared to use the existing size, then...
+            //
+            if (nWidth == -1 && nHeight == -1 &&
+                ((nSizeFlags & wxSIZE_AUTO) != wxSIZE_AUTO))
+            {
+                GetSize( &nWidth1
+                        ,&nHeight1
+                       );
+            }
+            if (nWidth1 < 0)
+                nWidth1 = 200;
+            if (nHeight1 < 0)
+                nHeight1 = 20;
+            ::WinSetWindowPos( GetHwnd()
+                              ,HWND_TOP
+                              ,(LONG)nX1
+                              ,(LONG)nY1
+                              ,(LONG)nWidth1
+                              ,(LONG)nHeight1
+                              ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+                             );
+        }
+    }
+
+    //
+    // Now deal with a vertical slider
+    //
+    else
+    {
+        if (m_windowStyle & wxSL_LABELS )
+        {
+            int                  nMinLen;
+            int                  nMaxLen;
+
+            ::WinQueryWindowText((HWND)m_hStaticMin, 300, zBuf);
+            GetTextExtent(zBuf, &nMinLen, &nCyf, NULL, NULL, &this->GetFont());
+            ::WinQueryWindowText((HWND)m_hStaticMax, 300, zBuf);
+            GetTextExtent(zBuf, &nMaxLen, &nCyf, NULL, NULL, &this->GetFont());
+            if (m_hStaticValue)
+            {
+                int              nNewWidth = wxMax(nMinLen, nMaxLen);
+                int              nValueHeight = nCyf;
+
+                nNewWidth += nCx;
+
+                //
+                // The height needs to be a bit bigger under Win95 if using native
+                // 3D effects.
+                //
+                nValueHeight = (int)(nValueHeight * 1.5);
+                ::WinSetWindowPos( (HWND)m_hStaticValue
+                                  ,HWND_TOP
+                                  ,(LONG)nXOffset
+                                  ,(LONG)nYOffset
+                                  ,(LONG)nNewWidth
+                                  ,(LONG)nValueHeight
+                                  ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+                                 );
+                nYOffset -= nValueHeight;
+                nUsedHeight += nValueHeight;
+            }
+            ::WinSetWindowPos( (HWND)m_hStaticMin
+                              ,HWND_TOP
+                              ,(LONG)nXOffset
+                              ,(LONG)nYOffset
+                              ,(LONG)nMinLen
+                              ,(LONG)nCy
+                              ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+                             );
+            nYOffset -= nCy;
+            nUsedHeight += nCy;
+
+            int                  nSliderLength = nHeight1 - (nUsedHeight + (2 * nCy));
+            int                  nSliderWidth  = nWidth1;
+
+            if (nSliderWidth < 0)
+                nSliderWidth = 20;
+
+            //
+            // Slider must have a minimum/default length
+            //
+            if (nSliderLength < 100)
+                nSliderLength = 100;
+
+            ::WinSetWindowPos( (HWND)m_hStaticMin
+                              ,HWND_TOP
+                              ,(LONG)nXOffset
+                              ,(LONG)nYOffset
+                              ,(LONG)nSliderWidth
+                              ,(LONG)nSliderLength
+                              ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+                             );
+            nYOffset -= nSliderLength;
+            nUsedHeight += nSliderLength;
+            ::WinSetWindowPos( (HWND)m_hStaticMax
+                              ,HWND_TOP
+                              ,(LONG)nXOffset
+                              ,(LONG)nYOffset
+                              ,(LONG)nMaxLen
+                              ,(LONG)nCy
+                              ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+                             );
+        }
+        else
+        {
+            //
+            // No labels
+            // If we're prepared to use the existing size, then...
+            //
+            if (nWidth == -1 && nHeight == -1 &&
+                ((nSizeFlags & wxSIZE_AUTO) != wxSIZE_AUTO))
+            {
+                GetSize( &nWidth1
+                        ,&nHeight1
+                       );
+            }
+            if (nWidth1 < 0)
+                nWidth1 = 20;
+            if (nHeight1 < 0)
+                nHeight1 = 200;
+            ::WinSetWindowPos( GetHwnd()
+                              ,HWND_TOP
+                              ,(LONG)nX1
+                              ,(LONG)nY1
+                              ,(LONG)nWidth1
+                              ,(LONG)nHeight1
+                              ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
+                             );
+        }
+    }
+} // end of void wxSlider::DoSetSize
+
+int wxSlider::GetLineSize() const
 {
-    // TODO
-    return 0;
-}
+    return 1;
+} // end of wxSlider::GetLineSize
 
-void wxSlider::SetValue(int value)
+int wxSlider::GetPageSize() const
 {
-    // TODO
-}
+    return m_nPageSize;
+} // end of wxSlider::GetPageSize
 
-void wxSlider::GetSize(int *width, int *height) const
+void wxSlider::GetPosition(
+  int*                              pnX
+, int*                              pnY
+) const
 {
-    // TODO
-}
+    wxWindowOS2*                    pParent = GetParent();
+    RECTL                           vRect;
+
+    vRect.xLeft   = -1;
+    vRect.xRight  = -1;
+    vRect.yTop    = -1;
+    vRect.yBottom = -1;
+    wxFindMaxSize( GetHWND()
+                  ,&vRect
+                 );
+
+    if (m_hStaticMin)
+        wxFindMaxSize( m_hStaticMin
+                      ,&vRect
+                     );
+    if (m_hStaticMax)
+        wxFindMaxSize( m_hStaticMax
+                      ,&vRect
+                     );
+    if (m_hStaticValue)
+        wxFindMaxSize( m_hStaticValue
+                      ,&vRect
+                     );
+
+    //
+    // Since we now have the absolute screen coords,
+    // if there's a parent we must subtract its top left corner
+    //
+    POINTL                          vPoint;
+
+    vPoint.x = vRect.xLeft;
+    vPoint.y = vRect.yTop;
+
+    if (pParent)
+    {
+        SWP                             vSwp;
+
+        ::WinQueryWindowPos((HWND)pParent->GetHWND(), &vSwp);
+        vPoint.x = vSwp.x;
+        vPoint.y = vSwp.y;
+    }
+
+    //
+    // We may be faking the client origin.
+    // So a window that's really at (0, 30) may appear
+    // (to wxWin apps) to be at (0, 0).
+    //
+    if (GetParent())
+    {
+        wxPoint                     vPt(GetParent()->GetClientAreaOrigin());
 
-void wxSlider::GetPosition(int *x, int *y) const
+        vPoint.x -= vPt.x;
+        vPoint.y -= vPt.y;
+    }
+    *pnX = vPoint.x;
+    *pnY = vPoint.y;
+} // end of wxSlider::GetPosition
+
+int wxSlider::GetSelEnd() const
 {
-    // TODO
-}
+    return 0;
+} // end of wxSlider::GetSelEnd
 
-void wxSlider::SetSize(int x, int y, int width, int height, int sizeFlags)
+int wxSlider::GetSelStart() const
 {
-    // TODO
-}
+    return 0;
+} // end of wxSlider::GetSelStart
 
-void wxSlider::SetRange(int minValue, int maxValue)
+void wxSlider::GetSize(
+  int*                              pnWidth
+, int*                              pnHeight
+) const
 {
-    m_rangeMin = minValue;
-    m_rangeMax = maxValue;
+    RECTL                           vRect;
 
-    // TODO
-}
+    vRect.xLeft   = -1;
+    vRect.xRight  = -1;
+    vRect.yTop    = -1;
+    vRect.yBottom = -1;
 
-// For trackbars only
-void wxSlider::SetTickFreq(int n, int pos)
-{
-    // TODO
-    m_tickFreq = n;
-}
+    wxFindMaxSize( GetHWND()
+                  ,&vRect
+                 );
 
-void wxSlider::SetPageSize(int pageSize)
-{
-    // TODO
-    m_pageSize = pageSize;
-}
+    if (m_hStaticMin)
+        wxFindMaxSize( m_hStaticMin
+                      ,&vRect
+                     );
+    if (m_hStaticMax)
+        wxFindMaxSize( m_hStaticMax
+                      ,&vRect
+                     );
+    if (m_hStaticValue)
+        wxFindMaxSize( m_hStaticValue
+                      ,&vRect
+                     );
+    *pnWidth  = vRect.xRight - vRect.xLeft;
+    *pnHeight = vRect.yBottom - vRect.yTop;
+} // end of wxSlider::GetSize
 
-int wxSlider::GetPageSize() const
+int wxSlider::GetThumbLength() const
 {
-    return m_pageSize;
-}
+    return m_nThumbLength;
+} // end of wxSlider::GetThumbLength
 
-void wxSlider::ClearSel()
+int wxSlider::GetValue() const
 {
-    // TODO
-}
+    int                             nPixelRange = SHORT1FROMMR(::WinSendMsg( GetHwnd()
+                                                                            ,SLM_QUERYSLIDERINFO
+                                                                            ,MPFROM2SHORT( SMA_SHAFTDIMENSIONS
+                                                                                          ,SMA_RANGEVALUE
+                                                                                         )
+                                                                            ,(MPARAM)0
+                                                                           )
+                                                              );
+    double                          dPixelToRange = (double)(nPixelRange - m_nThumbLength)/(double)(m_nRangeMax - m_nRangeMin);
+    int                             nNewPos = 0;
+    int                             nPixelPos = SHORT1FROMMR(::WinSendMsg( GetHwnd()
+                                                                          ,SLM_QUERYSLIDERINFO
+                                                                          ,MPFROM2SHORT( SMA_SLIDERARMPOSITION
+                                                                                        ,SMA_RANGEVALUE
+                                                                                       )
+                                                                          ,(MPARAM)0
+                                                                         )
+                                                            );
+    nNewPos = (int)(nPixelPos/dPixelToRange);
+    if (nNewPos > (m_nRangeMax - m_nRangeMin)/2)
+        nNewPos++;
+    return nNewPos;
+} // end of wxSlider::GetValue
 
-void wxSlider::ClearTicks()
+WXHBRUSH wxSlider::OnCtlColor(
+  WXHDC                             hDC
+, WXHWND                            hWnd
+, WXUINT                            uCtlColor
+, WXUINT                            uMessage
+, WXWPARAM                          wParam
+, WXLPARAM                          lParam
+)
 {
-    // TODO
-}
+    return (wxControl::OnCtlColor( hDC
+                                  ,hWnd
+                                  ,uCtlColor
+                                  ,uMessage
+                                  ,wParam
+                                  ,lParam
+                                 )
+           );
+} // end of wxSlider::OnCtlColor
 
-void wxSlider::SetLineSize(int lineSize)
+bool wxSlider::OS2OnScroll(
+  int                               WXUNUSED(nOrientation)
+, WXWORD                            wParam
+, WXWORD                            wPos
+, WXHWND                            hControl
+)
 {
-    m_lineSize = lineSize;
-    // TODO
-}
+    wxEventType                     eScrollEvent = wxEVT_NULL;
 
-int wxSlider::GetLineSize() const
+    switch (wParam)
+    {
+        case SLN_CHANGE:
+            if (m_windowStyle & wxSL_TOP)
+                eScrollEvent = wxEVT_SCROLL_TOP;
+            else if (m_windowStyle & wxSL_BOTTOM)
+                eScrollEvent = wxEVT_SCROLL_BOTTOM;
+            break;
+
+        case SLN_SLIDERTRACK:
+            eScrollEvent = wxEVT_SCROLL_THUMBTRACK;
+            break;
+
+        default:
+            return FALSE;
+    }
+
+    int                             nPixelRange = SHORT1FROMMR(::WinSendMsg( GetHwnd()
+                                                                            ,SLM_QUERYSLIDERINFO
+                                                                            ,MPFROM2SHORT( SMA_SHAFTDIMENSIONS
+                                                                                          ,SMA_RANGEVALUE
+                                                                                         )
+                                                                            ,(MPARAM)0
+                                                                           )
+                                                              );
+    m_dPixelToRange = (double)(nPixelRange - m_nThumbLength)/(double)(m_nRangeMax - m_nRangeMin);
+    int                             nNewPos = 0;
+    int                             nPixelPos = SHORT1FROMMR(::WinSendMsg( GetHwnd()
+                                                                          ,SLM_QUERYSLIDERINFO
+                                                                          ,MPFROM2SHORT( SMA_SLIDERARMPOSITION
+                                                                                        ,SMA_RANGEVALUE
+                                                                                       )
+                                                                          ,(MPARAM)0
+                                                                         )
+                                                            );
+    nNewPos = (nPixelPos/m_dPixelToRange);
+    if (nNewPos > (m_nRangeMax - m_nRangeMin)/2)
+        nNewPos++;
+    if ((nNewPos < GetMin()) || (nNewPos > GetMax()))
+    {
+        //
+        // Out of range - but we did process it
+        //
+        return TRUE;
+    }
+    SetValue(nNewPos);
+
+    wxScrollEvent                   vEvent( eScrollEvent
+                                           ,m_windowId
+                                          );
+
+    vEvent.SetPosition(nNewPos);
+    vEvent.SetEventObject(this);
+    GetEventHandler()->ProcessEvent(vEvent);
+
+    wxCommandEvent                  vCevent( wxEVT_COMMAND_SLIDER_UPDATED
+                                            ,GetId()
+                                           );
+
+    vCevent.SetInt(nNewPos);
+    vCevent.SetEventObject(this);
+    return (GetEventHandler()->ProcessEvent(vCevent));
+} // end of wxSlider::OS2OnScroll
+
+void wxSlider::SetLineSize(
+  int                               nLineSize
+)
 {
-    // TODO
-    return 0;
-}
+    m_nLineSize = nLineSize;
+} // end of wxSlider::SetLineSize
 
-int wxSlider::GetSelEnd() const
+
+void wxSlider::SetPageSize(
+  int                               nPageSize
+)
 {
-    // TODO
-    return 0;
-}
+    m_nPageSize = nPageSize;
+} // end of wxSlider::SetPageSize
 
-int wxSlider::GetSelStart() const
+void wxSlider::SetRange(
+  int                               nMinValue
+, int                               nMaxValue
+)
 {
-    // TODO
-    return 0;
-}
+    wxChar                          zBuf[10];
+
+    m_nRangeMin = nMinValue;
+    m_nRangeMax = nMaxValue;
+
+    int                             nPixelRange = SHORT1FROMMR(::WinSendMsg( GetHwnd()
+                                                                            ,SLM_QUERYSLIDERINFO
+                                                                            ,MPFROM2SHORT( SMA_SHAFTDIMENSIONS
+                                                                                          ,SMA_RANGEVALUE
+                                                                                         )
+                                                                            ,(MPARAM)0
+                                                                           )
+                                                              );
+    m_dPixelToRange = (double)(nPixelRange - m_nThumbLength)/(double)(m_nRangeMax - m_nRangeMin);
+    if (m_hStaticMin)
+    {
+        wxSprintf(zBuf, wxT("%d"), m_nRangeMin);
+        ::WinSetWindowText((HWND)m_hStaticMin, zBuf);
+    }
+
+    if (m_hStaticMax)
+    {
+        wxSprintf(zBuf, wxT("%d"), m_nRangeMax);
+        ::WinSetWindowText((HWND)m_hStaticMax, zBuf);
+    }
+} // end of wxSlider::SetRange
 
-void wxSlider::SetSelection(int minPos, int maxPos)
+void wxSlider::SetSelection(
+  int                               WXUNUSED(nMinPos)
+, int                               WXUNUSED(nMaxPos)
+)
 {
-    // TODO
-}
+} // end of wxSlider::SetSelection
 
-void wxSlider::SetThumbLength(int len)
+void wxSlider::SetThumbLength(
+  int                               nLen
+)
 {
-    // TODO
-}
+    int                             nBreadth;
 
-int wxSlider::GetThumbLength() const
+    m_nThumbLength = SHORT1FROMMR(::WinSendMsg( GetHwnd()
+                                               ,SLM_QUERYSLIDERINFO
+                                               ,MPFROM2SHORT( SMA_SLIDERARMDIMENSIONS
+                                                             ,SMA_RANGEVALUE
+                                                            )
+                                               ,(MPARAM)0
+                                              )
+                                 ) + 4; // for bordersizes
+    nBreadth = SHORT2FROMMR(::WinSendMsg( GetHwnd()
+                                         ,SLM_QUERYSLIDERINFO
+                                         ,MPFROM2SHORT( SMA_SLIDERARMDIMENSIONS
+                                                       ,SMA_RANGEVALUE
+                                                      )
+                                         ,(MPARAM)0
+                                        )
+                           );
+    ::WinSendMsg( GetHwnd()
+                 ,SLM_SETSLIDERINFO
+                 ,MPFROM2SHORT( SMA_SLIDERARMDIMENSIONS
+                               ,SMA_RANGEVALUE
+                              )
+                 ,MPFROM2SHORT(nLen, nBreadth)
+                );
+    m_nThumbLength = nLen + 4; // Borders
+} // end of wxSlider::SetThumbLength
+
+void wxSlider::SetTick(
+  int                               nTickPos
+)
 {
-    // TODO
-    return 0;
-}
+    nTickPos *= m_dPixelToRange;
+    ::WinSendMsg( GetHwnd()
+                 ,SLM_ADDDETENT
+                 ,MPFROMSHORT(nTickPos)
+                 ,NULL
+                );
+} // end of wxSlider::SetTick
 
-void wxSlider::SetTick(int tickPos)
+// For trackbars only
+void wxSlider::SetTickFreq(
+  int                               n
+, int                               nPos
+)
 {
-    // TODO
-}
+    SLDCDATA                        vSlData;
+    WNDPARAMS                       vWndParams;
+    int                             nPixelPos;
+    int                             i;
 
-void wxSlider::Command (wxCommandEvent & event)
+    vSlData.cbSize = sizeof(SLDCDATA);
+    if (m_windowStyle & wxSL_AUTOTICKS)
+    {
+        vSlData.usScale1Spacing = 0;
+        vSlData.usScale2Spacing = 0;
+    }
+    vSlData.usScale1Increments = (m_nRangeMax - m_nRangeMin)/n;
+    vSlData.usScale2Increments = (m_nRangeMax - m_nRangeMin)/n;
+
+    vWndParams.fsStatus = WPM_CTLDATA;
+    vWndParams.cchText  = 0L;
+    vWndParams.pszText  = NULL;
+    vWndParams.cbPresParams = 0L;
+    vWndParams.pPresParams = NULL;
+    vWndParams.cbCtlData = vSlData.cbSize;
+    vWndParams.pCtlData = (PVOID)&vSlData;
+    ::WinSendMsg(GetHwnd(), WM_SETWINDOWPARAMS, (MPARAM)&vWndParams, (MPARAM)0);
+    for (i = 1; i < (m_nRangeMax - m_nRangeMin)/n; i++)
+    {
+        nPixelPos = i * n * m_dPixelToRange;
+        ::WinSendMsg( GetHwnd()
+                     ,SLM_ADDDETENT
+                     ,MPFROMSHORT(nPixelPos)
+                     ,NULL
+                    );
+    }
+} // end of wxSlider::SetTickFreq
+
+void wxSlider::SetValue(
+  int                               nValue
+)
 {
-  SetValue (event.GetInt());
-  ProcessCommand (event);
-}
+    int                             nPixelPos = SHORT1FROMMR(::WinSendMsg( GetHwnd()
+                                                                          ,SLM_QUERYSLIDERINFO
+                                                                          ,MPFROM2SHORT( SMA_SLIDERARMPOSITION
+                                                                                        ,SMA_RANGEVALUE
+                                                                                       )
+                                                                          ,(MPARAM)0
+                                                                         )
+                                                            );
+    int                             nPixelRange = SHORT1FROMMR(::WinSendMsg( GetHwnd()
+                                                                            ,SLM_QUERYSLIDERINFO
+                                                                            ,MPFROM2SHORT( SMA_SHAFTDIMENSIONS
+                                                                                          ,SMA_RANGEVALUE
+                                                                                         )
+                                                                            ,(MPARAM)0
+                                                                           )
+                                                              );
+    m_dPixelToRange = (double)(nPixelRange - m_nThumbLength)/(double)(m_nRangeMax - m_nRangeMin);
+    int                             nNewPos = (int)(nValue * m_dPixelToRange);
+
+    ::WinSendMsg( GetHwnd()
+                 ,SLM_SETSLIDERINFO
+                 ,MPFROM2SHORT( SMA_SLIDERARMPOSITION
+                               ,SMA_RANGEVALUE
+                              )
+                 ,(MPARAM)nNewPos
+                );
+    if (m_hStaticValue)
+    {
+        wxSprintf(wxBuffer, wxT("%d"), nValue);
+        ::WinSetWindowText((HWND)m_hStaticValue, wxBuffer);
+    }
+} // end of wxSlider::SetValue
 
-bool wxSlider::Show(bool show)
+bool wxSlider::Show(
+  bool                              bShow
+)
 {
-    // TODO
+    wxWindowOS2::Show(bShow);
+    if(m_hStaticValue)
+        ::WinShowWindow((HWND)m_hStaticValue, bShow);
+    if(m_hStaticMin)
+        ::WinShowWindow((HWND)m_hStaticMin, bShow);
+    if(m_hStaticMax)
+        ::WinShowWindow((HWND)m_hStaticMax, bShow);
     return TRUE;
-}
+} // end of wxSlider::Show