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

📄 winsbar.2

📁 开放源码实时操作系统源码.
💻 2
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (c) 2000 Greg Haerr <greg@censoft.com>
 * Portions Copyright (c) 1999, 2000, Wei Yongming.
 * jmt: scrollbar thumb ported
 *
 * Microwindows win32 NonClient Scrollbars
 */
#define MWINCLUDECOLORS//jmt: for color macros
#include "windows.h"
#include "wintern.h"
#include "wintools.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>//printf
/* scrollbar status/positions*/
#define SBS_UNKNOWN		0x0000
#define SBS_LEFTARROW		0x0001
#define SBS_RIGHTARROW		0x0002
#define SBS_LEFTSPACE		0x0004
#define SBS_RIGHTSPACE		0x0008
#define SBS_HORZTHUMB		0x0010
#define SBS_UPARROW		0x0020
#define SBS_DOWNARROW		0x0040
#define SBS_UPSPACE		0x0080
#define SBS_DOWNSPACE		0x0100
#define SBS_VERTTHUMB		0x0200
#define SBS_MASK		0x03ff
#define SBS_DISABLED		0x4000
#define SBS_HIDE		0x8000

#define HSCROLLBARVISIBLE(hwnd)	((hwnd)->style & WS_HSCROLL)
#define VSCROLLBARVISIBLE(hwnd)	((hwnd)->style & WS_VSCROLL)

//#

/****************************** Drawing Helpers *******************************/
static void
Draw3DUpFrame(HDC hDC, int l, int t, int r, int b)
{
	RECT	rc;
	HBRUSH	hbr;

	SetRect(&rc, l, t, r, b);
	Draw3dBox(hDC, rc.left, rc.top,
		rc.right-rc.left, rc.bottom-rc.top,
		GetSysColor(COLOR_3DLIGHT),
		GetSysColor(COLOR_WINDOWFRAME));
	InflateRect(&rc, -1, -1);
	Draw3dBox(hDC, rc.left, rc.top,
		rc.right-rc.left, rc.bottom-rc.top,
		GetSysColor(COLOR_BTNHIGHLIGHT),
		GetSysColor(COLOR_BTNSHADOW));
	InflateRect(&rc, -1, -1);

	hbr = CreateSolidBrush(LTGRAY);
	FillRect(hDC, &rc, hbr);
	DeleteObject(hbr);
}


/* 
 * Adjust client area smaller if scrollbars visible.
 * Also, compute the NC hittest regions for the scrollbars.
 */
void
MwAdjustNCScrollbars(HWND hwnd)
{
	BOOL	vertbar = VSCROLLBARVISIBLE(hwnd);
        BOOL	horzbar = HSCROLLBARVISIBLE(hwnd);

	if (vertbar) {
		hwnd->clirect.right -= mwSYSMETRICS_CXVSCROLL;
		if (horzbar)
			hwnd->clirect.bottom -= mwSYSMETRICS_CYHSCROLL;
		hwnd->vscroll.rc.left = hwnd->clirect.right;
		hwnd->vscroll.rc.right = hwnd->clirect.right +
			mwSYSMETRICS_CXVSCROLL;
		hwnd->vscroll.rc.top = hwnd->clirect.top;
		hwnd->vscroll.rc.bottom = hwnd->clirect.bottom;
	} else
		SetRectEmpty(&hwnd->vscroll.rc);
	if (horzbar) {
		if (!vertbar)
			hwnd->clirect.bottom -= mwSYSMETRICS_CYHSCROLL;
		hwnd->hscroll.rc.top = hwnd->clirect.bottom;
		hwnd->hscroll.rc.bottom = hwnd->clirect.bottom +
			mwSYSMETRICS_CYHSCROLL;
		hwnd->hscroll.rc.left = hwnd->clirect.left;
		hwnd->hscroll.rc.right = hwnd->clirect.right;
	} else
		SetRectEmpty(&hwnd->hscroll.rc);
}

