⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 coolscroll.c

📁 功能强大的自制滚动条
💻 C
📖 第 1 页 / 共 5 页
字号:

	case HTSCROLL_THUMB: 

		//if the scrollbar is disabled, then do no further processing
		if(!IsScrollbarActive(sb))
			return 0;
		
		GetRealScrollRect(sb, &rect);
		RotateRect0(sb, &rect);
		CalcThumbSize(sb, &rect, &nThumbSize, &nThumbPos);
		RotateRect0(sb, &rect);
		
		//remember the bounding rectangle of the scrollbar work area
		rcThumbBounds = rect;
		
		sw->fThumbTracking = TRUE;
		sb->scrollInfo.nTrackPos = sb->scrollInfo.nPos;
		
		if(wParam == HTVSCROLL) 
			nThumbMouseOffset = pt.y - nThumbPos;
		else
			nThumbMouseOffset = pt.x - nThumbPos;

		nLastPos = -sb->scrollInfo.nPos;
		nThumbPos0 = nThumbPos;
	
		//if(sb->fFlatScrollbar)
		//{
			GetWindowRect(hwnd, &winrect);
			OffsetRect(&rect, -winrect.left, -winrect.top);
			hdc = GetWindowDC(hwnd);
			NCDrawScrollbar(sb, hwnd, hdc, &rect, HTSCROLL_THUMB);
			ReleaseDC(hwnd, hdc);
		//}

		break;

		//Any part of the scrollbar
	case HTSCROLL_LEFT:  
		if(sb->fScrollFlags & ESB_DISABLE_LEFT)		return 0;
		else										goto target1;
	
	case HTSCROLL_RIGHT: 
		if(sb->fScrollFlags & ESB_DISABLE_RIGHT)	return 0;
		else										goto target1;

		goto target1;	

	case HTSCROLL_PAGELEFT:  case HTSCROLL_PAGERIGHT:

		target1:

		//if the scrollbar is disabled, then do no further processing
		if(!IsScrollbarActive(sb))
			break;

		//ajust the horizontal rectangle to NOT include
		//any inserted buttons
		GetRealScrollRect(sb, &rect);

		SendScrollMessage(hwnd, uScrollTimerMsg, uCurrentScrollPortion, 0);

		// Check what area the mouse is now over :
		// If the scroll thumb has moved under the mouse in response to 
		// a call to SetScrollPos etc, then we don't hilight the scrollbar margin
		if(uCurrentScrollbar == SB_HORZ)
			uScrollTimerPortion = GetHorzScrollPortion(sb, hwnd, &rect, pt.x, pt.y);
		else
			uScrollTimerPortion = GetVertScrollPortion(sb, hwnd, &rect, pt.x, pt.y);

		GetWindowRect(hwnd, &winrect);
		OffsetRect(&rect, -winrect.left, -winrect.top);
		hdc = GetWindowDC(hwnd);
			
#ifndef HOT_TRACKING
		//if we aren't hot-tracking, then don't highlight 
		//the scrollbar thumb unless we click on it
		if(uScrollTimerPortion == HTSCROLL_THUMB)
			uScrollTimerPortion = HTSCROLL_NONE;
#endif
		NCDrawScrollbar(sb, hwnd, hdc, &rect, uScrollTimerPortion);
		ReleaseDC(hwnd, hdc);

		//Post the scroll message!!!!
		uScrollTimerPortion = uCurrentScrollPortion;

		//set a timer going on the first click.
		//if this one expires, then we can start off a more regular timer
		//to generate the auto-scroll behaviour
		uScrollTimerId = SetTimer(hwnd, COOLSB_TIMERID1, COOLSB_TIMERINTERVAL1, 0);
		break;
	default:
		return CallWindowProc(sw->oldproc, hwnd, WM_NCLBUTTONDOWN, wParam, lParam);
		//return 0;
	}
		
	SetCapture(hwnd);
	return 0;
}

