//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include <Vcl.Imaging.pngimage.hpp>
#include "SkinScrollBarUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)

//add by tj 2013/11/21
#define PIXEL_EXTERNAL_FRAME 1
#define PIXEL_EX2INTERNAL    1
#define PIXEL_INTERNAL_FARME 1
#define PIXEL_INTERNAL_BOUND 1
#define PIXEL_INTERNAL_LINE  6 //add by tj 2013/12/10


static  const COLORREF
		RGB_EXTERNAL_FRAME              =  RGB(29,31,35),
		RGB_EXTERNAL_NOR                =  RGB(60,66,72),
		RGB_EXTERNAL_HIG        	    =  RGB(74,80,88),
		RGB_INTERNAL_NOR                =  RGB(39,42,47), //272a2f
		RGB_INTERNAL_HIG                =  RGB(74,80,88), //4a5058
		RGB_INTERNAL_PUSH               =  RGB(50,54,60), //32363c
		RGB_INTERNAL_LINE_NOR           =  RGB(25,27,30), //191b1e
		RGB_INTERNAL_LINE_HIG           =  RGB(58,63,69), //3a3f45
		RGB_INTERNAL_LINE_PUSH          =  RGB(38,41,45), //26292d
		RGB_INTERNAL_LINE_NOR_TRANS[6]  ={ RGB(44,47,53), //2c2f35
										   RGB(47,51,57),
										   RGB(52,55,62),
										   RGB(56,59,67),
										   RGB(57,59,69),
										   RGB(59,61,71)
										 },
		RGB_INTERNAL_LINE_HIG_TRANS[6]  ={ RGB(79,86,94),//4f565e
										   RGB(83,90,99),
										   RGB(87,94,104),
										   RGB(91,99,109),
										   RGB(92,100,111),
										   RGB(94,104,115),
										 },
		RGB_INTERNAL_LINE_PUSH_TRANS[6] ={ RGB(55,59,66), //373b42
										   RGB(60,65,72),
										   RGB(64,69,77),
										   RGB(69,75,83),
										   RGB(70,77,86),
										   RGB(72,79,88)
										 },
		RGB_INTERNAL_FRAME_NOR          =  RGB(34,36,41),
		RGB_INTERNAL_ROUND_BKG_N_NOR    =  RGB(41,44,49),
		RGB_INTERNAL_ROUND_BKG_N_HIG    =  RGB(51,55,61),
		RGB_INTERNAL_ROUND_BKG_H_NOR    =  RGB(43,46,52),
		RGB_INTERNAL_ROUND_BKG_H_HIG    =  RGB(56,61,67);
//---------------------------------------------------------------------------
TBitmap *u_pPicLineUp = NULL,
		*u_pPicLineDown = NULL,
		*u_pPicLineLeft = NULL,
		*u_pPicLineRight = NULL;

int u_nPicRef = 0;

void InitialPictures()
{
	if( u_nPicRef==0 ){
		u_pPicLineUp = new TBitmap();
		u_pPicLineUp->LoadFromResourceName(int(HInstance), L"SBLineUp");
		u_pPicLineDown = new TBitmap();
		u_pPicLineDown->LoadFromResourceName(int(HInstance), L"SBLineDown");
		u_pPicLineLeft = new TBitmap();
		u_pPicLineLeft->LoadFromResourceName(int(HInstance), L"SBLineLeft");
		u_pPicLineRight = new TBitmap();
		u_pPicLineRight->LoadFromResourceName(int(HInstance), L"SBLineRight");
	}

	u_nPicRef++;
}

void ReleasePictures()
{
	u_nPicRef--;

	if( u_nPicRef==0 ){
		delete u_pPicLineUp;
		delete u_pPicLineDown;
		delete u_pPicLineLeft;
		delete u_pPicLineRight;
	}
}
//---------------------------------------------------------------------------

