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

📄 scrlbar.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 4 页
字号:
/******************************************************
Copyright(c) 版权所有,1998-2003微逻辑。保留所有权利。
******************************************************/


/*****************************************************
文件说明:滚动棒类(ScrollBar)
版本号:1.0.0
开发时期:1999-03-06
作者:李林
修改记录:
		LN 2004-12-21增加 自动处理鼠标消息和timer消息
        LN, 2003-07-12, 除零错
******************************************************/

#include <eframe.h>
#include <esymbols.h>
#include <eassert.h>
//#include <eapisrv.h>
#include "..\..\include\scrollbar.h"

//#include <epwin.h>
//#include <winsrv.h>
//#include <gdisrv.h>

#ifdef EML_DOS
    #include <emouse.h>
#endif

// this is all message handle proc
static LRESULT DoCREATE( HWND hWnd );
static LRESULT DoPAINT( HWND );
static LRESULT CALLBACK ScrollBarWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
static int Scrl_SetScrollState( HWND hWnd, int fnBar, UINT s, BOOL fEnable );
static int Scrl_GetScrollValue( HWND hWnd, int fnBar, int pos );
_SCROLLDATA * _GetWindowScrollBar( HWND hWnd, UINT type );

extern BOOL _GetFrameSize( SIZE FAR* lpSize, DWORD dwMainStyle );


static const char classSCROLLBAR[]="ScrollBar";

// **************************************************
// 声明:ATOM RegisterScrollBarClass(HINSTANCE hInst)
// 参数:
//		IN hInst - 实例句柄
// 返回值:
//		假如成功,返回非0值;失败,返回0
// 功能描述:
//		注册滚动棒类
// 引用: 
//		被sysclass.c 调用
// ************************************************

// register my define class
ATOM RegisterScrollBarClass(HINSTANCE hInst)
{
   WNDCLASS wc;

   wc.hInstance=hInst;
   wc.lpszClassName=classSCROLLBAR;
// the proc is class function
   wc.lpfnWndProc=(WNDPROC)ScrollBarWndProc;
   wc.style=CS_DBLCLKS|CS_CLASSDC;
   wc.hIcon= 0;
// at pen window, no cursor
   wc.hCursor= LoadCursor(NULL,IDC_ARROW);
// to auto erase background, must set a valid brush
// if 0, you must erase background yourself
   wc.hbrBackground = 0;
   wc.lpszMenuName=NULL;
   wc.cbClsExtra=0;
// !!! it's important to save state of button, align to long
   wc.cbWndExtra=0;//sizeof( _SCROLLDATA );

   return RegisterClass(&wc);
}

//得到窗口风格决定的滚动条
_SCROLLDATA * _GetWindowScrollBar( HWND hWnd, UINT type )
{
	_SCROLLDATA * lpret = NULL;

	if( type == SB_CTL )
	{
		DWORD dwStyle = GetWindowLong( hWnd, GWL_STYLE );
		if( dwStyle & SBS_VERT )
		{
			type = SB_VERT;
		}
		else
		{
			type = SB_HORZ;
		}
	}
	//else
		//type = fnBar;

	if( type == SB_VERT )
	{
		lpret = (_SCROLLDATA *)GetWindowLong( hWnd, GWL_VSCROLL );//lpws->lpvScrollBar;
	}
	else if( type == SB_HORZ )
	{
		lpret = (_SCROLLDATA *)GetWindowLong( hWnd, GWL_HSCROLL );//lpws->lphScrollBar;
	}
	if( lpret == NULL )
	{  //第一次		
		//EnterCriticalSection( &csWindow );
		
		if( type == SB_VERT )
		{
			//lpret = lpws->lpvScrollBar = BlockHeap_Alloc( hgwmeBlockHeap, BLOCKHEAP_ZERO_MEMORY, sizeof(_SCROLLDATA) );
			lpret = calloc( sizeof(_SCROLLDATA), 1 );
			SetWindowLong( hWnd, GWL_VSCROLL, (LONG)lpret );
		}
		else if( type == SB_HORZ )
		{
			//lpret = lpws->lphScrollBar = BlockHeap_Alloc( hgwmeBlockHeap, BLOCKHEAP_ZERO_MEMORY, sizeof(_SCROLLDATA) ); 
			lpret = calloc( sizeof(_SCROLLDATA), 1 );
			SetWindowLong( hWnd, GWL_HSCROLL, (LONG)lpret );
		}
		if( lpret )
			Scrl_Inital( lpret );		
		//LeaveEnterCriticalSection( &csWindow );
	}
	ASSERT( lpret || type == SB_CORNER );
	return lpret;
}