//
//	Left button released
//
static LRESULT LButtonUp(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lParam)
{
	RECT rect;
	//UINT thisportion;
	HDC hdc;
	POINT pt;
	RECT winrect;
	UINT buttonIdx = 0;
	
	//current scrollportion is the button that we clicked down on
	if(uCurrentScrollPortion != HTSCROLL_NONE)
	{
		SCROLLBAR *sb = &sw->sbarHorz;
		lParam = GetMessagePos();
		ReleaseCapture();

		GetWindowRect(hwnd, &winrect);
		pt.x = LOWORD(lParam);
		pt.y = HIWORD(lParam);

		//emulate the mouse input on a scrollbar here...
		if(uCurrentScrollbar == SB_HORZ)
		{
			//get the total area of the normal Horz scrollbar area
			sb = &sw->sbarHorz;
			GetHScrollRect(sw, hwnd, &rect);
		}
		else if(uCurrentScrollbar == SB_VERT)
		{
			//get the total area of the normal Horz scrollbar area
			sb = &sw->sbarVert;
			GetVScrollRect(sw, hwnd, &rect);
		}

		//we need to do different things depending on if the
		//user is activating the scrollbar itself, or one of
		//the inserted buttons
		switch(uCurrentScrollPortion)
		{
#ifdef INCLUDE_BUTTONS
		//inserted buttons are being clicked
		case HTSCROLL_INSERTED:
			
			//get the rectangle of the ACTIVE button 
			buttonIdx = GetButtonFromPt(sb, &rect, pt, FALSE);
			GetButtonRectFromId(sb, &rect, uCurrentButton);
	
			OffsetRect(&rect, -winrect.left, -winrect.top);

			//Send the notification BEFORE we redraw, so the
			//bitmap can be changed smoothly by the user if they require
			if(uCurrentButton == buttonIdx)
			{
				SCROLLBUT *sbut = &sb->sbButtons[buttonIdx];
				UINT cmdid = sbut->uCmdId;
				
				if((sbut->uButType & SBBT_MASK) == SBBT_TOGGLEBUTTON)
					sbut->uState ^= 1;

				//send a notify??				
				//only post a message if the command id is valid
				if(cmdid != -1 && cmdid > 0)
					SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(cmdid, CSBN_CLICKED), 0);
			
				//user might have deleted this button, so redraw whole area
				NCPaint(sw, hwnd, 1, 0);
			}
			else
			{
				//otherwise, just redraw the button in its new state
				hdc = GetWindowDC(hwnd);
				DrawScrollButton(&sb->sbButtons[uCurrentButton], hdc, &rect, SBBS_NORMAL);
				ReleaseDC(hwnd, hdc);
			}
	
			break;
#endif	// INCLUDE_BUTTONS

		//The scrollbar is active
		case HTSCROLL_LEFT:  case HTSCROLL_RIGHT: 
		case HTSCROLL_PAGELEFT:  case HTSCROLL_PAGERIGHT: 
		case HTSCROLL_NONE:
			
			KillTimer(hwnd, uScrollTimerId);

		case HTSCROLL_THUMB: 
	
			//In case we were thumb tracking, make sure we stop NOW
			if(sw->fThumbTracking == TRUE)
			{
				SendScrollMessage(hwnd, uScrollTimerMsg, SB_THUMBPOSITION, nLastPos);
				sw->fThumbTracking = FALSE;
			}

			//send the SB_ENDSCROLL message now that scrolling has finished
			SendScrollMessage(hwnd, uScrollTimerMsg, SB_ENDSCROLL, 0);

			//adjust the total scroll area to become where the scrollbar
			//really is (take into account the inserted buttons)
			GetRealScrollRect(sb, &rect);
			OffsetRect(&rect, -winrect.left, -winrect.top);
			hdc = GetWindowDC(hwnd);
			
			//draw whichever scrollbar sb is
			NCDrawScrollbar(sb, hwnd, hdc, &rect, HTSCROLL_NORMAL);

			ReleaseDC(hwnd, hdc);
			break;
		}

		//reset our state to default
		uCurrentScrollPortion = HTSCROLL_NONE;
		uScrollTimerPortion	  = HTSCROLL_NONE;
		uScrollTimerId		  = 0;

		uScrollTimerMsg       = 0;
		uCurrentScrollbar     = COOLSB_NONE;

		return 0;
	}
	else
	{
		/*
		// Can't remember why I did this!
		if(GetCapture() == hwnd)
		{
			ReleaseCapture();
		}*/
	}

	return CallWindowProc(sw->oldproc, hwnd, WM_LBUTTONUP, wParam, lParam);
}

