본문 바로가기
kxLibrary

KFC1.0 Class Update For KFCScrollBar

by 두루물 2011. 5. 5.
KRKIM's Foundation Classes Library(KFC)
Bugfix::

-대용량 사이즈(Large size) scroll supported.
-Drawing fixed.

 
RECT KFCScrollBar::GetRect(UINT nSBCode)
{
	SCROLLINFO si = m_si;

	int h = GetHeight();

	if(si.nPage > (UINT) si.nMax)
		si.nPage = si.nMax;

	if(si.nTrackPos==-1) 
		si.nTrackPos = si.nPos;

	//exception overflow Pos
	if(si.nTrackPos + si.nPage > si.nMax){//당 윈도우가 리사이징 되면서 문서편집기의 autowrap등의 여건등에 의해,
		//스크롤 크기가 변하는데 nPos는 그대로이고 nMax만 오히려 줄어든 경우에 해당한다.
		si.nTrackPos = max(0,si.nMax - si.nPage);
	}

	int nHeight = max(0,h - 2 * m_nBmpUnit);//Free Height
	int range = max(1,(si.nMax - si.nMin));
	int	nThumbHeight = si.nPage * nHeight / range;//nHeight : nThumbHeight = Range:nPage

	if(nThumbHeight<THUMB_MINSIZE) 
		nThumbHeight=THUMB_MINSIZE;
	if(nHeight<THUMB_MINSIZE) 
		nThumbHeight=0;
	if((si.nMax-si.nMin-si.nPage+1)==0) 
		nThumbHeight = 0;
	if(si.nMax == 0)
		nThumbHeight = nHeight;
	if(!IsWindowEnabled(m_hWnd))
		nThumbHeight = 0;
	int nEmptyHei = nHeight - nThumbHeight;
	int nArrowHei = (nHeight <= 0) ? (h / 2) : m_nBmpUnit;

	RECT rcItem = {0,0,m_nBmpUnit,nArrowHei};
	RECT rcThumb;
	switch(nSBCode){
		case SB_LINEUP:
			if(!IsVertical()){
				RECT rcItem2;
				SetRect(&rcItem2,rcItem.top,rcItem.left,rcItem.bottom,rcItem.right);
				return rcItem2;
			}
			return rcItem;
		case SB_LINEDOWN:
			rcItem.top = h - nArrowHei;
			rcItem.bottom = h;
			if(!IsVertical()){
				RECT rcItem2;
				SetRect(&rcItem2,rcItem.top,rcItem.left,rcItem.bottom,rcItem.right);
				return rcItem2;
			}
			return rcItem;
		case SB_PAGEUP:
		case SB_THUMBTRACK:
		case SB_PAGEDOWN:
			rcItem.top = rcItem.bottom;
			if(nThumbHeight <= 0)
				rcItem.bottom += nEmptyHei / 2;
			//else{
			//	int r = max(1,si.nMax-si.nMin-si.nPage);//트랙포스의 정상적인 최대위치임
			//	rcItem.bottom += nEmptyHei * si.nTrackPos / r; //트랙포스 영역(r) : 현재위치 = 공백부분 : 오프셋
			//}
			else{
				int r = max(1,si.nMax-si.nMin-si.nPage);//트랙포스의 정상적인 최대위치임
				UINT64 vv = (UINT64)nEmptyHei * (UINT64)si.nTrackPos;
				rcItem.bottom +=  (int)(vv / r); //트랙포스 영역(r) : 트랙포스 현재위치 = 스크롤바 그래픽영역 공백부분 : 스크롤 썸트랙 오프셋
				//r:T = E: ?
				// ? = (T*E)/r
			}
			rcThumb = rcItem;
			//Thumb rect
			rcThumb.top = rcThumb.bottom;   
			rcThumb.bottom += nThumbHeight;
			if(rcThumb.bottom > h - nArrowHei){
				rcThumb.bottom = h - nArrowHei;
				rcThumb.top = rcThumb.bottom - THUMB_MINSIZE;
			}
			if(m_bAutoHideThumb && nEmptyHei <= 0)
				rcThumb.bottom = rcThumb.top;//make Empty rect for non-drawing.

			if(nSBCode == SB_THUMBTRACK)
				rcItem = rcThumb;
			else if(nSBCode == SB_PAGEUP){
				if(rcItem.bottom > rcThumb.top){//check valid area prevent overlapped drawing
			//		rcItem.bottom -= rcItem.bottom - rcThumb.top;//prevent 0,no direct set, so sub diff
				}
			}
			if(nSBCode == SB_PAGEDOWN){
				rcItem.top = rcItem.bottom + nThumbHeight;
				if(m_bAutoHideThumb && nEmptyHei <= 0)
					rcItem.top = rcItem.bottom;//make Empty rect for non-drawing.
				rcItem.bottom = h - nArrowHei;
				if(rcItem.top < rcThumb.bottom){//check valid area prevent overlapped drawing
			//		rcItem.top += rcThumb.bottom - rcItem.top;//prevent 0, no direct set,so add diff
				}

			}
			if(IsVertical())
				return rcItem;
			RECT rcItem2;
			SetRect(&rcItem2,rcItem.top,rcItem.left,rcItem.bottom,rcItem.right);
			return rcItem2;
			break;
	}
	return rcItem;
BOOL KFCScrollBar::OnMouseMove(UINT nFlags,POINT point)
{
	if(!m_bTrace && nFlags != 0xFFFF)
	{
		m_bTrace=TRUE;
		TRACKMOUSEEVENT tme;
		tme.cbSize = sizeof(tme);
		tme.hwndTrack = m_hWnd;
		tme.dwFlags = TME_LEAVE;
		tme.dwHoverTime = 1;
		m_bTrace = _TrackMouseEvent(&tme);
	}

	if(m_bTracking)
	{
		int nInterHei=m_nHeight-2*m_nBmpUnit;
		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_ptTrackingStart.y:point.x-m_ptTrackingStart.x;
		//int nSlide=(nEmptyHei==0)?0:(nDragLen*(int)(m_si.nMax-m_si.nMin-m_si.nPage+1)/nEmptyHei);
		int nSlide=0;
		if(nEmptyHei > 0){
			UINT64 offpos = (UINT64)nDragLen*((UINT64)(m_si.nMax-m_si.nMin-m_si.nPage+1)/(UINT64)nEmptyHei);
			nSlide = (int)offpos;
		}

		int nNewTrackPos = m_nTrackingPos + 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)
		{
			m_nThumbState = 2;
			HDC hDC=GetDC(m_hWnd);
			RECT rcThumb1=GetRect(SB_THUMBTRACK);
			m_si.nTrackPos=nNewTrackPos;
			RECT rcThumb2=GetRect(SB_THUMBTRACK);

			RECT rcSourSlide=GetImageRect(SB_PAGEUP,0);
			RECT rcSourThumb=GetImageRect(SB_THUMBTRACK,m_nThumbState);
			RECT rcOld;
			if(IsVertical())
			{
				rcOld.left=0,rcOld.right=m_nBmpUnit;
				if(rcThumb2.bottom>rcThumb1.bottom)
				{
					rcOld.top=rcThumb1.top;
					rcOld.bottom=rcThumb2.top;
				}else
				{
					rcOld.top=rcThumb2.bottom;
					rcOld.bottom=rcThumb1.bottom;
				}
			}else
			{
				rcOld.top=0,rcOld.bottom=m_nBmpUnit;
				if(rcThumb2.right>rcThumb1.right)
				{
					rcOld.left=rcThumb1.left;
					rcOld.right=rcThumb2.left;
				}else
				{
					rcOld.left=rcThumb2.right;
					rcOld.right=rcThumb1.right;
				}
			}

			DrawSlider(hDC,rcOld,rcSourSlide);
			DrawThumb(hDC,&rcThumb2,&rcSourThumb);
			ReleaseDC(m_hWnd,hDC);
			if(nFlags & MK_LBUTTON){
				//TRACE("m_si.nTrackPos = %d\n",m_si.nTrackPos);
				//CWnd *parent = GetParent();
				//WM_VSCROLL THUMBTRACK AND THUMBPOSITION only 16bit
				//To EXPAND 32bit
				//KFCScrollBarPanel * pwnd = (KFCScrollBarPanel *)parent;
				SendMessage(::GetParent(m_hWnd),IsVertical()?WM_VSCROLL:WM_HSCROLL,MAKELONG(SB_THUMBTRACK,m_si.nTrackPos),(LPARAM)m_hWnd);
				//if(IsVertical())
				//	pCtrl->SetScrollPos(SB_VERT,m_si.nTrackPos);
				//else//2009.05.19
				//	pCtrl->SetScrollPos(SB_HORZ,m_si.nTrackPos);
			}
		}
	}else if(m_htLeftButton!=-1)
	{
		RECT rc = GetRect(m_htLeftButton);
		m_bPause = !::PtInRect(&rc,point);
		if(m_htLeftButton==SB_LINEUP||m_htLeftButton==SB_LINEDOWN)
		{
			DrawArrow(m_htLeftButton,m_bPause ? 0 : 2);
		}
	}else
	{
		int uHit=HitTest(point);
		if(uHit!=m_htPrevLeftButton)
		{
			if(m_htPrevLeftButton!=-1)
			{
				if(m_htPrevLeftButton==SB_THUMBTRACK)
				{
					m_nThumbState = 0;
					HDC hDC = GetDC(m_hWnd);
					DrawThumbBar(m_nThumbState,hDC);
					ReleaseDC(m_hWnd,hDC);
				}else if(m_htPrevLeftButton==SB_LINEUP||m_htPrevLeftButton==SB_LINEDOWN)
				{
					DrawArrow(m_htPrevLeftButton,0);
				}
			}
			if(uHit!=-1)
			{
				if(uHit==SB_THUMBTRACK)
				{
					m_nThumbState = 1;
					HDC hDC = GetDC(m_hWnd);
					DrawThumbBar(m_nThumbState,hDC);
					ReleaseDC(m_hWnd,hDC);
				}else if(uHit==SB_LINEUP||uHit==SB_LINEDOWN)
				{
					DrawArrow(uHit,1);
				}
			}
			m_htPrevLeftButton=uHit;
		}
	}
	return 1;
}

Download New Updated Class(Full Source Code):

'kxLibrary' 카테고리의 다른 글

KFCApp Class Updated  (0) 2012.04.11
kxBuffLib::kxFile Class Source Code  (0) 2011.10.06
KFC1.0 Class Update For KFCBitmap  (0) 2011.05.05
KFC1.0 Class Update For Thread Safe ResourceHandle  (0) 2010.12.18
KxLibrary로 DLL 만들기  (0) 2010.11.19