[0.4.13][WIN32SS] Fix regression CORE-16721 & scrollbar bug CORE-15557
authorJoachim Henze <Joachim.Henze@reactos.org>
Thu, 12 Mar 2020 22:10:35 +0000 (23:10 +0100)
committerJoachim Henze <Joachim.Henze@reactos.org>
Thu, 12 Mar 2020 22:10:35 +0000 (23:10 +0100)
"Scrolling by pressing the scrollbar arrows does not draw the arrows as pressed"
Fixed by a patch of JIRA-user 'I_kill_bugs'. Thank you very much!

The regression was introduced by 0.4.11-dev-586-g
929a2c6637b18cc14e259fe2f2d3d9635a10b2e9
(which itself aimed to fix CORE-13986,
but not CORE-13918 as erroneously stated in commit comment)

cherry-picked from 0.4.14-dev-1167-g
8bb9434d3eeeb3434348bb88f05a87ca31ba115e

and CORE-15557 "disabled scrollbars being clickable"
gets fixed as well due to squash of 0.4.14-dev-243-g
19fbdda95cb972f5d6f9652c238a2edc056538f3

win32ss/user/ntuser/scrollbar.c
win32ss/user/user32/controls/scrollbar.c

index 325be6f..565987b 100644 (file)
@@ -537,7 +537,6 @@ co_IntSetScrollInfo(PWND Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
          OldPos = Info->nPos;
          Info->nPos = lpsi->nPos;
          pSBData->pos = lpsi->nPos;
-         bChangeParams = TRUE;
       }
    }
 
@@ -611,11 +610,15 @@ co_IntSetScrollInfo(PWND Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
       else /* Show and enable scroll-bar only if no page only changed. */
       if (lpsi->fMask != SIF_PAGE)
       {
-         new_flags = ESB_ENABLE_BOTH;
          if ((nBar != SB_CTL) && bChangeParams)
          {
+            new_flags = ESB_ENABLE_BOTH;
             action |= SA_SSI_SHOW;
          }
+         else if (nBar == SB_CTL)
+         {
+            new_flags = ESB_ENABLE_BOTH;
+         }
       }
 
       if (Window->pSBInfo->WSBflags != new_flags) /* Check arrow flags */
index 3eb0242..8e5983e 100644 (file)
@@ -318,6 +318,26 @@ IntGetScrollBarInfo(HWND Wnd, INT Bar, PSCROLLBARINFO ScrollBarInfo)
   return NtUserGetScrollBarInfo(Wnd, IntScrollGetObjectId(Bar), ScrollBarInfo);
 }
 
+static VOID FASTCALL
+IntUpdateScrollArrows(HWND Wnd, HDC hDC, PSCROLLBARINFO ScrollBarInfo,
+                      SETSCROLLBARINFO *info, INT SBType, INT Arrow,
+                      BOOL Vertical, BOOL Pressed)
+{
+   if (Pressed)
+   {
+      ScrollBarInfo->rgstate[Arrow] |= STATE_SYSTEM_PRESSED;
+   }
+   else
+   {
+      ScrollBarInfo->rgstate[Arrow] &= ~STATE_SYSTEM_PRESSED;
+   }
+   /* Update arrow state */
+   info->rgstate[Arrow] = ScrollBarInfo->rgstate[Arrow];
+   NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), info);
+
+   IntDrawScrollArrows(hDC, ScrollBarInfo, Vertical);
+}
+
 void
 IntDrawScrollBar(HWND Wnd, HDC DC, INT Bar)
 {
@@ -831,9 +851,11 @@ IntScrollHandleScrollEvent(HWND Wnd, INT SBType, UINT Msg, POINT Pt)
         PrevPt = Pt;
         if (SBType == SB_CTL && (GetWindowLongPtrW(Wnd, GWL_STYLE) & WS_TABSTOP)) SetFocus(Wnd);
         SetCapture(Wnd);
-        ScrollBarInfo.rgstate[ScrollTrackHitTest] |= STATE_SYSTEM_PRESSED;
-        NewInfo.rgstate[ScrollTrackHitTest] = ScrollBarInfo.rgstate[ScrollTrackHitTest];
-        NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), &NewInfo);
+        /* Don't update scrollbar if disabled. */
+        if (ScrollBarInfo.rgstate[ScrollTrackHitTest] != STATE_SYSTEM_UNAVAILABLE)
+        {
+            IntUpdateScrollArrows (Wnd, Dc, &ScrollBarInfo, &NewInfo, SBType, ScrollTrackHitTest, Vertical, TRUE);
+        }
         break;
 
       case WM_MOUSEMOVE:
