📄 scrlbar.c
字号:
/******************************************************
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 + -