+    int         nPosition;
+    int         nMaxPos;
+    int         nTrackPos = wPos;
+    int         nMinPos;
+    int         nScrollInc;
+    wxEventType vScrollEvent = wxEVT_NULL;
+
+    MRESULT     vRange;
+
+    //
+    // When we're dragging the scrollbar we can't use pos parameter because it
+    // is limited to 16 bits
+    //
+    if (wParam == SB_SLIDERPOSITION || wParam == SB_SLIDERTRACK)
+    {
+        SBCDATA                     vScrollInfo;
+
+        vScrollInfo.sHilite = SB_SLIDERTRACK;
+
+        ::WinSendMsg((HWND)GetHwnd(), WM_QUERYWINDOWPARAMS, (PVOID)&vScrollInfo, NULL);
+
+        nTrackPos = vScrollInfo.posThumb;
+        nPosition = vScrollInfo.posFirst;
+        nMaxPos   = vScrollInfo.posLast;
+    }
+    else
+    {
+        nPosition = (int)(MRESULT)::WinSendMsg((HWND)GetHwnd(), SBM_QUERYPOS, (MPARAM)NULL, (MPARAM)NULL);
+        vRange = ::WinSendMsg((HWND)GetHwnd(), SBM_QUERYRANGE, (MPARAM)NULL, (MPARAM)NULL);
+        nMinPos = SHORT1FROMMR(vRange);
+        nMaxPos = SHORT2FROMMR(vRange);
+    }
+    //
+    // A page size greater than one has the effect of reducing the effective
+    // range, therefore the range has already been boosted artificially - so
+    // reduce it again.
+    //
+    if (m_nPageSize > 1)
+        nMaxPos -= (m_nPageSize - 1);
+    switch (wParam)
+    {
+        case SB_LINEUP:
+            nScrollInc   = -1;
+            vScrollEvent = wxEVT_SCROLL_LINEUP;
+            break;
+
+        case SB_LINEDOWN:
+            nScrollInc   = 1;
+            vScrollEvent = wxEVT_SCROLL_LINEDOWN;
+            break;
+
+        case SB_PAGEUP:
+            nScrollInc   = -GetPageSize();
+            vScrollEvent = wxEVT_SCROLL_PAGEUP;
+            break;
+
+        case SB_PAGEDOWN:
+            nScrollInc   = GetPageSize();
+            vScrollEvent = wxEVT_SCROLL_PAGEDOWN;
+            break;
+
+        case SB_SLIDERTRACK:
+            nScrollInc   = nTrackPos - nPosition;
+            vScrollEvent = wxEVT_SCROLL_THUMBTRACK;
+            break;
+
+        case SB_ENDSCROLL:
+            nScrollInc   = 0;
+            vScrollEvent = wxEVT_SCROLL_CHANGED;
+            break;
+
+        default:
+            nScrollInc = 0;
+    }
+    if (nScrollInc)
+    {
+        nPosition += nScrollInc;
+
+        if (nPosition < 0)
+            nPosition = 0;
+        if (nPosition > nMaxPos)
+            nPosition = nMaxPos;
+        SetThumbPosition(nPosition);
+    }
+    else if ( vScrollEvent != wxEVT_SCROLL_THUMBRELEASE &&
+              vScrollEvent != wxEVT_SCROLL_CHANGED
+            )
+    {
+        //
+        // Don't process the event if there is no displacement,
+        // unless this is a thumb release or end scroll event.
+        //
+        return false;
+    }
+
+    wxScrollEvent                   vEvent( vScrollEvent
+                                           ,m_windowId
+                                          );
+
+    vEvent.SetOrientation(IsVertical() ? wxVERTICAL : wxHORIZONTAL);
+    vEvent.SetPosition(nPosition);
+    vEvent.SetEventObject(this);
+    return GetEventHandler()->ProcessEvent(vEvent);
+} // end of wxScrollBar::OS2OnScroll
+
+void wxScrollBar::SetThumbPosition ( int nViewStart )
+{
+    SBCDATA                        vInfo;
+
+    memset(&vInfo, '\0', sizeof(SBCDATA));
+    vInfo.cb       = sizeof(SBCDATA);
+    vInfo.posThumb = (SHORT)nViewStart;
+
+    ::WinSendMsg((HWND)GetHwnd(), WM_SETWINDOWPARAMS, (MPARAM)&vInfo, (MPARAM)NULL);
+    ::WinSendMsg((HWND)GetHwnd(), SBM_SETPOS, (MPARAM)nViewStart, (MPARAM)NULL);
+} // end of wxScrollBar::SetThumbPosition