VOID _ReleaseWindowScrollBar( HWND hWnd, UINT type )
{
	_SCROLLDATA * lpret = NULL;
	//int type;

	//EnterCriticalSection( &csWindow );
	if( type == SB_CTL )
	{
		DWORD dwStyle = GetWindowLong( hWnd, GWL_STYLE );
		if( dwStyle & SBS_VERT )
		{
			type = SB_VERT;
		}
		else
		{
			type = SB_HORZ;
		}
	}


	if( type == SB_VERT )
	{		
		//lpret = lpws->lpvScrollBar;
		lpret = (_SCROLLDATA *)SetWindowLong( hWnd, GWL_VSCROLL, 0 );//(_SCROLLDATA *)GetWindowLong( hWnd, GWL_VSCROLL );
		//lpws->lpvScrollBar = NULL;
	}
	else if( type == SB_HORZ )
	{
		lpret = (_SCROLLDATA *)SetWindowLong( hWnd, GWL_HSCROLL, 0 );//(_SCROLLDATA *)GetWindowLong( hWnd, GWL_HSCROLL );
		
		//lpret = lpws->lphScrollBar;
		//lpws->lphScrollBar = NULL;
	}
	if( lpret )
	{
	    //BlockHeap_Free( hgwmeBlockHeap, 0, lpret, sizeof(_SCROLLDATA) );
		free( lpret );
	}

	//LeaveEnterCriticalSection( &csWindow );

	//return lpret;
}


// **************************************************
// 声明:void Scrl_GetBarRect( LPRECT lprect, DWORD dwMainStyle, DWORD dwExStyle, int which )
// 参数:
// 	IN/OUT lprect - 输入窗口矩形,输出滚动条矩形 
//	IN dwMainStyle - 窗口主风格
//	IN dwExStyle - 窗口扩展风格
//	IN which - 滚动条类型,如下值:
//				SB_VERT - 垂直滚动条
//				SB_HORZ - 水平滚动条
// 返回值:
//	无
// 功能描述:
//	得到滚动条矩形
// 引用: 
//	
// ************************************************

void Scrl_GetBarRect( LPRECT lprect, DWORD dwMainStyle, DWORD dwExStyle, int which )
{
    SIZE size;
	//得到边框厚度
    _GetFrameSize( &size, dwMainStyle );
	//客户边框 ?
	if( dwExStyle & WS_EX_CLIENTEDGE )
        InflateRect( lprect, -(size.cx+1), -(size.cy+1) );
	else
		InflateRect( lprect, -size.cx, -size.cy );
	
    if( which == SB_VERT )
    {   // 垂直 vertial scroll bar
        if( (dwMainStyle & WS_CAPTION) == WS_CAPTION ||
			(dwExStyle & WS_EX_TITLE) )
            lprect->top += GetSystemMetrics( SM_CYCAPTION );
        if( dwMainStyle & WS_HSCROLL )
             lprect->bottom -= GetSystemMetrics( SM_CYHSCROLL );
        lprect->left = lprect->right - GetSystemMetrics( SM_CXVSCROLL );
    }
    else if( which == SB_HORZ )
    {    // 水平horitonal scroll bar
        lprect->top = lprect->bottom - GetSystemMetrics( SM_CYHSCROLL );
        if( dwMainStyle & WS_VSCROLL )
            lprect->right -= GetSystemMetrics( SM_CXVSCROLL );
    }
    else
    {    // 右底矩形 right bottom corner
        lprect->top = lprect->bottom - GetSystemMetrics( SM_CYHSCROLL );
        lprect->left = lprect->right - GetSystemMetrics( SM_CXVSCROLL );
    }
}

// **************************************************
// 声明:static BOOL Scrl_GetScrollData( HWND hWnd, int fnBar, _LPSCROLL lpsd )
// 参数:
// 	IN hWnd - 窗口句柄
//	IN fnBar - 滚动条类型
//	OUT lpsd - 用于接受滚动条数据
// 返回值:
//	假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	得到滚动条数据
// 引用: 
//	
// ************************************************

static BOOL Scrl_GetScrollData( HWND hWnd, int fnBar, _LPSCROLL lpsd )
{
	
	DWORD dwStyle = GetWindowLong( hWnd, GWL_STYLE );
	//int type;
    //_LPWINDATA lpws = _GetHWNDPtr(hWnd);
	_LPSCROLLDATA p;
	p = _GetWindowScrollBar( hWnd, fnBar );
	
	if( p || fnBar == SB_CORNER )
	{	//得到私有数据
		//_LPSCROLLDATA p = (_LPSCROLLDATA)(lpws+1);
		if( fnBar == SB_CTL )
		{	//为滚动条窗口
			
			lpsd->sd = *p;
			GetClientRect( hWnd, &lpsd->rect );
			lpsd->fnBar = (dwStyle & SBS_VERT) ? SB_VERT : SB_HORZ;
		}
		else
		{	//窗口内部滚动条
			DWORD dwExStyle = GetWindowLong( hWnd, GWL_EXSTYLE );

			GetWindowRect( hWnd, &lpsd->rect );
			OffsetRect( &lpsd->rect, -lpsd->rect.left, -lpsd->rect.top );
			//得到滚动条矩形
			Scrl_GetBarRect( &lpsd->rect, dwStyle, dwExStyle, fnBar );
			//	2004-09-06 , modify
			//p = _GetWindowScrollBar( lpws, fnBar );
			if( fnBar != SB_CORNER )
				lpsd->sd = *p;
			//if( fnBar == SB_VERT )
			//	lpsd->sd = lpws->vScrollBar;
			//else if( fnBar == SB_HORZ )
			//	lpsd->sd = lpws->hScrollBar;
			// 2004-09-06
			lpsd->fnBar = fnBar;
		}
		return TRUE;
	}
	return FALSE;
}

// **************************************************
// 声明:static int Scrl_GetDrawPos( _LPSCROLL lpsd, int pos[6] )
// 参数:
//	IN lpsd - 滚动条数据对象指针
//	OUT pos[6] - 用于接受滚动条显示位置数据
// 返回值:
//	假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	得到滚动条各部分显示位置数据
// 引用: 
//	
// ************************************************

static int Scrl_GetDrawPos( _LPSCROLL lpsd, int pos[6] )
{
	RECT rect = lpsd->rect;
	long l, nSize;
	int arrowSize = 0, pSize, offset;

    if(lpsd->fnBar == SB_VERT)
    {	//垂直
    	nSize =  rect.bottom-rect.top;
        offset = rect.top;
    }
    else if(lpsd->fnBar == SB_HORZ)
    {	//水平
        nSize = rect.right-rect.left;
        offset = rect.left;
    }
	else   // error
		return FALSE;

	if( lpsd->fnBar == SB_VERT )
	{	//得到宽度
		arrowSize = GetSystemMetrics( SM_CYVSCROLL );
	}
    else if( lpsd->fnBar == SB_HORZ )
	{	//得到高度
		arrowSize = GetSystemMetrics( SM_CXHSCROLL );
	}
	//得到上下/左右 块显示位置
	pos[0] = 0;
	pos[1] = arrowSize;

	pos[4] = (short)(nSize - arrowSize);
	pos[5] = nSize;

	l = nSize - arrowSize * 2;
	if( lpsd->sd.nMin < lpsd->sd.nMax )
	    pSize = (int)( lpsd->sd.nPage * l / (lpsd->sd.nMax-lpsd->sd.nMin+1) );
	else
		pSize = l;
	pSize = min( pSize, l );
	pSize = max( MIN_THUMBSIZE, pSize );
	//得到滑动块显示位置
    if( lpsd->sd.nPos + lpsd->sd.nPage >= lpsd->sd.nMax + 1  )
	{	//滑动块超出下位置
		pos[3] = (short)(nSize - arrowSize);
		pos[2] = (short)(pos[3] - pSize);
	}
	else if( lpsd->sd.nPos <= lpsd->sd.nMin )
	{	//滑动块超出上位置
		pos[2] = pos[1];
		pos[3] = pos[2] + pSize;
	}
	else
	{	//最大/最小值有效吗 ?
		if( lpsd->sd.nMin < lpsd->sd.nMax )
		{	//有效
	        pos[2] = (short)(arrowSize + (lpsd->sd.nPos - lpsd->sd.nMin) * l / (lpsd->sd.nMax-lpsd->sd.nMin+1));
			pos[3] = pos[2] + pSize;
			if( pos[3] > pos[4] )
			{
				pos[3] = pos[4];
				pos[2] = pos[3] - pSize;
			}
			if( pos[2] < pos[1] )
				pos[2] = pos[1];
		}
		else
		{
			pos[2] = pos[1];
	        pos[3] = pos[2] + pSize;//
		}
	}

    for( l = 0; l < 6; l++ )
        pos[(int)l] += offset;
	return TRUE;
}

