-- v2: win32u: Move WM_NCCREATE scroll handling from user32. win32u: Move get_scroll_info_ptr implementation from user32. user32: Use GetScrollInfo for GetScrollRange implementation.
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 | 47 ++++++++++++++------------------------------ 1 file changed, 15 insertions(+), 32 deletions(-)
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index 566bf9ecb21..54517311731 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,24 @@ 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) + { + SendMessageW( hwnd, SBM_GETRANGE, (WPARAM)min, (LPARAM)max ); + return TRUE; + }
+ 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; }
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 54517311731..9453df9dedd 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 ); }
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;
This merge request was approved by Huw Davies.