Newer
Older
* SetScrollInfo32 can be used to set the position, upper bound,
* lower bound, and page size of a scrollbar control.
*
* RETURNS
* Scrollbar position
*
* NOTE
* For 100 lines of text to be displayed in a window of 25 lines,
* one would for instance use info->nMin=0, info->nMax=75
* (corresponding to the 76 different positions of the window on
* the text), and info->nPage=25.
INT WINAPI SetScrollInfo(
HWND hwnd /* [I] Handle of window whose scrollbar will be affected */,
INT nBar /* [I] One of SB_HORZ, SB_VERT, or SB_CTL */,
const SCROLLINFO *info /* [I] Specifies what to change and new values */,
BOOL bRedraw /* [I] Should scrollbar be redrawn afterwards ? */)
INT action;
INT retVal = SCROLL_SetScrollInfo( hwnd, nBar, info, &action );
if( action & SA_SSI_HIDE )
SCROLL_ShowScrollBar( hwnd, nBar, FALSE, FALSE );
else
{
if( action & SA_SSI_SHOW )
if( SCROLL_ShowScrollBar( hwnd, nBar, TRUE, TRUE ) )
return retVal; /* SetWindowPos() already did the painting */
if( bRedraw && (action & SA_SSI_REFRESH))
SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, TRUE );
else if( action & SA_SSI_REPAINT_ARROWS )
SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, FALSE );
}
return retVal;
}
INT SCROLL_SetScrollInfo( HWND hwnd, INT nBar,
const SCROLLINFO *info, INT *action )
{
/* Update the scrollbar state and set action flags according to
* what has to be done graphics wise. */
UINT new_flags;
*action = 0;
if (!(infoPtr = SCROLL_GetScrollInfo(hwnd, nBar))) return 0;
if (info->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL)) return 0;
if ((info->cbSize != sizeof(*info)) &&
(info->cbSize != sizeof(*info)-sizeof(info->nTrackPos))) return 0;
/* Set the page size */
if (info->fMask & SIF_PAGE)
{
if( infoPtr->Page != info->nPage )
{
infoPtr->Page = info->nPage;
*action |= SA_SSI_REFRESH;
}
}
/* Set the scroll pos */
if (info->fMask & SIF_POS)
{
if( infoPtr->CurVal != info->nPos )
{
infoPtr->CurVal = info->nPos;
*action |= SA_SSI_REFRESH;
}
}
/* Set the scroll range */
if (info->fMask & SIF_RANGE)
{
dsprintf(scroll, " min=%d max=%d", info->nMin, info->nMax );
/* Invalid range -> range is set to (0,0) */
if ((info->nMin > info->nMax) ||
((UINT)(info->nMax - info->nMin) >= 0x80000000))
{
infoPtr->MinVal = 0;
infoPtr->MaxVal = 0;
}
else
{
if( infoPtr->MinVal != info->nMin ||
infoPtr->MaxVal != info->nMax )
{
*action |= SA_SSI_REFRESH;
infoPtr->MinVal = info->nMin;
infoPtr->MaxVal = info->nMax;
}
TRACE("hwnd=%04x bar=%d %s\n",
/* Make sure the page size is valid */
if (infoPtr->Page < 0) infoPtr->Page = 0;
else if (infoPtr->Page > infoPtr->MaxVal - infoPtr->MinVal + 1 )
infoPtr->Page = infoPtr->MaxVal - infoPtr->MinVal + 1;
/* Make sure the pos is inside the range */
if (infoPtr->CurVal < infoPtr->MinVal)
infoPtr->CurVal = infoPtr->MinVal;
else if (infoPtr->CurVal > infoPtr->MaxVal - MAX( infoPtr->Page-1, 0 ))
infoPtr->CurVal = infoPtr->MaxVal - MAX( infoPtr->Page-1, 0 );
TRACE(" new values: page=%d pos=%d min=%d max=%d\n",
infoPtr->Page, infoPtr->CurVal,
infoPtr->MinVal, infoPtr->MaxVal );
/* Check if the scrollbar should be hidden or disabled */
if (info->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL))
new_flags = infoPtr->flags;
if (infoPtr->MinVal >= infoPtr->MaxVal - MAX( infoPtr->Page-1, 0 ))
/* Hide or disable scroll-bar */
if (info->fMask & SIF_DISABLENOSCROLL)
*action |= SA_SSI_REFRESH;
}
{
*action = SA_SSI_HIDE;
goto done;
}
}
else /* Show and enable scroll-bar */
{
new_flags = 0;
if (nBar != SB_CTL)
*action |= SA_SSI_SHOW;
if (infoPtr->flags != new_flags) /* check arrow flags */
*action |= SA_SSI_REPAINT_ARROWS;
done:
/* Return current position */
return infoPtr->CurVal;
}
/*************************************************************************
* GetScrollInfo16 (USER.476)
*/
BOOL16 WINAPI GetScrollInfo16( HWND16 hwnd, INT16 nBar, LPSCROLLINFO info )
return GetScrollInfo( hwnd, nBar, info );
}
/*************************************************************************
* GetScrollInfo32 can be used to retrieve the position, upper bound,
* lower bound, and page size of a scrollbar control.
*
* RETURNS STD
BOOL WINAPI GetScrollInfo(
HWND hwnd /* [I] Handle of window */ ,
INT nBar /* [I] One of SB_HORZ, SB_VERT, or SB_CTL */,
LPSCROLLINFO info /* [IO] (info.fMask [I] specifies which values are to retrieve) */)
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
{
SCROLLBAR_INFO *infoPtr;
if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, nBar ))) return FALSE;
if (info->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL)) return FALSE;
if ((info->cbSize != sizeof(*info)) &&
(info->cbSize != sizeof(*info)-sizeof(info->nTrackPos))) return FALSE;
if (info->fMask & SIF_PAGE) info->nPage = infoPtr->Page;
if (info->fMask & SIF_POS) info->nPos = infoPtr->CurVal;
if ((info->fMask & SIF_TRACKPOS) && (info->cbSize == sizeof(*info)))
info->nTrackPos = (SCROLL_TrackingWin==hwnd) ? SCROLL_TrackingVal : 0;
if (info->fMask & SIF_RANGE)
{
info->nMin = infoPtr->MinVal;
info->nMax = infoPtr->MaxVal;
}
return (info->fMask & SIF_ALL) != 0;
}
/*************************************************************************
* SetScrollPos16 (USER.62)
*/
INT16 WINAPI SetScrollPos16( HWND16 hwnd, INT16 nBar, INT16 nPos,
BOOL16 bRedraw )
return (INT16)SetScrollPos( hwnd, nBar, nPos, bRedraw );
/*************************************************************************
*
* RETURNS
* Success: Scrollbar position
* Failure: 0
*
* REMARKS
* Note the ambiguity when 0 is returned. Use GetLastError
* to make sure there was an error (and to know which one).
INT WINAPI SetScrollPos(
HWND hwnd /* [I] Handle of window whose scrollbar will be affected */,
INT nBar /* [I] One of SB_HORZ, SB_VERT, or SB_CTL */,
INT nPos /* [I] New value */,
BOOL bRedraw /* [I] Should scrollbar be redrawn afterwards ? */ )
INT oldPos;
if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, nBar ))) return 0;
oldPos = infoPtr->CurVal;
info.cbSize = sizeof(info);
info.nPos = nPos;
info.fMask = SIF_POS;
SetScrollInfo( hwnd, nBar, &info, bRedraw );
return oldPos;
}
/*************************************************************************
* GetScrollPos16 (USER.63)
*/
INT16 WINAPI GetScrollPos16( HWND16 hwnd, INT16 nBar )
return (INT16)GetScrollPos( hwnd, nBar );
/*************************************************************************
*
* RETURNS
* Success: Current position
* Failure: 0
*
* REMARKS
* Note the ambiguity when 0 is returned. Use GetLastError
* to make sure there was an error (and to know which one).
INT WINAPI GetScrollPos(
HWND hwnd, /* [I] Handle of window */
INT nBar /* [I] One of SB_HORZ, SB_VERT, or SB_CTL */)
if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, nBar ))) return 0;
return infoPtr->CurVal;
}
/*************************************************************************
* SetScrollRange16 (USER.64)
*/
void WINAPI SetScrollRange16( HWND16 hwnd, INT16 nBar,
INT16 MinVal, INT16 MaxVal, BOOL16 bRedraw )
{
/* Invalid range -> range is set to (0,0) */
if ((INT)MaxVal - (INT)MinVal > 0x7fff) MinVal = MaxVal = 0;
SetScrollRange( hwnd, nBar, MinVal, MaxVal, bRedraw );
/*************************************************************************
BOOL WINAPI SetScrollRange(
HWND hwnd, /* [I] Handle of window whose scrollbar will be affected */
INT nBar, /* [I] One of SB_HORZ, SB_VERT, or SB_CTL */
INT MinVal, /* [I] New minimum value */
INT MaxVal, /* [I] New maximum value */
BOOL bRedraw /* [I] Should scrollbar be redrawn afterwards ? */)
info.cbSize = sizeof(info);
info.nMin = MinVal;
info.nMax = MaxVal;
info.fMask = SIF_RANGE;
SetScrollInfo( hwnd, nBar, &info, bRedraw );
/*************************************************************************
* SCROLL_SetNCSbState
*
* Updates both scrollbars at the same time. Used by MDI CalcChildScroll().
INT SCROLL_SetNCSbState(WND* wndPtr, int vMin, int vMax, int vPos,
INT vA, hA;
SCROLLINFO vInfo, hInfo;
vInfo.cbSize = hInfo.cbSize = sizeof(SCROLLINFO);
vInfo.nMin = vMin; hInfo.nMin = hMin;
vInfo.nMax = vMax; hInfo.nMax = hMax;
vInfo.nPos = vPos; hInfo.nPos = hPos;
vInfo.fMask = hInfo.fMask = SIF_RANGE | SIF_POS;
SCROLL_SetScrollInfo( wndPtr->hwndSelf, SB_VERT, &vInfo, &vA );
SCROLL_SetScrollInfo( wndPtr->hwndSelf, SB_HORZ, &hInfo, &hA );
if( !SCROLL_ShowScrollBar( wndPtr->hwndSelf, SB_BOTH,
(hA & SA_SSI_SHOW),(vA & SA_SSI_SHOW) ) )
{
/* SetWindowPos() wasn't called, just redraw the scrollbars if needed */
if( vA & SA_SSI_REFRESH )
SCROLL_RefreshScrollBar( wndPtr->hwndSelf, SB_VERT, FALSE, TRUE );
if( hA & SA_SSI_REFRESH )
SCROLL_RefreshScrollBar( wndPtr->hwndSelf, SB_HORZ, FALSE, TRUE );
}
return 0;
/*************************************************************************
BOOL16 WINAPI GetScrollRange16( HWND16 hwnd, INT16 nBar,
LPINT16 lpMin, LPINT16 lpMax)
INT min, max;
BOOL16 ret = GetScrollRange( hwnd, nBar, &min, &max );
if (lpMin) *lpMin = min;
if (lpMax) *lpMax = max;
return ret;
}
/*************************************************************************
BOOL WINAPI GetScrollRange(
HWND hwnd, /* [I] Handle of window */
INT nBar, /* [I] One of SB_HORZ, SB_VERT, or SB_CTL */
LPINT lpMin, /* [O] Where to store minimum value */
LPINT lpMax /* [O] Where to store maximum value */)
if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, nBar )))
{
if (lpMin) lpMin = 0;
if (lpMax) lpMax = 0;
return FALSE;
}
if (lpMin) *lpMin = infoPtr->MinVal;
if (lpMax) *lpMax = infoPtr->MaxVal;
return TRUE;
}
/*************************************************************************
* SCROLL_ShowScrollBar()
* Back-end for ShowScrollBar(). Returns FALSE if no action was taken.
* NOTE: fShowV/fShowH must be zero when nBar is SB_HORZ/SB_VERT.
BOOL SCROLL_ShowScrollBar( HWND hwnd, INT nBar,
BOOL fShowH, BOOL fShowV )
TRACE("hwnd=%04x bar=%d horz=%d, vert=%d\n",
hwnd, nBar, fShowH, fShowV );
ShowWindow( hwnd, fShowH ? SW_SHOW : SW_HIDE );
retvalue = TRUE;
goto END;
case SB_BOTH:
if (fShowH)
fShowH = !(wndPtr->dwStyle & WS_HSCROLL);
wndPtr->dwStyle |= WS_HSCROLL;
}
else /* hide it */
{
fShowH = (wndPtr->dwStyle & WS_HSCROLL);
if( nBar == SB_HORZ ) break;
/* fall through */
if (fShowV)
fShowV = !(wndPtr->dwStyle & WS_VSCROLL);
else /* hide it */
fShowV = (wndPtr->dwStyle & WS_VSCROLL);
wndPtr->dwStyle &= ~WS_VSCROLL;
}
break;
default:
retvalue = FALSE; /* Nothing to do! */
goto END;
if( fShowH || fShowV ) /* frame has been changed, let the window redraw itself */
{
SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE
| SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
retvalue = TRUE;
goto END;
}
retvalue = FALSE; /* no frame changes */
END:
WIN_ReleaseWndPtr(wndPtr);
return retvalue;
}
/*************************************************************************
* ShowScrollBar16 (USER.267)
*/
void WINAPI ShowScrollBar16( HWND16 hwnd, INT16 nBar, BOOL16 fShow )
{
SCROLL_ShowScrollBar( hwnd, nBar, (nBar == SB_VERT) ? 0 : fShow,
(nBar == SB_HORZ) ? 0 : fShow );
}
/*************************************************************************
* ShowScrollBar32 (USER32.532)
*
* RETURNS STD
*/
BOOL WINAPI ShowScrollBar(
HWND hwnd, /* [I] Handle of window whose scrollbar(s) will be affected */
INT nBar, /* [I] One of SB_HORZ, SB_VERT, SB_BOTH or SB_CTL */
BOOL fShow /* [I] TRUE = show, FALSE = hide */)
{
SCROLL_ShowScrollBar( hwnd, nBar, (nBar == SB_VERT) ? 0 : fShow,
(nBar == SB_HORZ) ? 0 : fShow );
/*************************************************************************
BOOL16 WINAPI EnableScrollBar16( HWND16 hwnd, INT16 nBar, UINT16 flags )
return EnableScrollBar( hwnd, nBar, flags );
}
/*************************************************************************
BOOL WINAPI EnableScrollBar( HWND hwnd, INT nBar, UINT flags )
BOOL bFineWithMe;
TRACE("%04x %d %d\n", hwnd, nBar, flags );
if (nBar == SB_BOTH)
{
if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, SB_VERT ))) return FALSE;
if (!(bFineWithMe = (infoPtr->flags == flags)) )
{
infoPtr->flags = flags;
SCROLL_RefreshScrollBar( hwnd, SB_VERT, TRUE, TRUE );
}
nBar = SB_HORZ;
}
else
bFineWithMe = TRUE;
if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, nBar ))) return FALSE;
if (bFineWithMe && infoPtr->flags == flags) return FALSE;
SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, TRUE );