__fastcall TSkinScrollBar::TSkinScrollBar(TComponent* AOwner, bool bVertical)
 : TScrollBar(AOwner)
{
	Visible = false;
	ParentCtl3D = false;  //add by tj 2013/11/14
	InitialPictures();

	Kind = bVertical ? sbVertical : sbHorizontal;

	if( bVertical )
		Width = u_pPicLineUp->Height;//add by tj 2013/11/19
	else
		Height = u_pPicLineLeft->Width;

	DoubleBuffered = TRUE;

	m_nThumbSize = 0;
	m_nThumbPos = bVertical ? Width : Height;
	m_nPreThumbPos = bVertical ? Width : Height;
//	m_nTileHeight = 18; //add by tj 2013/11/14

	m_nTrackPos = m_nMax = m_nMin = m_nPos = m_nPage = 0;
	m_iClicked = -1;
	m_iHitPrev = -1;

	m_bAction = m_bPause = m_bNotify = m_bDrag = m_bTrace = false;

	m_pCanvas = new TControlCanvas();
	m_pCanvas->Control = this;
	Ctl3D = false;

	//鼠标长期按下的计时器
	m_pTimer = new TTimer(this);
	m_pTimer->Enabled = false;
	m_pTimer->OnTimer = TimerProc;

	OnMouseEnter = CMMouseEnter;
	OnMouseLeave = CMMouseLeave;
}
//---------------------------------------------------------------------------

__fastcall TSkinScrollBar::~TSkinScrollBar()
{
	if( m_pCanvas ){
		delete m_pCanvas;
		m_pCanvas = NULL;
	}

	if( m_pTimer ){
		delete m_pTimer;
		m_pTimer = NULL;
	}

	ReleasePictures();
}
//---------------------------------------------------------------------------

int TSkinScrollBar::HitTest( int X, int Y )
{
	if( Kind==sbVertical ){
		if( Y<0 )
			return -1;
		else if( Y<Width )
			return SB_LINEUP;
		else if( Y<m_nThumbPos )
			return SB_PAGEUP;
		else if( Y<m_nThumbPos+m_nThumbSize )
			return SB_THUMBTRACK;
		else if( Y<Height-Width )
			return SB_PAGEDOWN;
		else if( Y<Height )
			return SB_LINEDOWN;
	}
	else{
		if( X<0 )
			return -1;
		else if( X<Height )
			return SB_LINEUP;
		else if( X<m_nThumbPos )
			return SB_PAGEUP;
		else if( X<m_nThumbPos+m_nThumbSize )
			return SB_THUMBTRACK;
		else if( X<Width-Height )
			return SB_PAGEDOWN;
		else if( X<Width )
			return SB_LINEDOWN;
    }

	return -1;
}
//---------------------------------------------------------------------------

void TSkinScrollBar::CalcThumbSize()
{
	int hInter = Kind==sbVertical ? (Height - 2 * Width) : (Width - 2 * Height);
	int hThumb = m_nPage * hInter / (m_nMax-m_nMin+1);
	if( hThumb<THUMB_MINSIZE )
		hThumb = THUMB_MINSIZE;
	if( hInter<THUMB_MINSIZE )
		hThumb = 0;
	if( m_nMax-m_nMin-m_nPage+1 == 0 )
		hThumb = 0;

	m_nThumbSize = hThumb;
}
//---------------------------------------------------------------------------

void TSkinScrollBar::CalcThumbPos()
{
	bool bVertical = Kind==sbVertical;
	int	nPos;

	if( m_bDrag )
		nPos = m_nTrackPos;
	else
		nPos = m_nPos;

	int wid = bVertical ? Width : Height,
		len = bVertical ? Height :Width;

	if( nPos==0 )
		m_nThumbPos = wid;
	else{
		int nTrackLen = len - 2 * wid - m_nThumbSize;
		int nLenInSi = m_nMax-m_nMin-m_nPage+1;

		if( nLenInSi==0 )
			m_nThumbPos = nTrackLen / 2 + wid;
		else
			m_nThumbPos = (nTrackLen * nPos / nLenInSi) + wid;
	}
}
//---------------------------------------------------------------------------

void TSkinScrollBar::DrawArrow( int iDirection, int iState )
{
	bool bVertical = Kind==sbVertical;

	TBitmap * pPic = NULL;
	int wid = bVertical ? Width : Height,
		len = bVertical ? Height : Width,
		x, y;

	if( iDirection==SB_LINEUP ){
		if( bVertical ){
			pPic = u_pPicLineUp;
			x = - iState * wid;
			y = 0;
		}
		else{
			pPic = u_pPicLineLeft;
			x = 0;
			y = - iState * wid;
		}
	}
	else {
		if( bVertical ){
			pPic = u_pPicLineDown;
			x = - iState * wid;
			y = len - wid;
		}
		else{
			pPic = u_pPicLineRight;
			x = len - wid;
			y =  - iState * wid;
		}
	}

	if( wid==pPic->Width/3 )
		m_pCanvas->Draw( x, y, pPic );
	else{
		TRect tmpRect;

		if( bVertical ){
			tmpRect.Left = x;
			tmpRect.Right = tmpRect.Left + wid*3;
			tmpRect.Top = y;
			tmpRect.Bottom = tmpRect.top + wid;
		}
		else{
			tmpRect.Left = x;
			tmpRect.Right = tmpRect.Left + wid;
			tmpRect.Top = y;
			tmpRect.Bottom = tmpRect.top + wid*3;
		}

		m_pCanvas->StretchDraw( tmpRect, pPic);
	}
}
//---------------------------------------------------------------------------