static int
wndGetBorder(HWND hwnd)
{
	if (hwnd->style & WS_BORDER)  {
		if ((hwnd->style & WS_CAPTION) == WS_CAPTION)
			return mwSYSMETRICS_CXFRAME;
		return mwSYSMETRICS_CXBORDER;
	}
	return 0;
}

static BOOL
wndGetVScrollBarRect (HWND hwnd, RECT* rcVBar)
{
    if (hwnd->style & WS_VSCROLL) {
        rcVBar->left = hwnd->winrect.right - mwSYSMETRICS_CXVSCROLL
                        - wndGetBorder (hwnd);
        rcVBar->right = hwnd->winrect.right - wndGetBorder (hwnd);
        rcVBar->top  = hwnd->clirect.top;
        rcVBar->bottom = hwnd->winrect.bottom - wndGetBorder (hwnd);

        if (hwnd->style & WS_HSCROLL && !(hwnd->hscroll.status & SBS_HIDE))
            rcVBar->bottom -= mwSYSMETRICS_CYHSCROLL;
        
        return TRUE;
    }
    
    return FALSE;
}

static BOOL
wndGetHScrollBarRect (HWND hwnd, RECT* rcHBar)
{
    if (hwnd->style & WS_HSCROLL) {
        rcHBar->top = hwnd->winrect.bottom - mwSYSMETRICS_CYHSCROLL
                        - wndGetBorder (hwnd);
        rcHBar->bottom = hwnd->winrect.bottom - wndGetBorder (hwnd);
        rcHBar->left  = hwnd->clirect.left;
        rcHBar->right = hwnd->winrect.right - wndGetBorder (hwnd);

        if (hwnd->style & WS_VSCROLL && !(hwnd->vscroll.status & SBS_HIDE))
            rcHBar->right -= mwSYSMETRICS_CXVSCROLL;

        return TRUE;
    }
    
    return FALSE;
}

void
MwPaintNCScrollbars(HWND hwnd, HDC hdc)
{
	BOOL	vertbar = VSCROLLBARVISIBLE(hwnd);
        BOOL	horzbar = HSCROLLBARVISIBLE(hwnd);
	BOOL	fGotDC = FALSE;
	RECT	rc,rc2;

	POINT	p3[3];
	int	shrink=2;

        int start = 0;
        RECT rcHBar, rcVBar;


	if (!hdc && (horzbar || vertbar)) {
		hdc = GetWindowDC(hwnd);
		fGotDC = TRUE;
	}

	if (horzbar && vertbar) {
		rc.left = hwnd->clirect.right;
		rc.top = hwnd->clirect.bottom;
		rc.right = rc.left + mwSYSMETRICS_CXVSCROLL;
		rc.bottom = rc.top + mwSYSMETRICS_CYHSCROLL;
		FillRect(hdc, &rc, (HBRUSH)(COLOR_BTNFACE+1));
	}
	if (vertbar) {
		rc = hwnd->vscroll.rc;

		/* bkgnd */
		FillRect(hdc, &rc, (HBRUSH)(COLOR_BTNFACE+1));

		/* up */
		Draw3dUpDownState(hdc, rc.left, rc.top,
			mwSYSMETRICS_CXVSCROLL, mwSYSMETRICS_CYHSCROLL,
			hwnd->vscroll.status & SBS_UPARROW);
		/* down */
		Draw3dUpDownState(hdc, rc.left,rc.bottom-mwSYSMETRICS_CYHSCROLL,
			mwSYSMETRICS_CXVSCROLL, mwSYSMETRICS_CYHSCROLL,
			hwnd->vscroll.status & SBS_DOWNARROW);
#if 1//jmt: draw arrows
		SelectObject(hdc,GetStockObject(BLACK_BRUSH));
		/* up */
		p3[0].x= rc.left + (mwSYSMETRICS_CXVSCROLL/2) - 1;
		p3[0].y= rc.top + 2 + shrink;
		p3[1].x= rc.left + 2 + shrink - 1;
		p3[1].y= rc.top + (mwSYSMETRICS_CYHSCROLL-4) - shrink;
		p3[2].x= rc.left + (mwSYSMETRICS_CXVSCROLL-4) - shrink;
		p3[2].y= rc.top + (mwSYSMETRICS_CYHSCROLL-4) - shrink;
		Polygon(hdc,p3,3);
		/* down */
		p3[0].x= rc.left + (mwSYSMETRICS_CXVSCROLL/2) - 1;
		p3[0].y= rc.bottom - 4 - shrink;
		p3[1].x= rc.left + 2 + shrink - 1;
		p3[1].y= rc.bottom-mwSYSMETRICS_CYHSCROLL + 2 + shrink;
		p3[2].x= rc.left + (mwSYSMETRICS_CXVSCROLL-4) - shrink;
		p3[2].y= rc.bottom-mwSYSMETRICS_CYHSCROLL + 2 + shrink;
		Polygon(hdc,p3,3);
#endif
#if 1
        	// draw moving bar

    		wndGetVScrollBarRect (hwnd, &rcVBar);
    		rcVBar.left -- ;
    		rcVBar.right -- ;

        	start = rcVBar.top + mwSYSMETRICS_CYVSCROLL + hwnd->vscroll.barStart;
                    
        	if (start + hwnd->vscroll.barLen > rcVBar.bottom)
            		start = rcVBar.bottom - hwnd->vscroll.barLen;

		if (hwnd->vscroll.barLen == 0)
			hwnd->vscroll.barLen=rc.bottom-rc.top-(mwSYSMETRICS_CYVSCROLL*2); 
		
		/* bkgnd */
		rc2.left=rc.left; rc2.right=rc.right/*-1*/;
		rc2.top=rc.top+mwSYSMETRICS_CYHSCROLL;
		rc2.bottom=start;
		if (rc2.bottom>rc2.top)
			FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH));   

		rc2.top=start+hwnd->vscroll.barLen;
		rc2.bottom=rc.bottom-mwSYSMETRICS_CYHSCROLL;
		if (rc2.bottom>rc2.top)
			FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH));   

        	Draw3DUpFrame (hdc, rcVBar.left, start, rcVBar.right,
	    		start + hwnd->vscroll.barLen);
