* 'thumbSize' returns the size of the thumb, and 'thumbPos' returns the position of the thumb relative to the left or to
* the top. Return TRUE if the scrollbar is vertical, FALSE if horizontal.
*/
+static inline void mirror_rect( const RECT *window_rect, RECT *rect )
+{
+ int width = window_rect->right - window_rect->left;
+ int tmp = rect->left;
+ rect->left = width - rect->right;
+ rect->right = width - tmp;
+}
+
+PSBDATA FASTCALL
+IntGetSBData(PWND pwnd, INT Bar)
+{
+ PSBWND pSBWnd;
+ PSBINFO pSBInfo;
+
+ pSBInfo = pwnd->pSBInfo;
+ switch (Bar)
+ {
+ case SB_HORZ:
+ return &pSBInfo->Horz;
+ case SB_VERT:
+ return &pSBInfo->Vert;
+ case SB_CTL:
+ if ( pwnd->cbwndExtra != (sizeof(SBWND)-sizeof(WND)) )
+ {
+ ERR("IntGetSBData Wrong Extra bytes for CTL Scrollbar!\n");
+ return 0;
+ }
+ pSBWnd = (PSBWND)pwnd;
+ return (PSBDATA)&pSBWnd->SBCalc;
+ default:
+ ERR("IntGetSBData Bad Bar!\n");
+ }
+ return NULL;
+}
+
BOOL FASTCALL
IntGetScrollBarRect (PWND Wnd, INT nBar, RECTL *lprect)
{
BOOL vertical;
- RECTL ClientRect = Wnd->rcClient;
- RECTL WindowRect = Wnd->rcWindow;
+ *lprect = Wnd->rcClient;
+
+ RECTL_vOffsetRect( lprect, -Wnd->rcWindow.left, -Wnd->rcWindow.top );
+ if (Wnd->ExStyle & WS_EX_LAYOUTRTL)
+ mirror_rect( &Wnd->rcWindow, lprect );
switch (nBar)
{
case SB_HORZ:
- lprect->left = ClientRect.left - WindowRect.left;
- lprect->top = ClientRect.bottom - WindowRect.top;
- lprect->right = ClientRect.right - WindowRect.left;
- lprect->bottom = lprect->top + UserGetSystemMetrics (SM_CYHSCROLL);
+ lprect->top = lprect->bottom;
+ lprect->bottom += UserGetSystemMetrics (SM_CYHSCROLL);
+ if (Wnd->style & WS_BORDER)
+ {
+ lprect->left--;
+ lprect->right++;
+ }
+ else if (Wnd->style & WS_VSCROLL)
+ {
+ lprect->right++;
+ }
vertical = FALSE;
break;
case SB_VERT:
if(Wnd->ExStyle & WS_EX_LEFTSCROLLBAR)
{
- lprect->right = ClientRect.left - WindowRect.left;
- lprect->left = lprect->right - UserGetSystemMetrics(SM_CXVSCROLL);
+ lprect->right = lprect->right;;
+ lprect->left -= UserGetSystemMetrics(SM_CXVSCROLL);
}
else
{
- lprect->left = ClientRect.right - WindowRect.left;
- lprect->right = lprect->left + UserGetSystemMetrics(SM_CXVSCROLL);
+ lprect->left = lprect->right;
+ lprect->right += UserGetSystemMetrics(SM_CXVSCROLL);
+ }
+ if (Wnd->style & WS_BORDER)
+ {
+ lprect->top--;
+ lprect->bottom++;
+ }
+ else if (Wnd->style & WS_HSCROLL)
+ {
+ lprect->bottom++;
}
- lprect->top = ClientRect.top - WindowRect.top;
- lprect->bottom = ClientRect.bottom - WindowRect.top;
vertical = TRUE;
break;
case SB_CTL:
IntGetClientRect (Wnd, lprect);
- vertical = ((Wnd->style & SBS_VERT) != 0);
+ vertical = !!(Wnd->style & SBS_VERT);
break;
default:
}
BOOL FASTCALL
-IntCalculateThumb(PWND Wnd, LONG idObject, PSCROLLBARINFO psbi, LPSCROLLINFO psi)
+IntCalculateThumb(PWND Wnd, LONG idObject, PSCROLLBARINFO psbi, PSBDATA pSBData)
{
INT Thumb, ThumbBox, ThumbPos, cxy, mx;
RECTL ClientRect;
}
else
{
- ThumbBox = psi->nPage ? MINTRACKTHUMB : UserGetSystemMetrics(SM_CXHTHUMB);
+ ThumbBox = pSBData->page ? MINTRACKTHUMB : UserGetSystemMetrics(SM_CXHTHUMB);
cxy -= (2 * Thumb);
if(cxy >= ThumbBox)
{
- if(psi->nPage)
+ if(pSBData->page)
{
- ThumbBox = max(EngMulDiv(cxy, psi->nPage, psi->nMax - psi->nMin + 1), ThumbBox);
+ ThumbBox = max(EngMulDiv(cxy, pSBData->page, pSBData->posMax - pSBData->posMin + 1), ThumbBox);
}
if(cxy > ThumbBox)
{
- mx = psi->nMax - max(psi->nPage - 1, 0);
- if(psi->nMin < mx)
- ThumbPos = Thumb + EngMulDiv(cxy - ThumbBox, psi->nPos - psi->nMin, mx - psi->nMin);
+ mx = pSBData->posMax - max(pSBData->page - 1, 0);
+ if(pSBData->posMin < mx)
+ ThumbPos = Thumb + EngMulDiv(cxy - ThumbBox, pSBData->pos - pSBData->posMin, mx - pSBData->posMin);
else
ThumbPos = Thumb + ThumbBox;
}
return TRUE;
}
-
+/*
static VOID FASTCALL
IntUpdateSBInfo(PWND Window, int wBar)
{
PSCROLLBARINFO sbi;
- LPSCROLLINFO psi;
+ PSBDATA pSBData;
ASSERT(Window);
ASSERT(Window->pSBInfo);
ASSERT(Window->pSBInfoex);
sbi = IntGetScrollbarInfoFromWindow(Window, wBar);
- psi = IntGetScrollInfoFromWindow(Window, wBar);
+ pSBData = IntGetSBData(Window, wBar);
IntGetScrollBarRect(Window, wBar, &(sbi->rcScrollBar));
- IntCalculateThumb(Window, wBar, sbi, psi);
+ IntCalculateThumb(Window, wBar, sbi, pSBData);
}
-
+*/
static BOOL FASTCALL
-co_IntGetScrollInfo(PWND Window, INT nBar, LPSCROLLINFO lpsi)
+co_IntGetScrollInfo(PWND Window, INT nBar, PSBDATA pSBData, LPSCROLLINFO lpsi)
{
UINT Mask;
LPSCROLLINFO psi;
return FALSE;
}
- if (!Window->pSBInfo) return FALSE;
+ if (!Window->pSBInfo)
+ {
+ ERR("IntGetScrollInfo No window scrollbar info!\n");
+ return FALSE;
+ }
psi = IntGetScrollInfoFromWindow(Window, nBar);
PSCROLLBARINFO psbi;
UINT new_flags;
INT action = 0;
+ PSBDATA pSBData;
+ DWORD OldPos;
BOOL bChangeParams = FALSE; /* Don't show/hide scrollbar if params don't change */
ASSERT_REFS_CO(Window);
EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
- if (lpsi->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL))
+ if (lpsi->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL | SIF_PREVIOUSPOS))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
psbi = IntGetScrollbarInfoFromWindow(Window, nBar);
Info = IntGetScrollInfoFromWindow(Window, nBar);
+ pSBData = IntGetSBData(Window, nBar);
/* Set the page size */
if (lpsi->fMask & SIF_PAGE)
if (Info->nPage != lpsi->nPage)
{
Info->nPage = lpsi->nPage;
+ pSBData->page = lpsi->nPage;
bChangeParams = TRUE;
}
}
{
if (Info->nPos != lpsi->nPos)
{
+ OldPos = Info->nPos;
Info->nPos = lpsi->nPos;
+ pSBData->pos = lpsi->nPos;
bChangeParams = TRUE;
}
}
{
Info->nMin = 0;
Info->nMax = 0;
+ pSBData->posMin = 0;
+ pSBData->posMax = 0;
bChangeParams = TRUE;
}
else if (Info->nMin != lpsi->nMin || Info->nMax != lpsi->nMax)
{
Info->nMin = lpsi->nMin;
Info->nMax = lpsi->nMax;
+ pSBData->posMin = lpsi->nMin;
+ pSBData->posMax = lpsi->nMax;
bChangeParams = TRUE;
}
}
/* Make sure the page size is valid */
if (Info->nPage < 0)
- Info->nPage = 0;
+ {
+ pSBData->page = Info->nPage = 0;
+ }
else if ((Info->nMax - Info->nMin + 1UL) < Info->nPage)
{
- Info->nPage = Info->nMax - Info->nMin + 1;
+ pSBData->page = Info->nPage = Info->nMax - Info->nMin + 1;
}
/* Make sure the pos is inside the range */
if (Info->nPos < Info->nMin)
{
- Info->nPos = Info->nMin;
+ pSBData->pos = Info->nPos = Info->nMin;
}
else if (Info->nPos > (Info->nMax - max((int)Info->nPage - 1, 0)))
{
- Info->nPos = Info->nMax - max(Info->nPage - 1, 0);
+ pSBData->pos = Info->nPos = Info->nMax - max(Info->nPage - 1, 0);
}
/*
*/
if (!(lpsi->fMask & SIF_ALL))
{
- goto done; //return Info->nPos;
+ //goto done;
+ return lpsi->fMask & SIF_PREVIOUSPOS ? OldPos : pSBData->pos;
}
/* Check if the scrollbar should be hidden or disabled */
}
}
-done:
+//done:
if ( action & SA_SSI_HIDE )
{
co_UserShowScrollBar(Window, nBar, FALSE, FALSE);
{
if ( action & SA_SSI_SHOW )
if ( co_UserShowScrollBar(Window, nBar, TRUE, TRUE) )
- return Info->nPos; /* SetWindowPos() already did the painting */
+ return lpsi->fMask & SIF_PREVIOUSPOS ? OldPos : pSBData->pos; /* SetWindowPos() already did the painting */
if (bRedraw)
{ // FIXME: Arrows and interior.
RECTL UpdateRect = psbi->rcScrollBar;
UpdateRect.bottom -= Window->rcClient.top - Window->rcWindow.top;
co_UserRedrawWindow(Window, &UpdateRect, 0, RDW_INVALIDATE | RDW_FRAME);
} // FIXME: Arrows
- else if( action & SA_SSI_REPAINT_ARROWS )
+/* else if( action & SA_SSI_REPAINT_ARROWS )
{
RECTL UpdateRect = psbi->rcScrollBar;
UpdateRect.left -= Window->rcClient.left - Window->rcWindow.left;
UpdateRect.bottom -= Window->rcClient.top - Window->rcWindow.top;
co_UserRedrawWindow(Window, &UpdateRect, 0, RDW_INVALIDATE | RDW_FRAME);
}
- }
+*/ }
/* Return current position */
- return Info->nPos;
+ return lpsi->fMask & SIF_PREVIOUSPOS ? OldPos : pSBData->pos;
}
BOOL FASTCALL
{
INT Bar;
PSCROLLBARINFO sbi;
- LPSCROLLINFO psi;
+ PSBDATA pSBData;
ASSERT_REFS_CO(Window);
Bar = SBOBJ_TO_SBID(idObject);
if(!co_IntCreateScrollBars(Window))
{
+ ERR("Failed to create scrollbars for window.\n");
return FALSE;
}
sbi = IntGetScrollbarInfoFromWindow(Window, Bar);
- psi = IntGetScrollInfoFromWindow(Window, Bar);
+ pSBData = IntGetSBData(Window, Bar);
IntGetScrollBarRect(Window, Bar, &(sbi->rcScrollBar));
- IntCalculateThumb(Window, Bar, sbi, psi);
+ IntCalculateThumb(Window, Bar, sbi, pSBData);
RtlCopyMemory(psbi, sbi, sizeof(SCROLLBARINFO));
co_IntCreateScrollBars(PWND Window)
{
PSCROLLBARINFO psbi;
- LPSCROLLINFO psi;
+ PSBDATA pSBData;
ULONG Size, s;
INT i;
for (i = 0; i < CCHILDREN_SCROLLBAR + 1; i++)
psbi->rgstate[i] = 0;
- psi = IntGetScrollInfoFromWindow(Window, s);
- psi->cbSize = sizeof(LPSCROLLINFO);
- psi->nMax = 100;
+ pSBData = IntGetSBData(Window, s);
IntGetScrollBarRect(Window, s, &(psbi->rcScrollBar));
- IntCalculateThumb(Window, s, psbi, psi);
+ IntCalculateThumb(Window, s, psbi, pSBData);
}
return TRUE;
{
case SB_CTL:
{
- if (Wnd->pSBInfo) IntUpdateSBInfo(Wnd, SB_CTL); // Is this needed? Was tested w/o!
+ //IntUpdateSBInfo(Wnd, SB_CTL); // Is this needed? Was tested w/o!
co_WinPosShowWindow(Wnd, fShowH ? SW_SHOW : SW_HIDE);
return TRUE;
return FALSE;
}
-
- old_style = Wnd->style;
- Wnd->style = (Wnd->style | set_bits) & ~clear_bits;
-
- if (fShowH || fShowV)
- {
- if (!Wnd->pSBInfo) co_IntCreateScrollBars(Wnd);
- }
-
+ old_style = IntSetStyle( Wnd, set_bits, clear_bits );
if ((old_style & clear_bits) != 0 || (old_style & set_bits) != set_bits)
{
///// Is this needed? Was tested w/o!
- if (Wnd->style & WS_HSCROLL) IntUpdateSBInfo(Wnd, SB_HORZ);
- if (Wnd->style & WS_VSCROLL) IntUpdateSBInfo(Wnd, SB_VERT);
+ //if (Wnd->style & WS_HSCROLL) IntUpdateSBInfo(Wnd, SB_HORZ);
+ //if (Wnd->style & WS_VSCROLL) IntUpdateSBInfo(Wnd, SB_VERT);
/////
/* Frame has been changed, let the window redraw itself */
co_WinPosSetWindowPos(Wnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
return FALSE;
}
+LRESULT APIENTRY
+ScrollBarWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT lResult = 0;
+ PWND pWnd;
+ pWnd = UserGetWindowObject(hWnd);
+ if (!pWnd) return 0;
+
+ switch(Msg)
+ {
+ case WM_ENABLE:
+ {
+ if (pWnd->pSBInfo)
+ {
+ pWnd->pSBInfo->WSBflags = wParam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH;
+ }
+ }
+ break;
+ }
+ return lResult;
+}
+
////
BOOL
PSBDATA pSBData,
LPSCROLLINFO lpsi)
{
- NTSTATUS Status;
PWND Window;
SCROLLINFO psi;
- DWORD sz;
BOOL Ret;
+ SBDATA SBDataSafe;
DECLARE_RETURN(BOOL);
USER_REFERENCE_ENTRY Ref;
TRACE("Enter NtUserGetScrollInfo\n");
- UserEnterExclusive();
+ UserEnterShared();
- Status = MmCopyFromCaller(&psi.cbSize, &(lpsi->cbSize), sizeof(UINT));
- if(!NT_SUCCESS(Status) ||
- !((psi.cbSize == sizeof(SCROLLINFO)) || (psi.cbSize == sizeof(SCROLLINFO) - sizeof(psi.nTrackPos))))
+ _SEH2_TRY
{
- SetLastNtError(Status);
- RETURN(FALSE);
+ RtlCopyMemory(&psi, lpsi, sizeof(SCROLLINFO));
+ if (pSBData)
+ {
+ RtlCopyMemory(&SBDataSafe, pSBData, sizeof(SBDATA));
+ }
}
- sz = psi.cbSize;
- Status = MmCopyFromCaller(&psi, lpsi, sz);
- if (!NT_SUCCESS(Status))
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- SetLastNtError(Status);
- RETURN(FALSE);
+ ERR("NtUserGetScrollInfo Failed size.\n");
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(RETURN(FALSE));
}
+ _SEH2_END
if(!(Window = UserGetWindowObject(hWnd)))
{
+ ERR("NtUserGetScrollInfo Bad window.\n");
RETURN(FALSE);
}
UserRefObjectCo(Window, &Ref);
- Ret = co_IntGetScrollInfo(Window, fnBar, &psi);
+ Ret = co_IntGetScrollInfo(Window, fnBar, &SBDataSafe, &psi);
UserDerefObjectCo(Window);
- Status = MmCopyToCaller(lpsi, &psi, sz);
- if(!NT_SUCCESS(Status))
+ _SEH2_TRY
{
- SetLastNtError(Status);
- RETURN( FALSE);
+ RtlCopyMemory(lpsi, &psi, sizeof(SCROLLINFO));
}
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ERR("NtUserGetScrollInfo Failed copy to user.\n");
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(RETURN(FALSE));
+ }
+ _SEH2_END
RETURN( Ret);
TRACE("Enter NtUserEnableScrollBar\n");
UserEnterExclusive();
- if (!(Window = UserGetWindowObject(hWnd)))
+ if (!(Window = UserGetWindowObject(hWnd)) || // FIXME:
+ Window == UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
+ Window == UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
{
RETURN(FALSE);
}
// Done in user32:
// SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, TRUE );
+ RETURN( Chg);
if (OrigArrows == wArrows) RETURN( FALSE);
RETURN( TRUE);
TRACE("Enter NtUserSetScrollInfo\n");
UserEnterExclusive();
- if(!(Window = UserGetWindowObject(hWnd)))
+ if(!(Window = UserGetWindowObject(hWnd)) || // FIXME:
+ Window == UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
+ Window == UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
{
RETURN( 0);
}
/* Minimum size of the thumb in pixels */
#define SCROLL_MIN_THUMB 6
+ /* Overlap between arrows and thumb */
+#define SCROLL_ARROW_THUMB_OVERLAP 0
+
/* Thumb-tracking info */
static HWND ScrollTrackingWin = 0;
static INT ScrollTrackingBar = 0;
/* PRIVATE FUNCTIONS **********************************************************/
+static PSBDATA
+IntGetSBData(PWND pwnd, INT Bar)
+{
+ PSBWND pSBWnd;
+ PSBINFO pSBInfo;
+
+ pSBInfo = DesktopPtrToUser(pwnd->pSBInfo);
+ switch (Bar)
+ {
+ case SB_HORZ:
+ return &pSBInfo->Horz;
+ case SB_VERT:
+ return &pSBInfo->Vert;
+ case SB_CTL:
+ if ( pwnd->cbwndExtra != (sizeof(SBWND)-sizeof(WND)) )
+ {
+ ERR("IntGetSBData Wrong Extra bytes for CTL Scrollbar!\n");
+ return 0;
+ }
+ pSBWnd = (PSBWND)pwnd;
+ return (PSBDATA)&pSBWnd->SBCalc;
+ default:
+ ERR("IntGetSBData Bad Bar!\n");
+ }
+ return NULL;
+}
static void
IntDrawScrollInterior(HWND hWnd, HDC hDC, INT nBar, BOOL Vertical,
INT OldTop;
if (Vertical)
- {
MaxSize = ScrollBarInfo->rcScrollBar.bottom - ScrollBarInfo->rcScrollBar.top;
- }
else
- {
MaxSize = ScrollBarInfo->rcScrollBar.right - ScrollBarInfo->rcScrollBar.left;
- }
- MaxSize -= ScrollBarInfo->dxyLineButton + ScrollBarInfo->xyThumbBottom
- - ScrollBarInfo->xyThumbTop;
+ MaxSize -= ScrollBarInfo->dxyLineButton + ScrollBarInfo->xyThumbBottom - ScrollBarInfo->xyThumbTop;
if (Pos < ScrollBarInfo->dxyLineButton)
- {
Pos = ScrollBarInfo->dxyLineButton;
- }
else if (MaxSize < Pos)
- {
Pos = MaxSize;
- }
OldTop = ScrollBarInfo->xyThumbTop;
ScrollBarInfo->xyThumbBottom = Pos + ScrollBarInfo->xyThumbBottom - ScrollBarInfo->xyThumbTop;
ScrollBarInfo->xyThumbBottom = OldTop + ScrollBarInfo->xyThumbBottom - ScrollBarInfo->xyThumbTop;
ScrollBarInfo->xyThumbTop = OldTop;
- ScrollMovingThumb = ! ScrollMovingThumb;
+ ScrollMovingThumb = !ScrollMovingThumb;
}
static LONG FASTCALL
IntScrollGetObjectId(INT SBType)
{
- if (SB_VERT == SBType)
- {
+ if (SBType == SB_VERT)
return OBJID_VSCROLL;
- }
- if (SB_HORZ == SBType)
- {
+ if (SBType == SB_HORZ)
return OBJID_HSCROLL;
- }
-
return OBJID_CLIENT;
}
default:
return;
}
- if (! IntGetScrollBarInfo(Wnd, Bar, &Info))
- {
+ if (!IntGetScrollBarInfo(Wnd, Bar, &Info))
+ {
return;
- }
+ }
if (IsRectEmpty(&Info.rcScrollBar))
- {
+ {
return;
- }
+ }
//ThumbSize = pSBWnd->pSBCalc->pxThumbBottom - pSBWnd->pSBCalc->pxThumbTop;
* Draw the arrows.
*/
if (Info.dxyLineButton)
- {
+ {
IntDrawScrollArrows(DC, &Info, Vertical);
- }
+ }
/*
* Draw the interior.
* If scroll bar has focus, reposition the caret.
*/
if (Wnd == GetFocus() && SB_CTL == Bar)
- {
+ {
if (Vertical)
- {
+ {
SetCaretPos(Info.rcScrollBar.top + 1, Info.dxyLineButton + 1);
- }
+ }
else
- {
+ {
SetCaretPos(Info.dxyLineButton + 1, Info.rcScrollBar.top + 1);
- }
- }
+ }
+ }
}
static BOOL FASTCALL
IntScrollPtInRectEx(LPRECT Rect, POINT Pt, BOOL Vertical)
{
RECT TempRect = *Rect;
+ int scrollbarWidth;
+
+ /* Pad hit rect to allow mouse to be dragged outside of scrollbar and
+ * still be considered in the scrollbar. */
if (Vertical)
- {
- TempRect.left -= Rect->right - Rect->left;
- TempRect.right += Rect->right - Rect->left;
- }
- else
- {
- TempRect.top -= Rect->bottom - Rect->top;
- TempRect.bottom += Rect->bottom - Rect->top;
- }
+ {
+ scrollbarWidth = Rect->right - Rect->left;
+ TempRect.left -= scrollbarWidth*8;
+ TempRect.right += scrollbarWidth*8;
+ TempRect.top -= scrollbarWidth*2;
+ TempRect.bottom += scrollbarWidth*2;
+ }
+ else
+ {
+ scrollbarWidth = Rect->bottom - Rect->top;
+ TempRect.left -= scrollbarWidth*2;
+ TempRect.right += scrollbarWidth*2;
+ TempRect.top -= scrollbarWidth*8;
+ TempRect.bottom += scrollbarWidth*8;
+ }
- return PtInRect(&TempRect, Pt);
+ return PtInRect(&TempRect, Pt);
}
static DWORD FASTCALL
INT ArrowSize, ThumbSize, ThumbPos;
if ((Dragging && ! IntScrollPtInRectEx(&ScrollBarInfo->rcScrollBar, Pt, Vertical)) ||
- ! PtInRect(&ScrollBarInfo->rcScrollBar, Pt))
- {
- return SCROLL_NOWHERE;
- }
+ ! PtInRect(&ScrollBarInfo->rcScrollBar, Pt)) return SCROLL_NOWHERE;
ThumbPos = ScrollBarInfo->xyThumbTop;
ThumbSize = ScrollBarInfo->xyThumbBottom - ThumbPos;
ArrowSize = ScrollBarInfo->dxyLineButton;
if (Vertical)
- {
- if (Pt.y < ScrollBarInfo->rcScrollBar.top + ArrowSize)
- {
- return SCROLL_TOP_ARROW;
- }
- if (ScrollBarInfo->rcScrollBar.bottom - ArrowSize <= Pt.y)
- {
- return SCROLL_BOTTOM_ARROW;
- }
- if (0 == ThumbPos)
- {
- return SCROLL_TOP_RECT;
- }
+ {
+ if (Pt.y < ScrollBarInfo->rcScrollBar.top + ArrowSize) return SCROLL_TOP_ARROW;
+ if (Pt.y >= ScrollBarInfo->rcScrollBar.bottom - ArrowSize) return SCROLL_BOTTOM_ARROW;
+ if (!ThumbPos) return SCROLL_TOP_RECT;
Pt.y -= ScrollBarInfo->rcScrollBar.top;
- if (Pt.y < ThumbPos)
- {
- return SCROLL_TOP_RECT;
- }
- if (ThumbPos + ThumbSize <= Pt.y)
- {
- return SCROLL_BOTTOM_RECT;
- }
- }
+ if (Pt.y < ThumbPos) return SCROLL_TOP_RECT;
+ if (Pt.y >= ThumbPos + ThumbSize) return SCROLL_BOTTOM_RECT;
+ }
else
- {
- if (Pt.x < ScrollBarInfo->rcScrollBar.left + ArrowSize)
- {
- return SCROLL_TOP_ARROW;
- }
- if (ScrollBarInfo->rcScrollBar.right - ArrowSize <= Pt.x)
- {
- return SCROLL_BOTTOM_ARROW;
- }
- if (0 == ThumbPos)
- {
- return SCROLL_TOP_RECT;
- }
+ {
+ if (Pt.x < ScrollBarInfo->rcScrollBar.left + ArrowSize) return SCROLL_TOP_ARROW;
+ if (Pt.x >= ScrollBarInfo->rcScrollBar.right - ArrowSize) return SCROLL_BOTTOM_ARROW;
+ if (!ThumbPos) return SCROLL_TOP_RECT;
Pt.x -= ScrollBarInfo->rcScrollBar.left;
- if (Pt.x < ThumbPos)
- {
- return SCROLL_TOP_RECT;
- }
- if (ThumbPos + ThumbSize <= Pt.x)
- {
- return SCROLL_BOTTOM_RECT;
- }
- }
+ if (Pt.x < ThumbPos) return SCROLL_TOP_RECT;
+ if (Pt.x >= ThumbPos + ThumbSize) return SCROLL_BOTTOM_RECT;
+ }
return SCROLL_THUMB;
}
{
INT Pixels;
BOOL Vertical;
- RECT ClientRect;
- RECT WindowRect;
- DWORD Style, ExStyle;
PWND pWnd;
PSBINFO pSBInfo;
+ PSBDATA pSBData;
+ PSBWND pSBWnd;
pWnd = ValidateHwnd( Wnd );
+ if (!pWnd) return FALSE;
pSBInfo = DesktopPtrToUser(pWnd->pSBInfo);
- GetClientRect(Wnd, &ClientRect);
- if (SB_HORZ == Bar || SB_VERT == Bar)
- {
- ClientToScreen(Wnd, (LPPOINT) &ClientRect.left);
- ClientToScreen(Wnd, (LPPOINT) &ClientRect.right);
- GetWindowRect(Wnd, &WindowRect);
- }
- Style = GetWindowLongPtrW(Wnd, GWL_STYLE);
+ *Rect = pWnd->rcClient;
+ OffsetRect( Rect, -pWnd->rcWindow.left, -pWnd->rcWindow.top );
+ if (pWnd->ExStyle & WS_EX_LAYOUTRTL)
+ mirror_rect( &pWnd->rcWindow, Rect );
switch (Bar)
{
case SB_HORZ:
- Rect->left = ClientRect.left - WindowRect.left;
- Rect->top = ClientRect.bottom - WindowRect.top;
- Rect->right = ClientRect.right - WindowRect.left;
- Rect->bottom = Rect->top + GetSystemMetrics(SM_CYHSCROLL);
- if (0 != (Style & WS_BORDER))
- {
+// WIN_GetRectangles( Wnd, COORDS_WINDOW, NULL, Rect );
+ Rect->top = Rect->bottom;
+ Rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
+ if (pWnd->style & WS_BORDER)
+ {
Rect->left--;
Rect->right++;
- }
- else if (0 != (Style & WS_VSCROLL))
- {
+ }
+ else if (pWnd->style & WS_VSCROLL)
+ {
Rect->right++;
- }
+ }
Vertical = FALSE;
+ pSBData = &pSBInfo->Horz;
break;
case SB_VERT:
- ExStyle = GetWindowLongPtrW(Wnd, GWL_EXSTYLE);
- if (0 != (ExStyle & WS_EX_LEFTSCROLLBAR))
- {
- Rect->left = ClientRect.left - WindowRect.left - GetSystemMetrics(SM_CXVSCROLL);
- }
+// WIN_GetRectangles( Wnd, COORDS_WINDOW, NULL, Rect );
+ if (pWnd->ExStyle & WS_EX_LEFTSCROLLBAR)
+ {
+ Rect->right = Rect->left;
+ Rect->left -= GetSystemMetrics(SM_CXVSCROLL);
+ }
else
- {
- Rect->left = ClientRect.right - WindowRect.left;
- }
- Rect->top = ClientRect.top - WindowRect.top;
- Rect->right = Rect->left + GetSystemMetrics(SM_CXVSCROLL);
- Rect->bottom = ClientRect.bottom - WindowRect.top;
- if (0 != (Style & WS_BORDER))
- {
+ {
+ Rect->left = Rect->right;
+ Rect->right += GetSystemMetrics(SM_CXVSCROLL);
+ }
+ if (pWnd->style & WS_BORDER)
+ {
Rect->top--;
Rect->bottom++;
- }
- else if (0 != (Style & WS_HSCROLL))
- {
+ }
+ else if (pWnd->style & WS_HSCROLL)
+ {
Rect->bottom++;
- }
+ }
Vertical = TRUE;
+ pSBData = &pSBInfo->Vert;
break;
case SB_CTL:
- *Rect = ClientRect;
- Vertical = (0 != (Style & SBS_VERT));
+ GetClientRect( Wnd, Rect );
+ Vertical = (pWnd->style & SBS_VERT);
+ pSBWnd = (PSBWND)pWnd;
+ pSBData = (PSBDATA)&pSBWnd->SBCalc;
break;
default:
return FALSE;
}
- if (Vertical)
- {
- Pixels = Rect->bottom - Rect->top;
- }
- else
- {
- Pixels = Rect->right - Rect->left;
- }
+ if (Vertical) Pixels = Rect->bottom - Rect->top;
+ else Pixels = Rect->right - Rect->left;
if (Pixels <= 2 * GetSystemMetrics(SM_CXVSCROLL) + SCROLL_MIN_RECT)
- {
+ {
if (SCROLL_MIN_RECT < Pixels)
- {
*ArrowSize = (Pixels - SCROLL_MIN_RECT) / 2;
- }
else
- {
*ArrowSize = 0;
- }
*ThumbPos = *ThumbSize = 0;
- }
+ }
else
{
- SCROLLINFO Info;
-
- NtUserSBGetParms(Wnd, Bar, NULL, &Info);
*ArrowSize = GetSystemMetrics(SM_CXVSCROLL);
- Pixels -= (2 * GetSystemMetrics(SM_CXVSCROLL));
-
- if (0 != Info.nPage)
+ Pixels -= (2 * (GetSystemMetrics(SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP));
+ if (pSBData->page)
{
- *ThumbSize = MulDiv(Pixels, Info.nPage, (Info.nMax - Info.nMin + 1));
- if (*ThumbSize < SCROLL_MIN_THUMB)
- {
- *ThumbSize = SCROLL_MIN_THUMB;
- }
- }
- else
- {
- *ThumbSize = GetSystemMetrics(SM_CXVSCROLL);
+ *ThumbSize = MulDiv(Pixels, pSBData->page, (pSBData->posMax - pSBData->posMin + 1));
+ if (*ThumbSize < SCROLL_MIN_THUMB) *ThumbSize = SCROLL_MIN_THUMB;
}
+ else *ThumbSize = GetSystemMetrics(SM_CXVSCROLL);
-//#if 0 /* FIXME */
if (((Pixels -= *ThumbSize ) < 0) ||
(( pSBInfo->WSBflags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH))
-//#else
-// if ((Pixels -= *ThumbSize ) < 0)
-//#endif
{
/* Rectangle too small or scrollbar disabled -> no thumb */
*ThumbPos = *ThumbSize = 0;
}
else
{
- INT Max = Info.nMax - max(Info.nPage - 1, 0);
- if (Max <= Info.nMin)
- {
- *ThumbPos = *ArrowSize;
- }
+ INT Max = pSBData->posMax - max(pSBData->page - 1, 0);
+ if (pSBData->posMin >= Max)
+ *ThumbPos = *ArrowSize - SCROLL_ARROW_THUMB_OVERLAP;
else
- {
- *ThumbPos = *ArrowSize
- + MulDiv(Pixels, (Info.nPos - Info.nMin),
- (Max - Info.nMin));
- }
+ *ThumbPos = *ArrowSize - SCROLL_ARROW_THUMB_OVERLAP
+ + MulDiv(Pixels, (pSBData->pos - pSBData->posMin),(Max - pSBData->posMin));
}
}
-
return Vertical;
}
IntScrollGetThumbVal(HWND Wnd, INT SBType, PSCROLLBARINFO ScrollBarInfo,
BOOL Vertical, INT Pos)
{
- SCROLLINFO si;
+ PWND pWnd;
+ PSBDATA pSBData;
INT Pixels = Vertical ? ScrollBarInfo->rcScrollBar.bottom
- ScrollBarInfo->rcScrollBar.top
: ScrollBarInfo->rcScrollBar.right
- ScrollBarInfo->rcScrollBar.left;
- si.cbSize = sizeof(SCROLLINFO);
- si.fMask = SIF_RANGE | SIF_PAGE;
- NtUserSBGetParms(Wnd, SBType, NULL, &si);
+ pWnd = ValidateHwnd( Wnd );
+ if (!pWnd) return FALSE;
+
+ pSBData = IntGetSBData(pWnd, SBType);
+
if ((Pixels -= 2 * ScrollBarInfo->dxyLineButton) <= 0)
- {
- return si.nMin;
- }
+ {
+ return pSBData->posMin;
+ }
if ((Pixels -= (ScrollBarInfo->xyThumbBottom - ScrollBarInfo->xyThumbTop)) <= 0)
- {
- return si.nMin;
- }
+ {
+ return pSBData->posMin;
+ }
Pos = Pos - ScrollBarInfo->dxyLineButton;
if (Pos < 0)
- {
+ {
Pos = 0;
- }
- if (Pixels < Pos)
- {
- Pos = Pixels;
- }
+ }
+ if (Pos > Pixels) Pos = Pixels;
- if (0 == si.nPage)
- {
- Pos *= si.nMax - si.nMin;
- }
+ if (!pSBData->page)
+ Pos *= pSBData->posMax - pSBData->posMin;
else
- {
- Pos *= si.nMax - si.nMin - si.nPage + 1;
- }
- return si.nMin + ((Pos + Pixels / 2) / Pixels);
+ Pos *= pSBData->posMax - pSBData->posMin - pSBData->page + 1;
+
+ return pSBData->posMin + ((Pos + Pixels / 2) / Pixels);
}
/***********************************************************************
* IntScrollClipPos
*/
-static POINT IntScrollClipPos(PRECT Rect, POINT Pt)
+static POINT IntScrollClipPos(PRECT lpRect, POINT pt)
{
- if (Pt.x < Rect->left)
- {
- Pt.x = Rect->left;
- }
- else if (Rect->right < Pt.x)
- {
- Pt.x = Rect->right;
- }
-
- if (Pt.y < Rect->top)
- {
- Pt.y = Rect->top;
- }
- else if (Rect->bottom < Pt.y)
- {
- Pt.y = Rect->bottom;
- }
-
- return Pt;
+ if( pt.x < lpRect->left )
+ pt.x = lpRect->left;
+ else
+ if( pt.x > lpRect->right )
+ pt.x = lpRect->right;
+
+ if( pt.y < lpRect->top )
+ pt.y = lpRect->top;
+ else
+ if( pt.y > lpRect->bottom )
+ pt.y = lpRect->bottom;
+
+ return pt;
}
/***********************************************************************
ScrollBarInfo.rgstate[ScrollTrackHitTest] &= ~STATE_SYSTEM_PRESSED;
NewInfo.rgstate[ScrollTrackHitTest] = ScrollBarInfo.rgstate[ScrollTrackHitTest];
NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), &NewInfo);
-
+
IntDrawScrollArrows(Dc, &ScrollBarInfo, Vertical);
-
+
break;
case WM_SYSTIMER:
TRACE("hwnd=%p lpCreate=%p\n", Wnd, lpCreate);
-//#if 0 /* FIXME */
+#if 0 /* FIXME */
if (lpCreate->style & WS_DISABLED)
{
// info->flags = ESB_DISABLE_BOTH;
NtUserMessageCall( Wnd, WM_ENABLE, FALSE, 0, 0, FNID_SCROLLBAR, FALSE);
ERR("Created WS_DISABLED scrollbar\n");
}
-//#endif
+#endif
if (0 != (lpCreate->style & (SBS_SIZEGRIP | SBS_SIZEBOX)))
{
if (0 != (lpCreate->style & SBS_SIZEBOXTOPLEFTALIGN))
}
}
-static INT FASTCALL
-IntScrollGetScrollPos(HWND Wnd, INT Bar)
-{
- SCROLLINFO ScrollInfo;
-
- ScrollInfo.cbSize = sizeof(SCROLLINFO);
- ScrollInfo.fMask = SIF_POS;
- if (!NtUserSBGetParms(Wnd, Bar, NULL, &ScrollInfo))
- {
- return 0;
- }
-
- return ScrollInfo.nPos;
-}
-
-static BOOL FASTCALL
-IntScrollGetScrollRange(HWND Wnd, int Bar, LPINT MinPos, LPINT MaxPos)
-{
- BOOL Result;
- SCROLLINFO ScrollInfo;
-
- if (NULL == MinPos || NULL == MaxPos)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- ScrollInfo.cbSize = sizeof(SCROLLINFO);
- ScrollInfo.fMask = SIF_RANGE;
- Result = NtUserSBGetParms(Wnd, Bar, NULL, &ScrollInfo);
- *MinPos = Result ? ScrollInfo.nMin : 0;
- *MaxPos = Result ? ScrollInfo.nMax : 0;
-
- return Result;
-}
-
/* USER32 INTERNAL FUNCTIONS **************************************************/
/***********************************************************************
UINT XOffset = 0, YOffset = 0;
if (SBType != SB_CTL)
- { // Replace HAX for CMD mouse tracking.
+ { // Used with CMD mouse tracking.
PWND pwnd = ValidateHwnd(Wnd);
if (!pwnd) return;
XOffset = pwnd->rcClient.left - pwnd->rcWindow.left;
YOffset = pwnd->rcClient.top - pwnd->rcWindow.top;
// RECT rect;
-// GetClientRect(Wnd, &rect);
+// WIN_GetRectangles( Wnd, COORDS_CLIENT, &rect, NULL );
ScreenToClient(Wnd, &Pt);
// Pt.x -= rect.left;
// Pt.y -= rect.top;
}
+static DWORD FASTCALL
+IntSetScrollInfo(HWND Wnd, LPCSCROLLINFO Info, BOOL bRedraw)
+{
+ DWORD Ret = NtUserSetScrollInfo(Wnd, SB_CTL, Info, bRedraw);
+ if (Ret) IntNotifyWinEvent(EVENT_OBJECT_VALUECHANGE, Wnd, OBJID_CLIENT, CHILDID_SELF, WEF_SETBYWNDPTI);
+ return Ret;
+}
+
+
/***********************************************************************
* ScrollBarWndProc
*/
{
#ifdef __REACTOS__ // Do this now, remove after Server side is fixed.
PWND pWnd;
+ PSBWND pSBWnd;
+ SCROLLINFO ScrollInfo;
pWnd = ValidateHwnd(Wnd);
if (pWnd)
{
if (!pWnd->fnid)
{
+ ERR("ScrollBar CTL size %d\n",(sizeof(SBWND)-sizeof(WND)));
+ if ( pWnd->cbwndExtra != (sizeof(SBWND)-sizeof(WND)) )
+ {
+ ERR("Wrong Extra bytes for Scrollbar!\n");
+ return 0;
+ }
+
if (Msg != WM_CREATE)
{
return DefWindowProc(Wnd, Msg, wParam, lParam);
return 0;
}
+ // Must be a scroll bar control!
+ pSBWnd = (PSBWND)pWnd;
+
switch (Msg)
{
case WM_CREATE:
case WM_ENABLE:
{
- PWND pWnd = ValidateHwnd(Wnd);
- if (pWnd->pSBInfo)
- {
- ERR("ScrollBarWndProc WM_ENABLE\n");
- //NtUserEnableScrollBar(Wnd,SB_CTL,(wParam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH));
- NtUserMessageCall( Wnd, Msg, wParam, lParam, 0, FNID_SCROLLBAR, !unicode);
- /* Refresh Scrollbars. */
- SCROLL_RefreshScrollBar(Wnd, SB_CTL, TRUE, TRUE);
- }
- }
- return 0;
+ return SendMessageW( Wnd, SBM_ENABLE_ARROWS, wParam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH, 0);
+ }
case WM_LBUTTONDBLCLK:
case WM_LBUTTONDOWN:
}
break;
- case SBM_SETPOS:
- return SetScrollPos(Wnd, SB_CTL, wParam, (BOOL) lParam);
-
case SBM_GETPOS:
- return IntScrollGetScrollPos(Wnd, SB_CTL);
-
- case SBM_SETRANGEREDRAW:
- case SBM_SETRANGE:
- {
- INT OldPos = IntScrollGetScrollPos(Wnd, SB_CTL);
- SetScrollRange(Wnd, SB_CTL, wParam, lParam, FALSE);
- if (Msg == SBM_SETRANGEREDRAW)
- SCROLL_RefreshScrollBar( Wnd, SB_CTL, TRUE, TRUE );
- if (OldPos != IntScrollGetScrollPos(Wnd, SB_CTL)) return OldPos;
- }
- return 0;
+ return pSBWnd->SBCalc.pos;
case SBM_GETRANGE:
- return IntScrollGetScrollRange(Wnd, SB_CTL, (LPINT) wParam, (LPINT) lParam);
+ *(LPINT)wParam = pSBWnd->SBCalc.posMin;
+ *(LPINT)lParam = pSBWnd->SBCalc.posMax;
+ // This message does not return a value.
+ return 0;
case SBM_ENABLE_ARROWS:
return EnableScrollBar( Wnd, SB_CTL, wParam );
+ case SBM_SETPOS:
+ {
+ ScrollInfo.cbSize = sizeof(SCROLLINFO);
+ ScrollInfo.fMask = SIF_POS|SIF_PREVIOUSPOS;
+ ScrollInfo.nPos = wParam;
+ return IntSetScrollInfo(Wnd, &ScrollInfo, lParam);
+ }
+
+ case SBM_SETRANGEREDRAW:
+ case SBM_SETRANGE:
+ {
+ ScrollInfo.cbSize = sizeof(SCROLLINFO);
+ ScrollInfo.fMask = SIF_RANGE|SIF_PREVIOUSPOS;
+ ScrollInfo.nMin = wParam;
+ ScrollInfo.nMax = lParam;
+ return IntSetScrollInfo(Wnd, &ScrollInfo, Msg == SBM_SETRANGEREDRAW ? TRUE : FALSE);
+ }
+
case SBM_SETSCROLLINFO:
- return NtUserSetScrollInfo(Wnd, SB_CTL, (SCROLLINFO *) lParam, wParam);
+ return IntSetScrollInfo(Wnd, (LPCSCROLLINFO)lParam, wParam);
case SBM_GETSCROLLINFO:
- return NtUserSBGetParms(Wnd, SB_CTL, NULL, (SCROLLINFO *) lParam);
-
+ {
+ PSBDATA pSBData = (PSBDATA)&pSBWnd->SBCalc;
+ DWORD ret = NtUserSBGetParms(Wnd, SB_CTL, pSBData, (SCROLLINFO *) lParam);
+ if (!ret)
+ {
+ ERR("SBM_GETSCROLLINFO No ScrollInfo\n");
+ }
+ return ret;
+ }
case SBM_GETSCROLLBARINFO:
((PSCROLLBARINFO)lParam)->cbSize = sizeof(SCROLLBARINFO);
return NtUserGetScrollBarInfo(Wnd, OBJID_CLIENT, (PSCROLLBARINFO)lParam);
if (!Hook)
{
Ret = NtUserEnableScrollBar(hwnd, nBar, flags);
- if (GetLastError() == ERROR_INVALID_PARAMETER) return Ret;
- if (nBar == SB_CTL) return Ret;
+ if (!Ret) return Ret;
SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, TRUE );
return Ret;
}
RealGetScrollInfo(HWND Wnd, INT SBType, LPSCROLLINFO Info)
{
PWND pWnd;
- PSBDATA pSBData = NULL;
+ PSBDATA pSBData;
if (SB_CTL == SBType)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
- // FIXME add support to set pSBData from pWnd->pSBInfo
+ if (!pWnd->pSBInfo)
+ {
+ SetLastError(ERROR_NO_SCROLLBARS);
+ return FALSE;
+ }
+ pSBData = IntGetSBData(pWnd, SBType);
return NtUserSBGetParms(Wnd, SBType, pSBData, Info);
}
INT WINAPI
GetScrollPos(HWND Wnd, INT Bar)
{
+ PWND pwnd;
+ PSBDATA pSBData;
+
TRACE("Wnd=%p Bar=%d\n", Wnd, Bar);
/* Refer SB_CTL requests to the window */
if (SB_CTL == Bar)
- {
+ {
return SendMessageW(Wnd, SBM_GETPOS, (WPARAM) 0, (LPARAM) 0);
- }
- else
- {
- return IntScrollGetScrollPos(Wnd, Bar);
- }
+ }
+ else if (Bar == SB_HORZ || Bar == SB_VERT )
+ {
+ pwnd = ValidateHwnd(Wnd);
+ if (!pwnd) return 0;
+
+ if (pwnd->pSBInfo)
+ {
+ pSBData = IntGetSBData(pwnd, Bar);
+ return pSBData->pos;
+ }
+
+ SetLastError(ERROR_NO_SCROLLBARS);
+ ERR("GetScrollPos No Scroll Info\n");
+ return 0;
+ }
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
}
/*
BOOL WINAPI
GetScrollRange(HWND Wnd, int Bar, LPINT MinPos, LPINT MaxPos)
{
+ PWND pwnd;
+ PSBDATA pSBData;
+
TRACE("Wnd=%x Bar=%d Min=%p Max=%p\n", Wnd, Bar, MinPos, MaxPos);
/* Refer SB_CTL requests to the window */
if (SB_CTL == Bar)
- {
+ {
return SendMessageW(Wnd, SBM_GETRANGE, (WPARAM) MinPos, (LPARAM) MaxPos);
- }
- else
- {
- return IntScrollGetScrollRange(Wnd, Bar, MinPos, MaxPos);
- }
+ }
+ else if (Bar == SB_HORZ || Bar == SB_VERT )
+ {
+ pwnd = ValidateHwnd(Wnd);
+ if (!pwnd) return FALSE;
+
+ if (pwnd->pSBInfo)
+ {
+ pSBData = IntGetSBData(pwnd, Bar);
+ *MinPos = pSBData->posMin;
+ *MaxPos = pSBData->posMax;
+ }
+ else
+ {
+ SetLastError(ERROR_NO_SCROLLBARS);
+ *MinPos = 0;
+ *MaxPos = 0;
+ }
+ return TRUE;
+ }
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
}
INT WINAPI
INT WINAPI
SetScrollPos(HWND hWnd, INT nBar, INT nPos, BOOL bRedraw)
{
- PWND pWnd;
- INT Result = 0;
SCROLLINFO ScrollInfo;
- pWnd = ValidateHwnd(hWnd);
- if ( !pWnd || !pWnd->pSBInfo ) return 0;
-
ScrollInfo.cbSize = sizeof(SCROLLINFO);
- ScrollInfo.fMask = SIF_POS;
+ ScrollInfo.fMask = SIF_POS|SIF_PREVIOUSPOS;
+ ScrollInfo.nPos = nPos;
- /*
- * Call NtUserSBGetParms() to get the previous position that
- * we will later return.
- */
- if (NtUserSBGetParms(hWnd, nBar, NULL, &ScrollInfo))
- {
- Result = ScrollInfo.nPos;
- if (Result != nPos)
- {
- ScrollInfo.nPos = nPos;
- /* Finally set the new position */
- NtUserSetScrollInfo(hWnd, nBar, &ScrollInfo, bRedraw);
- }
- }
-
- return Result;
+ return RealSetScrollInfo(hWnd, nBar, &ScrollInfo, bRedraw);
}
/*
ScrollInfo.nMin = nMinPos;
ScrollInfo.nMax = nMaxPos;
SetScrollInfo(hWnd, nBar, &ScrollInfo, bRedraw); // do not bypass themes.
-
return TRUE;
}