void TSkinScrollBar::DrawThumb( int iState, bool bEraseBk, int iPageUD )
{
	bool bVertical = Kind==sbVertical;

	TRect rectDraw;
	int wid = bVertical ? Width : Height,
		len = bVertical ? Height : Width;

	LONG &rFixBegin = bVertical ? rectDraw.Left : rectDraw.Top,
		 &rFixEnd 	= bVertical ? rectDraw.Right : rectDraw.Bottom,
		&rVarBegin 	= bVertical ? rectDraw.Top : rectDraw.Left,
		&rVarEnd 	= bVertical ? rectDraw.Bottom : rectDraw.Right;

	//===========================
	//绘制 轨道

	rFixBegin = PIXEL_EXTERNAL_FRAME;
	rFixEnd = wid - rFixBegin;//rectDraw.Left;

	//绘制 上/左轨道
//	if(iPageUD == SB_PAGEUP || iState== STATE_PUSH ){
		m_pCanvas->Brush->Color = RGB_EXTERNAL_HIG;
		m_pCanvas->Pen->Color   = RGB_EXTERNAL_HIG;
//	}else {
//		m_pCanvas->Brush->Color = RGB_EXTERNAL_NOR;
//		m_pCanvas->Pen->Color   = RGB_EXTERNAL_NOR;
//	}

	if( bEraseBk )                        //重绘轨道
		rVarBegin = wid;
	else if( m_nPreThumbPos<m_nThumbPos ) //滚动条往下/右滑动
		rVarBegin = m_nPreThumbPos;
	else                                  //滚动条往上/左滑动
		rVarBegin = wid;

	if( rVarBegin<m_nThumbPos ){
		rVarEnd = m_nThumbPos;

		m_pCanvas->Rectangle(rectDraw.Left,  rectDraw.Top,
							 rectDraw.Right, rectDraw.Bottom);
	}

	//绘制 下/右轨道
//	if( iPageUD==SB_PAGEDOWN || iState==STATE_PUSH ){
		m_pCanvas->Brush->Color = RGB_EXTERNAL_HIG;
		m_pCanvas->Pen->Color   = RGB_EXTERNAL_HIG;
//	}else {
//		m_pCanvas->Brush->Color = RGB_EXTERNAL_NOR;
//		m_pCanvas->Pen->Color   = RGB_EXTERNAL_NOR;
//	}

	rVarBegin = m_nThumbPos + m_nThumbSize;

	if( bEraseBk )
		rVarEnd = len - wid;
	else if( m_nPreThumbPos>m_nThumbPos ){  //如果向上/左，则为当前滑动块底部的值
		rVarEnd = m_nThumbSize + m_nPreThumbPos;
		if( rVarEnd > len-wid )
			rVarEnd = len - wid;
	}else
		rVarEnd = len - wid;   //如果向下/右，则为当前滑动块底部的值

	if( rVarEnd > rVarBegin ){
		m_pCanvas->Rectangle(rectDraw.Left,  rectDraw.Top,
							 rectDraw.Right, rectDraw.Bottom);
	}

	//===========================
	//绘制 滑块
	if( m_nThumbSize>0 ){
		//===========================
		//绘制 滑块左右/上下区域
		if( iState==STATE_NORMAL || iState == STATE_HIGHLIGHT ){
			m_pCanvas->Brush->Color = RGB_EXTERNAL_NOR;
			m_pCanvas->Pen->Color   = RGB_EXTERNAL_NOR;
		}else if( iState== STATE_PUSH ){
			m_pCanvas->Brush->Color = RGB_EXTERNAL_HIG;
			m_pCanvas->Pen->Color   = RGB_EXTERNAL_HIG;
		}

		rVarBegin = m_nThumbPos;
		rVarEnd = m_nThumbPos + m_nThumbSize;

		//左/上区域
		rFixBegin   = PIXEL_EXTERNAL_FRAME;
		rFixEnd  = rFixBegin + PIXEL_EX2INTERNAL;
		m_pCanvas->Rectangle(rectDraw.Left,  rectDraw.Top,
							 rectDraw.Right, rectDraw.Bottom);
		//右/下区域
		rFixBegin  = wid - PIXEL_EXTERNAL_FRAME-PIXEL_EX2INTERNAL;
		rFixEnd = wid - PIXEL_EXTERNAL_FRAME;
		m_pCanvas->Rectangle(rectDraw.Left,  rectDraw.Top,
							 rectDraw.Right, rectDraw.Bottom);

		//===========================
		//绘制 滑块矩形区域
		if(iState == STATE_NORMAL){
			m_pCanvas->Brush->Color = RGB_INTERNAL_NOR;
			m_pCanvas->Pen->Color   = RGB_INTERNAL_NOR;
		}else if(iState == STATE_HIGHLIGHT){
			m_pCanvas->Brush->Color = RGB_INTERNAL_NOR;//HIG;
			m_pCanvas->Pen->Color   = RGB_INTERNAL_NOR;//HIG;
		}else if(iState == STATE_PUSH){
			m_pCanvas->Brush->Color = RGB_INTERNAL_PUSH;
			m_pCanvas->Pen->Color   = RGB_INTERNAL_PUSH;
		}

		rFixBegin = PIXEL_EXTERNAL_FRAME+PIXEL_EX2INTERNAL+PIXEL_INTERNAL_FARME;
		rFixEnd = wid - rFixBegin;
		rVarBegin    = m_nThumbPos + PIXEL_INTERNAL_BOUND;
		rVarEnd = m_nThumbPos + m_nThumbSize - PIXEL_INTERNAL_BOUND;
		m_pCanvas->Rectangle(rectDraw.Left,  rectDraw.Top,
							 rectDraw.Right, rectDraw.Bottom);

		//add by tj 2013/12/10
		//绘制 滑块矩形区域 横/竖线
		//===========================
		//绘制 滑块矩形区域
	    COLORREF colLine, *colLineTrans, *colLineLight;
		if(iState == STATE_NORMAL){
			colLine       = RGB_INTERNAL_LINE_NOR;
			colLineTrans  = (COLORREF *)RGB_INTERNAL_LINE_NOR_TRANS;
		}else{// if(iState == STATE_HIGHLIGHT){
			colLine       = RGB_INTERNAL_LINE_HIG;
			colLineTrans  = (COLORREF *)RGB_INTERNAL_LINE_HIG_TRANS;
//		}else if(iState == STATE_PUSH){
//			colLine       = RGB_INTERNAL_LINE_PUSH;
//			colLineTrans  = (COLORREF *)RGB_INTERNAL_LINE_PUSH_TRANS;
		}

		int X = rFixBegin + (wid - 2*rFixBegin - PIXEL_INTERNAL_LINE) / 2,
			Y = m_nThumbPos   + m_nThumbSize/2 - 3;

		for(int i=0; i<3; i++){
			int iPixlX  = bVertical ? X : Y+1,
				iPixlY  = bVertical ? Y+1 : X;

			for(int j=0; j<6; j++){
				m_pCanvas->Pixels[iPixlX][iPixlY] = colLineTrans[j];

				if( bVertical )
					iPixlX++;
				else
					iPixlY++;
			}

			iPixlX = bVertical ? X : Y;
			iPixlY = bVertical ? Y : X;
			m_pCanvas->Pen->Color = colLine;
			m_pCanvas->MoveTo(iPixlX,iPixlY);

			if( bVertical )
				iPixlX = wid - iPixlX;
			else
				iPixlY = wid - iPixlY;

			m_pCanvas->LineTo(iPixlX,iPixlY);

			Y += 3;
		}

		//===========================
		//绘制 滑块边框
		m_pCanvas->Brush->Color = RGB_INTERNAL_FRAME_NOR;
		m_pCanvas->Pen->Color   = RGB_INTERNAL_FRAME_NOR;

		rFixBegin   = PIXEL_EXTERNAL_FRAME + PIXEL_EX2INTERNAL;
		rFixEnd  	= wid - (PIXEL_EXTERNAL_FRAME+PIXEL_EX2INTERNAL);
		rVarBegin   = m_nThumbPos;
		rVarEnd 	= m_nThumbPos + m_nThumbSize;
		m_pCanvas->FrameRect( rectDraw );
/*		//左/上边框
		rFixBegin   = PIXEL_EXTERNAL_FRAME + PIXEL_EX2INTERNAL;
		rFixEnd  	= PIXEL_EXTERNAL_FRAME + PIXEL_EX2INTERNAL + PIXEL_INTERNAL_FARME;
		m_pCanvas->Rectangle(rectDraw.Left,  rectDraw.Top,
							 rectDraw.Right, rectDraw.Bottom);
		//右/下边框
		rFixBegin   = wid - (PIXEL_EXTERNAL_FRAME+PIXEL_EX2INTERNAL+PIXEL_INTERNAL_FARME);
		rFixEnd  	= wid - (PIXEL_EXTERNAL_FRAME+PIXEL_EX2INTERNAL);
		m_pCanvas->Rectangle(rectDraw.Left,  rectDraw.Top,
							 rectDraw.Right, rectDraw.Bottom);

		//上/左边框
		rFixBegin   = PIXEL_EXTERNAL_FRAME + PIXEL_EX2INTERNAL + PIXEL_INTERNAL_FARME;
		rFixEnd  	= wid - rFixBegin;
		rVarBegin   = m_nThumbPos;
		rVarEnd 	= m_nThumbPos + PIXEL_INTERNAL_BOUND;
		m_pCanvas->Rectangle(rectDraw.Left,  rectDraw.Top,
							 rectDraw.Right, rectDraw.Bottom);

		//下/右边框
		rVarBegin   = m_nThumbPos + m_nThumbSize-PIXEL_INTERNAL_BOUND;
		rVarEnd 	= m_nThumbPos + m_nThumbSize;
		m_pCanvas->Rectangle(rectDraw.Left,  rectDraw.Top,
							 rectDraw.Right, rectDraw.Bottom);
*/
		//===========================
		//绘制 滑块角
/*		if(iState == STATE_NORMAL){
			m_pCanvas->Pen->Color   = RGB_INTERNAL_ROUND_BKG_N_NOR;
		}else if(iState == STATE_HIGHLIGHT ){
			m_pCanvas->Pen->Color   = RGB_INTERNAL_ROUND_BKG_N_HIG;
		}else if( iState == STATE_PUSH){
			m_pCanvas->Pen->Color   = RGB_INTERNAL_ROUND_BKG_H_HIG;
		}

		//左上角
		rFixBegin  	= PIXEL_EXTERNAL_FRAME + PIXEL_EX2INTERNAL;
		rVarBegin   = m_nThumbPos;
		m_pCanvas->Pixels[rectDraw.Left][rectDraw.Top] = m_pCanvas->Pen->Color;

		//左下角
		rVarBegin   = m_nThumbPos + m_nThumbSize - PIXEL_INTERNAL_BOUND;
		m_pCanvas->Pixels[rectDraw.Left][rectDraw.Top] = m_pCanvas->Pen->Color;

		//右上角
		rFixBegin  	= Width - (PIXEL_EXTERNAL_FRAME+PIXEL_EX2INTERNAL+PIXEL_INTERNAL_BOUND);
		rVarBegin   = m_nThumbPos;
		m_pCanvas->Pixels[rectDraw.Left][rectDraw.Top] = m_pCanvas->Pen->Color;

		//右下角
		rVarBegin   = m_nThumbPos + m_nThumbSize - PIXEL_INTERNAL_BOUND;
		m_pCanvas->Pixels[rectDraw.Left][rectDraw.Top] = m_pCanvas->Pen->Color;
*/
	}

	m_nPreThumbPos = m_nThumbPos;
}
//---------------------------------------------------------------------------

