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

📄 coolsblib.c

📁 功能强大的自制滚动条
💻 C
📖 第 1 页 / 共 2 页
字号:
	//nMax-nMin must not be greater than MAXLONG
	mysi->nMin = nMinPos;
	mysi->nMax = nMaxPos;
	
	if(fRedraw)
		RedrawNonClient(hwnd, FALSE);

	return TRUE;
}

//
//	Show or hide the specified scrollbars
//
BOOL WINAPI CoolSB_ShowScrollBar (HWND hwnd, int wBar, BOOL fShow)
{
	SCROLLBAR *sbar;
	BOOL bFailed = FALSE;
	DWORD dwStyle = GetWindowLong(hwnd, GWL_STYLE);

	if(!CoolSB_IsCoolScrollEnabled(hwnd))
		return ShowScrollBar(hwnd, wBar, fShow);

	if((wBar == SB_HORZ || wBar == SB_BOTH) && 
	   (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ)))
	{
		sbar->fScrollFlags  =  sbar->fScrollFlags & ~CSBS_VISIBLE;
		sbar->fScrollFlags |= (fShow == TRUE ? CSBS_VISIBLE : 0);
		//bFailed = TRUE;

		if(fShow)	SetWindowLong(hwnd, GWL_STYLE, dwStyle | WS_HSCROLL);
		else		SetWindowLong(hwnd, GWL_STYLE, dwStyle & ~WS_HSCROLL);
	}

	if((wBar == SB_VERT || wBar == SB_BOTH) && 
	   (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT)))
	{
		sbar->fScrollFlags  =  sbar->fScrollFlags & ~CSBS_VISIBLE;
		sbar->fScrollFlags |= (fShow == TRUE ? CSBS_VISIBLE : 0);
		//bFailed = TRUE;

		if(fShow)	SetWindowLong(hwnd, GWL_STYLE, dwStyle | WS_VSCROLL);
		else		SetWindowLong(hwnd, GWL_STYLE, dwStyle & ~WS_VSCROLL);
	}

	if(bFailed)
	{
		return FALSE;
	}
	else
	{
		//DWORD style = GetWindowLong(hwnd, GWL_STYLE);
		//style |= WS_VSCROLL;
		
		//if(s
		//SetWindowLong(hwnd, GWL_STYLE, style);

		SetWindowPos(hwnd, 0, 0, 0, 0, 0, 
			SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | 
			SWP_NOACTIVATE | SWP_FRAMECHANGED);
		
		return TRUE;
	}
}

//
//	Remove cool scrollbars from the specified window.
//
HRESULT WINAPI UninitializeCoolSB(HWND hwnd)
{
	int i = 0;
	SCROLLWND *sw = GetScrollWndFromHwnd(hwnd);
	if(!sw) return E_FAIL;

	//restore the window procedure with the original one
	SetWindowLong(hwnd, GWL_WNDPROC, (LONG)sw->oldproc);

	RemoveProp(hwnd, szPropStr);
	//SetWindowLong(hwnd, GWL_USERDATA, 0);

	//finally, release the memory needed for the cool scrollbars
	HeapFree(GetProcessHeap(), 0, sw);

    //Force WM_NCCALCSIZE and WM_NCPAINT so the original scrollbars can kick in
    RedrawNonClient(hwnd, TRUE);

	return S_OK;
}

#ifdef INCLUDE_BUTTONS

//
//	Cool scrollbar specific interface (BUTTON support)
//

//
//	Insert a button into the scrollbar area
//
//	wSBflags - SB_HORZ / SB_VERT only
//	uPos     - position into which to insert.
//				can be 0 to insert at the start, or -1 to insert
//				at the end of previously inserted buttons
//

