Clean-up of scroll.c (1/4)

Andrew M. Johnston johnstonam at logica.com
Thu Feb 27 02:07:14 CST 2003


Hi,

This is part of a series of patches I sent several months ago to clean up the scrollbar code. 
The patch series removes about 400 lines of code (approx 25%) and some redundant calls
in the current design.  The patches have been updated for current CVS.

When I last submitted this patch there was a small problem found by Alexandre that has been fixed
by adding the following two lines in the SetScrollInfo function
if (enabled)
           infoPtr->flags &= ~ESB_DISABLE_BOTH;

Changelog:
    scrollbar.c - removes SCROLL_ShowScrollBar SCROLL_SetScrollInfo
                - breaks SCROLL_GetScrollInfo into two functions
                - significantly simplifies SetScrollInfo
                - simplifies other api functions

Use patch -p1 from within the top level wine directory to apply

License: X11

Andrew

--- wine/controls/scroll.c	2003-02-27 15:19:05.000000000 +0800
+++ wine/controls/scroll.a0.c	2003-02-27 13:46:18.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,33 +1542,38 @@
 
 /*************************************************************************
  *           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;
+
+    return (info->fMask & SIF_ALL);
 }
 
 
@@ -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 (BOOL)infoPtr;
 }
 
 
 /*************************************************************************
- *           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;
 }




More information about the wine-patches mailing list