void TSkinScrollBar::DrawBound()
{
	bool bVertical = Kind==sbVertical;
	TRect rectDraw;
	int wid = bVertical ? Width : Height,
		len = bVertical ? Height : Width;
	LONG &rFixBegin = bVertical ? rectDraw.Left : rectDraw.Top,
		 &rFixEnd 	= bVertical ? rectDraw.Right : rectDraw.Bottom,
		 &rVarBegin = bVertical ? rectDraw.Top : rectDraw.Left,
		 &rVarEnd 	= bVertical ? rectDraw.Bottom : rectDraw.Right;


	m_pCanvas->Brush->Color = RGB_EXTERNAL_FRAME;
	m_pCanvas->Pen->Color   = RGB_EXTERNAL_FRAME;

	rVarBegin	= wid;
	rVarEnd 	= len - wid;

	rFixBegin   = 0;
	rFixEnd  	= rFixBegin + PIXEL_EXTERNAL_FRAME;
	m_pCanvas->Rectangle(rectDraw.Left,  rectDraw.Top,
						 rectDraw.Right, rectDraw.Bottom);

	rFixBegin   = wid - PIXEL_EXTERNAL_FRAME;
	rFixEnd  	= wid;
	m_pCanvas->Rectangle(rectDraw.Left,  rectDraw.Top,
						 rectDraw.Right, rectDraw.Bottom);
}
//---------------------------------------------------------------------------