BOOL WINAPI CoolSB_InsertButton(HWND hwnd, int wSBflags, UINT nPos, SCROLLBUT *psb)
{
	SCROLLBAR *sbar;
	SCROLLBUT *sbut;
	UINT i;

	if(!psb) return FALSE;

	if(!(sbar = GetScrollBarFromHwnd(hwnd, wSBflags)))
		return FALSE;
	
	//check that we havn't reached the maximum allowed buttons yet
	if(sbar->nButtons == MAX_COOLSB_BUTS)
		return FALSE;

	//insert at end
	if(nPos == -1)
	{
		sbut = &sbar->sbButtons[sbar->nButtons];
	}
	//otherwise, need to make room
	else if((int)nPos < 0 || (int)nPos > (UINT)sbar->nButtons)
	{
		return FALSE;
	}
	else
	{
		//insert space for the button at the specified position
		for(i = sbar->nButtons; i > nPos; i--)
		{
			sbar->sbButtons[i] = sbar->sbButtons[i-1];
		}

		sbut = &sbar->sbButtons[nPos];
	}

	//only set the button's properties if they are
	//specified by the SCROLLBUT->fMask. 
	//Otherwise, use a default property value

	if(psb->fMask & SBBF_TYPE)
		sbut->uButType   = psb->uButType;
	else
		sbut->uButType	 = SBBT_PUSHBUTTON;

	if(psb->fMask & SBBF_STATE)
		sbut->uState	 = psb->uState;
	else
		sbut->uState	 = 0;

	if(psb->fMask & SBBF_ID)
		sbut->uCmdId     = psb->uCmdId;
	else
		sbut->uCmdId	 = 0;

	if(psb->fMask & SBBF_SIZE)
		sbut->nSize		 = psb->nSize;
	else
		sbut->nSize		 = -1;

	if(psb->fMask & SBBF_PLACEMENT)
		sbut->uPlacement = psb->uPlacement;
	else
		sbut->uPlacement = SBBP_LEFT;

	if(psb->fMask & SBBF_BITMAP)
		sbut->hBmp		 = psb->hBmp;
	else
		sbut->hBmp		 = 0;

	if(psb->fMask & SBBF_ENHMETAFILE)
		sbut->hEmf		 = psb->hEmf;
	else
		sbut->hEmf		 = 0;

	if(psb->fMask & SBBF_CURSOR)
		sbut->hCurs = psb->hCurs;
	else
		sbut->hCurs = 0;

	/*
		We don't use the callback function anymore. The uButType
		member must now specify SBBT_OWNERDRAW, and a WM_NOTIFY will
		be sent when a button must be drawn
	if((psb->fMask & SBBF_OWNERDRAW) && ((psb->uButType & SBBT_MASK) == SBBT_OWNERDRAW))
		pDrawProc	 = psb->pDrawProc;
	else
		pDrawProc	 = 0;*/

	sbar->nButtons++;
	sbut->nSizeReserved = sbut->nSize;

	//MAKE SURE that any resizable buttons are only to the left / above
	//a scrollbar. We don't support resize operations to the right of a scrollbar
	if((sbut->uButType & SBBM_RESIZABLE) &&	sbut->uPlacement == SBBP_RIGHT)
		sbut->uButType &= ~SBBM_RESIZABLE;

	if(psb->fMask & SBBF_BUTMINMAX)
	{
		sbut->nMinSize = psb->nMinSize;
		sbut->nMaxSize = psb->nMaxSize;
	}
	else
	{
		sbut->nMinSize = 0;
		sbut->nMaxSize = -1;
	}

	return TRUE;
}

static SCROLLBUT *GetButtonFromId(SCROLLBAR *sbar, UINT uCmdId)
{
	int i;
	for(i = 0; i < sbar->nButtons; i++)
	{
		if(sbar->sbButtons[i].uCmdId == uCmdId)
			return &sbar->sbButtons[i];
	}

	return 0;
}

