https://git.reactos.org/?p=reactos.git;a=commitdiff;h=236649c626f97c68a9d0a…
commit 236649c626f97c68a9d0a6709a1bb342681b2aa0
Author: Doug Lyons <douglyons(a)douglyons.com>
AuthorDate: Sat Jul 31 08:16:03 2021 -0500
Commit: Stanislav Motylkov <x86corez(a)gmail.com>
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 )
{