void __fastcall TSkinScrollBar::PaintWindow(HDC DC)
{
	if( !m_pCanvas->Handle )
		m_pCanvas->Handle = DC;

	// 绘制上/左箭头
	int iState = m_iHitPrev==SB_LINEUP ? STATE_HIGHLIGHT : STATE_NORMAL;
	DrawArrow( SB_LINEUP, iState );

	// 绘制滑块
	iState = m_iHitPrev==SB_THUMBTRACK ? STATE_HIGHLIGHT : STATE_NORMAL;
	DrawThumb( iState, true );

	// 绘制下/右箭头
	iState = m_iHitPrev==SB_LINEDOWN ? STATE_HIGHLIGHT : STATE_NORMAL;
	DrawArrow( SB_LINEDOWN, iState );

	//绘制 外面左右/上下边框
	DrawBound();
}
//---------------------------------------------------------------------------

void __fastcall TSkinScrollBar::WMPaint(TWMPaint &Message)
{
	PaintHandler(Message);
}
//---------------------------------------------------------------------------

void __fastcall TSkinScrollBar::SetPosition(int Value, bool bRedraw)
{
	if( m_nPos!=Value ){
		m_nPos = Value;

		CalcThumbPos();
		if( bRedraw ) DrawThumb( STATE_NORMAL, false );
	}
}
//---------------------------------------------------------------------------