//
//	Modify the properties of the specified scrollbar button.
//	wSBflags - SB_HORZ / SB_VERT only
//	uItem    - the command identifier specified when the button was created,
//			   or a non-negative position of the button, depending on if
//			   fByCmd is FALSE or TRUE, respectively
//
BOOL WINAPI CoolSB_ModifyButton (HWND hwnd, int wSBflags, UINT uItem, BOOL fByCmd, SCROLLBUT *psb)
{
	SCROLLBAR *sbar;
	SCROLLBUT *sbut;

	if(!psb) return FALSE;

	//find if this window is CoolScroll enabled
	if(!(sbar = GetScrollBarFromHwnd(hwnd, wSBflags)))
		return FALSE;

	//find the button to modify, depending on if we
	//are modifying by position or command id
	if(fByCmd == FALSE)
	{
		//button from position
		if((int)uItem < 0 || (int)uItem >= (UINT)sbar->nButtons)
			return FALSE;
		else
			sbut = &sbar->sbButtons[uItem];
	}
	else if(fByCmd == TRUE)
	{
		//button from command identifier
		if(!(sbut = GetButtonFromId(sbar, uItem)))
			return FALSE;
	}

	if(psb->fMask & SBBF_TYPE)			sbut->uButType   = psb->uButType;
	if(psb->fMask & SBBF_STATE)			sbut->uState	 = psb->uState;
	if(psb->fMask & SBBF_ID)			sbut->uCmdId     = psb->uCmdId;
	if(psb->fMask & SBBF_SIZE)			sbut->nSize		 = psb->nSize;
	if(psb->fMask & SBBF_PLACEMENT)		sbut->uPlacement = psb->uPlacement;
	if(psb->fMask & SBBF_BITMAP)		sbut->hBmp		 = psb->hBmp;
	if(psb->fMask & SBBF_ENHMETAFILE)	sbut->hEmf		 = psb->hEmf;
	if(psb->fMask & SBBF_CURSOR)		sbut->hCurs		 = psb->hCurs;
	
	if(psb->fMask & SBBF_BUTMINMAX)
	{
		sbut->nMinSize = psb->nMinSize;
		sbut->nMaxSize = psb->nMaxSize;
	}

	return TRUE;
}

BOOL WINAPI CoolSB_RemoveButton(HWND hwnd, int wSBflags, UINT uItem, BOOL fByCmd)
{
	int i;
	SCROLLBAR *sbar;

	//find if this window is CoolScroll enabled
	if(!(sbar = GetScrollBarFromHwnd(hwnd, wSBflags)))
		return FALSE;

	//find the button to modify, depending on if we
	//are modifying by position or command id
	if(fByCmd == FALSE && ((int)uItem < 0 || (int)uItem >= (UINT)sbar->nButtons))
	{
		return FALSE;
	}
	else if(fByCmd == TRUE)
	{
		//find the button with the specified command id
		for(i = 0; i < sbar->nButtons; i++)
		{
			if(sbar->sbButtons[i].uCmdId == uItem)
			{
				//change the id to an index
				uItem = i;
				break;
			}
		}

		//if we failed to find the button...
		if(i == sbar->nButtons) return FALSE;
	}

	//remove the button!
	for(i = uItem; i < sbar->nButtons - 1; i++)
	{
		sbar->sbButtons[i] = sbar->sbButtons[i+1];
	}

	sbar->nButtons--;
	
	RedrawNonClient(hwnd, TRUE);

	return TRUE;
}

//
//	fill in the supplied SCROLLBUT structure
//
BOOL WINAPI CoolSB_GetButton(HWND hwnd, int wSBflags, UINT uItem, BOOL fByCmd, SCROLLBUT *psb)
{
	SCROLLBAR *sbar;
	SCROLLBUT *sbut;

	if(!psb) return FALSE;

	//find if this window is CoolScroll enabled
	if(!(sbar = GetScrollBarFromHwnd(hwnd, wSBflags)))
		return FALSE;

	//find the button to modify, depending on if we
	//are modifying by position or command id
	if(fByCmd == FALSE)
	{
		//button from position
		if((int)uItem < 0 || (int)uItem >= (UINT)sbar->nButtons)
			return FALSE;
		else
			sbut = &sbar->sbButtons[uItem];
	}
	else if(fByCmd == TRUE)
	{
		//button from command identifier
		if(!(sbut = GetButtonFromId(sbar, uItem)))
			return FALSE;
	}

	//copy them across
	*psb = *sbut;

	return FALSE; 
}

#else