//
//	This function is called whenever the mouse is moved and 
//  we are dragging the scrollbar thumb about.
//
static LRESULT ThumbTrackHorz(SCROLLBAR *sbar, HWND hwnd, int x, int y)
{
	POINT pt;
	RECT rc, winrect, rc2;
	COLORREF crCheck1 = GetSBForeColor();
	COLORREF crCheck2 = GetSBBackColor();
	HDC hdc;
	int thumbpos = nThumbPos;
	int pos;
	int siMaxMin = 0;
	UINT flatflag = sbar->fFlatScrollbar ? BF_FLAT : 0;
	BOOL fCustomDraw = FALSE;

	SCROLLINFO *si;
	si = &sbar->scrollInfo;

	pt.x = x;
	pt.y = y;

	//draw the thumb at whatever position
	rc = rcThumbBounds;

	SetRect(&rc2, rc.left -  THUMBTRACK_SNAPDIST*2, rc.top -    THUMBTRACK_SNAPDIST, 
				  rc.right + THUMBTRACK_SNAPDIST*2, rc.bottom + THUMBTRACK_SNAPDIST);

	rc.left +=  GetScrollMetric(sbar, SM_CXHORZSB);
	rc.right -= GetScrollMetric(sbar, SM_CXHORZSB);

	//if the mouse is not in a suitable distance of the scrollbar,
	//then "snap" the thumb back to its initial position
#ifdef SNAP_THUMB_BACK
	if(!PtInRect(&rc2, pt))
	{
		thumbpos = nThumbPos0;
	}
	//otherwise, move the thumb to where the mouse is
	else
#endif //SNAP_THUMB_BACK
	{
		//keep the thumb within the scrollbar limits
		thumbpos = pt.x - nThumbMouseOffset;
		if(thumbpos < rc.left) thumbpos = rc.left;
		if(thumbpos > rc.right - nThumbSize) thumbpos = rc.right - nThumbSize;
	}

	GetWindowRect(hwnd, &winrect);

	if(sbar->nBarType == SB_VERT)
		RotateRect(&winrect);
	
	hdc = GetWindowDC(hwnd);
		
#ifdef CUSTOM_DRAW
	fCustomDraw = PostCustomPrePostPaint(hwnd, hdc, sbar, CDDS_PREPAINT) == CDRF_SKIPDEFAULT;
#endif

	OffsetRect(&rc, -winrect.left, -winrect.top);
	thumbpos -= winrect.left;

	//draw the margin before the thumb
	SetRect(&rc2, rc.left, rc.top, thumbpos, rc.bottom);
	RotateRect0(sbar, &rc2);

	if(fCustomDraw)
		PostCustomDrawNotify(hwnd, hdc, sbar->nBarType, &rc2, SB_PAGELEFT, 0, 0, 0);
	else
		DrawCheckedRect(hdc, &rc2, crCheck1, crCheck2);
	
	RotateRect0(sbar, &rc2);

	//draw the margin after the thumb 
	SetRect(&rc2, thumbpos+nThumbSize, rc.top, rc.right, rc.bottom);
	
	RotateRect0(sbar, &rc2);
	
	if(fCustomDraw)
		PostCustomDrawNotify(hwnd, hdc, sbar->nBarType, &rc2, SB_PAGERIGHT, 0, 0, 0);
	else
		DrawCheckedRect(hdc, &rc2, crCheck1, crCheck2);
	
	RotateRect0(sbar, &rc2);
	
	//finally draw the thumb itelf. This is how it looks on win2000, anyway
	SetRect(&rc2, thumbpos, rc.top, thumbpos+nThumbSize, rc.bottom);
	
	RotateRect0(sbar, &rc2);

	if(fCustomDraw)
		PostCustomDrawNotify(hwnd, hdc, sbar->nBarType, &rc2, SB_THUMBTRACK, TRUE, TRUE, FALSE);
	else
	{

#ifdef FLAT_SCROLLBARS	
		if(sbar->fFlatScrollbar)
			PaintRect(hdc, &rc2, GetSysColor(COLOR_3DSHADOW));
		else
#endif
		{
				DrawBlankButton(hdc, &rc2, flatflag);
		}
	}

	RotateRect0(sbar, &rc2);
	ReleaseDC(hwnd, hdc);

	//post a SB_TRACKPOS message!!!
	siMaxMin = si->nMax - si->nMin;

	if(siMaxMin > 0)
		pos = MulDiv(thumbpos-rc.left, siMaxMin-si->nPage + 1, rc.right-rc.left-nThumbSize);
	else
		pos = thumbpos - rc.left;

	if(pos != nLastPos)
	{
		si->nTrackPos = pos;	
		SendScrollMessage(hwnd, uScrollTimerMsg, SB_THUMBTRACK, pos);
	}

	nLastPos = pos;

#ifdef CUSTOM_DRAW
	PostCustomPrePostPaint(hwnd, hdc, sbar, CDDS_POSTPAINT);
#endif
	
	return 0;
}

