[WIN32SS] Improve Drawing Scrollbars
authorJoachim Henze <Joachim.Henze@reactos.org>
Wed, 4 Mar 2020 01:12:06 +0000 (02:12 +0100)
committerJoachim Henze <Joachim.Henze@reactos.org>
Wed, 4 Mar 2020 01:12:06 +0000 (02:12 +0100)
A very nice patch of JIRA user "I_kill_Bugs". Many many Thanks!

It addresses:
- CORE-14755 fixed, flashing scrollbar triangles (we know 131 affected apps just from rapps!)
- CORE-13931 fixed, FamiTracker invisible about-dlg
- CORE-14685 improves a bit, but is not entirely fixed
- CORE-11561 improves a bit, but is not entirely fixed
- The patch avoids unnecessary redraws, speeds up GUI interaction and NSIS install times

Jim Tabor had no complains about it, I just did some white-space-tweaks on EOL and indentation.

FTR A testbot run (not on master but on 0.4.13-RC-48-g818e5bc)
https://reactos.org/testman/compare.php?ids=71645,71666 VBox LGTM
https://reactos.org/testman/compare.php?ids=71646,71667 KVM LGTM

I felt tempted to port back, but decided to play safe and commit to master just.

win32ss/user/ntuser/scrollbar.c

index 325be6f..6bbc7ae 100644 (file)
@@ -61,6 +61,9 @@ DBG_DEFAULT_CHANNEL(UserScrollbar);
 BOOL APIENTRY
 IntEnableScrollBar(BOOL Horz, PSCROLLBARINFO Info, UINT wArrows);
 
+static void
+IntRefeshScrollInterior(PWND pWnd, INT nBar, PSCROLLBARINFO psbi);
+
 
 /* Ported from WINE20020904 */
 /* Compute the scroll bar rectangle, in drawing coordinates (i.e. client coords for SB_CTL, window coords for SB_VERT and
@@ -636,13 +639,21 @@ co_IntSetScrollInfo(PWND Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
          if ( co_UserShowScrollBar(Window, nBar, TRUE, TRUE) )
             return lpsi->fMask & SIF_PREVIOUSPOS ? OldPos : pSBData->pos; /* SetWindowPos() already did the painting */
       if (bRedraw)
-      { // FIXME: Arrows and interior.
-         RECTL UpdateRect = psbi->rcScrollBar;
-         UpdateRect.left -= Window->rcClient.left - Window->rcWindow.left;
-         UpdateRect.right -= Window->rcClient.left - Window->rcWindow.left;
-         UpdateRect.top -= Window->rcClient.top - Window->rcWindow.top;
-         UpdateRect.bottom -= Window->rcClient.top - Window->rcWindow.top;
-         co_UserRedrawWindow(Window, &UpdateRect, 0, RDW_INVALIDATE | RDW_FRAME);
+      {
+         if (action & SA_SSI_REPAINT_ARROWS)
+         {  // Redraw the entire bar.
+            RECTL UpdateRect = psbi->rcScrollBar;
+            UpdateRect.left -= Window->rcClient.left - Window->rcWindow.left;
+            UpdateRect.right -= Window->rcClient.left - Window->rcWindow.left;
+            UpdateRect.top -= Window->rcClient.top - Window->rcWindow.top;
+            UpdateRect.bottom -= Window->rcClient.top - Window->rcWindow.top;
+            co_UserRedrawWindow(Window, &UpdateRect, 0, RDW_INVALIDATE | RDW_FRAME);
+         }
+         else
+         {
+            // Redraw only the interior part of the bar.
+            IntRefeshScrollInterior(Window, nBar, psbi);
+         }
       } // FIXME: Arrows
 /*      else if( action & SA_SSI_REPAINT_ARROWS )
       {
@@ -1069,6 +1080,21 @@ IntScrollGetObjectId(INT SBType)
    return OBJID_CLIENT;
 }
 
+static void
+IntRefeshScrollInterior(PWND pWnd, INT nBar, PSCROLLBARINFO psbi)
+{
+   HDC hdc;
+   BOOL Vertical = ((nBar == SB_CTL) ? ((pWnd->style & SBS_VERT) != 0) : (nBar == SB_VERT));
+
+   hdc = UserGetDCEx(pWnd, NULL, DCX_CACHE | ((nBar == SB_CTL) ? 0 : DCX_WINDOW));
+   if (hdc)
+   {  /* Get updated info. */
+      co_IntGetScrollBarInfo(pWnd, IntScrollGetObjectId(nBar), psbi);
+      IntDrawScrollInterior(pWnd, hdc, nBar, Vertical, psbi);
+      UserReleaseDC(pWnd, hdc, FALSE);
+   }
+}
+
 void
 IntDrawScrollBar(PWND Wnd, HDC DC, INT Bar)
 {