BOOL WINAPI CoolSB_InsertButton(HWND hwnd, int wSBflags, UINT nPos,  SCROLLBUT *psb)				{	return FALSE; }
BOOL WINAPI CoolSB_ModifyButton(HWND hwnd, int wSBflags, UINT uItem, BOOL fByCmd, SCROLLBUT *psb)	{	return FALSE; }
BOOL WINAPI CoolSB_RemoveButton(HWND hwnd, int wSBflags, UINT uItem, BOOL fByCmd)					{	return FALSE; }
BOOL WINAPI CoolSB_GetButton   (HWND hwnd, int wSBflags, UINT uItem, BOOL fByCmd, SCROLLBUT *psb)	{	return FALSE; }

#endif //INCLUDE_BUTTONS

//
//	Set the size of the scrollbars
//
BOOL WINAPI CoolSB_SetSize	(HWND hwnd, int wBar, int nLength, int nWidth)
{
	SCROLLBAR *sbar;
	
	if(nLength == 0 || nWidth == 0)
		return FALSE;

	if(nLength < -8 || nWidth < -8)
		return FALSE;

	if(nLength > 256 || nWidth > 256)
		return FALSE;

	if(!GetScrollWndFromHwnd(hwnd))
		return FALSE;

	if((wBar == SB_HORZ || wBar == SB_BOTH) && 
	   (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ)))
	{
		sbar->nArrowLength = nLength;
		sbar->nArrowWidth  = nWidth;
	}

	if((wBar == SB_VERT || wBar == SB_BOTH) && 
	   (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT)))
	{
		sbar->nArrowLength = nLength;
		sbar->nArrowWidth  = nWidth;
	}

	RedrawNonClient(hwnd, TRUE);

	return TRUE;
}


//
//	Alter the display mode of the scrollbars
//	wBar   - SB_HORZ / SB_VERT / SB_BOTH
//	nStyle - CSBF_NORMAL / CSBF_FLAT / CSBF_HOTTRACKED
//
BOOL WINAPI CoolSB_SetStyle(HWND hwnd, int wBar, UINT nStyle)
{
	SCROLLBAR *sbar;

	if(!GetScrollWndFromHwnd(hwnd))
		return FALSE;

	if((wBar == SB_HORZ || wBar == SB_BOTH) && 
	   (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ)))
	{
		sbar->fFlatScrollbar = nStyle;
	}

	if((wBar == SB_VERT || wBar == SB_BOTH) && 
	   (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT)))
	{
		sbar->fFlatScrollbar = nStyle;
	}

	RedrawNonClient(hwnd, FALSE);

	return TRUE;
}

//
//	Set if the thumb is always visible, even if there is no data to
//  scroll. Setting this keeps the scrollbar enabled, but the thumb
//  covers the whole area
//	
BOOL WINAPI CoolSB_SetThumbAlways(HWND hwnd, int wBar, BOOL fThumbAlways)
{
	SCROLLBAR *sbar;

	if(!GetScrollWndFromHwnd(hwnd))
		return FALSE;

	if((wBar == SB_HORZ || wBar == SB_BOTH) && 
	   (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ)))
	{
		if(fThumbAlways)
			sbar->fScrollFlags |=  CSBS_THUMBALWAYS;
		else
			sbar->fScrollFlags &= ~CSBS_THUMBALWAYS;
	}

	if((wBar == SB_VERT || wBar == SB_BOTH) && 
	   (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT)))
	{
		if(fThumbAlways)
			sbar->fScrollFlags |=  CSBS_THUMBALWAYS;
		else
			sbar->fScrollFlags &= ~CSBS_THUMBALWAYS;
	}

	RedrawNonClient(hwnd, FALSE);

	return TRUE;
}

//
//	Set the minimum size, in pixels, that the thumb box will shrink to.
//
BOOL WINAPI CoolSB_SetMinThumbSize(HWND hwnd, UINT wBar, UINT size)
{
	SCROLLBAR *sbar;

	if(!GetScrollWndFromHwnd(hwnd))
		return FALSE;

	if(size == -1)
		size = CoolSB_GetDefaultMinThumbSize();

	if((wBar == SB_HORZ || wBar == SB_BOTH) && 
	   (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ)))
	{
		sbar->nMinThumbSize = size;
	}

	if((wBar == SB_VERT || wBar == SB_BOTH) && 
	   (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT)))
	{
		sbar->nMinThumbSize = size;
	}

	return TRUE;
}

⌨️ 快捷键说明

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