Exemple #1
0
void ScrollBar::LeftDown(Point p, dword) {
	push = GetMousePart();
	LLOG("ScrollBar::LeftDown(" << p << ")");
	LLOG("MousePos = " << GetMousePos() << ", ScreenView = " << GetScreenView()
	<< ", rel. pos = " << (GetMousePos() - GetScreenView().TopLeft()));
	LLOG("GetWorkArea = " << GetWorkArea());
	LLOG("VisibleScreenView = " << GetVisibleScreenView());
	LLOG("PartRect(0) = " << GetPartRect(0));
	LLOG("PartRect(1) = " << GetPartRect(1));
	LLOG("PartRect(2) = " << GetPartRect(2));
	LLOG("ScrollBar::LeftDown: mousepart = " << (int)push << ", rect = " << GetPartRect(push)
		<< ", overthumb = " << style->overthumb << ", slider = " << Slider());
	LLOG("thumbpos = " << thumbpos << ", thumbsize = " << thumbsize);
	if(push == 2)
		delta = GetHV(p.x, p.y) - thumbpos;
	else {
		if(jump) {
			delta = thumbsize / 2;
			Drag(p);
		}
		else
			if(push == 0)
				PrevPage();
			else
				NextPage();
	}
	SetCapture();
	Refresh();
	WhenLeftClick();
}
Exemple #2
0
void SSkinScrollbar::_Draw(IRenderTarget *pRT, LPCRECT prcDraw, DWORD dwState,BYTE byAlpha)
{
    if(!m_pImg) return;
    int nSbCode=LOWORD(dwState);
    int nState=LOBYTE(HIWORD(dwState));
    BOOL bVertical=HIBYTE(HIWORD(dwState));
    CRect rcMargin(0,0,0,0);
    if(bVertical)
        rcMargin.top=m_nMargin,rcMargin.bottom=m_nMargin;
    else
        rcMargin.left=m_nMargin,rcMargin.right=m_nMargin;

    CRect rcSour=GetPartRect(nSbCode,nState,bVertical);
    
    pRT->DrawBitmap9Patch(prcDraw,m_pImg,&rcSour,&rcMargin,m_bTile?EM_TILE:EM_STRETCH,byAlpha);
    
    if(nSbCode==SB_THUMBTRACK && m_bHasGripper)
    {
        rcSour=GetPartRect(SB_THUMBGRIPPER,0,bVertical);
        CRect rcDraw=*prcDraw;
        
        if (bVertical)
            rcDraw.top+=(rcDraw.Height()-rcSour.Height())/2,rcDraw.bottom=rcDraw.top+rcSour.Height();
        else
            rcDraw.left+=(rcDraw.Width()-rcSour.Width())/2,rcDraw.right=rcDraw.left+rcSour.Width();
        pRT->DrawBitmap9Patch(&rcDraw,m_pImg,&rcSour,&rcMargin,m_bTile?EM_TILE:EM_STRETCH,byAlpha);
    }
}
void CDuiScrollBar::OnMouseMove(UINT nFlags, CPoint point)
{
    if(m_bDrag)
    {
        int nInterHei=(IsVertical()?m_rcWindow.Height():m_rcWindow.Width())-2*m_uAllowSize;
        int	nSlideHei=m_si.nPage*nInterHei/(m_si.nMax-m_si.nMin+1);
        if(nSlideHei<THUMB_MINSIZE) nSlideHei=THUMB_MINSIZE;
        if(nInterHei<THUMB_MINSIZE) nSlideHei=0;
        int nEmptyHei=nInterHei-nSlideHei;
        int nDragLen=IsVertical()?(point.y-m_ptDrag.y):(point.x-m_ptDrag.x);
        int nSlide=(nEmptyHei==0)?0:(nDragLen*(int)(m_si.nMax-m_si.nMin-m_si.nPage+1)/nEmptyHei);
        int nNewTrackPos=m_nDragPos+nSlide;
        if(nNewTrackPos<m_si.nMin)
        {
            nNewTrackPos=m_si.nMin;
        }
        else if(nNewTrackPos>(int)(m_si.nMax-m_si.nMin-m_si.nPage+1))
        {
            nNewTrackPos=m_si.nMax-m_si.nMin-m_si.nPage+1;
        }
        if(nNewTrackPos!=m_si.nTrackPos)
        {
            CRect rcOldThumb=GetPartRect(SB_THUMBTRACK);
            m_si.nTrackPos=nNewTrackPos;
            CRect rcThumb=GetPartRect(SB_THUMBTRACK);
            CRect rcUnion;
            rcUnion.UnionRect(rcOldThumb,rcThumb);
            HDC hdc=GetDuiDC(&rcUnion,OLEDC_PAINTBKGND);

            m_pSkin->Draw(hdc,rcUnion,MAKESBSTATE(SB_PAGEUP,SBST_NORMAL,m_bVertical),m_byAlpha);
            m_pSkin->Draw(hdc,rcThumb,MAKESBSTATE(SB_THUMBTRACK,SBST_HOVER,m_bVertical),m_byAlpha);

            ReleaseDuiDC(hdc);
            NotifySbCode(SB_THUMBTRACK,m_si.nTrackPos);
        }
    }
    else
    {
        UINT uHit=HitTest(point);
        if(uHit!=m_uHtPrev)
        {
            if(m_uHtPrev!=-1)
            {
                CRect rc=GetPartRect(m_uHtPrev);
                HDC hdc=GetDuiDC(&rc,OLEDC_PAINTBKGND);
                m_pSkin->Draw(hdc,rc,MAKESBSTATE(m_uHtPrev,SBST_NORMAL,m_bVertical),m_byAlpha);
                ReleaseDuiDC(hdc);
            }
            if(uHit!=-1)
            {
                CRect rc=GetPartRect(uHit);
                HDC hdc=GetDuiDC(&rc,OLEDC_PAINTBKGND);
                m_pSkin->Draw(hdc,rc,MAKESBSTATE(uHit,SBST_HOVER,m_bVertical),m_byAlpha);
                ReleaseDuiDC(hdc);
            }
            m_uHtPrev=uHit;
        }
    }
}
Exemple #4
0
void SSliderBar::OnLButtonDown(UINT nFlags, CPoint point) 
{
    SetCapture();

    UINT uHit = HitTest(point);
    if (uHit == SC_THUMB)
    {
        m_bDrag    = TRUE;
        m_ptDrag   = point;
        m_nDragValue=m_nValue;
        Invalidate();
    }
    else
    {
        CRect rcRail=GetPartRect(SC_RAIL);
        int nValue=0;
        if(IsVertical())
        {
            nValue= (point.y-rcRail.top)*(m_nMaxValue-m_nMinValue+1)/rcRail.Height()+m_nMinValue;
        }else
        {
            nValue= (point.x-rcRail.left)*(m_nMaxValue-m_nMinValue+1)/rcRail.Width()+m_nMinValue;
        }
        SetValue(nValue);
        Invalidate();

        m_bDrag    = TRUE;
        m_ptDrag   = point;
        m_nDragValue=m_nValue;

		NotifyPos(SC_THUMB,m_nValue);
    }
}
void CDuiScrollBar::OnLButtonUp(UINT nFlags, CPoint point)
{
    ReleaseDuiCapture();
    if(m_bDrag)
    {
        m_bDrag=FALSE;
        m_si.nPos=m_si.nTrackPos;
        m_si.nTrackPos=-1;
        OnMouseMove(nFlags,point);
        NotifySbCode(SB_THUMBPOSITION,m_si.nPos);
    }
    else if(m_uClicked!=-1)
    {
        if(m_bNotify)
        {
            KillDuiTimer(TIMERID_NOTIFY1);
            m_bNotify=FALSE;
        }
        else
        {
            KillDuiTimer(TIMERID_DELAY1);
        }
        if(m_uClicked==SB_LINEUP||m_uClicked==SB_LINEDOWN)
        {
            CRect rc=GetPartRect(m_uClicked);
            HDC hdc=GetDuiDC(&rc,OLEDC_PAINTBKGND);
            m_pSkin->Draw(hdc,rc,MAKESBSTATE(m_uClicked,SBST_NORMAL,m_bVertical),m_byAlpha);
            ReleaseDuiDC(hdc);
        }
        m_uClicked=-1;
    }
}
Exemple #6
0
//+---------------------------------------------------------------------------
//
//  Member:     CScrollbar::InvalidatePart
//              
//  Synopsis:   Invalidate and immediately redraw the indicated scrollbar part.
//              
//  Arguments:  part                part to redraw
//              direction           0 for horizontal scroll bar, 1 for vertical
//              rcScrollbar         scroll bar bounds
//              contentSize         size of content controlled by scroll bar
//              containerSize       size of container
//              scrollAmount        current scroll amount
//              buttonWidth         width of scroll bar buttons
//              pDispNodeToInval    display node to invalidate
//              
//  Notes:      
//              
//----------------------------------------------------------------------------
void CScrollbar::InvalidatePart(
								CScrollbar::SCROLLBARPART part,
								int				direction,
								const CRect&	rcScrollbar,
								long			contentSize,
								long			containerSize,
								long			scrollAmount,
								long			buttonWidth,
								CDispNode*		pDispNodeToInvalidate,
								CDrawInfo*		pDI)
{
	// find bounds of part
	CRect rcPart;
	GetPartRect(
		&rcPart,
		part,
		direction,
		rcScrollbar,
		contentSize,
		containerSize,
		scrollAmount,
		buttonWidth,
		pDI,
		pDispNodeToInvalidate->IsRightToLeft());

	pDispNodeToInvalidate->Invalidate(rcPart, COORDSYS_CONTAINER, TRUE);
}
Exemple #7
0
void CMyStatusBar::OnAttach() 
{
	// Start a timer for the progress bar
	SetTimer(101, 100, 0);

	// Create the StatusBar parts
	SetStatusParts();

	// Set the background color (ignored if XP themes are enabled)
	SendMessage(SB_SETBKCOLOR, 0, RGB(125, 230, 255));

	// Create the Hyperlink
	m_Hyperlink.Create(*this);
	m_Hyperlink.SetWindowPos(NULL, CRect(3,3,100, 20), SWP_SHOWWINDOW);

	// Create the ProgressBar
	m_ProgressBar.Create(*this);
	CRect rcPart = GetPartRect(1);
	m_ProgressBar.SetWindowPos(NULL, rcPart, SWP_SHOWWINDOW);

	// Add the icon
	SetPartIcon(2, (HICON)GetApp().LoadImage(MAKEINTRESOURCE(IDW_MAIN), IMAGE_ICON, 16, 16));

	// Set a Part as owner drawn. The part's drawing is performed in CMainFrame::OnDrawItem.
	SetPartText(3, _T(""), SBT_OWNERDRAW);
}
Exemple #8
0
LRESULT CMyStatusBar::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{

	switch(uMsg)
	{
	case WM_TIMER:
		{	
			// Change the Progress Bar indication
			m_ProgressBar.OffsetPos(1);
			if (m_ProgressBar.GetRange(FALSE, 0) == m_ProgressBar.GetPos())
				m_ProgressBar.SetPos(0);

			break;
		}
	case WM_SIZE:
		{
			// Reposition the StatusBar parts
			SetStatusParts();

			// Reposition the Progress Bar
			CRect rcPart = GetPartRect(1);
			m_ProgressBar.SetWindowPos(NULL, rcPart, SWP_SHOWWINDOW);
			break;
		}
	}

	return CStatusBar::WndProc(uMsg, wParam, lParam);
}
UINT CDuiScrollBar::HitTest(CPoint pt)
{
    CRect rc;
    rc=GetPartRect(SB_LINEUP);
    if(rc.PtInRect(pt)) return SB_LINEUP;
    rc=GetPartRect(SB_LINEDOWN);
    if(rc.PtInRect(pt)) return SB_LINEDOWN;
    rc=GetPartRect(SB_THUMBTRACK);
    if(rc.PtInRect(pt)) return SB_THUMBTRACK;
    rc=GetPartRect(SB_PAGEUP);
    if(rc.PtInRect(pt)) return SB_PAGEUP;
    rc=GetPartRect(SB_PAGEDOWN);
    if(rc.PtInRect(pt)) return SB_PAGEDOWN;

    return -1;
}
void CDuiScrollBar::OnLButtonDown(UINT nFlags, CPoint point)
{
    SetDuiCapture();
    UINT uHit=HitTest(point);
    if(uHit==SB_THUMBTRACK)
    {
        m_bDrag=TRUE;
        m_ptDrag=point;
        m_si.nTrackPos=m_si.nPos;
        m_nDragPos=m_si.nPos;
    }
    else
    {
        m_uClicked=uHit;

        if(uHit==SB_LINEUP || uHit== SB_LINEDOWN)
        {
            CRect rc=GetPartRect(uHit);
            HDC hdc=GetDuiDC(&rc,OLEDC_PAINTBKGND);
            m_pSkin->Draw(hdc,rc,MAKESBSTATE(uHit,SBST_PUSHDOWN,m_bVertical),m_byAlpha);
            ReleaseDuiDC(hdc);
            NotifySbCode(uHit,m_si.nPos);
        }
        else if(uHit == SB_PAGEUP || uHit == SB_PAGEDOWN)
        {
            NotifySbCode(uHit,m_si.nPos);
        }
    }
}
void CDuiScrollBar::OnPaint(CDCHandle dc)
{
    if(!m_pSkin) return;

    int nState=IsDisabled(TRUE)?3:0;
    CRect rcDest;
    rcDest=GetPartRect(SB_LINEUP);
    m_pSkin->Draw(dc,rcDest,MAKESBSTATE(SB_LINEUP,nState,m_bVertical),m_byAlpha);
    rcDest=GetPartRect(SB_PAGEUP);
    m_pSkin->Draw(dc,rcDest,MAKESBSTATE(SB_PAGEUP,nState,m_bVertical),m_byAlpha);
    rcDest=GetPartRect(SB_THUMBTRACK);
    m_pSkin->Draw(dc,rcDest,MAKESBSTATE(SB_THUMBTRACK,nState,m_bVertical),m_byAlpha);
    rcDest=GetPartRect(SB_PAGEDOWN);
    m_pSkin->Draw(dc,rcDest,MAKESBSTATE(SB_PAGEDOWN,nState,m_bVertical),m_byAlpha);
    rcDest=GetPartRect(SB_LINEDOWN);
    m_pSkin->Draw(dc,rcDest,MAKESBSTATE(SB_LINEDOWN,nState,m_bVertical),m_byAlpha);
}
Exemple #12
0
int SSliderBar::HitTest(CPoint pt)
{
    CRect rc;

    rc = GetPartRect(SC_THUMB);
    if (rc.PtInRect(pt))
        return SC_THUMB;

    rc = GetPartRect(SC_SELECT);
    if (rc.PtInRect(pt))
        return SC_SELECT;

    rc = GetPartRect(SC_RAIL);
    if (rc.PtInRect(pt))
        return SC_RAIL;

    return -1;
}
Exemple #13
0
void SSliderBar::OnMouseLeave()
{
    if (!m_bDrag && m_uHtPrev==SC_THUMB)
    {
        CRect rcThumb = GetPartRect(SC_THUMB);
        InvalidateRect(rcThumb);
        Invalidate();
        m_uHtPrev=-1;
    }
}
Exemple #14
0
int  ScrollBar::GetMousePart()
{
	int q = -1;
	for(int i = 2; i >= 0; i--)
		if(HasMouseIn(GetPartRect(i))) {
			q = i;
			break;
		}
	return q;
}
Exemple #15
0
void SSliderBar::OnLButtonUp(UINT nFlags, CPoint point)
{
    ReleaseCapture();

    if (m_bDrag)
    {
        m_bDrag   = FALSE;
        CRect rcThumb = GetPartRect(SC_THUMB);
        InvalidateRect(rcThumb);
    }
    OnMouseMove(nFlags,point);
}
Exemple #16
0
void SSliderBar::OnPaint(IRenderTarget * pRT)
{
    SASSERT(m_pSkinThumb && m_pSkinBg && m_pSkinPos);

    SPainter painter;

    BeforePaint(pRT, painter);

    CRect rcRail=GetPartRect(SC_RAILBACK);
    m_pSkinBg->Draw(pRT,rcRail,0);
    if(m_nValue!=m_nMinValue)
    {
        CRect rcSel=GetPartRect(SC_SELECT);
        m_pSkinPos->Draw(pRT,rcSel,0);
    }
    CRect rcThumb = GetPartRect(SC_THUMB);
    int nState=0;//normal
    if(m_bDrag) nState=2;//pushback
    else if(m_uHtPrev==SC_THUMB) nState=1;//hover
    m_pSkinThumb->Draw(pRT, rcThumb, nState);

    AfterPaint(pRT, painter);
}
int CDuiScrollBar::SetPos(int nPos)
{
    if(nPos>(m_si.nMax-(int)m_si.nPage+1)) nPos=(m_si.nMax-m_si.nPage+1);
    if(nPos<m_si.nMin) nPos=m_si.nMin;
    if(nPos!=m_si.nPos)
    {
        if(m_si.nTrackPos==-1)
        {
            CRect rcOldThumb=GetPartRect(SB_THUMBTRACK);
            m_si.nTrackPos=nPos;
            CRect rcNewThumb=GetPartRect(SB_THUMBTRACK);
            CRect rcUnion;
            rcUnion.UnionRect(&rcOldThumb,&rcNewThumb);
            HDC hdc=GetDuiDC(&rcUnion,OLEDC_PAINTBKGND);
            m_pSkin->Draw(hdc,rcUnion,MAKESBSTATE(SB_PAGEDOWN,SBST_NORMAL,IsVertical()));
            m_pSkin->Draw(hdc,rcNewThumb,MAKESBSTATE(SB_THUMBTRACK,SBST_NORMAL,IsVertical()));
            ReleaseDuiDC(hdc);
            m_si.nTrackPos=-1;
        }
        m_si.nPos=nPos;
    }
    return m_si.nPos;
}
Exemple #18
0
void SSliderBar::OnMouseMove(UINT nFlags, CPoint point) 
{
    if (m_bDrag)
    {
        CRect rcRail=GetPartRect(SC_RAIL);

        int nInterHei=(IsVertical()?rcRail.Height():rcRail.Width());
        int nDragLen=IsVertical()?(point.y-m_ptDrag.y):(point.x-m_ptDrag.x);
        int nSlide=nDragLen*(m_nMaxValue-m_nMinValue+1)/nInterHei;

        int nNewTrackPos=m_nDragValue+nSlide;
        if(nNewTrackPos<m_nMinValue)
        {
            nNewTrackPos=m_nMinValue;
        }
        else if(nNewTrackPos>m_nMaxValue)
        {
            nNewTrackPos=m_nMaxValue;
        }
        if(nNewTrackPos!=m_nValue)
        {
            m_nValue=nNewTrackPos;
            Invalidate();
            NotifyPos(SC_THUMB,m_nValue);
        }
    }
    else
    {
        int uHit = HitTest(point);
        if (uHit != m_uHtPrev && (m_uHtPrev==SC_THUMB || uHit==SC_THUMB))
        {
            m_uHtPrev = uHit;
            CRect rcThumb = GetPartRect(SC_THUMB);
            InvalidateRect(rcThumb);
        }
    }
}
void CDuiScrollBar::OnTimer(char nIDEvent)
{
    // TODO: Add your message handler code here and/or call default
    if(nIDEvent==TIMERID_NOTIFY1)
    {
        DUIASSERT(m_uClicked!=-1 && m_uClicked!=SB_THUMBTRACK);

        switch(m_uClicked)
        {
        case SB_LINEUP:
            if(m_si.nPos==m_si.nMin)
            {
                KillDuiTimer(TIMERID_NOTIFY1);
                break;
            }
            break;
        case SB_LINEDOWN:
            if(m_si.nPos==m_si.nMax)
            {
                KillDuiTimer(TIMERID_NOTIFY1);
                break;
            }
            break;
        case SB_PAGEUP:
        case SB_PAGEDOWN:
        {
            CPoint pt;
            ::GetCursorPos(&pt);
            ::ScreenToClient(GetContainer()->GetHostHwnd(),&pt);
            CRect rc=GetPartRect(SB_THUMBTRACK);
            if(rc.PtInRect(pt))
            {
                KillDuiTimer(TIMERID_NOTIFY1);
                break;
            }
        }
        break;
        default:
            DUIASSERT(FALSE);
            break;
        }
    }
}
Exemple #20
0
void ScrollBar::Paint(Draw& w) {
	w.DrawRect(GetSize(), SColorPaper());
	int cc;
	Size sz = style->through ? GetSize() : Slider(cc).GetSize();
	light = GetMousePart();
	int p = push;
	if(!HasCapture())
		p = -1;
	const Value *hl[] = { style->hlower, style->hupper, style->hthumb };
	const Value *vl[] = { style->vupper, style->vlower, style->vthumb };

	const Value **l = IsHorz() ? hl : vl;

	if(prev.IsShowEnabled()) {
		for(int i = 0; i < 3; i++) {
			Rect pr = GetPartRect(i);
			if(i != 2) {
				w.Clip(pr);
				pr = style->through ? GetSize() : Slider();
			}
			if(i != 2 || thumbsize >= style->thumbmin)
				ChPaint(w, pr, l[i][p == i ? CTRL_PRESSED : light == i ? CTRL_HOT : CTRL_NORMAL]);
			if(i != 2)
				w.End();
		}
	}
	else
		if(style->through)
			ChPaint(w, sz, l[0][CTRL_DISABLED]);
		else
		if(IsHorz()) {
			ChPaint(w, cc, 0, sz.cx / 2, sz.cy, l[0][CTRL_DISABLED]);
			ChPaint(w, cc + sz.cx / 2, 0, sz.cx - sz.cx / 2, sz.cy, l[1][CTRL_DISABLED]);
		}
		else {
			ChPaint(w, 0, cc, sz.cx, sz.cy / 2, l[0][CTRL_DISABLED]);
			ChPaint(w, 0, cc + sz.cy / 2, sz.cx, sz.cy - sz.cy / 2, l[1][CTRL_DISABLED]);
//			w.DrawRect(0, cc, sz.cx, sz.cy / 2, Red()); _DBG_
//			w.DrawRect(0, cc + sz.cy / 2, sz.cx, sz.cy - sz.cy / 2, Green()); _DBG_
		}
}
Exemple #21
0
//+---------------------------------------------------------------------------
//
//  Member:     CScrollbar::GetPart
//              
//  Synopsis:   Return the scroll bar part hit by the given test point.
//              
//  Arguments:  direction       0 for horizontal scroll bar, 1 for vertical
//              rcScrollbar     scroll bar bounds
//              ptHit           test point
//              contentSize     size of content controlled by scroll bar
//              containerSize   size of container
//              scrollAmount    current scroll amount
//              buttonWidth     width of scroll bar buttons
//              fRightToLeft    The text flow is RTL...0,0 is at top right
//              
//  Returns:    The scroll bar part hit, or SBP_NONE if nothing was hit.
//              
//  Notes:      
//              
//----------------------------------------------------------------------------
CScrollbar::SCROLLBARPART CScrollbar::GetPart(
	int				direction,
	const CRect&	rcScrollbar,
	const CPoint&	ptHit,
	long			contentSize,
	long			containerSize,
	long			scrollAmount,
	long			buttonWidth,
	CDrawInfo*		pDI,
	BOOL			fRightToLeft)
{
	if(!rcScrollbar.Contains(ptHit))
	{
		return SBP_NONE;
	}

	// adjust button width if there isn't room for both buttons at full size
	long scaledButtonWidth = GetScaledButtonWidth(direction, rcScrollbar, buttonWidth);

	// now test just the axis that matters
	long x = ptHit[direction];

	if(x < rcScrollbar.TopLeft()[direction]+scaledButtonWidth)
	{
		return SBP_PREVBUTTON;
	}

	if(x >= rcScrollbar.BottomRight()[direction]-scaledButtonWidth)
	{
		return SBP_NEXTBUTTON;
	}

	// NOTE: if there is no thumb, return SBP_TRACK
	CRect rcThumb;
	GetPartRect(
		&rcThumb,
		SBP_THUMB,
		direction,
		rcScrollbar,
		contentSize,
		containerSize,
		scrollAmount,
		buttonWidth,
		pDI,
		fRightToLeft);
	if(rcThumb.IsEmpty())
	{
		return SBP_TRACK;
	}

	if(x < rcThumb.TopLeft()[direction])
	{
		return SBP_PREVTRACK;
	}
	if(x >= rcThumb.BottomRight()[direction])
	{
		return SBP_NEXTTRACK;
	}

	return SBP_THUMB;
}
Exemple #22
0
//+---------------------------------------------------------------------------
//
//  Member:     CScrollbar::Draw
//              
//  Synopsis:   Draw the scroll bar in the given direction.
//              
//  Arguments:  direction           0 for horizontal, 1 for vertical
//              rcScrollbar         bounds of entire scroll bar
//              rcRedraw            bounds to be redrawn
//              contentSize         size of content controlled by scroll bar
//              containerSize       size of area to scroll within
//              scrollAmount        amount that the content is scrolled
//              partPressed         which part, if any, is pressed
//              hdc                 DC to draw into
//              params              customizable scroll bar parameters
//              pDI                 draw info
//              dwFlags             rendering flags
//              
//  Notes:      
//              
//----------------------------------------------------------------------------
void CScrollbar::Draw(
					  int			direction,
					  const CRect&	rcScrollbar,
					  const CRect&	rcRedraw,
					  long			contentSize,
					  long			containerSize,
					  long			scrollAmount,
					  SCROLLBARPART	partPressed,
					  HDC			hdc,
					  const CScrollbarParams& params,
					  CDrawInfo*	pDI,
					  DWORD			dwFlags)
{
	Assert(hdc != NULL);
	// for now, we're using CDrawInfo, which should have the same hdc
	Assert(pDI->_hdc == hdc);

	// trivial rejection if nothing to draw
	if(!rcScrollbar.Intersects(rcRedraw))
	{
		return;
	}

	BOOL fDisabled = (params._fForceDisabled) || (containerSize>=contentSize);
	long scaledButtonWidth =
		GetScaledButtonWidth(direction, rcScrollbar, params._buttonWidth);

	// compute rects for buttons and track
	CRect rcTrack(rcScrollbar);
	rcTrack[direction] += scaledButtonWidth;
	rcTrack[direction+2] -= scaledButtonWidth;

	// draw buttons unless requested not to (it's expensive to draw these!)
	if((dwFlags & DISPSCROLLBARHINT_NOBUTTONDRAW) == 0)
	{
		CRect rcButton[2];
		rcButton[0] = rcScrollbar;
		rcButton[0][direction+2] = rcTrack[direction];
		rcButton[1] = rcScrollbar;
		rcButton[1][direction] = rcTrack[direction+2];

		// draw buttons
		CSize sizeButton;
		pDI->DocumentFromWindow(
			&sizeButton, rcButton[0].Width(), rcButton[0].Height());
		for(int i=0; i<2; i++)
		{
			if(rcRedraw.Intersects(rcButton[i]))
			{
				BOOL fButtonPressed = (i==0 && partPressed==SBP_PREVBUTTON) ||
					(i==1 && partPressed==SBP_NEXTBUTTON);
				CScrollButton scrollButton(params._pColors, params._fFlat);
				scrollButton.DrawButton(
					pDI,
					NULL, // no hwnd, we don't want to invalidate
					(direction==0?(i==0?BG_LEFT:BG_RIGHT):(i==0?BG_UP:BG_DOWN)),
					fButtonPressed,
					!fDisabled,
					FALSE, // never focused
					rcButton[i],
					sizeButton,
					0); // assume both button glyphs are the same size
			}
		}
	}

	// draw track
	if(rcRedraw.Intersects(rcTrack))
	{
		if(fDisabled)
		{
			// no thumb, so draw non-pressed track
			DrawTrack(rcTrack, FALSE, fDisabled, hdc, params);
		}

		else
		{
			// calculate thumb rect
			CRect rcThumb;
			GetPartRect(
				&rcThumb,
				SBP_THUMB,
				direction,
				rcScrollbar,
				contentSize,
				containerSize,
				scrollAmount,
				params._buttonWidth,
				pDI,
				FALSE);

			// can track contain the thumb?
			if(!rcTrack.Contains(rcThumb))
			{
				DrawTrack(rcTrack, FALSE, fDisabled, hdc, params);
			}
			else
			{
				// draw previous track
				CRect rcTrackPart(rcTrack);
				rcTrackPart[direction+2] = rcThumb[direction];
				if(rcRedraw.Intersects(rcTrackPart))
				{
					DrawTrack(rcTrackPart, partPressed==SBP_PREVTRACK, fDisabled, hdc, params);
				}

				// draw thumb
				if(rcRedraw.Intersects(rcThumb))
				{
					DrawThumb(rcThumb, partPressed==SBP_THUMB, hdc, params, pDI );
				}

				// draw next track
				rcTrackPart = rcTrack;
				rcTrackPart[direction] = rcThumb[direction+2];
				if(rcRedraw.Intersects(rcTrackPart))
				{
					DrawTrack(rcTrackPart, partPressed==SBP_NEXTTRACK, fDisabled, hdc, params);
				}
			}
		}
	}
}