#if 0
		printf("barv:(l,t,r,b):(%d,%d,%d,%d)\n",
        		rcVBar.left, start, rcVBar.right,
	    		start + hwnd->vscroll.barLen);
#endif
#endif
	}
	if (horzbar) {
		rc = hwnd->hscroll.rc;

		/* bkgnd */
		FillRect(hdc, &rc, (HBRUSH)(COLOR_BTNFACE+1));

		/* left */
		Draw3dUpDownState(hdc, rc.left, rc.top,
			mwSYSMETRICS_CXVSCROLL, mwSYSMETRICS_CYHSCROLL,
			hwnd->hscroll.status & SBS_LEFTARROW);
		/* right */
		Draw3dUpDownState(hdc, rc.right-mwSYSMETRICS_CXVSCROLL, rc.top,
			mwSYSMETRICS_CXVSCROLL, mwSYSMETRICS_CYHSCROLL,
			hwnd->hscroll.status & SBS_RIGHTARROW);
#if 1//jmt: draw arrows
		SelectObject(hdc,GetStockObject(BLACK_BRUSH));
		/* left */
		p3[0].x= rc.left + 2 + shrink;
		p3[0].y= rc.top + (mwSYSMETRICS_CYHSCROLL/2) ;
		p3[1].x= rc.left + (mwSYSMETRICS_CXVSCROLL-4) - shrink ;
		p3[1].y= rc.top + 2 + shrink;
		p3[2].x= rc.left + (mwSYSMETRICS_CXVSCROLL-4) - shrink;
		p3[2].y= rc.bottom - 4 - shrink + 1;
		Polygon(hdc,p3,3);
		/* right */
		p3[0].x= rc.right - 4 - shrink;
		p3[0].y= rc.top + (mwSYSMETRICS_CYHSCROLL/2) ;
		p3[1].x= rc.right-mwSYSMETRICS_CXVSCROLL + 2 + shrink ;
		p3[1].y= rc.top + 2 + shrink;
		p3[2].x= rc.right-mwSYSMETRICS_CXVSCROLL + 2 + shrink;
		p3[2].y= rc.bottom - 4 - shrink + 1;
		Polygon(hdc,p3,3);
#endif
#if 1
        	// draw moving bar.

    		wndGetHScrollBarRect (hwnd, &rcHBar);
    		rcHBar.top -- ;
    		rcHBar.bottom -- ;

        	start = rcHBar.left + mwSYSMETRICS_CXHSCROLL + hwnd->hscroll.barStart;

        	if (start + hwnd->hscroll.barLen > rcHBar.right)
            		start = rcHBar.right - hwnd->hscroll.barLen;

		if (hwnd->hscroll.barLen == 0)
			hwnd->hscroll.barLen=rc.right-rc.left-(mwSYSMETRICS_CXHSCROLL*2); 

		/* bkgnd */
		rc2.top=rc.top; rc2.bottom=rc.bottom/*-1*/;
		rc2.left=rc.left+mwSYSMETRICS_CXVSCROLL;
		rc2.right=start;
		if (rc2.right>rc2.left)
			FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH));   

		rc2.left=start+hwnd->hscroll.barLen;
		rc2.right=rc.right-mwSYSMETRICS_CXVSCROLL;
		if (rc2.right>rc2.left)
			FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH));   

        	Draw3DUpFrame (hdc, start, rcHBar.top, start + hwnd->hscroll.barLen,
	    		rcHBar.bottom);
#if 0
		printf("barh:(l,t,r,b):(%d,%d,%d,%d)\n",
        		start, rcHBar.top, start + hwnd->hscroll.barLen,
	    		rcHBar.bottom);
#endif
#endif
	}

	if (fGotDC)
		ReleaseDC(hwnd, hdc);
}

/* handle a non-client message for a scrollbar*/
void
MwHandleNCMessageScrollbar(HWND hwnd, WPARAM hitcode, LPARAM lParam, UINT msg/*BOOL fDown*/)
{
	int	pos = SBS_UNKNOWN;
	BOOL	vertbar = VSCROLLBARVISIBLE(hwnd);
        BOOL	horzbar = HSCROLLBARVISIBLE(hwnd);
	int *	pStat;
	POINT	pt;
	RECT	rc;

	static BOOL bDraw;

    	static int downPos = SBS_UNKNOWN;//
    	static int sbCode;
    	int newThumbPos;

	int itemMoveable,itemCount,itemVisible,moveRange;//jmt:2k0819
	int moveTop,moveBottom,moveLeft,moveRight;//jmt:2k0819

	POINTSTOPOINT(pt, lParam);
	for (;;) {	/* use for() to allow break statement*/
		if (hitcode == HTVSCROLL && vertbar) 
		{
			pStat = &hwnd->vscroll.status;
			rc = hwnd->vscroll.rc;
			rc.bottom = rc.top + mwSYSMETRICS_CYVSCROLL;
			if (PtInRect(&rc, pt)) 
			{
				pos = SBS_UPARROW;
				break;
			}
			rc.bottom = hwnd->vscroll.rc.bottom;
			rc.top = rc.bottom - mwSYSMETRICS_CYVSCROLL;
			if (PtInRect(&rc, pt)) 
			{
				pos = SBS_DOWNARROW;
				break;
			}
			pos = SBS_VERTTHUMB;
		} else if (hitcode == HTHSCROLL && horzbar) 
		{
			pStat = &hwnd->hscroll.status;
			rc = hwnd->hscroll.rc;
			rc.right = rc.left + mwSYSMETRICS_CXHSCROLL;
			if (PtInRect(&rc, pt)) {
				pos = SBS_LEFTARROW;
				break;
			}
			rc.right = hwnd->hscroll.rc.right;
			rc.left = rc.right - mwSYSMETRICS_CXHSCROLL;
			if (PtInRect(&rc, pt)) {
				pos = SBS_RIGHTARROW;
				break;
			}
			pos = SBS_HORZTHUMB;
		} else
			return;
		break;
	}

	if (pos == SBS_UNKNOWN)
		return;

	*pStat &= ~SBS_MASK;		/* remove stray mouse states*/

	if (msg == WM_NCLBUTTONDOWN || msg == WM_NCLBUTTONDBLCLK)//jmt:2k0819
		*pStat |= pos;
	else *pStat &= ~pos;

	if (msg == WM_NCLBUTTONDOWN || msg == WM_NCLBUTTONDBLCLK)//jmt:2k0819
		bDraw=TRUE;

	if (bDraw)
		MwPaintNCScrollbars(hwnd, NULL);

        if (pos == SBS_UPARROW || pos == SBS_LEFTARROW)//jmt:2k0820 
	{
                if (hwnd->vscroll.curPos != hwnd->vscroll.minPos)
			sbCode = SB_LINEUP;
        }
        else if (pos == SBS_DOWNARROW || pos == SBS_RIGHTARROW)//jmt:2k0820 
	{
                if (hwnd->vscroll.curPos != hwnd->vscroll.maxPos)
			sbCode = SB_LINEDOWN;
        }
        else if (pos == SBS_VERTTHUMB || pos == SBS_HORZTHUMB)// 
	{
                sbCode = SB_THUMBTRACK;//
        }

	switch(msg)
	{
	case WM_NCLBUTTONDOWN:
	case WM_NCLBUTTONDBLCLK://jmt:2k0819
	    downPos = pos;
        break;

        case WM_NCMOUSEMOVE://jmt:2k0819
	    if (hitcode == HTVSCROLL && vertbar) 
	    {
		if (sbCode == SB_THUMBTRACK && downPos == SBS_VERTTHUMB)// 
	    	{
			//jmt(2k0819): new algorithm for SB_THUMBTRACK

			rc = hwnd->vscroll.rc;
			moveTop = rc.top + mwSYSMETRICS_CYVSCROLL;
			moveBottom = hwnd->vscroll.rc.bottom - mwSYSMETRICS_CYVSCROLL;
			moveRange = moveBottom - moveTop;

			itemCount = hwnd->vscroll.maxPos - hwnd->vscroll.minPos + 1;
			itemVisible = hwnd->vscroll.pageStep;
			itemMoveable = itemCount - itemVisible + 1;

			newThumbPos = ((pt.y - moveTop) * itemMoveable) / moveRange;
			printf("((%d-%d)*%d)/%d=%d\n",
				pt.y,moveTop,itemMoveable,moveRange,newThumbPos);
			//#

                	if ( newThumbPos >= hwnd->vscroll.minPos &&
                    	     newThumbPos <= hwnd->vscroll.maxPos)
                    		SendMessage (hwnd,
                        		WM_VSCROLL, SB_THUMBTRACK, newThumbPos);
                	break;
            	}
	    }

	    if (hitcode == HTHSCROLL && horzbar) 
	    {
		if (sbCode == SB_THUMBTRACK && downPos == SBS_HORZTHUMB)// 
		{
			//jmt(2k0819): new algorithm for SB_THUMBTRACK

			rc = hwnd->hscroll.rc;
			moveLeft = rc.left + mwSYSMETRICS_CXHSCROLL;
			moveRight = hwnd->hscroll.rc.right - mwSYSMETRICS_CXHSCROLL;
			moveRange = moveRight - moveLeft;

			itemCount = hwnd->hscroll.maxPos - hwnd->hscroll.minPos + 1;
			itemVisible = hwnd->hscroll.pageStep;
			itemMoveable = itemCount - itemVisible + 1;

			newThumbPos = ((pt.x - moveLeft) * itemMoveable) / moveRange;
			printf("((%d-%d)*%d)/%d=%d\n",
				pt.y,moveLeft,itemMoveable,moveRange,newThumbPos);
			//#
    
			if ( newThumbPos >= hwnd->hscroll.minPos &&
			     newThumbPos <= hwnd->hscroll.maxPos)
			    	SendMessage (hwnd,
					WM_HSCROLL, SB_THUMBTRACK, newThumbPos);
			break;
		}
             }

        break;

	case WM_NCLBUTTONUP://jmt:2k0819
	    bDraw=FALSE;

⌨️ 快捷键说明

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