void __fastcall TSkinScrollBar::SetPageSize(int Value, bool bRedraw)
{
	if( m_nPage!=Value ){
		m_nPage = Value;

		CalcThumbSize();
		if( bRedraw ){
			DrawThumb( STATE_NORMAL, true );
			Invalidate();
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TSkinScrollBar::SetRange(int AMin, int AMax, bool bRedraw)
{
	if( m_nMin!=AMin || m_nMax!=AMax ){
		m_nMin = AMin;
		m_nMax = AMax;

		CalcThumbSize();
		if( bRedraw ){
			DrawThumb( STATE_NORMAL, true );
			Invalidate();
		}
	}
}
//---------------------------------------------------------------------------

int __fastcall TSkinScrollBar::GetScrollPos()
{
	return m_nPos;
}
//---------------------------------------------------------------------------

void __fastcall TSkinScrollBar::GetScrollRange(int* nMin, int* nMax)
{
	*nMin = m_nMin;
	*nMax = m_nMax;
}
//---------------------------------------------------------------------------

int __fastcall TSkinScrollBar::GetPageSize()
{
	return m_nPage;
}
//---------------------------------------------------------------------------

void __fastcall TSkinScrollBar::WMLButtonDown(TWMMouse &Message)
{
	SetCapture(Handle);

	m_bAction = true;
	m_pWndCtrl->SetFocus();

	bool bVertical = Kind==sbVertical;
	int iHit = HitTest( Message.XPos, Message.YPos );

	if( iHit==SB_THUMBTRACK ){
		m_bDrag = TRUE;
		m_nDragPoint = bVertical ? Message.YPos : Message.XPos;
		m_nDragPos = m_nPos;
		m_nTrackPos = m_nDragPos;
		DrawThumb( STATE_PUSH, false );
	}
	else{
		m_iClicked = iHit;
		if( m_pWndCtrl )
			m_pWndCtrl->Perform( bVertical ? WM_VSCROLL : WM_HSCROLL,
									MAKELONG(m_iClicked,0), LPARAM(Handle) );

		m_pTimer->Interval = TIME_DELAY;
		m_pTimer->Enabled = true;
		m_bPause = false;

		int nNewPos = m_nPos;
		if( iHit==SB_LINEUP || iHit==SB_LINEDOWN ){
			DrawArrow( iHit, STATE_PUSH );
			nNewPos += (iHit==SB_LINEUP) ? -1 : 1;
		}
		else if( iHit==SB_PAGEUP || iHit==SB_PAGEDOWN ){
			nNewPos += (iHit==SB_PAGEUP) ? -m_nPage : m_nPage;
		}

		int nLenInSi = m_nMax-m_nMin-m_nPage+1;
		if( nNewPos<m_nMin )
			nNewPos = m_nMin;
		else if( nNewPos>nLenInSi )
			nNewPos = nLenInSi;

		if( nNewPos!=m_nPos ){
		   m_nPos = nNewPos;
		   CalcThumbPos();
		   //add by tj 2013/11/14
		   DrawThumb( STATE_NORMAL, false, iHit );
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TSkinScrollBar::WMLButtonUp(TWMMouse &Message)
{
	ReleaseCapture();

	if( m_bDrag ){
		m_bDrag = false;
		m_pWndCtrl->Perform( Kind==sbVertical ? WM_VSCROLL : WM_HSCROLL,
							 MAKELONG(SB_THUMBPOSITION, m_nTrackPos), LPARAM(Handle) );
		if( m_nTrackPos!=m_nPos ){
			m_nPos = m_nTrackPos;
		}

		m_nTrackPos = 0;
		CalcThumbPos();

		int iHit = HitTest( Message.XPos, Message.YPos );
		if( iHit==SB_THUMBTRACK )
			DrawThumb( STATE_HIGHLIGHT, false );
		else
			DrawThumb( STATE_NORMAL, false );
	}
	else if( m_iClicked!=-1 ){
		m_pTimer->Enabled = false;
		if( m_bNotify ){
			m_bNotify = false;
		}

		if( m_iClicked==SB_LINEUP || m_iClicked==SB_LINEDOWN )
			DrawArrow( m_iClicked, STATE_NORMAL );

		//add by tj 2013/11/14
		if( m_iClicked==SB_PAGEUP || m_iClicked==SB_PAGEDOWN )
			DrawThumb( STATE_NORMAL, false);

		m_iClicked = -1;
	}

	m_bAction = false;
}
//---------------------------------------------------------------------------

void __fastcall TSkinScrollBar::WMLButtonDblClk(TWMMouse &Message)
{
	int uHit = HitTest( Message.XPos, Message.YPos );
	if( uHit!=SB_THUMBTRACK ){
		m_iClicked = uHit;

		WMLButtonDown( Message );
		m_bAction = false;
	}
}
//---------------------------------------------------------------------------

void __fastcall TSkinScrollBar::WMMouseMove(TWMMouse &Message)
{
	Commctrl::TTrackMouseEvent tme;
	if( !m_bTrace && (Message.Keys & MK_LBUTTON) ){
		tme.cbSize = sizeof(tme);
		tme.hwndTrack = Handle;
		tme.dwFlags = TME_LEAVE;
		tme.dwHoverTime = 1;
		m_bTrace = _TrackMouseEvent(&tme);
	}

	if( m_bDrag ){
		bool bVertical = Kind==sbVertical;
		int nDragLen = (bVertical ? Message.YPos : Message.XPos) - m_nDragPoint,
			nTrackLen = (bVertical ? Height-2*Width : Width-2*Height) - m_nThumbSize,
			nLenInSi = m_nMax - m_nMin - m_nPage + 1,
			nSlide = nTrackLen==0 ? 0 : nDragLen * nLenInSi / nTrackLen,
			nNewPos = m_nDragPos + nSlide;

		if( nNewPos<m_nMin )
			nNewPos = m_nMin;
		else if( nNewPos>nLenInSi )
			nNewPos = nLenInSi;

		if( nNewPos!=m_nTrackPos ){
		   m_nTrackPos = nNewPos;
		   CalcThumbPos();
		   DrawThumb( STATE_PUSH, false );
		   m_pWndCtrl->Perform( bVertical ? WM_VSCROLL : WM_HSCROLL,
								MAKELONG(SB_THUMBTRACK, m_nTrackPos), LPARAM(Handle) );
		}
	}
	else if( m_iClicked!=-1 ){
		int iState,
			iHit = HitTest( Message.XPos, Message.YPos );
		if( iHit==m_iClicked ){
			m_bPause = false;
			iState = STATE_PUSH; //add by tj 2013/11/18
		}
		else{
			m_bPause = true;
			iState = STATE_NORMAL;
		}

		if( m_iClicked==SB_LINEUP || m_iClicked==SB_LINEDOWN )
			  DrawArrow( m_iClicked, iState );
	}
	else{
		int iHit = HitTest( Message.XPos, Message.YPos );
		if( iHit!=m_iHitPrev ){
			if( m_iHitPrev!=-1 ){
				if( m_iHitPrev==SB_THUMBTRACK )
					DrawThumb( STATE_NORMAL, FALSE );
				else if( m_iHitPrev==SB_LINEUP || m_iHitPrev==SB_LINEDOWN )
					DrawArrow( m_iHitPrev, STATE_NORMAL );
			}

			if( iHit!=-1 ){
				if( iHit==SB_THUMBTRACK )
					DrawThumb( STATE_HIGHLIGHT, FALSE );
				else if( iHit==SB_LINEUP || iHit==SB_LINEDOWN )
					DrawArrow( iHit, STATE_HIGHLIGHT );
			}

			m_iHitPrev = iHit;
		}
	}
}

//---------------------------------------------------------------------------

void __fastcall TSkinScrollBar::CMMouseEnter(TObject *Sender)
{
	TPoint pt( Mouse->CursorPos.x, Mouse->CursorPos.y );
	pt = ScreenToClient( pt );

	int iHit = HitTest( pt.x, pt.y );
	if( iHit!=-1 ){
		if( iHit==SB_THUMBTRACK )
			DrawThumb( STATE_HIGHLIGHT, FALSE );
		else if( iHit==SB_LINEUP || iHit==SB_LINEDOWN )
			DrawArrow( iHit, STATE_HIGHLIGHT );

		m_iHitPrev = iHit;
	}
}
//---------------------------------------------------------------------------

void __fastcall TSkinScrollBar::CMMouseLeave(TObject *Sender)
{
	if( m_iHitPrev!=-1 ){
		if( m_iHitPrev==SB_THUMBTRACK )
			DrawThumb( STATE_NORMAL, false );
		else if( m_iHitPrev==SB_LINEUP || m_iHitPrev==SB_LINEDOWN )
			DrawArrow( m_iHitPrev, STATE_NORMAL );

		m_iHitPrev = -1;
	}
}
//---------------------------------------------------------------------------

void __fastcall TSkinScrollBar::TimerProc(TObject* Sender)
{
	if( m_pTimer->Interval==TIME_DELAY ){
		m_bNotify = true;

		m_pTimer->Enabled = false;
		m_pTimer->Interval = TIME_NOTIFY;
		m_pTimer->Enabled = true;
	}
	else if( m_pTimer->Interval==TIME_NOTIFY && !m_bPause ){
		int nNewPos = m_nPos;
		//add by tj 2013/11/14
		bool bPageUD = false;
		int iHit;

		switch( m_iClicked ){
			case SB_LINEUP:
				nNewPos -= 1;
				if( m_nPos==m_nMin ){
					m_pTimer->Enabled = false;
					return;
				}
				break;

			case SB_LINEDOWN:
				nNewPos += 1;
				if( m_nPos==m_nMax ){
					m_pTimer->Enabled = false;
					return;
				}
				break;

			case SB_PAGEUP:
			case SB_PAGEDOWN:
				{
					TPoint pt;
					GetCursorPos(&pt);
					pt = ScreenToClient(pt);

					iHit = HitTest( pt.X, pt.Y );
					if( iHit==SB_THUMBTRACK ){
						m_pTimer->Enabled = false;
						return;
					}
					nNewPos += (m_iClicked==SB_PAGEUP) ? -m_nPage+1 : m_nPage-1;
					bPageUD = true;
				}
				break;
		}

		int nLenInSi = m_nMax-m_nMin-m_nPage+1;
		if( nNewPos<m_nMin )
			nNewPos = m_nMin;
		else if( nNewPos>nLenInSi )
			nNewPos = nLenInSi;

		if( nNewPos!=m_nPos ){
		   m_nPos = nNewPos;
		   CalcThumbPos();
		   //add by tj 2013/11/14
		   if(bPageUD)
				DrawThumb( STATE_NORMAL, false, iHit );
		   else
            	DrawThumb( STATE_NORMAL, false );
		}

		m_pWndCtrl->Perform( Kind==sbVertical ? WM_VSCROLL : WM_HSCROLL,
							MAKELONG(m_iClicked,0), LPARAM(Handle) );
	}
}
//---------------------------------------------------------------------------

