https://git.reactos.org/?p=reactos.git;a=commitdiff;h=236649c626f97c68a9d0a6709a1bb342681b2aa0

commit 236649c626f97c68a9d0a6709a1bb342681b2aa0
Author:     Doug Lyons <[email protected]>
AuthorDate: Sat Jul 31 08:16:03 2021 -0500
Commit:     Stanislav Motylkov <[email protected]>
CommitDate: Fri Sep 3 22:34:26 2021 +0300

    [UXTHEME][NTUSER] Fix flashing of scrollbar when scrolling (#3868)
    
    Based on a patch by I_Kill_Bugs.
---
 dll/win32/uxtheme/themehooks.c  | 24 ++++++++++++++++++++
 sdk/include/psdk/winuser.h      |  1 +
 win32ss/user/ntuser/scrollbar.c | 49 +++++++++++++++++++++++++++++++++--------
 3 files changed, 65 insertions(+), 9 deletions(-)

diff --git a/dll/win32/uxtheme/themehooks.c b/dll/win32/uxtheme/themehooks.c
index 583fce34d4f..f9c045cea67 100644
--- a/dll/win32/uxtheme/themehooks.c
+++ b/dll/win32/uxtheme/themehooks.c
@@ -576,6 +576,29 @@ dodefault:
     return g_user32ApiHook.GetScrollInfo(hwnd, fnBar, lpsi);
 }
 
+INT WINAPI ThemeSetScrollInfo(HWND hWnd, int fnBar, LPCSCROLLINFO lpsi, BOOL 
bRedraw)
+{
+    PWND_DATA pwndData;
+    SCROLLINFO siout;
+    LPSCROLLINFO lpsiout = &siout;
+    BOOL IsThemed = FALSE;
+
+    pwndData = ThemeGetWndData(hWnd);
+
+    if (!pwndData)
+        goto dodefault;
+
+    if (pwndData->hthemeScrollbar)
+        IsThemed = TRUE;
+
+    memcpy(&siout, lpsi, sizeof(SCROLLINFO));
+    if (IsThemed)
+        siout.fMask |= SIF_THEMED;
+
+dodefault:
+    return g_user32ApiHook.SetScrollInfo(hWnd, fnBar, lpsiout, bRedraw);
+}
+
 /**********************************************************************
  *      Exports
  */
@@ -611,6 +634,7 @@ ThemeInitApiHook(UAPIHK State, PUSERAPIHOOK puah)
 
     puah->SetWindowRgn = ThemeSetWindowRgn;
     puah->GetScrollInfo = ThemeGetScrollInfo;
+    puah->SetScrollInfo = ThemeSetScrollInfo;
 
     UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCPAINT);
     UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCACTIVATE);
diff --git a/sdk/include/psdk/winuser.h b/sdk/include/psdk/winuser.h
index 7e1a9ff2eb3..487140761fc 100644
--- a/sdk/include/psdk/winuser.h
+++ b/sdk/include/psdk/winuser.h
@@ -1221,6 +1221,7 @@ extern "C" {
 #define SIF_RANGE 1
 #define SIF_DISABLENOSCROLL 8
 #define SIF_TRACKPOS   16
+#define SIF_THEMED 128      /* REACTOS Specific Only */
 #define SWP_DRAWFRAME 32
 #define SWP_FRAMECHANGED 32
 #define SWP_HIDEWINDOW 128
diff --git a/win32ss/user/ntuser/scrollbar.c b/win32ss/user/ntuser/scrollbar.c
index 75d499b25e6..359bc923f5b 100644
--- a/win32ss/user/ntuser/scrollbar.c
+++ b/win32ss/user/ntuser/scrollbar.c
@@ -276,6 +276,7 @@ co_IntGetScrollInfo(PWND Window, INT nBar, PSBDATA pSBData, 
LPSCROLLINFO lpsi)
 
    ASSERT_REFS_CO(Window);
 
+   lpsi->fMask &= ~SIF_THEMED;    // Remove Theme bit
    if(!SBID_IS_VALID(nBar))
    {
       EngSetLastError(ERROR_INVALID_PARAMETER);
@@ -334,6 +335,7 @@ NEWco_IntGetScrollInfo(
   UINT Mask;
   PSBTRACK pSBTrack = pWnd->head.pti->pSBTrack;
 
+  lpsi->fMask &= ~SIF_THEMED;         // Remove Theme bit
   if (!SBID_IS_VALID(nBar))
   {
      EngSetLastError(ERROR_INVALID_PARAMETER);
@@ -511,7 +513,7 @@ co_IntSetScrollInfo(PWND Window, INT nBar, LPCSCROLLINFO 
lpsi, BOOL bRedraw)
       EngSetLastError(ERROR_INVALID_PARAMETER);
       return 0;
    }
-   if (lpsi->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL | SIF_PREVIOUSPOS))
+   if ((lpsi->fMask & ~SIF_THEMED) & ~(SIF_ALL | SIF_DISABLENOSCROLL | 
SIF_PREVIOUSPOS))
    {
       EngSetLastError(ERROR_INVALID_PARAMETER);
       return 0;
@@ -611,7 +613,7 @@ 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)
+      if ((lpsi->fMask & ~SIF_THEMED) != SIF_PAGE)
       {
          if ((nBar != SB_CTL) && bChangeParams)
          {
@@ -643,20 +645,49 @@ co_IntSetScrollInfo(PWND Window, INT nBar, LPCSCROLLINFO 
lpsi, BOOL bRedraw)
             return lpsi->fMask & SIF_PREVIOUSPOS ? OldPos : pSBData->pos; /* 
SetWindowPos() already did the painting */
       if (bRedraw)
       {
-         if (action & SA_SSI_REPAINT_ARROWS)
-         {  // Redraw the entire bar.
+         if (!(lpsi->fMask & SIF_THEMED)) /* Not Using Themes */
+         {
+            TRACE("Not using themes.\n");
+            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);
+            }
+         }
+         else  /* Using Themes */
+         {
             RECTL UpdateRect = psbi->rcScrollBar;
+            TRACE("Using themes.\n");
             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;
+            /* Just paint the interior and not the arrows. */
+            if (!(action & SA_SSI_REPAINT_ARROWS))
+            {
+               if (nBar == SB_HORZ)
+               {
+                  UpdateRect.left += psbi->dxyLineButton;
+                  UpdateRect.right -= psbi->dxyLineButton;
+               }
+               if (nBar == SB_VERT)
+               {
+                  UpdateRect.top += psbi->dxyLineButton;
+                  UpdateRect.bottom -= psbi->dxyLineButton;
+               }
+            }
             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 )
       {

Reply via email to