//
//	remember to rotate the thumb bounds rectangle!!
//
static LRESULT ThumbTrackVert(SCROLLBAR *sb, HWND hwnd, int x, int y)
{
	//sw->swapcoords = TRUE;
	RotateRect(&rcThumbBounds);
	ThumbTrackHorz(sb, hwnd, y, x);
	RotateRect(&rcThumbBounds);
	//sw->swapcoords = FALSE;

	return 0;
}

//
//	Called when we have set the capture from the NCLButtonDown(...)
//	
static LRESULT MouseMove(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lParam)
{
	RECT rect;
	UINT thisportion;
	HDC hdc;
	static UINT lastportion = 0;
	static UINT lastbutton = 0;
	POINT pt;
	RECT winrect;
	UINT buttonIdx = 0;

	if(sw->fThumbTracking == TRUE)
	{
		int x, y;
		lParam = GetMessagePos();
		x = LOWORD(lParam);
		y = HIWORD(lParam);

		if(uCurrentScrollbar == SB_HORZ)
			return ThumbTrackHorz(&sw->sbarHorz, hwnd, x,y);


		else if(uCurrentScrollbar == SB_VERT)
			return ThumbTrackVert(&sw->sbarVert, hwnd, x,y);
	}

	if(uCurrentScrollPortion == HTSCROLL_NONE)
	{
		return CallWindowProc(sw->oldproc, hwnd, WM_MOUSEMOVE, wParam, lParam);
	}
	else
	{
		LPARAM nlParam;
		SCROLLBAR *sb = &sw->sbarHorz;
		SCROLLBUT *sbut = 0;

		nlParam = GetMessagePos();

		GetWindowRect(hwnd, &winrect);

		pt.x = LOWORD(nlParam);
		pt.y = HIWORD(nlParam);

		//emulate the mouse input on a scrollbar here...
		if(uCurrentScrollbar == SB_HORZ)
		{
			sb = &sw->sbarHorz;
		}
		else if(uCurrentScrollbar == SB_VERT)
		{
			sb = &sw->sbarVert;
		}

		//get the total area of the normal scrollbar area
		GetScrollRect(sw, sb->nBarType, hwnd, &rect);
		
		//see if we clicked in the inserted buttons / normal scrollbar
		//thisportion = GetPortion(sb, hwnd, &rect, LOWORD(lParam), HIWORD(lParam));
		thisportion = GetPortion(sb, hwnd, &rect, pt.x, pt.y);
		
		//we need to do different things depending on if the
		//user is activating the scrollbar itself, or one of
		//the inserted buttons
		switch(uCurrentScrollPortion)
		{
#ifdef INCLUDE_BUTTONS
		//inserted buttons are being clicked
		case HTSCROLL_INSERTED:
			
			//find the index of the button that has been clicked
			//Don't adjust the rectangle though
			buttonIdx = GetButtonFromPt(sb, &rect, pt, FALSE);
						
			//Get the rectangle of the active button
			GetButtonRectFromId(sb, &rect, uCurrentButton);

			//if the button to the LEFT of the current 
			//button is resizable, then resize it
#ifdef RESIZABLE_BUTTONS
			if(uCurrentButton > 0)
			{
				sbut = &sb->sbButtons[uCurrentButton - 1];
			
				//only resize if BOTH buttons are on same side of scrollbar
				if(sbut->uPlacement == (sbut+1)->uPlacement && (sbut->uButType & SBBM_RESIZABLE))
				{
					int oldsize = sbut->nSize;
					int butsize1, butsize2;
					RECT rect2;
					int scrollsize;

					if(uCurrentScrollbar == SB_HORZ)
					{
						rect.left -= GetSingleButSize(sb, sbut);
						sbut->nSize = pt.x - rect.left;
					}
					else
					{
						rect.top -= GetSingleButSize(sb, sbut);
						sbut->nSize = pt.y - rect.top;
					}

					//if(sbut->nSize < 0)	sbut->nSize = 0;
					if(sbut->nSize < (int)sbut->nMinSize)
						sbut->nSize = sbut->nMinSize;

					if((UINT)sbut->nSize > (UINT)sbut->nMaxSize)
						sbut->nSize = sbut->nMaxSize;
					
					GetScrollRect(sw, uCurrentScrollbar, hwnd, &rect2);
					
					if(uCurrentScrollbar == SB_HORZ)
						scrollsize

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -