MRESULT EXPENTRY MpmFnwpScrollBar( hwnd, msg, mp1, mp2 )
    HWND        hwnd;
    USHORT      msg;
    MPARAM      mp1;
    MPARAM      mp2;
{
    USHORT      id;
    ControlHandle hctl, hctl1;
    Rect        rect;
    Rect*       prect;
    SHORT       sPart;
    POINTL      ptl;
    SHORT       cmd;
    Handle      hcdef;
    LONG        lPoint;
    Point       point;
    static BOOL fTrackThumb = FALSE;
    static SHORT sInitValue;

    if( ! MpmValidateWindow(hwnd) )
      return FALSE;

    id   = MYWNDOF(hwnd).id;
    hctl = MYWNDOF(hwnd).hctl;

    switch( msg )
    {
      /* Return the current position */

      case SBM_QUERYPOS:
        return MRFROMSHORT( fTrackThumb ? sInitValue
                                        : (**hctl).contrlValue );

      /* Return the scroll bar range */

      case SBM_QUERYRANGE:
        return MRFROM2SHORT( (**hctl).contrlMin, (**hctl).contrlMax );

      /* Set the scroll bar position and range */

      case SBM_SETSCROLLBAR:
        (**hctl).contrlMin = SHORT1FROMMP(mp2);
        (**hctl).contrlMax = SHORT2FROMMP(mp2);
        /* fall through */

      /* Set the scroll bar position only */

      case SBM_SETPOS:
        if( MYWNDOF(hwnd).flStyle & WS_VISIBLE )
          SetCtlValue( hctl, SHORT1FROMMP(mp1) );
        else
          (**hctl).contrlValue = SHORT1FROMMP(mp1);
        fTrackThumb = FALSE;
        return MRFROMSHORT(1);

      /* Handle mouse button down: call TrackControl to track it */

      case WM_BUTTON1DOWN:
        ptl.x = SHORT1FROMMP(mp1);
        ptl.y = SHORT2FROMMP(mp1);
        MpmMapMacOfPtl( hwnd, &point, &ptl );
        sPart = FindControl( point, PWINOFHWND(hwnd), &hctl1 );
        ASSERT( sPart  &&  hctl1 == hctl,
                "MpmFnwpScrollBar: FindControl failed" );
        _hwndTrack = hwnd;
        if( sPart == inThumb )
        {
          fTrackThumb = TRUE;
          sInitValue = (**hctl).contrlValue;
          if( TrackControl( hctl, point, NULL ) )
            MpmTrackScrollBarNotify( SB_SLIDERPOSITION );
          fTrackThumb = FALSE;
        }
        else
        {
          TrackControl( hctl, point, (ProcPtr)MpmTrackScrollBar );
          MpmTrackScrollBarNotify( SB_ENDSCROLL );
        }
        return 0L;

      /* Handle scroll bar creation: call NewControl to create it */

      case WM_CREATE:
        rect.left = rect.top = 0;
        if( MYWNDOF(hwnd).flStyle & SBS_VERT )
          rect.right = _alSysVal[SV_CXVSCROLL], rect.bottom = 100;
        else
          rect.bottom = _alSysVal[SV_CYHSCROLL], rect.right = 100;
        hctl = NewControl( PWINOFHWND(hwnd), &rect, _szNull,
                           MYWNDOF(hwnd).flStyle & WS_VISIBLE,
                           0, 0, 1, scrollBarProc, (long)hwnd );
        if( ! hctl )
          return MRFROMSHORT(1);
        MYWNDOF(hwnd).hctl = hctl;
        return 0L;

      /* Destroy scroll bar */

      case WM_DESTROY:
        MYWNDOF(hwnd).hctl = NULL;
        DisposeControl( hctl );
        return 0L;

      /* Handle window movement: use MoveControl to move the bar */

      case WM_MOVE:
        MpmQueryMacRect( hwnd, &rect );
        if( MYWNDOF(hwnd).flStyle & WS_VISIBLE )
          MoveControl( hctl, rect.left, rect.top );
        else
        {
          prect = &(**hctl).contrlRect;
          prect->right  += rect.left - prect->left;
          prect->left    = rect.left;
          prect->bottom += rect.top  - prect->top;
          prect->top     = rect.top;
        }
        return 0L;

      /* Show or hide the scroll bar */

      case WM_SHOW:
        if( mp1 )
          ShowControl( hctl );
        else
          HideControl( hctl );
        return 0L;

      /* Handle window resizing: use SizeControl to resize it */

      case WM_SIZE:
        if( SHORT1FROMMP(mp2) && SHORT2FROMMP(mp2) )
        {
          if( MYWNDOF(hwnd).flStyle & WS_VISIBLE )
            SizeControl( hctl,
                         SHORT1FROMMP(mp2),
                         SHORT2FROMMP(mp2) );
          else
          {
            prect = &(**hctl).contrlRect;
            prect->right  = prect->left + SHORT1FROMMP(mp2);
            prect->bottom = prect->top  + SHORT2FROMMP(mp2);
          }
        }
        return 0L;
    }
    
    return WinDefWindowProc( hwnd, msg, mp1, mp2 );
}