@@ -846,13 +868,12 @@ IntScrollHandleScrollEvent(HWND Wnd, INT SBType, UINT Msg, POINT Pt)
         ReleaseCapture();
         /* if scrollbar has focus, show back caret */
         if (Wnd == GetFocus()) ShowCaret(Wnd);
-        ScrollBarInfo.rgstate[ScrollTrackHitTest] &= ~STATE_SYSTEM_PRESSED;
-        NewInfo.rgstate[ScrollTrackHitTest] = ScrollBarInfo.rgstate[ScrollTrackHitTest];
-        NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), &NewInfo);
-
-        IntDrawScrollInterior(Wnd,Dc,SBType,Vertical,&ScrollBarInfo);
-        IntDrawScrollArrows(Dc, &ScrollBarInfo, Vertical);
-
+        /* Don't update scrollbar if disabled. */
+        if (ScrollBarInfo.rgstate[ScrollTrackHitTest] != STATE_SYSTEM_UNAVAILABLE)
+        {
+            IntUpdateScrollArrows (Wnd, Dc, &ScrollBarInfo, &NewInfo, SBType, ScrollTrackHitTest, Vertical, FALSE);
+            IntDrawScrollInterior(Wnd,Dc,SBType,Vertical,&ScrollBarInfo);
+        }
         break;
 
       case WM_SYSTIMER:
@@ -883,9 +904,17 @@ IntScrollHandleScrollEvent(HWND Wnd, INT SBType, UINT Msg, POINT Pt)
            SetSystemTimer(Wnd, SCROLL_TIMER, (WM_LBUTTONDOWN == Msg) ?
                            SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
                            (TIMERPROC) NULL);
+            if (ScrollBarInfo.rgstate[ScrollTrackHitTest] != STATE_SYSTEM_UNAVAILABLE)
+            {
+               if (!(ScrollBarInfo.rgstate[ScrollTrackHitTest] &= STATE_SYSTEM_PRESSED))
+               {
+                  IntUpdateScrollArrows (Wnd, Dc, &ScrollBarInfo, &NewInfo, SBType, ScrollTrackHitTest, Vertical, TRUE);
+               }
+            }
           }
         else
           {
+            IntUpdateScrollArrows (Wnd, Dc, &ScrollBarInfo, &NewInfo, SBType, ScrollTrackHitTest, Vertical, FALSE);
             KillSystemTimer(Wnd, SCROLL_TIMER);
           }
         break;
@@ -985,8 +1014,20 @@ IntScrollHandleScrollEvent(HWND Wnd, INT SBType, UINT Msg, POINT Pt)
            SetSystemTimer(Wnd, SCROLL_TIMER, (WM_LBUTTONDOWN == Msg) ?
                            SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
                            (TIMERPROC) NULL);
+            if (ScrollBarInfo.rgstate[ScrollTrackHitTest] != STATE_SYSTEM_UNAVAILABLE)
+            {
+               if (!(ScrollBarInfo.rgstate[ScrollTrackHitTest] &= STATE_SYSTEM_PRESSED))
+               {
+                  TRACE("Set Arrow\n");
+                  IntUpdateScrollArrows (Wnd, Dc, &ScrollBarInfo, &NewInfo, SBType, ScrollTrackHitTest, Vertical, TRUE);
+               }
+            }
           }
-        else KillSystemTimer(Wnd, SCROLL_TIMER);
+        else
+        {
+            IntUpdateScrollArrows (Wnd, Dc, &ScrollBarInfo, &NewInfo, SBType, ScrollTrackHitTest, Vertical, FALSE);
+            KillSystemTimer(Wnd, SCROLL_TIMER);
+        }
         break;
     }