/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * PURPOSE: Scrollbars * FILE: subsys/win32k/ntuser/scrollbar.c * PROGRAMER: Thomas Weidenmueller (w3seek@users.sourceforge.net) * Jason Filby (jasonfilby@yahoo.com) * REVISION HISTORY: * 16-11-2002 Jason Filby Created */ /* INCLUDES ******************************************************************/ #include #define NDEBUG #include #define MINTRACKTHUMB 8 /* Minimum size of the rectangle between the arrows */ #define SBRG_SCROLLBAR 0 /* the scrollbar itself */ #define SBRG_TOPRIGHTBTN 1 /* the top or right button */ #define SBRG_PAGEUPRIGHT 2 /* the page up or page right region */ #define SBRG_SCROLLBOX 3 /* the scroll box */ #define SBRG_PAGEDOWNLEFT 4 /* the page down or page left region */ #define SBRG_BOTTOMLEFTBTN 5 /* the bottom or left button */ #define CHANGERGSTATE(item, status) \ if(Info->rgstate[(item)] != (status)) \ Chg = TRUE; \ Info->rgstate[(item)] = (status); /* FUNCTIONS *****************************************************************/ /* Ported from WINE20020904 */ /* Compute the scroll bar rectangle, in drawing coordinates (i.e. client coords for SB_CTL, window coords for SB_VERT and * SB_HORZ). 'arrowSize' returns the width or height of an arrow (depending on * the orientation of the scrollbar), * '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. */ BOOL FASTCALL IntGetScrollBarRect (PWINDOW_OBJECT Window, INT nBar, RECTL *lprect) { BOOL vertical; PWND Wnd = Window->Wnd; RECTL ClientRect = Window->Wnd->rcClient; RECTL WindowRect = Window->Wnd->rcWindow; 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); 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); } else { lprect->left = ClientRect.right - WindowRect.left; lprect->right = lprect->left + UserGetSystemMetrics(SM_CXVSCROLL); } lprect->top = ClientRect.top - WindowRect.top; lprect->bottom = ClientRect.bottom - WindowRect.top; vertical = TRUE; break; case SB_CTL: IntGetClientRect (Window, lprect); vertical = ((Wnd->style & SBS_VERT) != 0); break; default: return FALSE; } return vertical; } BOOL FASTCALL IntCalculateThumb(PWINDOW_OBJECT Window, LONG idObject, PSCROLLBARINFO psbi, LPSCROLLINFO psi) { PWND Wnd = Window->Wnd; INT Thumb, ThumbBox, ThumbPos, cxy, mx; RECTL ClientRect; switch(idObject) { case SB_HORZ: Thumb = UserGetSystemMetrics(SM_CXHSCROLL); cxy = psbi->rcScrollBar.right - psbi->rcScrollBar.left; break; case SB_VERT: Thumb = UserGetSystemMetrics(SM_CYVSCROLL); cxy = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top; break; case SB_CTL: IntGetClientRect(Window, &ClientRect); if(Wnd->style & SBS_VERT) { Thumb = UserGetSystemMetrics(SM_CYVSCROLL); cxy = ClientRect.bottom - ClientRect.top; } else { Thumb = UserGetSystemMetrics(SM_CXHSCROLL); cxy = ClientRect.right - ClientRect.left; } break; default: return FALSE; } ThumbPos = Thumb; /* calculate Thumb */ if(cxy <= (2 * Thumb)) { Thumb = cxy / 2; psbi->xyThumbTop = 0; psbi->xyThumbBottom = 0; ThumbPos = Thumb; } else { ThumbBox = psi->nPage ? MINTRACKTHUMB : UserGetSystemMetrics(SM_CXHTHUMB); cxy -= (2 * Thumb); if(cxy >= ThumbBox) { if(psi->nPage) { ThumbBox = max(EngMulDiv(cxy, psi->nPage, psi->nMax - psi->nMin + 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); else ThumbPos = Thumb + ThumbBox; } psbi->xyThumbTop = ThumbPos; psbi->xyThumbBottom = ThumbPos + ThumbBox; } else { psbi->xyThumbTop = 0; psbi->xyThumbBottom = 0; } } psbi->dxyLineButton = Thumb; return TRUE; } static VOID FASTCALL IntUpdateSBInfo(PWINDOW_OBJECT Window, int wBar) { PSCROLLBARINFO sbi; LPSCROLLINFO psi; ASSERT(Window); ASSERT(Window->pSBInfo); sbi = IntGetScrollbarInfoFromWindow(Window, wBar); psi = IntGetScrollInfoFromWindow(Window, wBar); IntGetScrollBarRect(Window, wBar, &(sbi->rcScrollBar)); IntCalculateThumb(Window, wBar, sbi, psi); } static BOOL FASTCALL co_IntGetScrollInfo(PWINDOW_OBJECT Window, INT nBar, LPSCROLLINFO lpsi) { UINT Mask; LPSCROLLINFO psi; ASSERT_REFS_CO(Window); if(!SBID_IS_VALID(nBar)) { SetLastWin32Error(ERROR_INVALID_PARAMETER); DPRINT1("Trying to get scrollinfo for unknown scrollbar type %d\n", nBar); return FALSE; } if(!co_IntCreateScrollBars(Window)) { return FALSE; } psi = IntGetScrollInfoFromWindow(Window, nBar); if (lpsi->fMask == SIF_ALL) { Mask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS; } else { Mask = lpsi->fMask; } if (0 != (Mask & SIF_PAGE)) { lpsi->nPage = psi->nPage; } if (0 != (Mask & SIF_POS)) { lpsi->nPos = psi->nPos; } if (0 != (Mask & SIF_RANGE)) { lpsi->nMin = psi->nMin; lpsi->nMax = psi->nMax; } if (0 != (Mask & SIF_TRACKPOS)) { lpsi->nTrackPos = psi->nTrackPos; } return TRUE; } BOOL FASTCALL NEWco_IntGetScrollInfo( PWND pWnd, INT nBar, PSBDATA pSBData, LPSCROLLINFO lpsi) { UINT Mask; PSBTRACK pSBTrack = pWnd->head.pti->pSBTrack; if (!SBID_IS_VALID(nBar)) { SetLastWin32Error(ERROR_INVALID_PARAMETER); DPRINT1("Trying to get scrollinfo for unknown scrollbar type %d\n", nBar); return FALSE; } Mask = lpsi->fMask; if (0 != (Mask & SIF_PAGE)) { lpsi->nPage = pSBData->page; } if (0 != (Mask & SIF_POS)) { lpsi->nPos = pSBData->pos; } if (0 != (Mask & SIF_RANGE)) { lpsi->nMin = pSBData->posMin; lpsi->nMax = pSBData->posMax; } if (0 != (Mask & SIF_TRACKPOS)) { if ( pSBTrack && pSBTrack->nBar == nBar && pSBTrack->spwndTrack == pWnd ) lpsi->nTrackPos = pSBTrack->posNew; else lpsi->nTrackPos = pSBData->pos; } return (Mask & SIF_ALL) !=0; } static DWORD FASTCALL co_IntSetScrollInfo(PWINDOW_OBJECT Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw) { /* * Update the scrollbar state and set action flags according to * what has to be done graphics wise. */ LPSCROLLINFO Info; PSCROLLBARINFO psbi; /* UINT new_flags;*/ BOOL bChangeParams = FALSE; /* don't show/hide scrollbar if params don't change */ ASSERT_REFS_CO(Window); if(!SBID_IS_VALID(nBar)) { SetLastWin32Error(ERROR_INVALID_PARAMETER); DPRINT1("Trying to set scrollinfo for unknown scrollbar type %d", nBar); return FALSE; } if(!co_IntCreateScrollBars(Window)) { return FALSE; } if (lpsi->cbSize != sizeof(SCROLLINFO) && lpsi->cbSize != (sizeof(SCROLLINFO) - sizeof(lpsi->nTrackPos))) { SetLastWin32Error(ERROR_INVALID_PARAMETER); return 0; } if (lpsi->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL)) { SetLastWin32Error(ERROR_INVALID_PARAMETER); return 0; } psbi = IntGetScrollbarInfoFromWindow(Window, nBar); Info = IntGetScrollInfoFromWindow(Window, nBar); /* Set the page size */ if (0 != (lpsi->fMask & SIF_PAGE)) { if (Info->nPage != lpsi->nPage) { Info->nPage = lpsi->nPage; bChangeParams = TRUE; } } /* Set the scroll pos */ if (0 != (lpsi->fMask & SIF_POS)) { if (Info->nPos != lpsi->nPos) { Info->nPos = lpsi->nPos; } } /* Set the scroll range */ if (0 != (lpsi->fMask & SIF_RANGE)) { /* Invalid range -> range is set to (0,0) */ if (lpsi->nMin > lpsi->nMax || 0x80000000 <= (UINT)(lpsi->nMax - lpsi->nMin)) { Info->nMin = 0; Info->nMax = 0; bChangeParams = TRUE; } else if (Info->nMin != lpsi->nMin || Info->nMax != lpsi->nMax) { Info->nMin = lpsi->nMin; Info->nMax = lpsi->nMax; bChangeParams = TRUE; } } /* Make sure the page size is valid */ if (Info->nMax - Info->nMin + 1 < Info->nPage) { Info->nPage = Info->nMax - Info->nMin + 1; } /* Make sure the pos is inside the range */ if (Info->nPos < Info->nMin) { Info->nPos = Info->nMin; } else if (Info->nPos > Info->nMax - max(Info->nPage - 1, 0)) { Info->nPos = Info->nMax - max(Info->nPage - 1, 0); } /* * Don't change the scrollbar state if SetScrollInfo is just called * with SIF_DISABLENOSCROLL */ if (0 == (lpsi->fMask & SIF_ALL)) { return Info->nPos; } /* Check if the scrollbar should be hidden or disabled */ if (0 != (lpsi->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL))) { if (Info->nMin >= (int)(Info->nMax - max(Info->nPage - 1, 0))) { /* Hide or disable scroll-bar */ if (0 != (lpsi->fMask & SIF_DISABLENOSCROLL)) { /* new_flags = ESB_DISABLE_BOTH;*/ } else if ((nBar != SB_CTL) && bChangeParams) { co_UserShowScrollBar(Window, nBar, FALSE); return Info->nPos; } } else /* Show and enable scroll-bar */ { /* new_flags = 0;*/ if ((nBar != SB_CTL) && bChangeParams) { co_UserShowScrollBar(Window, nBar, TRUE); } } #if 0 if (infoPtr->flags != new_flags) /* check arrow flags */ { infoPtr->flags = new_flags; *Action |= SA_SSI_REPAINT_ARROWS; } #endif } if (bRedraw) { RECTL UpdateRect = psbi->rcScrollBar; UpdateRect.left -= Window->Wnd->rcClient.left - Window->Wnd->rcWindow.left; UpdateRect.right -= Window->Wnd->rcClient.left - Window->Wnd->rcWindow.left; UpdateRect.top -= Window->Wnd->rcClient.top - Window->Wnd->rcWindow.top; UpdateRect.bottom -= Window->Wnd->rcClient.top - Window->Wnd->rcWindow.top; co_UserRedrawWindow(Window, &UpdateRect, 0, RDW_INVALIDATE | RDW_FRAME); } /* Return current position */ return Info->nPos; } BOOL FASTCALL co_IntGetScrollBarInfo(PWINDOW_OBJECT Window, LONG idObject, PSCROLLBARINFO psbi) { INT Bar; PSCROLLBARINFO sbi; LPSCROLLINFO psi; ASSERT_REFS_CO(Window); Bar = SBOBJ_TO_SBID(idObject); if(!SBID_IS_VALID(Bar)) { SetLastWin32Error(ERROR_INVALID_PARAMETER); DPRINT1("Trying to get scrollinfo for unknown scrollbar type %d\n", Bar); return FALSE; } if(!co_IntCreateScrollBars(Window)) { return FALSE; } sbi = IntGetScrollbarInfoFromWindow(Window, Bar); psi = IntGetScrollInfoFromWindow(Window, Bar); IntGetScrollBarRect(Window, Bar, &(sbi->rcScrollBar)); IntCalculateThumb(Window, Bar, sbi, psi); RtlCopyMemory(psbi, sbi, sizeof(SCROLLBARINFO)); return TRUE; } BOOL FASTCALL co_IntCreateScrollBars(PWINDOW_OBJECT Window) { PSCROLLBARINFO psbi; LPSCROLLINFO psi; LRESULT Result; ULONG Size, s; INT i; ASSERT_REFS_CO(Window); if(Window->pSBInfo) { /* no need to create it anymore */ return TRUE; } /* allocate memory for all scrollbars (HORZ, VERT, CONTROL) */ Size = 3 * (sizeof(SBINFOEX)); if(!(Window->pSBInfo = ExAllocatePoolWithTag(PagedPool, Size, TAG_SBARINFO))) { DPRINT1("Unable to allocate memory for scrollbar information for window 0x%x\n", Window->hSelf); return FALSE; } RtlZeroMemory(Window->pSBInfo, Size); Result = co_WinPosGetNonClientSize(Window, &Window->Wnd->rcWindow, &Window->Wnd->rcClient); for(s = SB_HORZ; s <= SB_VERT; s++) { psbi = IntGetScrollbarInfoFromWindow(Window, s); psbi->cbSize = sizeof(SCROLLBARINFO); for (i = 0; i < CCHILDREN_SCROLLBAR + 1; i++) psbi->rgstate[i] = 0; psi = IntGetScrollInfoFromWindow(Window, s); psi->cbSize = sizeof(LPSCROLLINFO); psi->nMax = 100; IntGetScrollBarRect(Window, s, &(psbi->rcScrollBar)); IntCalculateThumb(Window, s, psbi, psi); } return TRUE; } BOOL FASTCALL IntDestroyScrollBars(PWINDOW_OBJECT Window) { if(Window->pSBInfo) { ExFreePool(Window->pSBInfo); Window->pSBInfo = NULL; return TRUE; } return FALSE; } BOOL APIENTRY IntEnableScrollBar(BOOL Horz, PSCROLLBARINFO Info, UINT wArrows) { BOOL Chg = FALSE; switch(wArrows) { case ESB_DISABLE_BOTH: CHANGERGSTATE(SBRG_TOPRIGHTBTN, STATE_SYSTEM_UNAVAILABLE); CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, STATE_SYSTEM_UNAVAILABLE); break; case ESB_DISABLE_RTDN: if(Horz) { CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, STATE_SYSTEM_UNAVAILABLE); } else { CHANGERGSTATE(SBRG_TOPRIGHTBTN, STATE_SYSTEM_UNAVAILABLE); } break; case ESB_DISABLE_LTUP: if(Horz) { CHANGERGSTATE(SBRG_TOPRIGHTBTN, STATE_SYSTEM_UNAVAILABLE); } else { CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, STATE_SYSTEM_UNAVAILABLE); } break; case ESB_ENABLE_BOTH: CHANGERGSTATE(SBRG_TOPRIGHTBTN, 0); CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, 0); break; } return Chg; } BOOL APIENTRY NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi) { NTSTATUS Status; SCROLLBARINFO sbi; PWINDOW_OBJECT Window; BOOL Ret; DECLARE_RETURN(BOOL); USER_REFERENCE_ENTRY Ref; DPRINT("Enter NtUserGetScrollBarInfo\n"); UserEnterExclusive(); Status = MmCopyFromCaller(&sbi, psbi, sizeof(SCROLLBARINFO)); if(!NT_SUCCESS(Status) || (sbi.cbSize != sizeof(SCROLLBARINFO))) { SetLastNtError(Status); RETURN(FALSE); } if(!(Window = UserGetWindowObject(hWnd))) { RETURN(FALSE); } UserRefObjectCo(Window, &Ref); Ret = co_IntGetScrollBarInfo(Window, idObject, &sbi); UserDerefObjectCo(Window); Status = MmCopyToCaller(psbi, &sbi, sizeof(SCROLLBARINFO)); if(!NT_SUCCESS(Status)) { SetLastNtError(Status); Ret = FALSE; } RETURN( Ret); CLEANUP: DPRINT("Leave NtUserGetScrollBarInfo, ret=%i\n",_ret_); UserLeave(); END_CLEANUP; } BOOL APIENTRY NtUserSBGetParms( HWND hWnd, int fnBar, PSBDATA pSBData, LPSCROLLINFO lpsi) { NTSTATUS Status; PWINDOW_OBJECT Window; SCROLLINFO psi; DWORD sz; BOOL Ret; DECLARE_RETURN(BOOL); USER_REFERENCE_ENTRY Ref; DPRINT("Enter NtUserGetScrollInfo\n"); UserEnterExclusive(); Status = MmCopyFromCaller(&psi.cbSize, &(lpsi->cbSize), sizeof(UINT)); if(!NT_SUCCESS(Status) || !((psi.cbSize == sizeof(SCROLLINFO)) || (psi.cbSize == sizeof(SCROLLINFO) - sizeof(psi.nTrackPos)))) { SetLastNtError(Status); RETURN(FALSE); } sz = psi.cbSize; Status = MmCopyFromCaller(&psi, lpsi, sz); if (!NT_SUCCESS(Status)) { SetLastNtError(Status); RETURN(FALSE); } if(!(Window = UserGetWindowObject(hWnd))) { RETURN(FALSE); } UserRefObjectCo(Window, &Ref); Ret = co_IntGetScrollInfo(Window, fnBar, &psi); UserDerefObjectCo(Window); Status = MmCopyToCaller(lpsi, &psi, sz); if(!NT_SUCCESS(Status)) { SetLastNtError(Status); RETURN( FALSE); } RETURN( Ret); CLEANUP: DPRINT("Leave NtUserGetScrollInfo, ret=%i\n",_ret_); UserLeave(); END_CLEANUP; } BOOL APIENTRY NtUserEnableScrollBar( HWND hWnd, UINT wSBflags, UINT wArrows) { PWINDOW_OBJECT Window = NULL; PSCROLLBARINFO InfoV = NULL, InfoH = NULL; BOOL Chg = FALSE; DECLARE_RETURN(BOOL); USER_REFERENCE_ENTRY Ref; DPRINT("Enter NtUserEnableScrollBar\n"); UserEnterExclusive(); if(!(Window = UserGetWindowObject(hWnd))) { RETURN(FALSE); } UserRefObjectCo(Window, &Ref); if(wSBflags == SB_CTL) { /* FIXME Enable or Disable SB Ctrl*/ DPRINT1("Enable Scrollbar SB_CTL\n"); InfoV = IntGetScrollbarInfoFromWindow(Window, SB_CTL); Chg = IntEnableScrollBar(FALSE, InfoV ,wArrows); /* Chg? Scrollbar is Refresh in user32/controls/scrollbar.c. */ RETURN(TRUE); } if(wSBflags != SB_BOTH && !SBID_IS_VALID(wSBflags)) { SetLastWin32Error(ERROR_INVALID_PARAMETER); DPRINT1("Trying to set scrollinfo for unknown scrollbar type %d", wSBflags); RETURN(FALSE); } if(!co_IntCreateScrollBars(Window)) { RETURN( FALSE); } switch(wSBflags) { case SB_BOTH: InfoV = IntGetScrollbarInfoFromWindow(Window, SB_VERT); /* fall through */ case SB_HORZ: InfoH = IntGetScrollbarInfoFromWindow(Window, SB_HORZ); break; case SB_VERT: InfoV = IntGetScrollbarInfoFromWindow(Window, SB_VERT); break; default: RETURN(FALSE); } if(InfoV) Chg = IntEnableScrollBar(FALSE, InfoV, wArrows); if(InfoH) Chg = (IntEnableScrollBar(TRUE, InfoH, wArrows) || Chg); //if(Chg && (Window->style & WS_VISIBLE)) /* FIXME - repaint scrollbars */ RETURN( TRUE); CLEANUP: if (Window) UserDerefObjectCo(Window); DPRINT("Leave NtUserEnableScrollBar, ret=%i\n",_ret_); UserLeave(); END_CLEANUP; } BOOL APIENTRY NtUserSetScrollBarInfo( HWND hWnd, LONG idObject, SETSCROLLBARINFO *info) { PWINDOW_OBJECT Window = NULL; SETSCROLLBARINFO Safeinfo; PSCROLLBARINFO sbi; LPSCROLLINFO psi; NTSTATUS Status; LONG Obj; DECLARE_RETURN(BOOL); USER_REFERENCE_ENTRY Ref; DPRINT("Enter NtUserSetScrollBarInfo\n"); UserEnterExclusive(); if(!(Window = UserGetWindowObject(hWnd))) { RETURN( FALSE); } UserRefObjectCo(Window, &Ref); Obj = SBOBJ_TO_SBID(idObject); if(!SBID_IS_VALID(Obj)) { SetLastWin32Error(ERROR_INVALID_PARAMETER); DPRINT1("Trying to set scrollinfo for unknown scrollbar type %d\n", Obj); RETURN( FALSE); } if(!co_IntCreateScrollBars(Window)) { RETURN(FALSE); } Status = MmCopyFromCaller(&Safeinfo, info, sizeof(SETSCROLLBARINFO)); if(!NT_SUCCESS(Status)) { SetLastNtError(Status); RETURN(FALSE); } sbi = IntGetScrollbarInfoFromWindow(Window, Obj); psi = IntGetScrollInfoFromWindow(Window, Obj); psi->nTrackPos = Safeinfo.nTrackPos; sbi->reserved = Safeinfo.reserved; RtlCopyMemory(&sbi->rgstate, &Safeinfo.rgstate, sizeof(Safeinfo.rgstate)); RETURN(TRUE); CLEANUP: if (Window) UserDerefObjectCo(Window); DPRINT("Leave NtUserSetScrollBarInfo, ret=%i\n",_ret_); UserLeave(); END_CLEANUP; } DWORD APIENTRY NtUserSetScrollInfo( HWND hWnd, int fnBar, LPCSCROLLINFO lpsi, BOOL bRedraw) { PWINDOW_OBJECT Window = NULL; NTSTATUS Status; SCROLLINFO ScrollInfo; DECLARE_RETURN(DWORD); USER_REFERENCE_ENTRY Ref; DPRINT("Enter NtUserSetScrollInfo\n"); UserEnterExclusive(); if(!(Window = UserGetWindowObject(hWnd))) { RETURN( 0); } UserRefObjectCo(Window, &Ref); Status = MmCopyFromCaller(&ScrollInfo, lpsi, sizeof(SCROLLINFO) - sizeof(ScrollInfo.nTrackPos)); if(!NT_SUCCESS(Status)) { SetLastNtError(Status); RETURN( 0); } RETURN(co_IntSetScrollInfo(Window, fnBar, &ScrollInfo, bRedraw)); CLEANUP: if (Window) UserDerefObjectCo(Window); DPRINT("Leave NtUserSetScrollInfo, ret=%i\n",_ret_); UserLeave(); END_CLEANUP; } /* Ported from WINE20020904 (SCROLL_ShowScrollBar) */ DWORD FASTCALL co_UserShowScrollBar(PWINDOW_OBJECT Window, int wBar, DWORD bShow) { DWORD Style, OldStyle; PWND Wnd; ASSERT_REFS_CO(Window); Wnd = Window->Wnd; switch(wBar) { case SB_HORZ: Style = WS_HSCROLL; break; case SB_VERT: Style = WS_VSCROLL; break; case SB_BOTH: Style = WS_HSCROLL | WS_VSCROLL; break; case SB_CTL: Style = 0; break; default: SetLastWin32Error(ERROR_INVALID_PARAMETER); return( FALSE); } if(!co_IntCreateScrollBars(Window)) { return( FALSE); } if (wBar == SB_CTL) { IntUpdateSBInfo(Window, SB_CTL); co_WinPosShowWindow(Window, bShow ? SW_SHOW : SW_HIDE); return( TRUE); } OldStyle = Wnd->style; if(bShow) Wnd->style |= Style; else Wnd->style &= ~Style; if(Wnd->style != OldStyle) { if(Wnd->style & WS_HSCROLL) IntUpdateSBInfo(Window, SB_HORZ); if(Wnd->style & WS_VSCROLL) IntUpdateSBInfo(Window, SB_VERT); if(Wnd->style & WS_VISIBLE) { /* Frame has been changed, let the window redraw itself */ co_WinPosSetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING); } } return( TRUE); } DWORD APIENTRY NtUserShowScrollBar(HWND hWnd, int wBar, DWORD bShow) { PWINDOW_OBJECT Window; DECLARE_RETURN(DWORD); DWORD ret; USER_REFERENCE_ENTRY Ref; DPRINT("Enter NtUserShowScrollBar\n"); UserEnterExclusive(); if (!(Window = UserGetWindowObject(hWnd))) { RETURN(0); } UserRefObjectCo(Window, &Ref); ret = co_UserShowScrollBar(Window, wBar, bShow); UserDerefObjectCo(Window); RETURN(ret); CLEANUP: DPRINT("Leave NtUserShowScrollBar, ret%i\n",_ret_); UserLeave(); END_CLEANUP; } /* EOF */