2014-11-29 17:29:50 -06:00
// 29 november 2014
static void vscrollto ( struct table * t , intptr_t newpos )
{
SCROLLINFO si ;
RECT scrollArea ;
if ( newpos < 0 )
newpos = 0 ;
if ( newpos > ( t - > count - t - > pagesize ) )
newpos = ( t - > count - t - > pagesize ) ;
scrollArea = realClientRect ( t ) ;
// negative because ScrollWindowEx() is "backwards"
if ( ScrollWindowEx ( t - > hwnd , 0 , ( - ( newpos - t - > firstVisible ) ) * rowHeight ( t ) ,
& scrollArea , & scrollArea , NULL , NULL ,
SW_ERASE | SW_INVALIDATE ) = = ERROR )
abort ( ) ;
t - > firstVisible = newpos ;
ZeroMemory ( & si , sizeof ( SCROLLINFO ) ) ;
si . cbSize = sizeof ( SCROLLINFO ) ;
si . fMask = SIF_PAGE | SIF_POS | SIF_RANGE ;
si . nPage = t - > pagesize ;
si . nMin = 0 ;
si . nMax = t - > count - 1 ; // nMax is inclusive
si . nPos = t - > firstVisible ;
SetScrollInfo ( t - > hwnd , SB_VERT , & si , TRUE ) ;
}
static void vscrollby ( struct table * t , intptr_t n )
{
vscrollto ( t , t - > firstVisible + n ) ;
}
static void wheelscroll ( struct table * t , WPARAM wParam )
{
int delta ;
int lines ;
UINT scrollAmount ;
delta = GET_WHEEL_DELTA_WPARAM ( wParam ) ;
if ( SystemParametersInfoW ( SPI_GETWHEELSCROLLLINES , 0 , & scrollAmount , 0 ) = = 0 )
abort ( ) ;
if ( scrollAmount = = WHEEL_PAGESCROLL )
scrollAmount = t - > pagesize ;
if ( scrollAmount = = 0 ) // no mouse wheel scrolling (or t->pagesize == 0)
return ;
// the rest of this is basically http://blogs.msdn.com/b/oldnewthing/archive/2003/08/07/54615.aspx and http://blogs.msdn.com/b/oldnewthing/archive/2003/08/11/54624.aspx
// see those pages for information on subtleties
delta + = t - > wheelCarry ;
lines = delta * ( ( int ) scrollAmount ) / WHEEL_DELTA ;
t - > wheelCarry = delta - lines * WHEEL_DELTA / ( ( int ) scrollAmount ) ;
vscrollby ( t , - lines ) ;
}
static void vscroll ( struct table * t , WPARAM wParam )
{
SCROLLINFO si ;
intptr_t newpos ;
ZeroMemory ( & si , sizeof ( SCROLLINFO ) ) ;
si . cbSize = sizeof ( SCROLLINFO ) ;
si . fMask = SIF_POS | SIF_TRACKPOS ;
if ( GetScrollInfo ( t - > hwnd , SB_VERT , & si ) = = 0 )
abort ( ) ;
newpos = t - > firstVisible ;
switch ( LOWORD ( wParam ) ) {
case SB_TOP :
newpos = 0 ;
break ;
case SB_BOTTOM :
newpos = t - > count - t - > pagesize ;
break ;
case SB_LINEUP :
newpos - - ;
break ;
case SB_LINEDOWN :
newpos + + ;
break ;
case SB_PAGEUP :
newpos - = t - > pagesize ;
break ;
case SB_PAGEDOWN :
newpos + = t - > pagesize ;
break ;
case SB_THUMBPOSITION :
newpos = ( intptr_t ) ( si . nPos ) ;
break ;
case SB_THUMBTRACK :
newpos = ( intptr_t ) ( si . nTrackPos ) ;
}
vscrollto ( t , newpos ) ;
}
2014-12-01 14:34:26 -06:00
HANDLER ( vscroll )
{
switch ( uMsg ) {
case WM_VSCROLL :
vscroll ( t , wParam ) ;
* lResult = 0 ;
return TRUE ;
case WM_MOUSEWHEEL :
wheelscroll ( t , wParam ) ;
* lResult = 0 ;
return TRUE ;
}
return FALSE ;
}