mirror of
https://github.com/reactos/reactos.git
synced 2025-04-20 04:20:46 +00:00
implemented calculating of tracking thumb in scrollbars
svn path=/trunk/; revision=6014
This commit is contained in:
parent
eca8e8ad7c
commit
205f58421e
3 changed files with 240 additions and 40 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $Id: scrollbar.c,v 1.13 2003/09/08 02:14:20 weiden Exp $
|
||||
/* $Id: scrollbar.c,v 1.14 2003/09/08 15:08:56 weiden Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -353,22 +353,6 @@ SCROLL_PtInRectEx( LPRECT lpRect, POINT pt, BOOL vertical )
|
|||
return PtInRect( &rect, pt );
|
||||
}
|
||||
|
||||
/*
|
||||
DWORD FASTCALL
|
||||
SCROLL_HitTest(HWND hwnd, LONG idObject, POINT Point)
|
||||
{
|
||||
RECT WindowRect;
|
||||
|
||||
GetWindowRect(hwnd, &WindowRect);
|
||||
if (!PtInRect(&WindowRect, Point))
|
||||
{
|
||||
return(SCROLL_NOWHERE);
|
||||
}
|
||||
|
||||
return SCROLL_NOWHERE;
|
||||
}
|
||||
*/
|
||||
|
||||
DWORD
|
||||
SCROLL_HitTest( HWND hwnd, INT nBar, POINT pt, BOOL bDragging )
|
||||
{
|
||||
|
@ -386,11 +370,13 @@ SCROLL_HitTest( HWND hwnd, INT nBar, POINT pt, BOOL bDragging )
|
|||
|
||||
if ( (bDragging && !SCROLL_PtInRectEx( &sbi.rcScrollBar, pt, vertical )) ||
|
||||
(!PtInRect( &sbi.rcScrollBar, pt )) ) return SCROLL_NOWHERE;
|
||||
|
||||
|
||||
thumbPos = sbi.xyThumbTop;
|
||||
thumbSize = sbi.xyThumbBottom - thumbPos;
|
||||
arrowSize = sbi.dxyLineButton;
|
||||
|
||||
if (vertical)
|
||||
{
|
||||
arrowSize = GetSystemMetrics(SM_CYVSCROLL);
|
||||
if (pt.y < sbi.rcScrollBar.top + arrowSize) return SCROLL_TOP_ARROW;
|
||||
if (pt.y >= sbi.rcScrollBar.bottom - arrowSize) return SCROLL_BOTTOM_ARROW;
|
||||
if (!thumbPos) return SCROLL_TOP_RECT;
|
||||
|
@ -400,7 +386,6 @@ SCROLL_HitTest( HWND hwnd, INT nBar, POINT pt, BOOL bDragging )
|
|||
}
|
||||
else /* horizontal */
|
||||
{
|
||||
arrowSize = GetSystemMetrics(SM_CXHSCROLL);
|
||||
if (pt.x < sbi.rcScrollBar.left + arrowSize) return SCROLL_TOP_ARROW;
|
||||
if (pt.x >= sbi.rcScrollBar.right - arrowSize) return SCROLL_BOTTOM_ARROW;
|
||||
if (!thumbPos) return SCROLL_TOP_RECT;
|
||||
|
@ -416,13 +401,12 @@ SCROLL_HitTest( HWND hwnd, INT nBar, POINT pt, BOOL bDragging )
|
|||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
WINBOOL STDCALL
|
||||
EnableScrollBar(HWND hWnd, UINT wSBflags, UINT wArrows)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
return NtUserEnableScrollBar(hWnd, wSBflags, wArrows);
|
||||
}
|
||||
|
||||
|
||||
|
@ -444,7 +428,9 @@ GetScrollBarInfo(HWND hwnd, LONG idObject, PSCROLLBARINFO psbi)
|
|||
RtlCopyMemory(&sbi, psbi, sizeof(SCROLLBARINFO));
|
||||
ret = NtUserGetScrollBarInfo (hwnd, idObject, psbi);
|
||||
if(ret)
|
||||
{
|
||||
RtlCopyMemory(psbi, &sbi, sizeof(SCROLLBARINFO));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -484,13 +470,20 @@ GetScrollRange (HWND hWnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos)
|
|||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
int STDCALL
|
||||
SetScrollInfo (HWND hwnd, int fnBar, LPCSCROLLINFO lpsi, WINBOOL fRedraw)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
SCROLLINFO si;
|
||||
|
||||
if(!lpsi)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
RtlCopyMemory(&si, lpsi, lpsi->cbSize);
|
||||
return (int)NtUserSetScrollInfo(hwnd, fnBar, &si, fRedraw);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: metric.c,v 1.12 2003/08/29 09:29:11 gvg Exp $
|
||||
/* $Id: metric.c,v 1.13 2003/09/08 15:08:56 weiden Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -113,6 +113,7 @@ NtUserGetSystemMetrics(ULONG Index)
|
|||
case SM_CXHSCROLL:
|
||||
case SM_CYHSCROLL:
|
||||
return(16);
|
||||
case SM_CYVTHUMB:
|
||||
case SM_CXHTHUMB:
|
||||
return(16);
|
||||
case SM_CXICON:
|
||||
|
@ -192,7 +193,6 @@ NtUserGetSystemMetrics(ULONG Index)
|
|||
return(19);
|
||||
case SM_CYSMCAPTION:
|
||||
return(16);
|
||||
case SM_CYVTHUMB:
|
||||
case SM_DBCSENABLED:
|
||||
case SM_DEBUG:
|
||||
case SM_MENUDROPALIGNMENT:
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: scrollbar.c,v 1.11 2003/09/08 02:14:20 weiden Exp $
|
||||
/* $Id: scrollbar.c,v 1.12 2003/09/08 15:08:56 weiden Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -52,6 +52,55 @@
|
|||
#define SBRG_PAGEDOWNLEFT 4 /* the page down or page left region */
|
||||
#define SBRG_BOTTOMLEFTBTN 5 /* the bottom or left button */
|
||||
|
||||
/***********************************************************************
|
||||
* MulDiv (copied from kernel32)
|
||||
*/
|
||||
static INT IntMulDiv(
|
||||
INT nMultiplicand,
|
||||
INT nMultiplier,
|
||||
INT nDivisor)
|
||||
{
|
||||
#if SIZEOF_LONG_LONG >= 8
|
||||
long long ret;
|
||||
|
||||
if (!nDivisor) return -1;
|
||||
|
||||
/* We want to deal with a positive divisor to simplify the logic. */
|
||||
if (nDivisor < 0)
|
||||
{
|
||||
nMultiplicand = - nMultiplicand;
|
||||
nDivisor = -nDivisor;
|
||||
}
|
||||
|
||||
/* If the result is positive, we "add" to round. else, we subtract to round. */
|
||||
if ( ( (nMultiplicand < 0) && (nMultiplier < 0) ) ||
|
||||
( (nMultiplicand >= 0) && (nMultiplier >= 0) ) )
|
||||
ret = (((long long)nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor;
|
||||
else
|
||||
ret = (((long long)nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor;
|
||||
|
||||
if ((ret > 2147483647) || (ret < -2147483647)) return -1;
|
||||
return ret;
|
||||
#else
|
||||
if (!nDivisor) return -1;
|
||||
|
||||
/* We want to deal with a positive divisor to simplify the logic. */
|
||||
if (nDivisor < 0)
|
||||
{
|
||||
nMultiplicand = - nMultiplicand;
|
||||
nDivisor = -nDivisor;
|
||||
}
|
||||
|
||||
/* If the result is positive, we "add" to round. else, we subtract to round. */
|
||||
if ( ( (nMultiplicand < 0) && (nMultiplier < 0) ) ||
|
||||
( (nMultiplicand >= 0) && (nMultiplier >= 0) ) )
|
||||
return ((nMultiplicand * nMultiplier) + (nDivisor/2)) / nDivisor;
|
||||
|
||||
return ((nMultiplicand * nMultiplier) - (nDivisor/2)) / nDivisor;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
@ -113,16 +162,106 @@ IntGetScrollBarRect (PWINDOW_OBJECT Window, INT nBar, PRECT lprect)
|
|||
return vertical;
|
||||
}
|
||||
|
||||
#define MINTRACKTHUMB (8)
|
||||
BOOL FASTCALL
|
||||
IntCalculateThumb(PWINDOW_OBJECT Window, LONG idObject, PSCROLLBARINFO psbi, LPSCROLLINFO psi)
|
||||
{
|
||||
INT xThumb, yThumb, ThumbBox, cxy;
|
||||
switch(idObject)
|
||||
{
|
||||
case SB_HORZ:
|
||||
xThumb = NtUserGetSystemMetrics(SM_CXHSCROLL);
|
||||
cxy = psbi->rcScrollBar.right - psbi->rcScrollBar.left;
|
||||
if(cxy < (2 * xThumb))
|
||||
{
|
||||
xThumb = cxy / 2;
|
||||
psbi->xyThumbTop = 0;
|
||||
psbi->xyThumbBottom = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ThumbBox = psi->nPage ? MINTRACKTHUMB : NtUserGetSystemMetrics(SM_CXHTHUMB);
|
||||
cxy -= (2 * xThumb);
|
||||
if(cxy > ThumbBox)
|
||||
{
|
||||
if(psi->nPage)
|
||||
{
|
||||
DbgPrint("cxy = %d, max = %d, min = %d, page = %d\n", cxy, (UINT)psi->nMax, (UINT)psi->nMin, psi->nPage);
|
||||
//ThumbBox = ((UINT)cxy / ((UINT)psi->nMax - (UINT)psi->nMin)) * psi->nPage;
|
||||
ThumbBox = IntMulDiv(cxy, psi->nPage, psi->nMax - psi->nMin + 1);
|
||||
DbgPrint("ThumbBox = %d\n", ThumbBox);
|
||||
}
|
||||
psbi->xyThumbTop = xThumb;
|
||||
psbi->xyThumbBottom = xThumb + ThumbBox;
|
||||
}
|
||||
else
|
||||
{
|
||||
psbi->xyThumbTop = 0;
|
||||
psbi->xyThumbBottom = 0;
|
||||
}
|
||||
}
|
||||
psbi->dxyLineButton = xThumb;
|
||||
return TRUE;
|
||||
case SB_VERT:
|
||||
yThumb = NtUserGetSystemMetrics(SM_CYVSCROLL);
|
||||
cxy = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top;
|
||||
if(cxy < (2 * yThumb))
|
||||
{
|
||||
yThumb = cxy / 2;
|
||||
psbi->xyThumbTop = 0;
|
||||
psbi->xyThumbBottom = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ThumbBox = psi->nPage ? MINTRACKTHUMB : NtUserGetSystemMetrics(SM_CYVTHUMB);
|
||||
cxy -= (2 * yThumb);
|
||||
if(cxy > ThumbBox)
|
||||
{
|
||||
if(psi->nPage)
|
||||
{
|
||||
//ThumbBox = ((UINT)cxy / ((UINT)psi->nMax - (UINT)psi->nMin)) * psi->nPage;
|
||||
ThumbBox = IntMulDiv(cxy, psi->nPage, psi->nMax - psi->nMin + 1);
|
||||
}
|
||||
psbi->xyThumbTop = yThumb;
|
||||
psbi->xyThumbBottom = yThumb + ThumbBox;
|
||||
}
|
||||
else
|
||||
{
|
||||
psbi->xyThumbTop = 0;
|
||||
psbi->xyThumbBottom = 0;
|
||||
}
|
||||
}
|
||||
psbi->dxyLineButton = yThumb;
|
||||
return TRUE;
|
||||
case SB_CTL:
|
||||
/* FIXME */
|
||||
return FALSE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD FASTCALL
|
||||
IntCreateScrollBar(PWINDOW_OBJECT Window, LONG idObject)
|
||||
{
|
||||
PSCROLLBARINFO psbi;
|
||||
LPSCROLLINFO psi;
|
||||
LRESULT Result;
|
||||
INT i;
|
||||
|
||||
psbi = ExAllocatePool(PagedPool, sizeof(SCROLLBARINFO));
|
||||
psbi = ExAllocatePool(PagedPool, sizeof(SCROLLBARINFO) + sizeof(SCROLLINFO));
|
||||
if(!psbi)
|
||||
return FALSE;
|
||||
|
||||
psi = (LPSCROLLINFO)((PSCROLLBARINFO)(psbi + 1));
|
||||
|
||||
psi->cbSize = sizeof(LPSCROLLINFO);
|
||||
psi->nMin = 0;
|
||||
psi->nMax = 100;
|
||||
psi->nPage = 0;
|
||||
psi->nPos = 0;
|
||||
psi->nTrackPos = 0;
|
||||
|
||||
Result = WinPosGetNonClientSize(Window->Self,
|
||||
&Window->WindowRect,
|
||||
|
@ -136,12 +275,15 @@ IntCreateScrollBar(PWINDOW_OBJECT Window, LONG idObject)
|
|||
switch(idObject)
|
||||
{
|
||||
case SB_HORZ:
|
||||
//psbi->dxyLineButton = NtUserGetSystemMetrics(SM_CXHSCROLL);
|
||||
Window->pHScroll = psbi;
|
||||
break;
|
||||
case SB_VERT:
|
||||
//psbi->dxyLineButton = NtUserGetSystemMetrics(SM_CYVSCROLL);
|
||||
Window->pVScroll = psbi;
|
||||
break;
|
||||
case SB_CTL:
|
||||
/* FIXME - set psbi->dxyLineButton */
|
||||
Window->wExtra = psbi;
|
||||
break;
|
||||
default:
|
||||
|
@ -149,7 +291,8 @@ IntCreateScrollBar(PWINDOW_OBJECT Window, LONG idObject)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
IntGetScrollBarRect (Window, idObject, &(psbi->rcScrollBar));
|
||||
IntGetScrollBarRect(Window, idObject, &(psbi->rcScrollBar));
|
||||
IntCalculateThumb(Window, idObject, psbi, psi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -237,6 +380,8 @@ STDCALL
|
|||
NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
|
||||
{
|
||||
PWINDOW_OBJECT Window;
|
||||
PSCROLLBARINFO sbi;
|
||||
LPSCROLLINFO psi;
|
||||
INT Bar;
|
||||
|
||||
if(!psbi || (psbi->cbSize != sizeof(SCROLLBARINFO)))
|
||||
|
@ -259,7 +404,7 @@ NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
|
|||
if(Window->pHScroll)
|
||||
{
|
||||
Bar = SB_HORZ;
|
||||
memcpy(psbi, Window->pHScroll, sizeof(SCROLLBARINFO));
|
||||
sbi = Window->pHScroll;
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
|
@ -267,7 +412,7 @@ NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
|
|||
if(Window->pVScroll)
|
||||
{
|
||||
Bar = SB_VERT;
|
||||
memcpy(psbi, Window->pVScroll, sizeof(SCROLLBARINFO));
|
||||
sbi = Window->pVScroll;
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
|
@ -275,7 +420,7 @@ NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
|
|||
if(Window->wExtra)
|
||||
{
|
||||
Bar = SB_CTL;
|
||||
memcpy(psbi, Window->wExtra, sizeof(SCROLLBARINFO));
|
||||
sbi = Window->wExtra;
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
|
@ -284,8 +429,13 @@ NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
|
|||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
psi = (LPSCROLLINFO)((PSCROLLBARINFO)(sbi + 1));
|
||||
|
||||
IntGetScrollBarRect (Window, Bar, &(psbi->rcScrollBar));
|
||||
IntGetScrollBarRect(Window, Bar, &(sbi->rcScrollBar));
|
||||
IntCalculateThumb(Window, Bar, sbi, psi);
|
||||
|
||||
memcpy(psbi, sbi, sizeof(SCROLLBARINFO));
|
||||
|
||||
IntReleaseWindowObject(Window);
|
||||
return TRUE;
|
||||
|
@ -372,7 +522,7 @@ NtUserEnableScrollBar(
|
|||
if(InfoH)
|
||||
Chg = (IntEnableScrollBar(TRUE, InfoH, wArrows) || Chg);
|
||||
|
||||
if(Chg)
|
||||
//if(Chg && (Window->Style & WS_VISIBLE))
|
||||
/* FIXME - repaint scrollbars */
|
||||
|
||||
IntReleaseWindowObject(Window);
|
||||
|
@ -406,6 +556,17 @@ NtUserSetScrollInfo(
|
|||
{
|
||||
PWINDOW_OBJECT Window;
|
||||
PSCROLLBARINFO Info = NULL;
|
||||
LPSCROLLINFO psi;
|
||||
BOOL Chg = FALSE;
|
||||
UINT Mask;
|
||||
DWORD Ret;
|
||||
|
||||
if(!lpsi || ((lpsi->cbSize != sizeof(SCROLLINFO)) &&
|
||||
(lpsi->cbSize != sizeof(SCROLLINFO) - sizeof(lpsi->nTrackPos))))
|
||||
{
|
||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Window = IntGetWindowObject(hwnd);
|
||||
|
||||
|
@ -419,20 +580,66 @@ NtUserSetScrollInfo(
|
|||
{
|
||||
case SB_HORZ:
|
||||
Info = Window->pHScroll;
|
||||
break;
|
||||
if(Info)
|
||||
break;
|
||||
/* fall through */
|
||||
case SB_VERT:
|
||||
Info = Window->pVScroll;
|
||||
break;
|
||||
if(Info)
|
||||
break;
|
||||
/* fall through */
|
||||
case SB_CTL:
|
||||
Info = Window->wExtra;
|
||||
break;
|
||||
if(Info)
|
||||
break;
|
||||
/* fall through */
|
||||
default:
|
||||
IntReleaseWindowObject(Window);
|
||||
return 0;
|
||||
}
|
||||
|
||||
psi = (LPSCROLLINFO)((PSCROLLBARINFO)(Info + 1));
|
||||
|
||||
if(lpsi->fMask == SIF_ALL)
|
||||
Mask = SIF_DISABLENOSCROLL | SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS;
|
||||
else
|
||||
Mask = lpsi->fMask;
|
||||
|
||||
if(Mask & SIF_DISABLENOSCROLL)
|
||||
{
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
if((Mask & SIF_PAGE) && (psi->nPage != lpsi->nPage))
|
||||
{
|
||||
psi->nPage = lpsi->nPage;
|
||||
Chg = TRUE;
|
||||
}
|
||||
|
||||
if((Mask & SIF_POS) && (psi->nPos != lpsi->nPos))
|
||||
{
|
||||
psi->nPos = lpsi->nPos;
|
||||
Chg = TRUE;
|
||||
}
|
||||
|
||||
if((Mask & SIF_RANGE) && ((psi->nMin != lpsi->nMin) || (psi->nMax != lpsi->nMax)))
|
||||
{
|
||||
psi->nMin = lpsi->nMin;
|
||||
psi->nMax = lpsi->nMax;
|
||||
Chg = TRUE;
|
||||
}
|
||||
|
||||
/* FIXME check assigned values */
|
||||
|
||||
if(fRedraw && Chg && (Window->Style & WS_VISIBLE))
|
||||
{
|
||||
/* FIXME - Redraw */
|
||||
}
|
||||
|
||||
Ret = psi->nPos;
|
||||
|
||||
IntReleaseWindowObject(Window);
|
||||
return 0;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/* Ported from WINE20020904 (SCROLL_ShowScrollBar) */
|
||||
|
|
Loading…
Reference in a new issue