📄 scrlbar.c
字号:
Scrl_SendScrollMsg( hWnd, fnBar, dwMsg, MAKELONG( SB_BOTTOM, 0 ), (LPARAM)hWnd );
oldPos = pos;
}
else
{
pos = si.sd.nMin;
Scrl_SendScrollMsg( hWnd, fnBar, dwMsg, MAKELONG( SB_THUMBTRACK, si.sd.nMin ), (LPARAM)hWnd );
Scrl_SendScrollMsg( hWnd, fnBar, dwMsg, MAKELONG( SB_TOP, 0 ), (LPARAM)hWnd );
oldPos = pos;
}
edgeMsg = TRUE;
}
}
else if( si.fnBar == SB_HORZ )
{
nx = LOWORD( msg.lParam );
Scrl_TranslatePos( hWnd, fnBar, &nx, 0 );
nx = nx - x;
rect.left = posv[2] + nx;
rect.right = posv[3] + nx;
if( rect.right <= posv[4] && rect.left >= posv[1] )
{
#ifdef EML_DOS
_HideMouse();
#endif
// clear background//
// draw thumb box
Scrl_DrawThumbBox( hdc, fnBar, si.sd.state, &oldRect, &rect );
#ifdef EML_DOS
_ShowMouse();
#endif
oldRect = rect;
{ // LN, 2003-07-12 error: ( posv[4] - posv[1] - (posv[3]-posv[2]) ) == 0
//pos = si.sd.nMin + (rect.left-posv[1]) * (si.sd.nMax-si.sd.nMin-si.sd.nPage+1) / ( posv[4] - posv[1] - (posv[3]-posv[2]) );
int diff = ( posv[4] - posv[1] - (posv[3]-posv[2]) );
if( diff )
{
pos = si.sd.nMin + (rect.left-posv[1]) * (si.sd.nMax-si.sd.nMin-si.sd.nPage+1) / diff;
}
else
{
; // nothing to do
}
}
if( pos != oldPos )
{
Scrl_SendScrollMsg( hWnd, fnBar, dwMsg, MAKELONG( SB_THUMBTRACK, pos ), (LPARAM)hWnd );
oldPos = pos;
}
edgeMsg = FALSE;
}
else if( edgeMsg == FALSE )
{
if( rect.right > posv[4] )
{
pos = si.sd.nMax - si.sd.nPage + 1;
Scrl_SendScrollMsg( hWnd, fnBar, dwMsg, MAKELONG( SB_THUMBTRACK, pos ), (LPARAM)hWnd );
Scrl_SendScrollMsg( hWnd, fnBar, dwMsg, MAKELONG( SB_BOTTOM, 0 ), (LPARAM)hWnd );
oldPos = pos;
}
else
{
pos = si.sd.nMin;
Scrl_SendScrollMsg( hWnd, fnBar, dwMsg, MAKELONG( SB_THUMBTRACK, pos ), (LPARAM)hWnd );
Scrl_SendScrollMsg( hWnd, fnBar, dwMsg, MAKELONG( SB_TOP, 0 ), (LPARAM)hWnd );
oldPos = pos;
}
edgeMsg = TRUE;
}
}
}
else
{
if( GetTickCount() - dwTickCount >= SLEEP_TICK )
{ //足够的延迟
bHandleTimer = TRUE;
dwTickCount = GetTickCount();
}
}
}
else if( msg.message == WM_SYSTIMER && msg.wParam == IDSCROLLBAR )
{
if( i != 2 )
{ // up arrow or down arrow or page
bHandleTimer = TRUE;
}
}
if( bHandleTimer )
{ //2004-12-21增加 自动处理鼠标消息和timer消息
Scrl_GetScrollData( hWnd, fnBar, &si );
Scrl_GetDrawPos( &si, posv );
//if( pos >= posv[2] && pos < posv[3] )
if( ( ncode == SB_PAGEDOWN && pos <= posv[3] ) ||
( ncode == SB_PAGEUP && pos >= posv[2] ) )
{
bHasTimer = FALSE;
}
else
Scrl_SendScrollMsg( hWnd, fnBar, dwMsg, MAKELONG( ncode, 0 ), (LPARAM)hWnd );
}
else if( !(msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST) )
{
DispatchMessage( &msg );
}
}
else
{ // idel handle
// PostMessage( hWnd, 0x118, 0, 0 );
ASSERT( 0 );
}
}
KillSysTimer( hWnd, IDSCROLLBAR );
#ifdef EML_DOS
_HideMouse();
#endif
SelectObject( hdc, hBrush );
ReleaseDC( hWnd, hdc );
ReleaseCapture();
return 0;
}
// **************************************************
// 声明:LRESULT Scrl_DoSETSCROLLINFO( HWND hWnd, int fnBar, LPCSCROLLINFO lpsi, BOOL fRedraw )
// 参数:
// IN hWnd - 窗口句柄
// IN fnBar - 滚动条类型,为下值:
// SB_VERT - 垂直
// SB_HORT - 水平
// IN lpsi - 包含滚动条信息的结构指针
// IN fRedraw - 是否重绘
// 返回值:
// 返回0
// 功能描述:
// 配置滚动条数据
// 引用:
//
// ************************************************
#define SCRL_DEBUG 0
LRESULT Scrl_DoSETSCROLLINFO( HWND hWnd, int fnBar, LPCSCROLLINFO lpsi, BOOL fRedraw )
{
HDC hdc;
_SCROLL srd;
BOOL fChange = FALSE;
RECT rect, newRect;
int nPos, nPage;
int nLimit;
//得到滚动条对象数据
Scrl_GetScrollData( hWnd, fnBar ,&srd );
Scrl_GetThumbRect( &srd, &rect );
if( lpsi->fMask & SIF_RANGE )
{ //设置滚动条范围数据
if( lpsi->nMin >= lpsi->nMax )
goto _HIDE_OR_DISABLE;
if( srd.sd.nMin != lpsi->nMin )
{
RETAILMSG( SCRL_DEBUG, (TEXT("Scrl:nMin=%d\r\n"), lpsi->nMin ));
Scrl_SetScrollValue( hWnd, fnBar, OFF_MIN, lpsi->nMin );
fChange = TRUE;
}
if( srd.sd.nMax != lpsi->nMax )
{
RETAILMSG( SCRL_DEBUG, (TEXT("Scrl:nMax=%d\r\n"), lpsi->nMax ));
Scrl_SetScrollValue( hWnd, fnBar, OFF_MAX, lpsi->nMax );
fChange = TRUE;
}
nPage = srd.sd.nPage;
nLimit = lpsi->nMax - lpsi->nMin + 1;
// if possible, change page and pos size
if( !(lpsi->fMask & SIF_PAGE) &&
nPage > nLimit )
{
nPage = nLimit;
RETAILMSG( SCRL_DEBUG, (TEXT("Scrl:change nPage=%d\r\n"), nPage ));
Scrl_SetScrollValue( hWnd, fnBar, OFF_PAGE, nPage );
fChange = TRUE;
}
nLimit = lpsi->nMax - MAX( nPage - 1, 0);
if( !(lpsi->fMask & SIF_POS) &&
( srd.sd.nPos > nLimit || srd.sd.nPos < lpsi->nMin ) )
{
if( srd.sd.nPos > nLimit )
Scrl_SetScrollValue( hWnd, fnBar, OFF_POS, nLimit );
else
Scrl_SetScrollValue( hWnd, fnBar, OFF_POS, lpsi->nMin );
fChange = TRUE;
}
}
if( lpsi->fMask & SIF_PAGE )
{ //设置页数据
if( lpsi->fMask & SIF_RANGE )
{
if( lpsi->nPage >= (UINT)(lpsi->nMax - lpsi->nMin + 1) )
goto _HIDE_OR_DISABLE;
}
else
{
if( lpsi->nPage >= (UINT)(srd.sd.nMax - srd.sd.nMin + 1) )
goto _HIDE_OR_DISABLE;
}
if( (UINT)srd.sd.nPage != lpsi->nPage )
{
RETAILMSG( SCRL_DEBUG, (TEXT("Scrl:nPage=%d\r\n"), lpsi->nPage ));
Scrl_SetScrollValue( hWnd, fnBar, OFF_PAGE, lpsi->nPage );
fChange = TRUE;
}
}
if( lpsi->fMask & SIF_POS )
{
//设置位置数据
nPos = lpsi->nPos;
Scrl_GetScrollData( hWnd, fnBar ,&srd );
nPage = srd.sd.nPage;
nLimit = srd.sd.nMax - MAX( nPage - 1, 0);
if( nPos > nLimit )
nPos = nLimit;
if( nPos < srd.sd.nMin )
nPos = srd.sd.nMin;
if( nPos != srd.sd.nPos )
{
RETAILMSG( SCRL_DEBUG, (TEXT("Scrl:nPos=%d\r\n"), nPos ));
Scrl_SetScrollValue( hWnd, fnBar, OFF_POS, nPos );
fChange = TRUE;
}
}
if( fRedraw &&
(srd.sd.state & SBS_TRACKTHUMB) == 0 &&
fChange )
{ // 重绘 redraw
if( fnBar != SB_CTL )
{
DWORD dwStyle = GetWindowLong( hWnd, GWL_STYLE );
if( ( fnBar == SB_HORZ && (dwStyle & WS_HSCROLL) == 0 ) ||
( fnBar == SB_VERT && (dwStyle & WS_VSCROLL) == 0 ) )
{
ShowScrollBar( hWnd, fnBar, TRUE );
goto _RET;
}
}
hdc = Scrl_GetScrollDC( hWnd, fnBar );
// get new thumb rect
Scrl_GetScrollData( hWnd, fnBar ,&srd );
Scrl_GetThumbRect( &srd, &newRect );
// show thumb
Scrl_DrawThumbBox( hdc, fnBar, srd.sd.state, &rect, &newRect );
ReleaseDC( hWnd, hdc );
}
_RET:
return Scrl_GetScrollValue( hWnd, fnBar, OFF_POS );
//处理无效或隐含情况
_HIDE_OR_DISABLE:
RETAILMSG( SCRL_DEBUG, (TEXT("Scrl:Hide or disable\r\n") ));
if( fnBar != SB_CTL )
{
if( lpsi->fMask & SIF_DISABLENOSCROLL )
EnableScrollBar( hWnd, fnBar, ESB_DISABLE_BOTH );
else
ShowScrollBar( hWnd, fnBar, FALSE );
}
return Scrl_GetScrollValue( hWnd, fnBar, OFF_POS );
}
// **************************************************
// 声明:LRESULT Scrl_DoGETSCROLLINFO( HWND hWnd, int fnBar, void * lp )
// 参数:
// IN hWnd - 窗口句柄
// IN fnBar - 滚动条类型,为下值:
// SB_VERT - 垂直
// SB_HORT - 水平
// OUT lp - 用于接受滚动条数据的 SCROLLINFO 结构指针
// 返回值:
// 返回0
// 功能描述:
// 得到滚动条数据
// 引用:
//
// ************************************************
LRESULT Scrl_DoGETSCROLLINFO( HWND hWnd, int fnBar, void * lp )
{
_SCROLL srl;
LPSCROLLINFO lpsi = (LPSCROLLINFO)lp;
//得到滚动条数据
Scrl_GetScrollData( hWnd, fnBar, &srl );
if( lpsi->fMask & SIF_PAGE )
lpsi->nPage = srl.sd.nPage;
if( lpsi->fMask & SIF_POS )
lpsi->nPos = srl.sd.nPos;
if( lpsi->fMask & SIF_RANGE )
{
lpsi->nMax = srl.sd.nMax;
lpsi->nMin = srl.sd.nMin;
}
return TRUE;
}
// **************************************************
// 声明:static LRESULT Scrl_DoSETPOS( HWND hWnd, int fnBar, int nPos, BOOL fRedraw )
// 参数:
// IN hWnd - 窗口句柄
// IN fnBar - 滚动条类型,为下值:
// SB_VERT - 垂直
// SB_HORT - 水平
// IN nPos - 位置数据
// IN fRedraw - 是否重绘
// 返回值:
// 返回0
// 功能描述:
// 设置滚动条位置
// 引用:
//
// ************************************************
static LRESULT Scrl_DoSETPOS( HWND hWnd, int fnBar, int nPos, BOOL fRedraw )
{
HDC hdc = 0;
_SCROLL srl;
int i, state, fUpdate = FALSE;
RECT rcOld, rcNew;
//得到滚动条数据
Scrl_GetScrollData( hWnd, fnBar, &srl );
state = srl.sd.state;
// 检查有效性 check valid
if( nPos + srl.sd.nPage > srl.sd.nMax + 1 )
nPos = srl.sd.nMax - srl.sd.nPage + 1;
if( nPos < srl.sd.nMin )
nPos = srl.sd.nMin;
// set new pos
i = srl.sd.nPos;
if( fRedraw &&
(state & SBS_TRACKTHUMB) == 0 &&
i != nPos )
{
fUpdate = TRUE;
Scrl_GetThumbRect( &srl, &rcOld );
}
//设置值
Scrl_SetScrollValue( hWnd, fnBar, OFF_POS, nPos );
if( fUpdate )
{
Scrl_GetScrollData( hWnd, fnBar, &srl );
Scrl_GetThumbRect( &srl, &rcNew );
//得到绘图DC
hdc = Scrl_GetScrollDC( hWnd, fnBar );
//绘制
Scrl_DrawThumbBox( hdc, srl.fnBar, srl.sd.state, &rcOld, &rcNew );
ReleaseDC( hWnd, hdc );
}
return i;
}
// **************************************************
// 声明:static LRESULT Scrl_DoGETPOS( HWND hWnd, int fnBar )
// 参数:
// IN hWnd - 窗口句柄
// IN fnBar - 滚动条类型,为下值:
// SB_VERT - 垂直
// SB_HORT - 水平
// 返回值:
// 返回滑快位置数据
// 功能描述:
// 得到滑快位置数据
// 引用:
//
// ************************************************
static LRESULT Scrl_DoGETPOS( HWND hWnd, int fnBar )
{
return Scrl_GetScrollValue( hWnd, fnBar, OFF_POS );
}
// **************************************************
// 声明:static LRESULT Scrl_DoGETRANGE( HWND hWnd, int fnBar, LPINT lpnMinPos, LPINT lpnMaxPos )
// 参数:
// IN hWnd - 窗口句柄
// IN fnBar - 滚动条类型,为下值:
// SB_VERT - 垂直
// SB_HORT - 水平
// OUT lpnMinPos - 用于接受范围的小值
// OUT lpnMaxPos - 用于接受范围的大值
// 返回值:
// 返回0
// 功能描述:
// 得到滚动条范围
// 引用:
//
// ************************************************
static LRESULT Scrl_DoGETRANGE( HWND hWnd, int fnBar, LPINT lpnMinPos, LPINT lpnMaxPos )
{
_SCROLL srl;
//得到滚动条数据
Scrl_GetScrollData( hWnd, fnBar, &srl );
*lpnMinPos = srl.sd.nMin;
*lpnMaxPos = srl.sd.nMax;
return 0;
}
// **************************************************
// 声明:static LRESULT Scrl_DoSETRANGE( HWND hWnd, int fnBar, int nMinPos, int nMaxPos, BOOL fRedraw )
// 参数:
// IN hWnd - 窗口句柄
// IN fnBar - 滚动条类型,为下值:
// SB_VERT - 垂直
// SB_HORT - 水平
// IN nMinPos - 最小值
// IN nMaxPos - 最大值
// IN fRedraw - 是否重绘
// 返回值:
// 返回0
// 功能描述:
// 设置滚动条范围
// 引用:
//
// ************************************************
static LRESULT Scrl_DoSETRANGE( HWND hWnd, int fnBar, int nMinPos, int nMaxPos, BOOL fRedraw )
{
HDC hdc = 0;
_SCROLL srl;
int nPos, nPage, state;
int fUpdate = FALSE;
RECT rcOld, rcNew;
if( nMinPos > nMaxPos )
return 0;
//得到滚动条数据
Scrl_GetScrollData( hWnd, fnBar, &srl );
state = srl.sd.state;
if( fRedraw && (state & SBS_TRACKTHUMB) == 0 )
{ //
fUpdate = TRUE;
Scrl_GetThumbRect( &srl, &rcOld );
}
nPos = srl.sd.nPos;
nPage = srl.sd.nPage;
//设置范围
Scrl_SetScrollValue( hWnd, fnBar, OFF_MIN, nMinPos );
Scrl_SetScrollValue( hWnd, fnBar, OFF_MAX, nMaxPos );
//检查范围
if( nPage > nMaxPos - nMinPos )
nPage=nMaxPos-nMinPos;
if( nPos < nMinPos )
Scrl_SetScrollValue( hWnd, fnBar, OFF_POS, nMinPos );
else if( nPos + nPage > nMaxPos + 1 )
Scrl_SetScrollValue( hWnd, fnBar, OFF_POS, nMaxPos - nPage + 1 );
if( fUpdate )
{
Scrl_GetScrollData( hWnd, fnBar, &srl );
Scrl_GetThumbRect( &srl, &rcNew );
hdc = Scrl_GetScrollDC( hWnd, fnBar );
Scrl_DrawThumbBox( hdc, srl.fnBar, srl.sd.state, &rcOld, &rcNew );
ReleaseDC( hWnd, hdc );
}
return nPos;
}
// **************************************************
// 声明:static BOOL Scrl_SendScrollMsg( HWND hWnd, int fnBar, UINT dwMsg, WPARAM wParam, LPARAM lParam )
// 参数:
// IN hWnd - 窗口句柄
// IN fnBar - 滚动条类型,为下值:
// SB_VERT - 垂直
// SB_HORT - 水平
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -