Hi, Resend with minor requested changes Changelog: scrollbar.c - removes SCROLL_ShowScrollBar SCROLL_SetScrollInfo - breaks SCROLL_GetScrollInfo into two functions - significantly simplifies SetScrollInfo - simplifies other api functions License: X11 Andrew --- wine-20030219/controls/scroll.c 2003-02-28 10:46:42.000000000 +0800 +++ wine/controls/scroll.c 2003-02-28 10:43:04.000000000 +0800 @@ -37,7 +37,7 @@ INT maxVal; /* Maximum scroll-bar value */ INT page; /* Page size of scroll bar (Win32) */ UINT flags; /* EnableScrollBar flags */ -} SCROLLBAR_INFO; +} SCROLLBAR_INFO, *LPSCROLLBAR_INFO; static HBITMAP hUpArrow; @@ -81,6 +81,12 @@ /* Scroll timer id */ #define SCROLL_TIMER 0 +/* Determine if the info is valid */ +#define SCROLL_INFO_INVALID(info) \ + ((info->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL)) || \ + ((info->cbSize != sizeof(*info)) && \ + (info->cbSize != sizeof(*info) - sizeof(info->nTrackPos)))) + /* Scroll-bar hit testing */ enum SCROLL_HITTEST { @@ -111,10 +117,6 @@ static BOOL SCROLL_MovingThumb = FALSE; /* Local functions */ -static BOOL SCROLL_ShowScrollBar( HWND hwnd, INT nBar, - BOOL fShowH, BOOL fShowV ); -static INT SCROLL_SetScrollInfo( HWND hwnd, INT nBar, - const SCROLLINFO *info, INT *action ); static void SCROLL_DrawInterior_9x( HWND hwnd, HDC hdc, INT nBar, RECT *rect, INT arrowSize, INT thumbSize, INT thumbPos, @@ -1412,6 +1414,7 @@ /************************************************************************* * SetScrollInfo (USER32.@) + * * SetScrollInfo can be used to set the position, upper bound, * lower bound, and page size of a scrollbar control. * @@ -1420,166 +1423,118 @@ * * 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 + * 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. + * the text), and info->nPage = 25. */ -INT WINAPI SetScrollInfo( -HWND hwnd /* [in] Handle of window whose scrollbar will be affected */, -INT nBar /* [in] One of SB_HORZ, SB_VERT, or SB_CTL */, +INT WINAPI SetScrollInfo( +HWND hwnd /* [in] Handle of window with scrollbar(s) */, +INT nBar /* [in] One of SB_HORZ, SB_VERT, or SB_CTL */, const SCROLLINFO *info /* [in] Specifies what to change and new values */, BOOL bRedraw /* [in] 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. */ - - SCROLLBAR_INFO *infoPtr; - UINT new_flags; - BOOL bChangeParams = FALSE; /* don't show/hide scrollbar if params don't change */ - - *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; + LPSCROLLBAR_INFO infoPtr; + INT gap, value; + UINT oldFlags; + BOOL enabled; + BOOL changed = FALSE; /* only show/hide scrollbar if params change */ + + /* handle invalid data structure */ + if (SCROLL_INFO_INVALID(info)) return 0; + infoPtr = SCROLL_GetScrollInfo(hwnd, nBar); + if (!infoPtr) return 0; if (TRACE_ON(scroll)) { TRACE("hwnd=%p bar=%d", hwnd, nBar); - if (info->fMask & SIF_PAGE) DPRINTF( " page=%d", info->nPage ); - if (info->fMask & SIF_POS) DPRINTF( " pos=%d", info->nPos ); - if (info->fMask & SIF_RANGE) DPRINTF( " min=%d max=%d", info->nMin, info->nMax ); - DPRINTF("\n"); + if (info->fMask & SIF_PAGE) DPRINTF(" page=%d", info->nPage); + if (info->fMask & SIF_POS) DPRINTF(" pos=%d", info->nPos); + if (info->fMask & SIF_RANGE) + DPRINTF(" min=%d max=%d", info->nMin, info->nMax); + DPRINTF(" bRedraw=%d\n", bRedraw); } - /* Set the page size */ - - if (info->fMask & SIF_PAGE) - { - if( infoPtr->page != info->nPage ) - { - infoPtr->page = info->nPage; - *action |= SA_SSI_REFRESH; - bChangeParams = TRUE; - } - } - - /* 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 */ - + /* set the scroll range */ if (info->fMask & SIF_RANGE) { - /* Invalid range -> range is set to (0,0) */ if ((info->nMin > info->nMax) || ((UINT)(info->nMax - info->nMin) >= 0x80000000)) { + /* invalid range -> range is set to (0,0) */ + changed = ((infoPtr->minVal) || (infoPtr->maxVal)); infoPtr->minVal = 0; infoPtr->maxVal = 0; - bChangeParams = TRUE; } - else + else if ((infoPtr->minVal != info->nMin) || + (infoPtr->maxVal != info->nMax)) { - if( infoPtr->minVal != info->nMin || - infoPtr->maxVal != info->nMax ) - { - *action |= SA_SSI_REFRESH; - infoPtr->minVal = info->nMin; - infoPtr->maxVal = info->nMax; - bChangeParams = TRUE; - } + infoPtr->minVal = info->nMin; + infoPtr->maxVal = info->nMax; + changed = TRUE; } } - /* 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 ); + /* determine desired page size */ + value = infoPtr->page; + if ((info->fMask & SIF_PAGE) && (value != info->nPage)) + value = info->nPage; + + /* make sure the page size is valid */ + gap = infoPtr->maxVal - infoPtr->minVal + 1; + if (value > gap) + value = gap; + else if (value < 1) + value = 1; + /* change page if required */ + if (value != infoPtr->page) + { + infoPtr->page = value; + changed = TRUE; + } + + /* set the scroll pos */ + value = infoPtr->curVal; + if ((info->fMask & SIF_POS) && (value != info->nPos)) + value = info->nPos; + + /* make sure the pos is inside the range */ + gap = infoPtr->maxVal - infoPtr->page + 1; + if (value < infoPtr->minVal) + value = infoPtr->minVal; + else if (value > gap) + value = gap; TRACE(" new values: page=%d pos=%d min=%d max=%d\n", - infoPtr->page, infoPtr->curVal, - infoPtr->minVal, infoPtr->maxVal ); + infoPtr->page, value, infoPtr->minVal, infoPtr->maxVal); - /* don't change the scrollbar state if SetScrollInfo - * is just called with SIF_DISABLENOSCROLL - */ - if(!(info->fMask & SIF_ALL)) goto done; - - /* Check if the scrollbar should be hidden or disabled */ - - if (info->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL)) + /* determine the activation state */ + oldFlags = infoPtr->flags; + enabled = infoPtr->minVal < gap; + if (!(info->fMask & SIF_ALL)) + ; /* if called without SIF_ALL don't change state */ + else if (!enabled && info->fMask & SIF_DISABLENOSCROLL) + infoPtr->flags |= ESB_DISABLE_BOTH; + else { - new_flags = infoPtr->flags; - if (infoPtr->minVal >= infoPtr->maxVal - max( infoPtr->page-1, 0 )) - { - /* Hide or disable scroll-bar */ - if (info->fMask & SIF_DISABLENOSCROLL) - { - new_flags = ESB_DISABLE_BOTH; - *action |= SA_SSI_REFRESH; - } - else if ((nBar != SB_CTL) && bChangeParams) - { - *action = SA_SSI_HIDE; - goto done; - } - } - else /* Show and enable scroll-bar */ - { - new_flags = 0; - if ((nBar != SB_CTL) && bChangeParams) - *action |= SA_SSI_SHOW; - } - - if (infoPtr->flags != new_flags) /* check arrow flags */ - { - infoPtr->flags = new_flags; - *action |= SA_SSI_REPAINT_ARROWS; - } - } - -done: - /* Return current position */ + if (enabled) + infoPtr->flags &= ~ESB_DISABLE_BOTH; + if (changed && (nBar != SB_CTL) && + (info->fMask & (SIF_RANGE | SIF_PAGE))) + ShowScrollBar(hwnd, nBar, enabled); + } + + /* change position if required */ + if (value != infoPtr->curVal) + { + infoPtr->curVal = value; + changed = TRUE; + } + + /* redraw the scroll bar if desired or required */ + if (WIN_IsWindowDrawable(hwnd, FALSE) && + ((infoPtr->flags != oldFlags) || + (bRedraw && changed && (infoPtr->minVal < gap)))) + SCROLL_RefreshScrollBar(hwnd, nBar, TRUE, TRUE); return infoPtr->curVal; } @@ -1587,32 +1542,37 @@ /************************************************************************* * GetScrollInfo (USER32.@) - * GetScrollInfo can be used to retrieve the position, upper bound, + * + * GetScrollInfo 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 /* [in] Handle of window */ , - INT nBar /* [in] One of SB_HORZ, SB_VERT, or SB_CTL */, - LPSCROLLINFO info /* [in/out] (info.fMask [in] specifies which values are to retrieve) */) +BOOL WINAPI GetScrollInfo( +HWND hwnd /* [in] Handle of window with scrollbar(s) */, +INT nBar /* [in] One of SB_HORZ, SB_VERT, or SB_CTL */, +LPSCROLLINFO info /* [in/out] (fMask specifies which values to retrieve) */) { - SCROLLBAR_INFO *infoPtr; + LPSCROLLBAR_INFO infoPtr; + + /* handle invalid data structure */ + if (SCROLL_INFO_INVALID(info)) return FALSE; + infoPtr = SCROLL_GetScrollInfo(hwnd, nBar); + if (!infoPtr) return FALSE; - 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; + TRACE("hwnd=%p nBar=%d info=%p\n", hwnd, nBar, info); + /* fill in the desired scroll info structure */ 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 == WIN_GetFullHandle(hwnd)) ? SCROLL_TrackingVal : infoPtr->curVal; if (info->fMask & SIF_RANGE) { - info->nMin = infoPtr->minVal; - info->nMax = infoPtr->maxVal; + info->nMin = infoPtr->minVal; + info->nMax = infoPtr->maxVal; } + return (info->fMask & SIF_ALL) != 0; } @@ -1628,23 +1588,25 @@ * 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 /* [in] Handle of window whose scrollbar will be affected */, +INT WINAPI SetScrollPos( +HWND hwnd /* [in] Handle of window with scrollbar(s) */, INT nBar /* [in] One of SB_HORZ, SB_VERT, or SB_CTL */, INT nPos /* [in] New value */, -BOOL bRedraw /* [in] Should scrollbar be redrawn afterwards ? */ ) +BOOL bRedraw /* [in] Should scrollbar be redrawn afterwards ? */) { + INT oldPos = GetScrollPos(hwnd, nBar); SCROLLINFO info; - SCROLLBAR_INFO *infoPtr; - INT oldPos; - if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, nBar ))) return 0; - oldPos = infoPtr->curVal; + TRACE("hwnd=%p nBar=%d nPos=%d bRedraw=%d\n", + hwnd, nBar, nPos, bRedraw); + + /* fill in an info structure and use common set info code */ info.cbSize = sizeof(info); info.nPos = nPos; info.fMask = SIF_POS; - SetScrollInfo( hwnd, nBar, &info, bRedraw ); - return oldPos; + SetScrollInfo(hwnd, nBar, &info, bRedraw); + + return oldPos; } @@ -1653,20 +1615,21 @@ * * RETURNS * Success: Current position - * Failure: 0 + * Failure: 0 * * REMARKS - * Note the ambiguity when 0 is returned. Use GetLastError + * There is ambiguity when 0 is returned. Use GetLastError * to make sure there was an error (and to know which one). */ -INT WINAPI GetScrollPos( -HWND hwnd, /* [in] Handle of window */ +INT WINAPI GetScrollPos( +HWND hwnd /* [in] Handle of window with scrollbar(s) */, INT nBar /* [in] One of SB_HORZ, SB_VERT, or SB_CTL */) { - SCROLLBAR_INFO *infoPtr; + LPSCROLLBAR_INFO infoPtr = SCROLL_GetScrollInfo(hwnd, nBar); - if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, nBar ))) return 0; - return infoPtr->curVal; + TRACE("hwnd=%p nBar=%d\n", hwnd, nBar); + + return infoPtr ? infoPtr->curVal: 0; } @@ -1675,58 +1638,26 @@ * * RETURNS STD */ -BOOL WINAPI SetScrollRange( -HWND hwnd, /* [in] Handle of window whose scrollbar will be affected */ -INT nBar, /* [in] One of SB_HORZ, SB_VERT, or SB_CTL */ -INT minVal, /* [in] New minimum value */ -INT maxVal, /* [in] New maximum value */ +BOOL WINAPI SetScrollRange( +HWND hwnd /* [in] Handle of window with scrollbar(s) */, +INT nBar /* [in] One of SB_HORZ, SB_VERT, or SB_CTL */, +INT minVal /* [in] New minimum value */, +INT maxVal /* [in] New maximum value */, BOOL bRedraw /* [in] Should scrollbar be redrawn afterwards ? */) { SCROLLINFO info; + TRACE("hwnd=%p nBar=%d minVal=%d maxVal=%d bRedraw=%d\n", + hwnd, nBar, minVal, maxVal, bRedraw); + + /* fill in an info structure and use common set info code */ info.cbSize = sizeof(info); info.nMin = minVal; info.nMax = maxVal; info.fMask = SIF_RANGE; - SetScrollInfo( hwnd, nBar, &info, bRedraw ); - return TRUE; -} - - -/************************************************************************* - * SCROLL_SetNCSbState - * - * Updates both scrollbars at the same time. Used by MDI CalcChildScroll(). - */ -INT SCROLL_SetNCSbState(HWND hwnd, int vMin, int vMax, int vPos, - int hMin, int hMax, int hPos) -{ - INT vA, hA; - SCROLLINFO vInfo, hInfo; - - vInfo.cbSize = hInfo.cbSize = sizeof(SCROLLINFO); - vInfo.nMin = vMin; - vInfo.nMax = vMax; - vInfo.nPos = vPos; - hInfo.nMin = hMin; - hInfo.nMax = hMax; - hInfo.nPos = hPos; - vInfo.fMask = hInfo.fMask = SIF_RANGE | SIF_POS; + SetScrollInfo(hwnd, nBar, &info, bRedraw); - SCROLL_SetScrollInfo( hwnd, SB_VERT, &vInfo, &vA ); - SCROLL_SetScrollInfo( hwnd, SB_HORZ, &hInfo, &hA ); - - if( !SCROLL_ShowScrollBar( hwnd, 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( hwnd, SB_VERT, FALSE, TRUE ); - - if( hA & SA_SSI_REFRESH ) - SCROLL_RefreshScrollBar( hwnd, SB_HORZ, FALSE, TRUE ); - } - return 0; + return TRUE; } @@ -1735,137 +1666,105 @@ * * RETURNS STD */ -BOOL WINAPI GetScrollRange( -HWND hwnd, /* [in] Handle of window */ -INT nBar, /* [in] One of SB_HORZ, SB_VERT, or SB_CTL */ -LPINT lpMin, /* [out] Where to store minimum value */ +BOOL WINAPI GetScrollRange( +HWND hwnd /* [in] Handle of window with scrollbar(s) */, +INT nBar /* [in] One of SB_HORZ, SB_VERT, or SB_CTL */, +LPINT lpMin /* [out] Where to store minimum value */, LPINT lpMax /* [out] Where to store maximum value */) { - SCROLLBAR_INFO *infoPtr; + LPSCROLLBAR_INFO infoPtr = SCROLL_GetScrollInfo(hwnd, nBar); - 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; + TRACE("hwnd=%p nBar=%d lpMin=%p lpMax=%p\n", hwnd, nBar, lpMin, lpMax); + + if (lpMin) *lpMin = infoPtr ? infoPtr->minVal : 0; + if (lpMax) *lpMax = infoPtr ? infoPtr->maxVal : 0; + + return infoPtr ? TRUE : FALSE; } /************************************************************************* - * SCROLL_ShowScrollBar() + * ShowScrollBar (USER32.@) * - * Back-end for ShowScrollBar(). Returns FALSE if no action was taken. + * RETURNS STD */ -BOOL SCROLL_ShowScrollBar( HWND hwnd, INT nBar, - BOOL fShowH, BOOL fShowV ) +BOOL WINAPI ShowScrollBar( +HWND hwnd /* [in] Handle of window with scrollbar(s) */, +INT nBar /* [in] One of SB_HORZ, SB_VERT, SB_BOTH or SB_CTL */, +BOOL fShow /* [in] TRUE = show, FALSE = hide */) { - LONG style = GetWindowLongW( hwnd, GWL_STYLE ); + LONG style = GetWindowLongW(hwnd, GWL_STYLE); + LONG oldStyle = style; - TRACE("hwnd=%p bar=%d horz=%d, vert=%d\n", hwnd, nBar, fShowH, fShowV ); + TRACE("hwnd=%p nBar=%d fShow=%d\n", hwnd, nBar, fShow); - switch(nBar) + /* change the show state as requested */ + switch (nBar) { case SB_CTL: - ShowWindow( hwnd, fShowH ? SW_SHOW : SW_HIDE ); + ShowWindow(hwnd, fShow ? SW_SHOW : SW_HIDE); return TRUE; case SB_BOTH: case SB_HORZ: - if (fShowH) - { - fShowH = !(style & WS_HSCROLL); + if (fShow) style |= WS_HSCROLL; - } else /* hide it */ - { - fShowH = (style & WS_HSCROLL); style &= ~WS_HSCROLL; - } - if( nBar == SB_HORZ ) { - fShowV = FALSE; - break; - } - /* fall through */ - + if (nBar == SB_HORZ) break; + /* fall through */ case SB_VERT: - if (fShowV) - { - fShowV = !(style & WS_VSCROLL); + if (fShow) style |= WS_VSCROLL; - } - else /* hide it */ - { - fShowV = (style & WS_VSCROLL); + else /* hide it */ style &= ~WS_VSCROLL; - } - if ( nBar == SB_VERT ) - fShowH = FALSE; - break; - default: - return FALSE; /* Nothing to do! */ + break; } - if( fShowH || fShowV ) /* frame has been changed, let the window redraw itself */ + /* update the window if frame has changed */ + if (style != oldStyle) { - WIN_SetStyle( hwnd, style ); - SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE - | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ); - return TRUE; + WIN_SetStyle(hwnd, style); + SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | + SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED); } - return FALSE; /* no frame changes */ -} - - -/************************************************************************* - * ShowScrollBar (USER32.@) - * - * RETURNS STD - */ -BOOL WINAPI ShowScrollBar( -HWND hwnd, /* [in] Handle of window whose scrollbar(s) will be affected */ -INT nBar, /* [in] One of SB_HORZ, SB_VERT, SB_BOTH or SB_CTL */ -BOOL fShow /* [in] TRUE = show, FALSE = hide */) -{ - SCROLL_ShowScrollBar( hwnd, nBar, (nBar == SB_VERT) ? 0 : fShow, - (nBar == SB_HORZ) ? 0 : fShow ); return TRUE; } /************************************************************************* * EnableScrollBar (USER32.@) + * + * RETURNS STD */ -BOOL WINAPI EnableScrollBar( HWND hwnd, INT nBar, UINT flags ) +BOOL WINAPI EnableScrollBar( +HWND hwnd /* [in] Handle of window with scrollbar(s) */, +INT nBar /* [in] One of SB_HORZ, SB_VERT, SB_BOTH or SB_CTL */, +UINT flags /* [in] Flags indicating which scroll bars to enable */) { - BOOL bFineWithMe; - SCROLLBAR_INFO *infoPtr; - - TRACE("%p %d %d\n", hwnd, nBar, flags ); + BOOL ret = TRUE; + LPSCROLLBAR_INFO infoPtr; - flags &= ESB_DISABLE_BOTH; + TRACE("hwnd=%p nBar=%d flags=%04x\n", hwnd, nBar, flags); + /* use recursion to handle the case of two scroll bars */ 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; + ret = EnableScrollBar(hwnd, SB_VERT, flags); + nBar = SB_HORZ; } - else - bFineWithMe = TRUE; - if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, nBar ))) return FALSE; - if (bFineWithMe && infoPtr->flags == flags) return FALSE; - infoPtr->flags = flags; + /* change the enable flags of the bar and redraw if necessary */ + flags &= ~ESB_DISABLE_BOTH; + infoPtr = SCROLL_GetScrollInfo(hwnd, nBar); + ret = ret && infoPtr && (infoPtr->flags != flags); + if (ret) + { + infoPtr->flags = flags; + if (WIN_IsWindowDrawable(hwnd, FALSE)) + SCROLL_RefreshScrollBar(hwnd, nBar, TRUE, TRUE); + } - SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, TRUE ); - return TRUE; + return ret; }