// **************************************************
// 声明:static BOOL Scrl_GetThumbRect( _LPSCROLL lpsd, LPRECT lprect )
// 参数:
//	IN lpsd - 滚动条数据对象指针
//	OUT lprect - 用于接受滑动块矩形
// 返回值:
//	假入成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	得到滑动块矩形
// 引用: 
//	
// ************************************************

static BOOL Scrl_GetThumbRect( _LPSCROLL lpsd, LPRECT lprect )
{
	int drawPos[6];

    *lprect = lpsd->rect;
    Scrl_GetDrawPos( lpsd, drawPos );

	if( lpsd->fnBar == SB_VERT )
	{	//垂直
		lprect->top = drawPos[2];
		lprect->bottom = drawPos[3];
	}
	else if( lpsd->fnBar == SB_HORZ )
	{	//水平
		lprect->left = drawPos[2];
		lprect->right = drawPos[3];
	}
	return TRUE;
}

// **************************************************
// 声明:static int Scrl_DrawThumbBox( HDC hdc, int fnBar, UINT uiState, LPCRECT lprcOld, LPCRECT lprcNew )
// 参数:
// 	IN hdc - 显示DC
//	IN fnBar - 滚动条类型,为下值:
//						SB_VERT - 垂直
//						SB_HORT - 水平
//						
//	IN uiState - 状态
//	IN lprcOld - 之前的显示矩形
//	IN lprcNew - 新的显示矩形
// 返回值:
//	返回0
// 功能描述:
//	画滚动条的滑块
// 引用: 
//	
// ************************************************

static int Scrl_DrawThumbBox( HDC hdc, int fnBar, UINT uiState, LPCRECT lprcOld, LPCRECT lprcNew )
{
    HBRUSH hBrush;
	RECT rect;

	if( (uiState & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH )
	{	//无效状态
		//联合矩形
		if( lprcOld && lprcNew )
			UnionRect( &rect, lprcOld, lprcNew );
		else if( lprcOld )
			rect = *lprcOld;
		else
			rect = *lprcNew;
		//
#ifdef ZT_PHONE
		if( fnBar == SB_HORZ )
			InflateRect( &rect, 0, -1 );
		else
			InflateRect( &rect, -1, 0 );
#endif
		FillRect( hdc, &rect, GetSysColorBrush(COLOR_SCROLLBAR) );
		return 0;
	}
	//清除背景
    if( lprcOld && lprcNew )
    {
		if( SubtractRect( &rect, lprcOld, lprcNew ) )
		{	// 清除老矩形 clear old rect
#ifdef ZT_PHONE
			if( fnBar == SB_HORZ )
				InflateRect( &rect, 0, -1 );
			else
				InflateRect( &rect, -1, 0 );
#endif

			FillRect( hdc, &rect, GetSysColorBrush(COLOR_SCROLLBAR) );
		}
		else
		{   // 清除老矩形 clear old rect
			rect = *lprcOld;
#ifdef ZT_PHONE
			if( fnBar == SB_HORZ )
				InflateRect( &rect, 0, -1 );
			else
				InflateRect( &rect, -1, 0 );
#endif

			FillRect( hdc, &rect, GetSysColorBrush(COLOR_SCROLLBAR) );
		}
    }

    if( fnBar == SB_VERT )
	{	//垂直
		if( (lprcNew->bottom - lprcNew->top) < MIN_THUMBSIZE )
		{
			rect = *lprcNew;
#ifdef ZT_PHONE
			InflateRect( &rect, -1, 0 );
#endif
			FillRect( hdc, &rect, GetSysColorBrush(COLOR_SCROLLBAR) );
			return 0;

⌨️ 快捷键说明

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