From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/tests/scroll.c | 13 +++++++++++++ dlls/win32u/scroll.c | 9 ++++++--- include/ntuser.h | 3 +++ 3 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/tests/scroll.c b/dlls/user32/tests/scroll.c index 20bb0dc111b..95782a47a6e 100644 --- a/dlls/user32/tests/scroll.c +++ b/dlls/user32/tests/scroll.c @@ -671,6 +671,19 @@ static void test_SetScrollInfo(void) ret = IsWindowEnabled(hScroll); ok(ret, "Unexpected enabled state.\n");
+ EnableScrollBar(mainwnd, SB_CTL, ESB_ENABLE_BOTH); + + si.fMask = SIF_POS; + si.nPos = 3; + ret = SetScrollInfo(mainwnd, SB_HORZ, &si, FALSE); + ok(ret == 3, "SetScrollInfo returned %d\n", ret); + + /* undocumented flag making SetScrollInfo return previous position */ + si.fMask = SIF_POS | 0x1000; + si.nPos = 4; + ret = SetScrollInfo(mainwnd, SB_HORZ, &si, FALSE); + ok(ret == 3, "SetScrollInfo returned %d\n", ret); + DestroyWindow(hScroll); DestroyWindow(mainwnd); } diff --git a/dlls/win32u/scroll.c b/dlls/win32u/scroll.c index a51c7d3cf93..d48755cec7c 100644 --- a/dlls/win32u/scroll.c +++ b/dlls/win32u/scroll.c @@ -824,7 +824,7 @@ void track_scroll_bar( HWND hwnd, int scrollbar, POINT pt ) */ static inline BOOL validate_scroll_info( const SCROLLINFO *info ) { - return !(info->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL) || + return !(info->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL | SIF_RETURNPREV) || (info->cbSize != sizeof(*info) && info->cbSize != sizeof(*info) - sizeof(info->nTrackPos))); } @@ -862,7 +862,7 @@ static int set_scroll_info( HWND hwnd, int bar, const SCROLLINFO *info, BOOL red { struct scroll_info *scroll; UINT new_flags; - int action = 0, ret; + int action = 0, ret = 0;
/* handle invalid data structure */ if (!validate_scroll_info( info ) || @@ -878,6 +878,9 @@ static int set_scroll_info( HWND hwnd, int bar, const SCROLLINFO *info, BOOL red TRACE( "\n" ); }
+ /* undocumented flag, return previous position instead of modified */ + if (info->fMask & SIF_RETURNPREV) ret = scroll->curVal; + /* Set the page size */ if ((info->fMask & SIF_PAGE) && scroll->page != info->nPage) { @@ -970,7 +973,7 @@ static int set_scroll_info( HWND hwnd, int bar, const SCROLLINFO *info, BOOL red }
done: - ret = scroll->curVal; + if (!(info->fMask & SIF_RETURNPREV)) ret = scroll->curVal; release_scroll_info_ptr( scroll ); if (action & SA_SSI_HIDE) show_scroll_bar( hwnd, bar, FALSE, FALSE ); diff --git a/include/ntuser.h b/include/ntuser.h index fecdbbbe253..34701d21533 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -269,6 +269,9 @@ struct send_message_callback_params /* NtUserScrollWindowEx flag */ #define SW_NODCCACHE 0x8000
+/* NtUserSetScrollInfo flag */ +#define SIF_RETURNPREV 0x1000 + /* NtUserInitializeClientPfnArrays parameter, not compatible with Windows */ struct user_client_procs {
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/scroll.c | 12 ++++-------- dlls/user32/tests/scroll.c | 2 -- 2 files changed, 4 insertions(+), 10 deletions(-)
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index e368a2feb70..c92ec6459d9 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -518,18 +518,14 @@ BOOL WINAPI DECLSPEC_HOTPATCH GetScrollInfo(HWND hwnd, INT nBar, LPSCROLLINFO in * Note the ambiguity when 0 is returned. Use GetLastError * to make sure there was an error (and to know which one). */ -INT WINAPI DECLSPEC_HOTPATCH SetScrollPos( HWND hwnd, INT nBar, INT nPos, BOOL bRedraw) +int WINAPI DECLSPEC_HOTPATCH SetScrollPos( HWND hwnd, int bar, int pos, BOOL redraw ) { SCROLLINFO info; - SCROLLBAR_INFO *infoPtr; - INT oldPos = 0;
- if ((infoPtr = SCROLL_GetInternalInfo( hwnd, nBar, FALSE ))) oldPos = infoPtr->curVal; info.cbSize = sizeof(info); - info.nPos = nPos; - info.fMask = SIF_POS; - NtUserSetScrollInfo( hwnd, nBar, &info, bRedraw ); - return oldPos; + info.nPos = pos; + info.fMask = SIF_POS | SIF_RETURNPREV; + return NtUserSetScrollInfo( hwnd, bar, &info, redraw ); }
diff --git a/dlls/user32/tests/scroll.c b/dlls/user32/tests/scroll.c index 95782a47a6e..481219665ec 100644 --- a/dlls/user32/tests/scroll.c +++ b/dlls/user32/tests/scroll.c @@ -738,7 +738,6 @@ static void test_subclass(void) res = SetScrollPos(hwnd, SB_CTL, 1, FALSE); ok(res == 2, "SetScrollPos returned %Iu\n", res); ok(set_scrollinfo.cbSize == sizeof(SCROLLINFO), "cbSize = %u\n", set_scrollinfo.cbSize); - todo_wine ok(set_scrollinfo.fMask == (0x1000 | SIF_POS), "fMask = %x\n", set_scrollinfo.fMask); ok(set_scrollinfo.nPos == 1, "nPos = %x\n", set_scrollinfo.nPos);
@@ -780,7 +779,6 @@ static void test_subclass(void) res = SetScrollPos(hwnd, SB_CTL, 1, FALSE); ok(res == 0, "SetScrollPos returned %Iu\n", res); ok(set_scrollinfo.cbSize == sizeof(SCROLLINFO), "cbSize = %u\n", set_scrollinfo.cbSize); - todo_wine ok(set_scrollinfo.fMask == (0x1000 | SIF_POS), "fMask = %x\n", set_scrollinfo.fMask); ok(set_scrollinfo.nPos == 1, "nPos = %x\n", set_scrollinfo.nPos);
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/scroll.c | 65 +-------------------------------- dlls/win32u/scroll.c | 87 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 64 deletions(-)
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index c92ec6459d9..8eb4b1d23ff 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -311,42 +311,6 @@ void WINAPI USER_ScrollBarDraw( HWND hwnd, HDC hdc, INT nBar, enum SCROLL_HITTES } }
-/*********************************************************************** - * SCROLL_HandleKbdEvent - * - * Handle a keyboard event (only for SB_CTL scrollbars with focus). - * - * PARAMS - * hwnd [I] Handle of window with scrollbar(s) - * wParam [I] Variable input including enable state - * lParam [I] Variable input including input point - */ -static void SCROLL_HandleKbdEvent(HWND hwnd, WPARAM wParam, LPARAM lParam) -{ - TRACE("hwnd=%p wParam=%Id lParam=%Id\n", hwnd, wParam, lParam); - - /* hide caret on first KEYDOWN to prevent flicker */ - if ((lParam & PFD_DOUBLEBUFFER_DONTCARE) == 0) - NtUserHideCaret( hwnd ); - - switch(wParam) - { - case VK_PRIOR: wParam = SB_PAGEUP; break; - case VK_NEXT: wParam = SB_PAGEDOWN; break; - case VK_HOME: wParam = SB_TOP; break; - case VK_END: wParam = SB_BOTTOM; break; - case VK_UP: wParam = SB_LINEUP; break; - case VK_DOWN: wParam = SB_LINEDOWN; break; - case VK_LEFT: wParam = SB_LINEUP; break; - case VK_RIGHT: wParam = SB_LINEDOWN; break; - default: return; - } - SendMessageW(GetParent(hwnd), - ((GetWindowLongW( hwnd, GWL_STYLE ) & SBS_VERT) ? - WM_VSCROLL : WM_HSCROLL), wParam, (LPARAM)hwnd); -} - - /************************************************************************* * SCROLL_GetScrollPos * @@ -391,18 +355,10 @@ static BOOL SCROLL_GetScrollRange(HWND hwnd, INT nBar, LPINT lpMin, LPINT lpMax)
LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, BOOL unicode ) { - if (!IsWindow( hwnd )) return 0; - switch(message) { case WM_KEYDOWN: - SCROLL_HandleKbdEvent(hwnd, wParam, lParam); - break; - case WM_KEYUP: - NtUserShowCaret( hwnd ); - break; - case WM_ENABLE: case WM_SETFOCUS: case WM_KILLFOCUS: @@ -415,28 +371,11 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA case SBM_GETSCROLLINFO: case SBM_GETSCROLLBARINFO: case SBM_SETSCROLLINFO: - return NtUserMessageCall( hwnd, message, wParam, lParam, 0, NtUserScrollBarWndProc, !unicode ); - case WM_SETCURSOR: - if (GetWindowLongW( hwnd, GWL_STYLE ) & SBS_SIZEGRIP) - { - ULONG_PTR cursor = (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) ? IDC_SIZENESW : IDC_SIZENWSE; - return (LRESULT)NtUserSetCursor( LoadCursorA( 0, (LPSTR)cursor )); - } - return DefWindowProcW( hwnd, message, wParam, lParam ); - case SBM_SETPOS: - return SetScrollPos( hwnd, SB_CTL, wParam, (BOOL)lParam ); - case SBM_GETPOS: - return SCROLL_GetScrollPos(hwnd, SB_CTL); - case SBM_GETRANGE: - return SCROLL_GetScrollRange(hwnd, SB_CTL, (LPINT)wParam, (LPINT)lParam); - case SBM_ENABLE_ARROWS: - return NtUserEnableScrollBar( hwnd, SB_CTL, wParam ); - case 0x00e5: case 0x00e7: case 0x00e8: @@ -444,9 +383,7 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA case 0x00ed: case 0x00ee: case 0x00ef: - ERR("unknown Win32 msg %04x wp=%08Ix lp=%08Ix\n", - message, wParam, lParam ); - break; + return NtUserMessageCall( hwnd, message, wParam, lParam, 0, NtUserScrollBarWndProc, !unicode );
default: if (message >= WM_USER) diff --git a/dlls/win32u/scroll.c b/dlls/win32u/scroll.c index d48755cec7c..c4c26e3bc6e 100644 --- a/dlls/win32u/scroll.c +++ b/dlls/win32u/scroll.c @@ -1130,6 +1130,32 @@ static void create_scroll_bar( HWND hwnd, CREATESTRUCTW *create ) } }
+static void handle_kbd_event( HWND hwnd, WPARAM wparam, LPARAM lparam ) +{ + TRACE( "hwnd=%p wparam=%ld lparam=%ld\n", hwnd, wparam, lparam ); + + /* hide caret on first KEYDOWN to prevent flicker */ + if ((lparam & PFD_DOUBLEBUFFER_DONTCARE) == 0) + NtUserHideCaret( hwnd ); + + switch (wparam) + { + case VK_PRIOR: wparam = SB_PAGEUP; break; + case VK_NEXT: wparam = SB_PAGEDOWN; break; + case VK_HOME: wparam = SB_TOP; break; + case VK_END: wparam = SB_BOTTOM; break; + case VK_UP: wparam = SB_LINEUP; break; + case VK_DOWN: wparam = SB_LINEDOWN; break; + case VK_LEFT: wparam = SB_LINEUP; break; + case VK_RIGHT: wparam = SB_LINEDOWN; break; + default: return; + } + + send_message( get_parent(hwnd), + (get_window_long( hwnd, GWL_STYLE ) & SBS_VERT) ? WM_VSCROLL : WM_HSCROLL, + wparam, (LPARAM)hwnd); +} + static int get_scroll_pos(HWND hwnd, int bar) { struct scroll_info *scroll = get_scroll_info_ptr( hwnd, bar, FALSE ); @@ -1155,14 +1181,35 @@ static BOOL set_scroll_range( HWND hwnd, int bar, int min_val, int max_val ) return TRUE; }
+static BOOL get_scroll_range( HWND hwnd, int nBar, int *min, int *max ) +{ + struct scroll_info *info; + + if (!(info = get_scroll_info_ptr( hwnd, nBar, FALSE ))) return FALSE; + if (min) *min = info ? info->minVal : 0; + if (max) *max = info ? info->maxVal : 0; + release_scroll_info_ptr( info ); + return TRUE; +} + LRESULT scroll_bar_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi ) { + if (!is_window( hwnd )) return 0; + switch (msg) { case WM_CREATE: create_scroll_bar( hwnd, (CREATESTRUCTW *)lparam ); return 0;
+ case WM_KEYDOWN: + handle_kbd_event( hwnd, wparam, lparam ); + return 0; + + case WM_KEYUP: + NtUserShowCaret( hwnd ); + return 0; + case WM_LBUTTONDBLCLK: case WM_LBUTTONDOWN: if (get_window_long( hwnd, GWL_STYLE ) & SBS_SIZEGRIP) @@ -1282,7 +1329,47 @@ LRESULT scroll_bar_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara case SBM_SETSCROLLINFO: return set_scroll_info( hwnd, SB_CTL, (SCROLLINFO *)lparam, wparam );
+ case WM_SETCURSOR: + if (get_window_long( hwnd, GWL_STYLE ) & SBS_SIZEGRIP) + { + ULONG_PTR cursor = (get_window_long( hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) ? + IDC_SIZENESW : IDC_SIZENWSE; + return (LRESULT)NtUserSetCursor( LoadImageW( 0, (const WCHAR *)cursor, IMAGE_CURSOR, + 0, 0, LR_SHARED | LR_DEFAULTSIZE )); + } + return default_window_proc( hwnd, msg, wparam, lparam, ansi ); + + case SBM_SETPOS: + { + SCROLLINFO info; + info.cbSize = sizeof(info); + info.nPos = wparam; + info.fMask = SIF_POS | SIF_RETURNPREV; + return NtUserSetScrollInfo( hwnd, SB_CTL, &info, lparam ); + } + + case SBM_GETPOS: + return get_scroll_pos( hwnd, SB_CTL ); + + case SBM_GETRANGE: + return get_scroll_range( hwnd, SB_CTL, (int *)wparam, (int *)lparam ); + + case SBM_ENABLE_ARROWS: + return NtUserEnableScrollBar( hwnd, SB_CTL, wparam ); + + case 0x00e5: + case 0x00e7: + case 0x00e8: + case 0x00ec: + case 0x00ed: + case 0x00ee: + case 0x00ef: + ERR( "unknown Win32 msg %04x wp=%08lx lp=%08lx\n", msg, wparam, lparam ); + return 0; + default: + if (msg >= WM_USER) + WARN( "unknown msg %04x wp=%08lx lp=%08lx\n", msg, wparam, lparam ); return default_window_proc( hwnd, msg, wparam, lparam, ansi ); } }
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/scroll.c | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-)
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index 8eb4b1d23ff..566bf9ecb21 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -311,22 +311,6 @@ void WINAPI USER_ScrollBarDraw( HWND hwnd, HDC hdc, INT nBar, enum SCROLL_HITTES } }
-/************************************************************************* - * SCROLL_GetScrollPos - * - * Internal helper for the API function - * - * PARAMS - * hwnd [I] Handle of window with scrollbar(s) - * nBar [I] One of SB_HORZ, SB_VERT, or SB_CTL - */ -static INT SCROLL_GetScrollPos(HWND hwnd, INT nBar) -{ - LPSCROLLBAR_INFO infoPtr = SCROLL_GetInternalInfo(hwnd, nBar, FALSE); - return infoPtr ? infoPtr->curVal: 0; -} - - /************************************************************************* * SCROLL_GetScrollRange * @@ -483,15 +467,19 @@ int WINAPI DECLSPEC_HOTPATCH SetScrollPos( HWND hwnd, int bar, int pos, BOOL red * There is ambiguity when 0 is returned. Use GetLastError * to make sure there was an error (and to know which one). */ -INT WINAPI DECLSPEC_HOTPATCH GetScrollPos(HWND hwnd, INT nBar) +int WINAPI DECLSPEC_HOTPATCH GetScrollPos( HWND hwnd, int bar ) { - TRACE("hwnd=%p nBar=%d\n", hwnd, nBar); + SCROLLINFO info; + + TRACE( "hwnd=%p bar=%d\n", hwnd, bar );
/* Refer SB_CTL requests to the window */ - if (nBar == SB_CTL) - return SendMessageW(hwnd, SBM_GETPOS, 0, 0); - else - return SCROLL_GetScrollPos(hwnd, nBar); + if (bar == SB_CTL) + return SendMessageW( hwnd, SBM_GETPOS, 0, 0 ); + + info.cbSize = sizeof(info); + info.fMask = SIF_POS; + return GetScrollInfo( hwnd, bar, &info ) ? info.nPos : 0; }
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/scroll.c | 44 ++++++++++++-------------------------------- 1 file changed, 12 insertions(+), 32 deletions(-)
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index 566bf9ecb21..11c37ed6428 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -311,32 +311,6 @@ void WINAPI USER_ScrollBarDraw( HWND hwnd, HDC hdc, INT nBar, enum SCROLL_HITTES } }
-/************************************************************************* - * SCROLL_GetScrollRange - * - * Internal helper for the API function - * - * PARAMS - * hwnd [I] Handle of window with scrollbar(s) - * nBar [I] One of SB_HORZ, SB_VERT, or SB_CTL - * lpMin [O] Where to store minimum value - * lpMax [O] Where to store maximum value - * - * RETURNS - * Success: TRUE - * Failure: FALSE - */ -static BOOL SCROLL_GetScrollRange(HWND hwnd, INT nBar, LPINT lpMin, LPINT lpMax) -{ - LPSCROLLBAR_INFO infoPtr = SCROLL_GetInternalInfo(hwnd, nBar, FALSE); - - if (lpMin) *lpMin = infoPtr ? infoPtr->minVal : 0; - if (lpMax) *lpMax = infoPtr ? infoPtr->maxVal : 0; - - return TRUE; -} - - LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, BOOL unicode ) { switch(message) @@ -530,15 +504,21 @@ BOOL WINAPI DECLSPEC_HOTPATCH SetScrollRange(HWND hwnd, INT nBar, INT minVal, IN * RETURNS * TRUE if values is filled */ -BOOL WINAPI DECLSPEC_HOTPATCH GetScrollRange(HWND hwnd, INT nBar, LPINT lpMin, LPINT lpMax) +BOOL WINAPI DECLSPEC_HOTPATCH GetScrollRange( HWND hwnd, int bar, int *min, int *max ) { - TRACE("hwnd=%p nBar=%d lpMin=%p lpMax=%p\n", hwnd, nBar, lpMin, lpMax); + SCROLLINFO info; + + TRACE( "hwnd=%p nBar=%d lpMin=%p lpMax=%p\n", hwnd, bar, min, max );
/* Refer SB_CTL requests to the window */ - if (nBar == SB_CTL) - SendMessageW(hwnd, SBM_GETRANGE, (WPARAM)lpMin, (LPARAM)lpMax); - else - SCROLL_GetScrollRange(hwnd, nBar, lpMin, lpMax); + if (bar == SB_CTL) + return SendMessageW( hwnd, SBM_GETPOS, 0, 0 );
+ info.cbSize = sizeof(info); + info.fMask = SIF_RANGE; + info.nMin = info.nMax = 0; + GetScrollInfo( hwnd, bar, &info ); + if (min) *min = info.nMin; + if (max) *max = info.nMax; return TRUE; }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=118212
Your paranoid android.
=== debian11 (32 bit report) ===
user32: msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1 msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1
=== debian11 (32 bit Chinese:China report) ===
user32: msg.c:4905: Test failed: GetScrollRange error 5 msg.c:4920: Test failed: GetScrollRange error 5 msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1
=== debian11 (32 bit WoW report) ===
user32: msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1 msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1
=== debian11 (64 bit WoW report) ===
user32: msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1 msg.c:4905: Test failed: GetScrollRange error 5 msg.c:4920: Test failed: GetScrollRange error 5
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/scroll.c | 73 +----------------------------------- dlls/user32/user_main.c | 7 ---- dlls/win32u/defwnd.c | 2 +- dlls/win32u/ntuser_private.h | 4 +- dlls/win32u/scroll.c | 66 +++++++++++++++++++++++++++++--- dlls/win32u/window.c | 4 +- 6 files changed, 66 insertions(+), 90 deletions(-)
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index 11c37ed6428..2543870b0eb 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -31,17 +31,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(scroll);
-typedef struct scroll_info SCROLLBAR_INFO, *LPSCROLLBAR_INFO; -typedef struct scroll_bar_win_data SCROLLBAR_WNDDATA; - -/* data for window that has (one or two) scroll bars */ -typedef struct -{ - SCROLLBAR_INFO horz; - SCROLLBAR_INFO vert; -} WINSCROLLBAR_INFO, *LPWINSCROLLBAR_INFO; - -#define SCROLLBAR_MAGIC 0x5c6011ba
/* Overlap between arrows and thumb */ #define SCROLL_ARROW_THUMB_OVERLAP 0 @@ -54,71 +43,11 @@ const struct builtin_class_descr SCROLL_builtin_class = L"ScrollBar", /* name */ CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC, /* style */ WINPROC_SCROLLBAR, /* proc */ - sizeof(SCROLLBAR_WNDDATA), /* extra */ + sizeof(struct scroll_bar_win_data), /* extra */ IDC_ARROW, /* cursor */ 0 /* brush */ };
-/*********************************************************************** - * SCROLL_GetInternalInfo - - * Returns pointer to internal SCROLLBAR_INFO structure for nBar - * or NULL if failed (f.i. scroll bar does not exist yet) - * If alloc is TRUE and the struct does not exist yet, create it. - */ -SCROLLBAR_INFO *SCROLL_GetInternalInfo( HWND hwnd, INT nBar, BOOL alloc ) -{ - SCROLLBAR_INFO *infoPtr = NULL; - WND *wndPtr = WIN_GetPtr( hwnd ); - - if (!wndPtr || wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP) return NULL; - switch(nBar) - { - case SB_HORZ: - if (wndPtr->pScroll) infoPtr = &((LPWINSCROLLBAR_INFO)wndPtr->pScroll)->horz; - break; - case SB_VERT: - if (wndPtr->pScroll) infoPtr = &((LPWINSCROLLBAR_INFO)wndPtr->pScroll)->vert; - break; - case SB_CTL: - if (wndPtr->cbWndExtra >= sizeof(SCROLLBAR_WNDDATA)) - { - SCROLLBAR_WNDDATA *data = (SCROLLBAR_WNDDATA*)wndPtr->wExtra; - if (data->magic == SCROLLBAR_MAGIC) - infoPtr = &data->info; - } - if (!infoPtr) WARN("window is not a scrollbar control\n"); - break; - case SB_BOTH: - WARN("with SB_BOTH\n"); - break; - } - - if (!infoPtr && alloc) - { - WINSCROLLBAR_INFO *winInfoPtr; - - if (nBar != SB_HORZ && nBar != SB_VERT) - WARN("Cannot initialize nBar=%d\n",nBar); - else if ((winInfoPtr = HeapAlloc( GetProcessHeap(), 0, sizeof(WINSCROLLBAR_INFO) ))) - { - /* Set default values */ - winInfoPtr->horz.minVal = 0; - winInfoPtr->horz.curVal = 0; - winInfoPtr->horz.page = 0; - /* From MSDN and our own tests: - * max for a standard scroll bar is 100 by default. */ - winInfoPtr->horz.maxVal = 100; - winInfoPtr->horz.flags = ESB_ENABLE_BOTH; - winInfoPtr->vert = winInfoPtr->horz; - wndPtr->pScroll = winInfoPtr; - infoPtr = nBar == SB_HORZ ? &winInfoPtr->horz : &winInfoPtr->vert; - } - } - WIN_ReleasePtr( wndPtr ); - return infoPtr; -} -
/*********************************************************************** * SCROLL_DrawArrows diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index fb9ce74736d..26427bd2cf6 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -135,11 +135,6 @@ static void WINAPI unregister_imm( HWND hwnd ) imm_unregister_window( hwnd ); }
-static void CDECL free_win_ptr( WND *win ) -{ - HeapFree( GetProcessHeap(), 0, win->pScroll ); -} - static NTSTATUS try_finally( NTSTATUS (CDECL *func)( void *), void *arg, void (CALLBACK *finally_func)( BOOL )) { @@ -157,8 +152,6 @@ static const struct user_callbacks user_funcs = ImmProcessKey, ImmTranslateMessage, NtWaitForMultipleObjects, - free_win_ptr, - SCROLL_GetInternalInfo, notify_ime, post_dde_message, unpack_dde_message, diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index 702673e0cdd..f44540f7f98 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -2379,7 +2379,7 @@ LRESULT default_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, if (!win) return 0; free( win->text ); win->text = NULL; - if (user_callbacks) user_callbacks->free_win_ptr( win ); + free( win->pScroll ); win->pScroll = NULL; release_win_ptr( win ); break; diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index b2765a70a3d..fb6e5a5200b 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -35,8 +35,6 @@ struct user_callbacks BOOL (WINAPI *pImmProcessKey)(HWND, HKL, UINT, LPARAM, DWORD); BOOL (WINAPI *pImmTranslateMessage)(HWND, UINT, WPARAM, LPARAM); NTSTATUS (WINAPI *pNtWaitForMultipleObjects)(ULONG,const HANDLE*,BOOLEAN,BOOLEAN,const LARGE_INTEGER*); - void (CDECL *free_win_ptr)( struct tagWND *win ); - struct scroll_info *(CDECL *get_scroll_info)( HWND hwnd, INT nBar, BOOL alloc ); void (CDECL *notify_ime)( HWND hwnd, UINT param ); BOOL (CDECL *post_dde_message)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, DWORD dest_tid, DWORD type ); @@ -97,7 +95,7 @@ typedef struct tagWND POINT min_pos; /* Position for minimized window */ POINT max_pos; /* Position for maximized window */ WCHAR *text; /* Window text */ - void *pScroll; /* Scroll-bar info */ + struct win_scroll_bar_info *pScroll; /* Scroll-bar info */ DWORD dwStyle; /* Window style (from CreateWindow) */ DWORD dwExStyle; /* Extended style (from CreateWindowEx) */ UINT_PTR wIDmenu; /* ID or hmenu (from CreateWindow) */ diff --git a/dlls/win32u/scroll.c b/dlls/win32u/scroll.c index c4c26e3bc6e..cb6d4b7a7c9 100644 --- a/dlls/win32u/scroll.c +++ b/dlls/win32u/scroll.c @@ -62,13 +62,69 @@ static struct SCROLL_TRACKING_INFO g_tracking_info; /* Is the moving thumb being displayed? */ static BOOL scroll_moving_thumb = FALSE;
+/* data for window that has (one or two) scroll bars */ +struct win_scroll_bar_info +{ + struct scroll_info horz; + struct scroll_info vert; +}; + +#define SCROLLBAR_MAGIC 0x5c6011ba + + static struct scroll_info *get_scroll_info_ptr( HWND hwnd, int bar, BOOL alloc ) { - struct scroll_info *ret = NULL; - user_lock(); - if (user_callbacks) ret = user_callbacks->get_scroll_info( hwnd, bar, alloc ); - if (!ret) user_unlock(); - return ret; + struct scroll_info *info = NULL; + WND *win = get_win_ptr( hwnd ); + + if (!win || win == WND_OTHER_PROCESS || win == WND_DESKTOP) return NULL; + + switch (bar) + { + case SB_HORZ: + if (win->pScroll) info = &win->pScroll->horz; + break; + case SB_VERT: + if (win->pScroll) info = &win->pScroll->vert; + break; + case SB_CTL: + if (win->cbWndExtra >= sizeof(struct scroll_bar_win_data)) + { + struct scroll_bar_win_data *data = (struct scroll_bar_win_data *)win->wExtra; + if (data->magic == SCROLLBAR_MAGIC) info = &data->info; + } + if (!info) WARN( "window is not a scrollbar control\n" ); + break; + case SB_BOTH: + WARN( "with SB_BOTH\n" ); + break; + } + + if (!info && alloc) + { + struct win_scroll_bar_info *win_info; + + if (bar != SB_HORZ && bar != SB_VERT) + WARN("Cannot initialize bar=%d\n",bar); + else if ((win_info = malloc( sizeof(struct win_scroll_bar_info) ))) + { + /* Set default values */ + win_info->horz.minVal = 0; + win_info->horz.curVal = 0; + win_info->horz.page = 0; + /* From MSDN and our own tests: + * max for a standard scroll bar is 100 by default. */ + win_info->horz.maxVal = 100; + win_info->horz.flags = ESB_ENABLE_BOTH; + win_info->vert = win_info->horz; + win->pScroll = win_info; + info = bar == SB_HORZ ? &win_info->horz : &win_info->vert; + } + } + + if (info) user_lock(); + release_win_ptr( win ); + return info; }
static void release_scroll_info_ptr( struct scroll_info *info ) diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index de4779aee59..e7ccbf7a928 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -4662,7 +4662,7 @@ static void free_window_handle( HWND hwnd ) } SERVER_END_REQ; user_unlock(); - if (user_callbacks) user_callbacks->free_win_ptr( win ); + free( win->pScroll ); free( win->text ); free( win ); } @@ -4865,7 +4865,7 @@ void destroy_thread_windows(void) register_window_surface( win->surface, NULL ); window_surface_release( win->surface ); } - if (user_callbacks) user_callbacks->free_win_ptr( win ); + free( win->pScroll ); free( win->text ); free( win ); }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=118213
Your paranoid android.
=== debian11 (32 bit report) ===
user32: msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1 msg.c:4905: Test failed: GetScrollRange error 5 msg.c:4920: Test failed: GetScrollRange error 5
=== debian11 (32 bit Chinese:China report) ===
user32: msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1 msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1
=== debian11 (32 bit WoW report) ===
user32: msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1 msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1
=== debian11 (64 bit WoW report) ===
user32: msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1 msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/defwnd.c | 32 -------------------------------- dlls/win32u/defwnd.c | 8 ++++++++ 2 files changed, 8 insertions(+), 32 deletions(-)
diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c index 8373aa8e797..70d62c4f718 100644 --- a/dlls/user32/defwnd.c +++ b/dlls/user32/defwnd.c @@ -93,22 +93,6 @@ LRESULT WINAPI DefWindowProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam
switch(msg) { - case WM_NCCREATE: - if (lParam) - { - CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam; - - result = NtUserMessageCall( hwnd, msg, wParam, lParam, 0, NtUserDefWindowProc, TRUE ); - - if(cs->style & (WS_HSCROLL | WS_VSCROLL)) - { - SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0}; - NtUserSetScrollInfo( hwnd, SB_HORZ, &si, FALSE ); - NtUserSetScrollInfo( hwnd, SB_VERT, &si, FALSE ); - } - } - break; - case WM_SYSCOMMAND: result = NC_HandleSysCommand( hwnd, wParam, lParam ); break; @@ -220,22 +204,6 @@ LRESULT WINAPI DefWindowProcW(
switch(msg) { - case WM_NCCREATE: - if (lParam) - { - CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam; - - result = NtUserMessageCall( hwnd, msg, wParam, lParam, 0, NtUserDefWindowProc, FALSE ); - - if(cs->style & (WS_HSCROLL | WS_VSCROLL)) - { - SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0}; - NtUserSetScrollInfo( hwnd, SB_HORZ, &si, FALSE ); - NtUserSetScrollInfo( hwnd, SB_VERT, &si, FALSE ); - } - } - break; - case WM_SYSCOMMAND: result = NC_HandleSysCommand( hwnd, wParam, lParam ); break; diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index f44540f7f98..3e42e3b1e22 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -2369,6 +2369,14 @@ LRESULT default_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, { CREATESTRUCTW *cs = (CREATESTRUCTW *)lparam; set_window_text( hwnd, cs->lpszName, ansi ); + + if (cs->style & (WS_HSCROLL | WS_VSCROLL)) + { + SCROLLINFO si = { .cbSize = sizeof(si), .fMask = SIF_ALL, .nMax = 100 }; + NtUserSetScrollInfo( hwnd, SB_HORZ, &si, FALSE ); + NtUserSetScrollInfo( hwnd, SB_VERT, &si, FALSE ); + } + result = 1; } break;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=118214
Your paranoid android.
=== debian11 (32 bit report) ===
user32: msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1 msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1
=== debian11 (32 bit Chinese:China report) ===
user32: msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1 msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1
=== debian11 (32 bit WoW report) ===
user32: msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1 msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1
=== debian11 (64 bit WoW report) ===
user32: msg.c:4905: Test failed: GetScrollRange error -1 msg.c:4920: Test failed: GetScrollRange error -1 msg.c:4905: Test failed: GetScrollRange error 5 msg.c:4920: Test failed: GetScrollRange error 5
Huw Davies (@huw) commented about dlls/user32/scroll.c:
*/ -BOOL WINAPI DECLSPEC_HOTPATCH GetScrollRange(HWND hwnd, INT nBar, LPINT lpMin, LPINT lpMax) +BOOL WINAPI DECLSPEC_HOTPATCH GetScrollRange( HWND hwnd, int bar, int *min, int *max ) {
- TRACE("hwnd=%p nBar=%d lpMin=%p lpMax=%p\n", hwnd, nBar, lpMin, lpMax);
SCROLLINFO info;
TRACE( "hwnd=%p nBar=%d lpMin=%p lpMax=%p\n", hwnd, bar, min, max );
/* Refer SB_CTL requests to the window */
- if (nBar == SB_CTL)
SendMessageW(hwnd, SBM_GETRANGE, (WPARAM)lpMin, (LPARAM)lpMax);
- else
SCROLL_GetScrollRange(hwnd, nBar, lpMin, lpMax);
- if (bar == SB_CTL)
return SendMessageW( hwnd, SBM_GETPOS, 0, 0 );
This looks like a copy-and-paste error from the previous commit which explains the test failures. I'll push a fix.