From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/listbox.c | 2 +- dlls/user32/mdi.c | 4 +- dlls/user32/scroll.c | 25 ----------- dlls/user32/user32.spec | 2 +- dlls/win32u/Makefile.in | 1 + dlls/win32u/gdiobj.c | 1 + dlls/win32u/scroll.c | 80 ++++++++++++++++++++++++++++++++++++ dlls/win32u/win32u.spec | 2 +- dlls/win32u/win32u_private.h | 1 + dlls/win32u/wrappers.c | 6 +++ include/ntuser.h | 1 + 11 files changed, 95 insertions(+), 30 deletions(-) create mode 100644 dlls/win32u/scroll.c
diff --git a/dlls/user32/listbox.c b/dlls/user32/listbox.c index 1e7231b4c05..b8b683e6e3c 100644 --- a/dlls/user32/listbox.c +++ b/dlls/user32/listbox.c @@ -395,7 +395,7 @@ static void LISTBOX_UpdateScroll( LB_DESCR *descr ) } else { - ShowScrollBar( descr->self, SB_HORZ, FALSE ); + NtUserShowScrollBar( descr->self, SB_HORZ, FALSE ); } } } diff --git a/dlls/user32/mdi.c b/dlls/user32/mdi.c index 11c17a6dbd8..fbac63dd881 100644 --- a/dlls/user32/mdi.c +++ b/dlls/user32/mdi.c @@ -1158,7 +1158,7 @@ LRESULT MDIClientWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPARAM
case WM_MDITILE: ci->mdiFlags |= MDIF_NEEDUPDATE; - ShowScrollBar( hwnd, SB_BOTH, FALSE ); + NtUserShowScrollBar( hwnd, SB_BOTH, FALSE ); MDITile( hwnd, ci, wParam ); ci->mdiFlags &= ~MDIF_NEEDUPDATE; return 0; @@ -1701,7 +1701,7 @@ void WINAPI CalcChildScroll( HWND hwnd, INT scroll ) if (style & WS_MAXIMIZE) { HeapFree( GetProcessHeap(), 0, list ); - ShowScrollBar( hwnd, SB_BOTH, FALSE ); + NtUserShowScrollBar( hwnd, SB_BOTH, FALSE ); return; } if (style & WS_VISIBLE) diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index b6f15b4a295..d7972e2c6e8 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -2003,31 +2003,6 @@ static BOOL SCROLL_ShowScrollBar( HWND hwnd, INT nBar, BOOL fShowH, BOOL fShowV }
-/************************************************************************* - * ShowScrollBar (USER32.@) - * - * Shows or hides the scroll bar. - * - * PARAMS - * hwnd [I] Handle of window with scrollbar(s) - * nBar [I] One of SB_HORZ, SB_VERT, or SB_CTL - * fShow [I] TRUE = show, FALSE = hide - * - * RETURNS - * Success: TRUE - * Failure: FALSE - */ -BOOL WINAPI DECLSPEC_HOTPATCH ShowScrollBar(HWND hwnd, INT nBar, BOOL fShow) -{ - if ( !hwnd ) - return FALSE; - - SCROLL_ShowScrollBar( hwnd, nBar, (nBar == SB_VERT) ? 0 : fShow, - (nBar == SB_HORZ) ? 0 : fShow ); - return TRUE; -} - - /************************************************************************* * EnableScrollBar (USER32.@) * diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index e1cc18f7287..ce8365b1336 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -739,7 +739,7 @@ @ stdcall ShowCaret(long) NtUserShowCaret @ stdcall -import ShowCursor(long) NtUserShowCursor @ stdcall ShowOwnedPopups(long long) -@ stdcall ShowScrollBar(long long long) +@ stdcall ShowScrollBar(long long long) NtUserShowScrollBar @ stub ShowStartGlass @ stdcall ShowWindow(long long) NtUserShowWindow @ stdcall ShowWindowAsync(long long) NtUserShowWindowAsync diff --git a/dlls/win32u/Makefile.in b/dlls/win32u/Makefile.in index 13b329b0233..153f5f45d9f 100644 --- a/dlls/win32u/Makefile.in +++ b/dlls/win32u/Makefile.in @@ -45,6 +45,7 @@ C_SRCS = \ printdrv.c \ rawinput.c \ region.c \ + scroll.c \ spy.c \ syscall.c \ sysparams.c \ diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c index 9d95d3cf94a..d843716e4c0 100644 --- a/dlls/win32u/gdiobj.c +++ b/dlls/win32u/gdiobj.c @@ -1236,6 +1236,7 @@ static struct unix_funcs unix_funcs = NtUserSetWindowWord, NtUserShowCaret, NtUserShowCursor, + NtUserShowScrollBar, NtUserShowWindow, NtUserShowWindowAsync, NtUserSystemParametersInfo, diff --git a/dlls/win32u/scroll.c b/dlls/win32u/scroll.c new file mode 100644 index 00000000000..380ce5fc75b --- /dev/null +++ b/dlls/win32u/scroll.c @@ -0,0 +1,80 @@ +/* + * Scrollbar control + * + * Copyright 1993 Martin Ayotte + * Copyright 1994, 1996 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep unix +#endif + +#include "win32u_private.h" +#include "ntuser_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(scroll); + + +static BOOL show_scroll_bar( HWND hwnd, int bar, BOOL show_horz, BOOL show_vert ) +{ + ULONG old_style, set_bits = 0, clear_bits = 0; + + TRACE( "hwnd=%p bar=%d horz=%d, vert=%d\n", hwnd, bar, show_horz, show_vert ); + + switch (bar) + { + case SB_CTL: + NtUserShowWindow( hwnd, show_horz ? SW_SHOW : SW_HIDE ); + return TRUE; + + case SB_BOTH: + case SB_HORZ: + if (show_horz) set_bits |= WS_HSCROLL; + else clear_bits |= WS_HSCROLL; + if (bar == SB_HORZ) break; + /* fall through */ + case SB_VERT: + if (show_vert) set_bits |= WS_VSCROLL; + else clear_bits |= WS_VSCROLL; + break; + + default: + return FALSE; /* Nothing to do! */ + } + + old_style = set_window_style( hwnd, set_bits, clear_bits ); + if ((old_style & clear_bits) != 0 || (old_style & set_bits) != set_bits) + { + /* frame has been changed, let the window redraw itself */ + NtUserSetWindowPos( hwnd, 0, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ); + return TRUE; + } + return FALSE; /* no frame changes */ +} + +/************************************************************************* + * NtUserShowScrollBar (win32u.@) + */ +BOOL WINAPI NtUserShowScrollBar( HWND hwnd, INT bar, BOOL show ) +{ + if (!hwnd) return FALSE; + + show_scroll_bar( hwnd, bar, bar == SB_VERT ? 0 : show, bar == SB_HORZ ? 0 : show ); + return TRUE; +} diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 68201f763ab..428e8aadf1c 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1259,7 +1259,7 @@ @ stdcall -syscall NtUserSetWindowsHookEx(ptr ptr long long ptr long) @ stdcall NtUserShowCaret(long) @ stdcall NtUserShowCursor(long) -@ stub NtUserShowScrollBar +@ stdcall NtUserShowScrollBar(long long long) @ stub NtUserShowSystemCursor @ stdcall NtUserShowWindow(long long) @ stdcall NtUserShowWindowAsync(long long) diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index d3f359fd4ee..00bc3e16828 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -310,6 +310,7 @@ struct unix_funcs WORD (WINAPI *pNtUserSetWindowWord)( HWND hwnd, INT offset, WORD newval ); BOOL (WINAPI *pNtUserShowCaret)( HWND hwnd ); INT (WINAPI *pNtUserShowCursor)( BOOL show ); + BOOL (WINAPI *pNtUserShowScrollBar)( HWND hwnd, INT bar, BOOL show ); BOOL (WINAPI *pNtUserShowWindow)( HWND hwnd, INT cmd ); BOOL (WINAPI *pNtUserShowWindowAsync)( HWND hwnd, INT cmd ); BOOL (WINAPI *pNtUserSystemParametersInfo)( UINT action, UINT val, PVOID ptr, UINT winini ); diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c index b451e57e3b1..e7ab66cadcb 100644 --- a/dlls/win32u/wrappers.c +++ b/dlls/win32u/wrappers.c @@ -1334,6 +1334,12 @@ INT WINAPI NtUserShowCursor( BOOL show ) return unix_funcs->pNtUserShowCursor( show ); }
+BOOL WINAPI NtUserShowScrollBar( HWND hwnd, INT bar, BOOL show ) +{ + if (!unix_funcs) return FALSE; + return unix_funcs->pNtUserShowScrollBar( hwnd, bar, show ); +} + BOOL WINAPI NtUserShowWindowAsync( HWND hwnd, INT cmd ) { if (!unix_funcs) return FALSE; diff --git a/include/ntuser.h b/include/ntuser.h index 3862eb55054..2f6b8863228 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -718,6 +718,7 @@ HWINEVENTHOOK WINAPI NtUserSetWinEventHook( DWORD event_min, DWORD event_max, HM DWORD pid, DWORD tid, DWORD flags ); BOOL WINAPI NtUserShowCaret( HWND hwnd ); INT WINAPI NtUserShowCursor( BOOL show ); +BOOL WINAPI NtUserShowScrollBar( HWND hwnd, INT bar, BOOL show ); BOOL WINAPI NtUserShowWindow( HWND hwnd, INT cmd ); BOOL WINAPI NtUserShowWindowAsync( HWND hwnd, INT cmd ); BOOL WINAPI NtUserSystemParametersInfo( UINT action, UINT val, void *ptr, UINT winini );
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/scroll.c | 4 +--- dlls/win32u/message.c | 14 ++++++++++++++ dlls/win32u/scroll.c | 15 +++++++++++++++ dlls/win32u/win32u_private.h | 4 ++++ include/ntuser.h | 1 + 5 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index d7972e2c6e8..d9bc69895aa 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -1513,10 +1513,8 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA break;
case WM_ERASEBKGND: - return 1; - case WM_GETDLGCODE: - return DLGC_WANTARROWS; /* Windows returns this value */ + return NtUserMessageCall( hwnd, message, wParam, lParam, 0, NtUserScrollBarWndProc, !unicode );
case WM_PAINT: { diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 0603a248f60..65f44783fe6 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2889,17 +2889,25 @@ LRESULT WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa { switch (type) { + case NtUserScrollBarWndProc: + return scroll_bar_window_proc( hwnd, msg, wparam, lparam, ansi ); + case NtUserPopupMenuWndProc: return popup_menu_window_proc( hwnd, msg, wparam, lparam ); + case NtUserDesktopWindowProc: return desktop_window_proc( hwnd, msg, wparam, lparam ); + case NtUserDefWindowProc: return default_window_proc( hwnd, msg, wparam, lparam, ansi ); + case NtUserCallWindowProc: return init_win_proc_params( (struct win_proc_params *)result_info, hwnd, msg, wparam, lparam, ansi ); + case NtUserSendMessage: return send_window_message( hwnd, msg, wparam, lparam, ansi ); + case NtUserSendMessageTimeout: { struct send_message_timeout_params *params = (void *)result_info; @@ -2908,18 +2916,24 @@ LRESULT WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa params->timeout, &res, ansi ); return res; } + case NtUserSendNotifyMessage: return send_notify_message( hwnd, msg, wparam, lparam, ansi ); + case NtUserSendMessageCallback: return send_message_callback( hwnd, msg, wparam, lparam, (void *)result_info, ansi ); + case NtUserClipboardWindowProc: return user_driver->pClipboardWindowProc( hwnd, msg, wparam, lparam ); + case NtUserSpyEnter: spy_enter_message( ansi, hwnd, msg, wparam, lparam ); return 0; + case NtUserSpyExit: spy_exit_message( ansi, hwnd, msg, (LPARAM)result_info, wparam, lparam ); return 0; + default: FIXME( "%p %x %lx %lx %p %x %x\n", hwnd, msg, wparam, lparam, result_info, type, ansi ); } diff --git a/dlls/win32u/scroll.c b/dlls/win32u/scroll.c index 380ce5fc75b..ff60ec5c4ce 100644 --- a/dlls/win32u/scroll.c +++ b/dlls/win32u/scroll.c @@ -68,6 +68,21 @@ static BOOL show_scroll_bar( HWND hwnd, int bar, BOOL show_horz, BOOL show_vert return FALSE; /* no frame changes */ }
+LRESULT scroll_bar_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi ) +{ + switch (msg) + { + case WM_ERASEBKGND: + return 1; + + case WM_GETDLGCODE: + return DLGC_WANTARROWS; /* Windows returns this value */ + + default: + return default_window_proc( hwnd, msg, wparam, lparam, ansi ); + } +} + /************************************************************************* * NtUserShowScrollBar (win32u.@) */ diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 00bc3e16828..90ca0e9b143 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -440,6 +440,10 @@ extern LRESULT send_message_timeout( HWND hwnd, UINT msg, WPARAM wparam, LPARAM extern BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ) DECLSPEC_HIDDEN; extern BOOL rawinput_device_get_usages( HANDLE handle, USHORT *usage_page, USHORT *usage ) DECLSPEC_HIDDEN;
+/* scroll.c */ +extern LRESULT scroll_bar_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, + BOOL ansi ) DECLSPEC_HIDDEN; + /* sysparams.c */ extern BOOL enable_thunk_lock DECLSPEC_HIDDEN; extern DWORD process_layout DECLSPEC_HIDDEN; diff --git a/include/ntuser.h b/include/ntuser.h index 2f6b8863228..08a49cbd123 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -211,6 +211,7 @@ struct render_synthesized_format_params /* NtUserMessageCall codes */ enum { + NtUserScrollBarWndProc = 0x029a, NtUserPopupMenuWndProc = 0x029c, NtUserDesktopWindowProc = 0x029d, NtUserDefWindowProc = 0x029e,
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/scroll.c | 13 ++----------- dlls/user32/user_main.c | 2 +- dlls/user32/user_private.h | 2 +- dlls/win32u/dce.c | 6 +++--- dlls/win32u/ntuser_private.h | 15 ++++++++++++++- dlls/win32u/scroll.c | 28 ++++++++++++++++++++++++++++ dlls/win32u/win32u_private.h | 1 + 7 files changed, 50 insertions(+), 17 deletions(-)
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index d9bc69895aa..9cb07af0706 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -31,16 +31,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(scroll);
-/* data for a single scroll bar */ -typedef struct -{ - INT curVal; /* Current scroll-bar value */ - INT minVal; /* Minimum scroll-bar value */ - INT maxVal; /* Maximum scroll-bar value */ - INT page; /* Page size of scroll bar (Win32) */ - UINT flags; /* EnableScrollBar flags */ - BOOL painted; /* Whether the scroll bar is painted by DefWinProc() */ -} SCROLLBAR_INFO, *LPSCROLLBAR_INFO; +typedef struct scroll_info SCROLLBAR_INFO, *LPSCROLLBAR_INFO;
/* data for window that has (one or two) scroll bars */ typedef struct @@ -127,7 +118,7 @@ static inline BOOL SCROLL_ScrollInfoValid( LPCSCROLLINFO info ) * 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. */ -static SCROLLBAR_INFO *SCROLL_GetInternalInfo( HWND hwnd, INT nBar, BOOL alloc ) +SCROLLBAR_INFO *SCROLL_GetInternalInfo( HWND hwnd, INT nBar, BOOL alloc ) { SCROLLBAR_INFO *infoPtr = NULL; WND *wndPtr = WIN_GetPtr( hwnd ); diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index 2391131e4a5..7a85a86d786 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -159,9 +159,9 @@ static const struct user_callbacks user_funcs = NtWaitForMultipleObjects, SCROLL_DrawNCScrollBar, free_win_ptr, + SCROLL_GetInternalInfo, notify_ime, post_dde_message, - SCROLL_SetStandardScrollPainted, unpack_dde_message, register_imm, unregister_imm, diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index a646f9a234d..f34818ea258 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -179,6 +179,6 @@ LRESULT WINAPI USER_ScrollBarProc(HWND, UINT, WPARAM, LPARAM, BOOL) DECLSPEC_HID void WINAPI USER_ScrollBarDraw(HWND, HDC, INT, enum SCROLL_HITTEST, const struct SCROLL_TRACKING_INFO *, BOOL, BOOL, RECT *, INT, INT, INT, BOOL) DECLSPEC_HIDDEN; -void WINAPI SCROLL_SetStandardScrollPainted(HWND hwnd, INT bar, BOOL visible); +struct scroll_info *SCROLL_GetInternalInfo( HWND hwnd, INT nBar, BOOL alloc );
#endif /* __WINE_USER_PRIVATE_H */ diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 67590e80fa3..9041b5bbaaf 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -1188,14 +1188,14 @@ static HRGN send_ncpaint( HWND hwnd, HWND *child, UINT *flags )
if (whole_rgn) /* NOTE: WM_NCPAINT allows wParam to be 1 */ { - if ((*flags & UPDATE_NONCLIENT) && user_callbacks) + if (*flags & UPDATE_NONCLIENT) { /* Mark standard scroll bars as not painted before sending WM_NCPAINT */ style = get_window_long( hwnd, GWL_STYLE ); if (style & WS_HSCROLL) - user_callbacks->set_standard_scroll_painted( hwnd, SB_HORZ, FALSE ); + set_standard_scroll_painted( hwnd, SB_HORZ, FALSE ); if (style & WS_VSCROLL) - user_callbacks->set_standard_scroll_painted( hwnd, SB_VERT, FALSE ); + set_standard_scroll_painted( hwnd, SB_VERT, FALSE );
send_message( hwnd, WM_NCPAINT, (WPARAM)whole_rgn, 0 ); } diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 82d70ec93bb..609f7018b07 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -37,10 +37,10 @@ struct user_callbacks NTSTATUS (WINAPI *pNtWaitForMultipleObjects)(ULONG,const HANDLE*,BOOLEAN,BOOLEAN,const LARGE_INTEGER*); void (CDECL *draw_nc_scrollbar)( HWND hwnd, HDC hdc, BOOL draw_horizontal, BOOL draw_vertical ); 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 ); - void (WINAPI *set_standard_scroll_painted)( HWND hwnd, INT bar, BOOL visible ); BOOL (CDECL *unpack_dde_message)( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam, void **buffer, size_t size ); BOOL (WINAPI *register_imm)( HWND hwnd ); @@ -203,6 +203,19 @@ enum builtin_winprocs NB_BUILTIN_AW_WINPROCS = WINPROC_DESKTOP };
+/* FIXME: make it private to scroll.c */ + +/* data for a single scroll bar */ +struct scroll_info +{ + INT curVal; /* Current scroll-bar value */ + INT minVal; /* Minimum scroll-bar value */ + INT maxVal; /* Maximum scroll-bar value */ + INT page; /* Page size of scroll bar (Win32) */ + UINT flags; /* EnableScrollBar flags */ + BOOL painted; /* Whether the scroll bar is painted by DefWinProc() */ +}; + /* FIXME: make it private to class.c */ typedef struct tagWINDOWPROC { diff --git a/dlls/win32u/scroll.c b/dlls/win32u/scroll.c index ff60ec5c4ce..d6c21fc6992 100644 --- a/dlls/win32u/scroll.c +++ b/dlls/win32u/scroll.c @@ -30,6 +30,20 @@ WINE_DEFAULT_DEBUG_CHANNEL(scroll);
+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; +} + +static void release_scroll_info_ptr( struct scroll_info *info ) +{ + user_unlock(); +} + static BOOL show_scroll_bar( HWND hwnd, int bar, BOOL show_horz, BOOL show_vert ) { ULONG old_style, set_bits = 0, clear_bits = 0; @@ -83,6 +97,20 @@ LRESULT scroll_bar_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara } }
+void set_standard_scroll_painted( HWND hwnd, int bar, BOOL painted ) +{ + struct scroll_info *info; + + if (bar != SB_HORZ && bar != SB_VERT) + return; + + if ((info = get_scroll_info_ptr( hwnd, bar, FALSE ))) + { + info->painted = painted; + release_scroll_info_ptr( info ); + } +} + /************************************************************************* * NtUserShowScrollBar (win32u.@) */ diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 90ca0e9b143..684a5e59c5b 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -443,6 +443,7 @@ extern BOOL rawinput_device_get_usages( HANDLE handle, USHORT *usage_page, USHOR /* scroll.c */ extern LRESULT scroll_bar_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi ) DECLSPEC_HIDDEN; +extern void set_standard_scroll_painted( HWND hwnd, int bar, BOOL painted ) DECLSPEC_HIDDEN;
/* sysparams.c */ extern BOOL enable_thunk_lock DECLSPEC_HIDDEN;
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/scroll.c | 81 +----------------------------------- dlls/win32u/ntuser_private.h | 6 +++ dlls/win32u/scroll.c | 62 +++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 79 deletions(-)
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index 9cb07af0706..cc847b48ec6 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -32,6 +32,7 @@ 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 @@ -40,12 +41,6 @@ typedef struct SCROLLBAR_INFO vert; } WINSCROLLBAR_INFO, *LPWINSCROLLBAR_INFO;
-typedef struct -{ - DWORD magic; - SCROLLBAR_INFO info; -} SCROLLBAR_WNDDATA; - #define SCROLLBAR_MAGIC 0x5c6011ba
/* Minimum size of the rectangle between the arrows */ @@ -1127,75 +1122,6 @@ void SCROLL_TrackScrollBar( HWND hwnd, INT scrollbar, POINT pt ) }
-/*********************************************************************** - * SCROLL_CreateScrollBar - * - * Create a scroll bar - * - * PARAMS - * hwnd [I] Handle of window with scrollbar(s) - * lpCreate [I] The style and place of the scroll bar - */ -static void SCROLL_CreateScrollBar(HWND hwnd, LPCREATESTRUCTW lpCreate) -{ - LPSCROLLBAR_INFO info = NULL; - WND *win; - - TRACE("hwnd=%p lpCreate=%p\n", hwnd, lpCreate); - - win = WIN_GetPtr(hwnd); - if (win->cbWndExtra >= sizeof(SCROLLBAR_WNDDATA)) - { - SCROLLBAR_WNDDATA *data = (SCROLLBAR_WNDDATA*)win->wExtra; - data->magic = SCROLLBAR_MAGIC; - info = &data->info; - } - else WARN("Not enough extra data\n"); - WIN_ReleasePtr(win); - if (!info) return; - - if (lpCreate->style & WS_DISABLED) - { - info->flags = ESB_DISABLE_BOTH; - TRACE("Created WS_DISABLED scrollbar\n"); - } - - if (lpCreate->style & (SBS_SIZEGRIP | SBS_SIZEBOX)) - { - if (lpCreate->style & SBS_SIZEBOXTOPLEFTALIGN) - NtUserMoveWindow( hwnd, lpCreate->x, lpCreate->y, GetSystemMetrics(SM_CXVSCROLL)+1, - GetSystemMetrics(SM_CYHSCROLL)+1, FALSE ); - else if(lpCreate->style & SBS_SIZEBOXBOTTOMRIGHTALIGN) - NtUserMoveWindow( hwnd, lpCreate->x+lpCreate->cx-GetSystemMetrics(SM_CXVSCROLL)-1, - lpCreate->y+lpCreate->cy-GetSystemMetrics(SM_CYHSCROLL)-1, - GetSystemMetrics(SM_CXVSCROLL)+1, - GetSystemMetrics(SM_CYHSCROLL)+1, FALSE ); - } - else if (lpCreate->style & SBS_VERT) - { - if (lpCreate->style & SBS_LEFTALIGN) - NtUserMoveWindow( hwnd, lpCreate->x, lpCreate->y, - GetSystemMetrics(SM_CXVSCROLL)+1, lpCreate->cy, FALSE ); - else if (lpCreate->style & SBS_RIGHTALIGN) - NtUserMoveWindow( hwnd, - lpCreate->x+lpCreate->cx-GetSystemMetrics(SM_CXVSCROLL)-1, - lpCreate->y, - GetSystemMetrics(SM_CXVSCROLL)+1, lpCreate->cy, FALSE ); - } - else /* SBS_HORZ */ - { - if (lpCreate->style & SBS_TOPALIGN) - NtUserMoveWindow( hwnd, lpCreate->x, lpCreate->y, - lpCreate->cx, GetSystemMetrics(SM_CYHSCROLL)+1, FALSE ); - else if (lpCreate->style & SBS_BOTTOMALIGN) - NtUserMoveWindow( hwnd, - lpCreate->x, - lpCreate->y+lpCreate->cy-GetSystemMetrics(SM_CYHSCROLL)-1, - lpCreate->cx, GetSystemMetrics(SM_CYHSCROLL)+1, FALSE ); - } -} - - /************************************************************************* * SCROLL_GetScrollInfo * @@ -1409,10 +1335,6 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA
switch(message) { - case WM_CREATE: - SCROLL_CreateScrollBar(hwnd, (LPCREATESTRUCTW)lParam); - break; - case WM_ENABLE: { SCROLLBAR_INFO *infoPtr; @@ -1503,6 +1425,7 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA } break;
+ case WM_CREATE: case WM_ERASEBKGND: case WM_GETDLGCODE: return NtUserMessageCall( hwnd, message, wParam, lParam, 0, NtUserScrollBarWndProc, !unicode ); diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 609f7018b07..36c11a49c4e 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -216,6 +216,12 @@ struct scroll_info BOOL painted; /* Whether the scroll bar is painted by DefWinProc() */ };
+struct scroll_bar_win_data +{ + DWORD magic; + struct scroll_info info; +}; + /* FIXME: make it private to class.c */ typedef struct tagWINDOWPROC { diff --git a/dlls/win32u/scroll.c b/dlls/win32u/scroll.c index d6c21fc6992..a15c8bfd36d 100644 --- a/dlls/win32u/scroll.c +++ b/dlls/win32u/scroll.c @@ -30,6 +30,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(scroll);
+#define SCROLLBAR_MAGIC 0x5c6011ba + static struct scroll_info *get_scroll_info_ptr( HWND hwnd, int bar, BOOL alloc ) { struct scroll_info *ret = NULL; @@ -82,10 +84,70 @@ static BOOL show_scroll_bar( HWND hwnd, int bar, BOOL show_horz, BOOL show_vert return FALSE; /* no frame changes */ }
+static void create_scroll_bar( HWND hwnd, CREATESTRUCTW *create ) +{ + struct scroll_info *info = NULL; + WND *win; + + TRACE( "hwnd=%p create=%p\n", hwnd, create ); + + win = get_win_ptr( hwnd ); + if (win->cbWndExtra >= sizeof(struct scroll_bar_win_data)) + { + struct scroll_bar_win_data *data = (struct scroll_bar_win_data *)win->wExtra; + data->magic = SCROLLBAR_MAGIC; + info = &data->info; + } + else WARN( "Not enough extra data\n" ); + release_win_ptr( win ); + if (!info) return; + + if (create->style & WS_DISABLED) + { + info->flags = ESB_DISABLE_BOTH; + TRACE( "Created WS_DISABLED scrollbar\n" ); + } + + if (create->style & (SBS_SIZEGRIP | SBS_SIZEBOX)) + { + if (create->style & SBS_SIZEBOXTOPLEFTALIGN) + NtUserMoveWindow( hwnd, create->x, create->y, get_system_metrics( SM_CXVSCROLL ) + 1, + get_system_metrics( SM_CYHSCROLL ) + 1, FALSE ); + else if(create->style & SBS_SIZEBOXBOTTOMRIGHTALIGN) + NtUserMoveWindow( hwnd, create->x + create->cx - get_system_metrics( SM_CXVSCROLL ) - 1, + create->y + create->cy-get_system_metrics( SM_CYHSCROLL ) - 1, + get_system_metrics( SM_CXVSCROLL ) + 1, + get_system_metrics( SM_CYHSCROLL ) + 1, FALSE ); + } + else if (create->style & SBS_VERT) + { + if (create->style & SBS_LEFTALIGN) + NtUserMoveWindow( hwnd, create->x, create->y, get_system_metrics( SM_CXVSCROLL ) + 1, + create->cy, FALSE ); + else if (create->style & SBS_RIGHTALIGN) + NtUserMoveWindow( hwnd, create->x + create->cx - get_system_metrics( SM_CXVSCROLL ) - 1, + create->y, get_system_metrics( SM_CXVSCROLL ) + 1, create->cy, FALSE ); + } + else /* SBS_HORZ */ + { + if (create->style & SBS_TOPALIGN) + NtUserMoveWindow( hwnd, create->x, create->y, create->cx, + get_system_metrics( SM_CYHSCROLL ) + 1, FALSE ); + else if (create->style & SBS_BOTTOMALIGN) + NtUserMoveWindow( hwnd, create->x, + create->y + create->cy - get_system_metrics( SM_CYHSCROLL ) - 1, + create->cx, get_system_metrics( SM_CYHSCROLL ) + 1, FALSE ); + } +} + LRESULT scroll_bar_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi ) { switch (msg) { + case WM_CREATE: + create_scroll_bar( hwnd, (CREATESTRUCTW *)lparam ); + return 0; + case WM_ERASEBKGND: return 1;
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/scroll.c | 39 --------- dlls/win32u/ntgdi_private.h | 1 - dlls/win32u/scroll.c | 158 +++++++++++++++++++++++++++++++++++ dlls/win32u/win32u_private.h | 1 + 4 files changed, 159 insertions(+), 40 deletions(-)
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index cc847b48ec6..01f7f3b88ae 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -1385,46 +1385,7 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA break;
case WM_SETFOCUS: - { - /* Create a caret when a ScrollBar get focus */ - RECT rect; - int arrowSize, thumbSize, thumbPos, vertical; - vertical = SCROLL_GetScrollBarRect( hwnd, SB_CTL, &rect, - &arrowSize, &thumbSize, &thumbPos ); - if (!vertical) - { - NtUserCreateCaret( hwnd, (HBITMAP)1, thumbSize - 2, rect.bottom - rect.top - 2 ); - SetCaretPos(thumbPos+1, rect.top+1); - } - else - { - NtUserCreateCaret( hwnd, (HBITMAP)1, rect.right - rect.left - 2, thumbSize - 2); - SetCaretPos(rect.top+1, thumbPos+1); - } - NtUserShowCaret( hwnd ); - } - break; - case WM_KILLFOCUS: - { - RECT rect; - int arrowSize, thumbSize, thumbPos, vertical; - vertical = SCROLL_GetScrollBarRect( hwnd, SB_CTL, &rect,&arrowSize, &thumbSize, &thumbPos ); - if (!vertical){ - rect.left=thumbPos+1; - rect.right=rect.left+thumbSize; - } - else - { - rect.top=thumbPos+1; - rect.bottom=rect.top+thumbSize; - } - NtUserHideCaret( hwnd ); - NtUserInvalidateRect( hwnd, &rect, 0 ); - DestroyCaret(); - } - break; - case WM_CREATE: case WM_ERASEBKGND: case WM_GETDLGCODE: diff --git a/dlls/win32u/ntgdi_private.h b/dlls/win32u/ntgdi_private.h index ac552897769..0397138b109 100644 --- a/dlls/win32u/ntgdi_private.h +++ b/dlls/win32u/ntgdi_private.h @@ -391,7 +391,6 @@ extern void lp_to_dp( DC *dc, POINT *points, INT count ) DECLSPEC_HIDDEN; extern BOOL set_map_mode( DC *dc, int mode ) DECLSPEC_HIDDEN; extern void combine_transform( XFORM *result, const XFORM *xform1, const XFORM *xform2 ) DECLSPEC_HIDDEN; -extern int muldiv( int a, int b, int c ) DECLSPEC_HIDDEN;
/* driver.c */ extern BOOL is_display_device( LPCWSTR name ) DECLSPEC_HIDDEN; diff --git a/dlls/win32u/scroll.c b/dlls/win32u/scroll.c index a15c8bfd36d..14bec1e3b83 100644 --- a/dlls/win32u/scroll.c +++ b/dlls/win32u/scroll.c @@ -32,6 +32,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(scroll);
#define SCROLLBAR_MAGIC 0x5c6011ba
+/* Minimum size of the rectangle between the arrows */ +#define SCROLL_MIN_RECT 4 + +/* Minimum size of the thumb in pixels */ +#define SCROLL_MIN_THUMB 8 + +/* Overlap between arrows and thumb */ +#define SCROLL_ARROW_THUMB_OVERLAP 0 + static struct scroll_info *get_scroll_info_ptr( HWND hwnd, int bar, BOOL alloc ) { struct scroll_info *ret = NULL; @@ -84,6 +93,113 @@ static BOOL show_scroll_bar( HWND hwnd, int bar, BOOL show_horz, BOOL show_vert return FALSE; /* no frame changes */ }
+/*********************************************************************** + * get_scroll_bar_rect + * + * Compute the scroll bar rectangle, in drawing coordinates (i.e. client + * coords for SB_CTL, window coords for SB_VERT and SB_HORZ). + * 'arrow_size' returns the width or height of an arrow (depending on + * the orientation of the scrollbar), 'thumb_size' returns the size of + * the thumb, and 'thumb_pos' returns the position of the thumb + * relative to the left or to the top. + * Return TRUE if the scrollbar is vertical, FALSE if horizontal. + */ +static BOOL get_scroll_bar_rect( HWND hwnd, int bar, RECT *rect, int *arrow_size, + int *thumb_size, int *thumb_pos ) +{ + int pixels, min_thumb_size; + BOOL vertical; + WND *win = get_win_ptr( hwnd ); + + if (!win || win == WND_OTHER_PROCESS || win == WND_DESKTOP) return FALSE; + + switch(bar) + { + case SB_HORZ: + get_window_rects( hwnd, COORDS_WINDOW, NULL, rect, get_thread_dpi() ); + rect->top = rect->bottom; + rect->bottom += get_system_metrics( SM_CYHSCROLL ); + if (win->dwStyle & WS_VSCROLL) rect->right++; + vertical = FALSE; + break; + + case SB_VERT: + get_window_rects( hwnd, COORDS_WINDOW, NULL, rect, get_thread_dpi() ); + if (win->dwExStyle & WS_EX_LEFTSCROLLBAR) + { + rect->right = rect->left; + rect->left -= get_system_metrics( SM_CXVSCROLL ); + } + else + { + rect->left = rect->right; + rect->right += get_system_metrics( SM_CXVSCROLL ); + } + if (win->dwStyle & WS_HSCROLL) rect->bottom++; + vertical = TRUE; + break; + + case SB_CTL: + get_client_rect( hwnd, rect ); + vertical = (win->dwStyle & SBS_VERT) != 0; + break; + + default: + release_win_ptr( win ); + return FALSE; + } + + if (vertical) pixels = rect->bottom - rect->top; + else pixels = rect->right - rect->left; + + if (pixels <= 2 * get_system_metrics( SM_CXVSCROLL ) + SCROLL_MIN_RECT) + { + if (pixels > SCROLL_MIN_RECT) + *arrow_size = (pixels - SCROLL_MIN_RECT) / 2; + else + *arrow_size = 0; + *thumb_pos = *thumb_size = 0; + } + else + { + struct scroll_info *info = get_scroll_info_ptr( hwnd, bar, TRUE ); + if (!info) + { + WARN( "called for missing scroll bar\n" ); + release_win_ptr( win ); + return FALSE; + } + *arrow_size = get_system_metrics( SM_CXVSCROLL ); + pixels -= 2 * (get_system_metrics( SM_CXVSCROLL ) - SCROLL_ARROW_THUMB_OVERLAP); + + if (info->page) + { + *thumb_size = muldiv( pixels,info->page, info->maxVal - info->minVal + 1 ); + min_thumb_size = muldiv( SCROLL_MIN_THUMB, get_dpi_for_window( hwnd ), 96 ); + if (*thumb_size < min_thumb_size) *thumb_size = min_thumb_size; + } + else *thumb_size = get_system_metrics( SM_CXVSCROLL ); + + if ((pixels -= *thumb_size ) < 0 || (info->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH) + { + /* Rectangle too small or scrollbar disabled -> no thumb */ + *thumb_pos = *thumb_size = 0; + } + else + { + int max = info->maxVal - max( info->page-1, 0 ); + if (info->minVal >= max) + *thumb_pos = *arrow_size - SCROLL_ARROW_THUMB_OVERLAP; + else + *thumb_pos = *arrow_size - SCROLL_ARROW_THUMB_OVERLAP + + muldiv( pixels, info->curVal - info->minVal, max - info->minVal ); + } + release_scroll_info_ptr( info ); + } + release_win_ptr( win ); + return vertical; +} + static void create_scroll_bar( HWND hwnd, CREATESTRUCTW *create ) { struct scroll_info *info = NULL; @@ -148,6 +264,48 @@ LRESULT scroll_bar_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara create_scroll_bar( hwnd, (CREATESTRUCTW *)lparam ); return 0;
+ case WM_SETFOCUS: + { + /* Create a caret when a ScrollBar get focus */ + RECT rect; + int arrow_size, thumb_size, thumb_pos, vertical; + vertical = get_scroll_bar_rect( hwnd, SB_CTL, &rect, &arrow_size, + &thumb_size, &thumb_pos ); + if (!vertical) + { + NtUserCreateCaret( hwnd, (HBITMAP)1, thumb_size - 2, rect.bottom - rect.top - 2 ); + set_caret_pos( thumb_pos + 1, rect.top + 1 ); + } + else + { + NtUserCreateCaret( hwnd, (HBITMAP)1, rect.right - rect.left - 2, thumb_size - 2 ); + set_caret_pos( rect.top + 1, thumb_pos + 1 ); + } + NtUserShowCaret( hwnd ); + } + return 0; + + case WM_KILLFOCUS: + { + int arrow_size, thumb_size, thumb_pos, vertical; + RECT rect; + vertical = get_scroll_bar_rect( hwnd, SB_CTL, &rect,&arrow_size, &thumb_size, &thumb_pos ); + if (!vertical) + { + rect.left = thumb_pos + 1; + rect.right = rect.left + thumb_size; + } + else + { + rect.top = thumb_pos + 1; + rect.bottom = rect.top + thumb_size; + } + NtUserHideCaret( hwnd ); + NtUserInvalidateRect( hwnd, &rect, 0 ); + destroy_caret(); + } + return 0; + case WM_ERASEBKGND: return 1;
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 684a5e59c5b..49c81ea3bef 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -535,6 +535,7 @@ extern NTSTATUS gdi_init(void) DECLSPEC_HIDDEN; extern NTSTATUS callbacks_init( void *args ) DECLSPEC_HIDDEN; extern void winstation_init(void) DECLSPEC_HIDDEN; extern void sysparams_init(void) DECLSPEC_HIDDEN; +extern int muldiv( int a, int b, int c ) DECLSPEC_HIDDEN;
extern HKEY reg_create_key( HKEY root, const WCHAR *name, ULONG name_len, DWORD options, DWORD *disposition ) DECLSPEC_HIDDEN;
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/controls.h | 3 - dlls/user32/defwnd.c | 24 +- dlls/user32/edit.c | 4 +- dlls/user32/listbox.c | 14 +- dlls/user32/mdi.c | 4 +- dlls/user32/nonclient.c | 69 -- dlls/user32/scroll.c | 1304 +--------------------------------- dlls/user32/user32.spec | 6 +- dlls/user32/user_main.c | 12 +- dlls/user32/win.c | 14 - dlls/user32/win.h | 1 - dlls/win32u/defwnd.c | 77 +- dlls/win32u/gdiobj.c | 3 + dlls/win32u/ntuser_private.h | 1 - dlls/win32u/scroll.c | 1032 ++++++++++++++++++++++++++- dlls/win32u/win32u.spec | 6 +- dlls/win32u/win32u_private.h | 8 + dlls/win32u/window.c | 11 +- dlls/win32u/wrappers.c | 18 + include/ntuser.h | 36 +- 20 files changed, 1219 insertions(+), 1428 deletions(-)
diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h index 48127ca6bb2..955c9092a54 100644 --- a/dlls/user32/controls.h +++ b/dlls/user32/controls.h @@ -113,13 +113,10 @@ extern HBRUSH DEFWND_ControlColor( HDC hDC, UINT ctlType ) DECLSPEC_HIDDEN; extern BOOL update_wallpaper( const WCHAR *wallpaper, const WCHAR *pattern ) DECLSPEC_HIDDEN;
/* nonclient area */ -extern LRESULT NC_HandleNCMouseMove( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN; -extern LRESULT NC_HandleNCMouseLeave( HWND hwnd ) DECLSPEC_HIDDEN; extern LRESULT NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN;
/* scrollbar */
-extern void SCROLL_DrawNCScrollBar( HWND hwnd, HDC hdc, BOOL draw_horizontal, BOOL draw_vertical ) DECLSPEC_HIDDEN; extern void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, INT nBar, enum SCROLL_HITTEST hit_test, const struct SCROLL_TRACKING_INFO *tracking_info, BOOL arrows, BOOL interior ) DECLSPEC_HIDDEN; diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c index d29846ad623..8373aa8e797 100644 --- a/dlls/user32/defwnd.c +++ b/dlls/user32/defwnd.c @@ -103,20 +103,12 @@ LRESULT WINAPI DefWindowProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam if(cs->style & (WS_HSCROLL | WS_VSCROLL)) { SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0}; - SetScrollInfo( hwnd, SB_HORZ, &si, FALSE ); - SetScrollInfo( hwnd, SB_VERT, &si, FALSE ); + NtUserSetScrollInfo( hwnd, SB_HORZ, &si, FALSE ); + NtUserSetScrollInfo( hwnd, SB_VERT, &si, FALSE ); } } break;
- case WM_NCMOUSEMOVE: - result = NC_HandleNCMouseMove( hwnd, wParam, lParam ); - break; - - case WM_NCMOUSELEAVE: - result = NC_HandleNCMouseLeave( hwnd ); - break; - case WM_SYSCOMMAND: result = NC_HandleSysCommand( hwnd, wParam, lParam ); break; @@ -238,20 +230,12 @@ LRESULT WINAPI DefWindowProcW( if(cs->style & (WS_HSCROLL | WS_VSCROLL)) { SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0}; - SetScrollInfo( hwnd, SB_HORZ, &si, FALSE ); - SetScrollInfo( hwnd, SB_VERT, &si, FALSE ); + NtUserSetScrollInfo( hwnd, SB_HORZ, &si, FALSE ); + NtUserSetScrollInfo( hwnd, SB_VERT, &si, FALSE ); } } break;
- case WM_NCMOUSEMOVE: - result = NC_HandleNCMouseMove( hwnd, wParam, lParam ); - break; - - case WM_NCMOUSELEAVE: - result = NC_HandleNCMouseLeave( hwnd ); - break; - case WM_SYSCOMMAND: result = NC_HandleSysCommand( hwnd, wParam, lParam ); break; diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c index 439e33c0b14..80758dd60ef 100644 --- a/dlls/user32/edit.c +++ b/dlls/user32/edit.c @@ -1639,7 +1639,7 @@ static void EDIT_UpdateScrollInfo(EDITSTATE *es) si.nPos = es->y_offset; TRACE("SB_VERT, nMin=%d, nMax=%d, nPage=%d, nPos=%d\n", si.nMin, si.nMax, si.nPage, si.nPos); - SetScrollInfo(es->hwndSelf, SB_VERT, &si, TRUE); + NtUserSetScrollInfo(es->hwndSelf, SB_VERT, &si, TRUE); }
if ((es->style & WS_HSCROLL) && !(es->flags & EF_HSCROLL_TRACK)) @@ -1653,7 +1653,7 @@ static void EDIT_UpdateScrollInfo(EDITSTATE *es) si.nPos = es->x_offset; TRACE("SB_HORZ, nMin=%d, nMax=%d, nPage=%d, nPos=%d\n", si.nMin, si.nMax, si.nPage, si.nPos); - SetScrollInfo(es->hwndSelf, SB_HORZ, &si, TRUE); + NtUserSetScrollInfo(es->hwndSelf, SB_HORZ, &si, TRUE); } }
diff --git a/dlls/user32/listbox.c b/dlls/user32/listbox.c index b8b683e6e3c..d96fc8c219d 100644 --- a/dlls/user32/listbox.c +++ b/dlls/user32/listbox.c @@ -329,7 +329,7 @@ static void LISTBOX_UpdateScroll( LB_DESCR *descr ) SCROLLINFO info;
/* Check the listbox scroll bar flags individually before we call - SetScrollInfo otherwise when the listbox style is WS_HSCROLL and + NtUserSetScrollInfo otherwise when the listbox style is WS_HSCROLL and no WS_VSCROLL, we end up with an uninitialized, visible horizontal scroll bar when we do not need one. if (!(descr->style & WS_VSCROLL)) return; @@ -357,11 +357,11 @@ static void LISTBOX_UpdateScroll( LB_DESCR *descr ) if (descr->style & LBS_DISABLENOSCROLL) info.fMask |= SIF_DISABLENOSCROLL; if (descr->style & WS_HSCROLL) - SetScrollInfo( descr->self, SB_HORZ, &info, TRUE ); + NtUserSetScrollInfo( descr->self, SB_HORZ, &info, TRUE ); info.nMax = 0; info.fMask = SIF_RANGE; if (descr->style & WS_VSCROLL) - SetScrollInfo( descr->self, SB_VERT, &info, TRUE ); + NtUserSetScrollInfo( descr->self, SB_VERT, &info, TRUE ); } else { @@ -373,7 +373,7 @@ static void LISTBOX_UpdateScroll( LB_DESCR *descr ) if (descr->style & LBS_DISABLENOSCROLL) info.fMask |= SIF_DISABLENOSCROLL; if (descr->style & WS_VSCROLL) - SetScrollInfo( descr->self, SB_VERT, &info, TRUE ); + NtUserSetScrollInfo( descr->self, SB_VERT, &info, TRUE );
if ((descr->style & WS_HSCROLL) && descr->horz_extent) { @@ -382,7 +382,7 @@ static void LISTBOX_UpdateScroll( LB_DESCR *descr ) info.fMask = SIF_POS | SIF_PAGE; if (descr->style & LBS_DISABLENOSCROLL) info.fMask |= SIF_DISABLENOSCROLL; - SetScrollInfo( descr->self, SB_HORZ, &info, TRUE ); + NtUserSetScrollInfo( descr->self, SB_HORZ, &info, TRUE ); } else { @@ -391,7 +391,7 @@ static void LISTBOX_UpdateScroll( LB_DESCR *descr ) info.nMin = 0; info.nMax = 0; info.fMask = SIF_RANGE | SIF_DISABLENOSCROLL; - SetScrollInfo( descr->self, SB_HORZ, &info, TRUE ); + NtUserSetScrollInfo( descr->self, SB_HORZ, &info, TRUE ); } else { @@ -1366,7 +1366,7 @@ static LRESULT LISTBOX_SetHorizontalExtent( LB_DESCR *descr, INT extent ) info.fMask = SIF_RANGE; if (descr->style & LBS_DISABLENOSCROLL) info.fMask |= SIF_DISABLENOSCROLL; - SetScrollInfo( descr->self, SB_HORZ, &info, TRUE ); + NtUserSetScrollInfo( descr->self, SB_HORZ, &info, TRUE ); } if (descr->horz_pos > extent - descr->width) LISTBOX_SetHorizontalPos( descr, extent - descr->width ); diff --git a/dlls/user32/mdi.c b/dlls/user32/mdi.c index fbac63dd881..11ba1382804 100644 --- a/dlls/user32/mdi.c +++ b/dlls/user32/mdi.c @@ -1730,7 +1730,7 @@ void WINAPI CalcChildScroll( HWND hwnd, INT scroll ) info.nMin = childRect.left; info.nMax = childRect.right - clientRect.right; info.nPos = clientRect.left - childRect.left; - SetScrollInfo(hwnd, SB_HORZ, &info, TRUE); + NtUserSetScrollInfo(hwnd, SB_HORZ, &info, TRUE); } if (scroll == SB_HORZ) break; /* fall through */ @@ -1740,7 +1740,7 @@ void WINAPI CalcChildScroll( HWND hwnd, INT scroll ) info.nMin = childRect.top; info.nMax = childRect.bottom - clientRect.bottom; info.nPos = clientRect.top - childRect.top; - SetScrollInfo(hwnd, SB_VERT, &info, TRUE); + NtUserSetScrollInfo(hwnd, SB_VERT, &info, TRUE); } break; } diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c index 3eb7ce7883b..095bcb3e24d 100644 --- a/dlls/user32/nonclient.c +++ b/dlls/user32/nonclient.c @@ -142,65 +142,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH AdjustWindowRectExForDpi( LPRECT rect, DWORD style }
-LRESULT NC_HandleNCMouseMove(HWND hwnd, WPARAM wParam, LPARAM lParam) -{ - RECT rect; - POINT pt; - - TRACE("hwnd=%p wparam=%#Ix lparam=%#Ix\n", hwnd, wParam, lParam); - - if (wParam != HTHSCROLL && wParam != HTVSCROLL) - return 0; - - WIN_GetRectangles(hwnd, COORDS_CLIENT, &rect, NULL); - - pt.x = (short)LOWORD(lParam); - pt.y = (short)HIWORD(lParam); - ScreenToClient(hwnd, &pt); - pt.x -= rect.left; - pt.y -= rect.top; - SCROLL_HandleScrollEvent(hwnd, wParam == HTHSCROLL ? SB_HORZ : SB_VERT, WM_NCMOUSEMOVE, pt); - return 0; -} - -LRESULT NC_HandleNCMouseLeave(HWND hwnd) -{ - LONG style = GetWindowLongW(hwnd, GWL_STYLE); - POINT pt = {0, 0}; - - TRACE("hwnd=%p\n", hwnd); - - if (style & WS_HSCROLL) - SCROLL_HandleScrollEvent(hwnd, SB_HORZ, WM_NCMOUSELEAVE, pt); - if (style & WS_VSCROLL) - SCROLL_HandleScrollEvent(hwnd, SB_VERT, WM_NCMOUSELEAVE, pt); - - return 0; -} - - -/*********************************************************************** - * NC_TrackScrollBar - * - * Track a mouse button press on the horizontal or vertical scroll-bar. - */ -static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt ) -{ - INT scrollbar; - - if ((wParam & 0xfff0) == SC_HSCROLL) - { - if ((wParam & 0x0f) != HTHSCROLL) return; - scrollbar = SB_HORZ; - } - else /* SC_VSCROLL */ - { - if ((wParam & 0x0f) != HTVSCROLL) return; - scrollbar = SB_VERT; - } - SCROLL_TrackScrollBar( hwnd, scrollbar, pt ); -} -
/*********************************************************************** * NC_HandleSysCommand @@ -214,16 +155,6 @@ LRESULT NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam )
switch (wParam & 0xfff0) { - case SC_VSCROLL: - case SC_HSCROLL: - { - POINT pt; - pt.x = (short)LOWORD(lParam); - pt.y = (short)HIWORD(lParam); - NC_TrackScrollBar( hwnd, wParam, pt ); - } - break; - case SC_TASKLIST: WinExec( "taskman.exe", SW_SHOWNORMAL ); break; diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index 01f7f3b88ae..bf0a7d3350a 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -43,42 +43,9 @@ typedef struct
#define SCROLLBAR_MAGIC 0x5c6011ba
- /* Minimum size of the rectangle between the arrows */ -#define SCROLL_MIN_RECT 4 - - /* Minimum size of the thumb in pixels */ -#define SCROLL_MIN_THUMB 8 - /* Overlap between arrows and thumb */ #define SCROLL_ARROW_THUMB_OVERLAP 0
- /* Delay (in ms) before first repetition when holding the button down */ -#define SCROLL_FIRST_DELAY 200 - - /* Delay (in ms) between scroll repetitions */ -#define SCROLL_REPEAT_DELAY 50 - - /* Scroll timer id */ -#define SCROLL_TIMER 0 - - /* What to do after SCROLL_SetScrollInfo() */ -#define SA_SSI_HIDE 0x0001 -#define SA_SSI_SHOW 0x0002 -#define SA_SSI_REFRESH 0x0004 -#define SA_SSI_REPAINT_ARROWS 0x0008 - -/* Scroll Bar tracking information */ -static struct SCROLL_TRACKING_INFO g_tracking_info; - - /* Is the moving thumb being displayed? */ -static BOOL SCROLL_MovingThumb = FALSE; - - /* Local functions */ -static BOOL SCROLL_ShowScrollBar( HWND hwnd, INT nBar, - BOOL fShowH, BOOL fShowV ); -static INT SCROLL_SetScrollInfo( HWND hwnd, INT nBar, - const SCROLLINFO *info, BOOL bRedraw ); - /********************************************************************* * scrollbar class descriptor */ @@ -92,20 +59,6 @@ const struct builtin_class_descr SCROLL_builtin_class = 0 /* brush */ };
-/*********************************************************************** - * SCROLL_ScrollInfoValid - * - * Determine if the supplied SCROLLINFO struct is valid. - * info [in] The SCROLLINFO struct to be tested - */ -static inline BOOL SCROLL_ScrollInfoValid( LPCSCROLLINFO info ) -{ - return !(info->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL) - || (info->cbSize != sizeof(*info) - && info->cbSize != sizeof(*info) - sizeof(info->nTrackPos))); -} - - /*********************************************************************** * SCROLL_GetInternalInfo
@@ -167,270 +120,6 @@ SCROLLBAR_INFO *SCROLL_GetInternalInfo( HWND hwnd, INT nBar, BOOL alloc ) }
-/*********************************************************************** - * SCROLL_GetScrollBarRect - * - * Compute the scroll bar rectangle, in drawing coordinates (i.e. client - * coords for SB_CTL, window coords for SB_VERT and SB_HORZ). - * 'arrowSize' returns the width or height of an arrow (depending on - * the orientation of the scrollbar), 'thumbSize' returns the size of - * the thumb, and 'thumbPos' returns the position of the thumb - * relative to the left or to the top. - * Return TRUE if the scrollbar is vertical, FALSE if horizontal. - */ -static BOOL SCROLL_GetScrollBarRect( HWND hwnd, INT nBar, RECT *lprect, - INT *arrowSize, INT *thumbSize, - INT *thumbPos ) -{ - INT pixels, min_thumb_size; - BOOL vertical; - WND *wndPtr = WIN_GetPtr( hwnd ); - - if (!wndPtr || wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP) return FALSE; - - switch(nBar) - { - case SB_HORZ: - WIN_GetRectangles( hwnd, COORDS_WINDOW, NULL, lprect ); - lprect->top = lprect->bottom; - lprect->bottom += GetSystemMetrics(SM_CYHSCROLL); - if(wndPtr->dwStyle & WS_VSCROLL) - lprect->right++; - vertical = FALSE; - break; - - case SB_VERT: - WIN_GetRectangles( hwnd, COORDS_WINDOW, NULL, lprect ); - if((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) != 0) - { - lprect->right = lprect->left; - lprect->left -= GetSystemMetrics(SM_CXVSCROLL); - } - else - { - lprect->left = lprect->right; - lprect->right += GetSystemMetrics(SM_CXVSCROLL); - } - if(wndPtr->dwStyle & WS_HSCROLL) - lprect->bottom++; - vertical = TRUE; - break; - - case SB_CTL: - GetClientRect( hwnd, lprect ); - vertical = ((wndPtr->dwStyle & SBS_VERT) != 0); - break; - - default: - WIN_ReleasePtr( wndPtr ); - return FALSE; - } - - if (vertical) pixels = lprect->bottom - lprect->top; - else pixels = lprect->right - lprect->left; - - if (pixels <= 2*GetSystemMetrics(SM_CXVSCROLL) + SCROLL_MIN_RECT) - { - if (pixels > SCROLL_MIN_RECT) - *arrowSize = (pixels - SCROLL_MIN_RECT) / 2; - else - *arrowSize = 0; - *thumbPos = *thumbSize = 0; - } - else - { - SCROLLBAR_INFO *info = SCROLL_GetInternalInfo( hwnd, nBar, TRUE ); - if (!info) - { - WARN("called for missing scroll bar\n"); - WIN_ReleasePtr( wndPtr ); - return FALSE; - } - *arrowSize = GetSystemMetrics(SM_CXVSCROLL); - pixels -= (2 * (GetSystemMetrics(SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP)); - - if (info->page) - { - *thumbSize = MulDiv(pixels,info->page,(info->maxVal-info->minVal+1)); - min_thumb_size = MulDiv(SCROLL_MIN_THUMB, GetDpiForWindow(hwnd), 96); - if (*thumbSize < min_thumb_size) *thumbSize = min_thumb_size; - } - else *thumbSize = GetSystemMetrics(SM_CXVSCROLL); - - if (((pixels -= *thumbSize ) < 0) || - ((info->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH)) - { - /* Rectangle too small or scrollbar disabled -> no thumb */ - *thumbPos = *thumbSize = 0; - } - else - { - INT max = info->maxVal - max( info->page-1, 0 ); - if (info->minVal >= max) - *thumbPos = *arrowSize - SCROLL_ARROW_THUMB_OVERLAP; - else - *thumbPos = *arrowSize - SCROLL_ARROW_THUMB_OVERLAP - + MulDiv(pixels, (info->curVal-info->minVal),(max - info->minVal)); - } - } - WIN_ReleasePtr( wndPtr ); - return vertical; -} - -static void SCROLL_GetScrollBarDrawInfo( HWND hwnd, INT bar, - const struct SCROLL_TRACKING_INFO *tracking_info, - RECT *rect, INT *arrow_size, INT *thumb_size, - INT *thumb_pos, BOOL *vertical ) -{ - INT pos, max_size; - - if (bar == SB_CTL && GetWindowLongW( hwnd, GWL_STYLE ) & (SBS_SIZEGRIP | SBS_SIZEBOX)) - { - GetClientRect( hwnd, rect ); - *arrow_size = 0; - *thumb_pos = 0; - *thumb_size = 0; - *vertical = FALSE; - return; - } - - *vertical = SCROLL_GetScrollBarRect( hwnd, bar, rect, arrow_size, thumb_size, thumb_pos ); - - if (SCROLL_MovingThumb && tracking_info->win == hwnd && tracking_info->bar == bar) - { - max_size = *vertical ? rect->bottom - rect->top : rect->right - rect->left; - max_size -= *arrow_size - SCROLL_ARROW_THUMB_OVERLAP + *thumb_size; - - pos = tracking_info->thumb_pos; - if (pos < *arrow_size - SCROLL_ARROW_THUMB_OVERLAP) - pos = *arrow_size - SCROLL_ARROW_THUMB_OVERLAP; - else if (pos > max_size) - pos = max_size; - - *thumb_pos = pos; - } -} - -/*********************************************************************** - * SCROLL_GetThumbVal - * - * Compute the current scroll position based on the thumb position in pixels - * from the top of the scroll-bar. - */ -static UINT SCROLL_GetThumbVal( HWND hwnd, SCROLLBAR_INFO *infoPtr, RECT *rect, BOOL vertical, - INT pos ) -{ - INT thumbSize, minThumbSize; - INT pixels = vertical ? rect->bottom-rect->top : rect->right-rect->left; - INT range; - - if ((pixels -= 2*(GetSystemMetrics(SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP)) <= 0) - return infoPtr->minVal; - - if (infoPtr->page) - { - thumbSize = MulDiv(pixels,infoPtr->page,(infoPtr->maxVal-infoPtr->minVal+1)); - minThumbSize = MulDiv(SCROLL_MIN_THUMB, GetDpiForWindow(hwnd), 96); - if (thumbSize < minThumbSize) thumbSize = minThumbSize; - } - else thumbSize = GetSystemMetrics(SM_CXVSCROLL); - - if ((pixels -= thumbSize) <= 0) return infoPtr->minVal; - - pos = max( 0, pos - (GetSystemMetrics(SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP) ); - if (pos > pixels) pos = pixels; - - if (!infoPtr->page) - range = infoPtr->maxVal - infoPtr->minVal; - else - range = infoPtr->maxVal - infoPtr->minVal - infoPtr->page + 1; - - return infoPtr->minVal + MulDiv(pos, range, pixels); -} - -/*********************************************************************** - * SCROLL_PtInRectEx - */ -static BOOL SCROLL_PtInRectEx( LPRECT lpRect, POINT pt, BOOL vertical ) -{ - RECT rect = *lpRect; - int scrollbarWidth; - - /* Pad hit rect to allow mouse to be dragged outside of scrollbar and - * still be considered in the scrollbar. */ - if (vertical) - { - scrollbarWidth = lpRect->right - lpRect->left; - InflateRect(&rect, scrollbarWidth * 8, scrollbarWidth * 2); - } - else - { - scrollbarWidth = lpRect->bottom - lpRect->top; - InflateRect(&rect, scrollbarWidth * 2, scrollbarWidth * 8); - } - return PtInRect( &rect, pt ); -} - -/*********************************************************************** - * SCROLL_ClipPos - */ -static POINT SCROLL_ClipPos( LPRECT lpRect, POINT pt ) -{ - if( pt.x < lpRect->left ) - pt.x = lpRect->left; - else - if( pt.x > lpRect->right ) - pt.x = lpRect->right; - - if( pt.y < lpRect->top ) - pt.y = lpRect->top; - else - if( pt.y > lpRect->bottom ) - pt.y = lpRect->bottom; - - return pt; -} - - -/*********************************************************************** - * SCROLL_HitTest - * - * Scroll-bar hit testing (don't confuse this with WM_NCHITTEST!). - */ -static enum SCROLL_HITTEST SCROLL_HitTest( HWND hwnd, INT nBar, - POINT pt, BOOL bDragging ) -{ - INT arrowSize, thumbSize, thumbPos; - RECT rect; - - BOOL vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect, - &arrowSize, &thumbSize, &thumbPos ); - - if ( (bDragging && !SCROLL_PtInRectEx( &rect, pt, vertical )) || - (!PtInRect( &rect, pt )) ) return SCROLL_NOWHERE; - - if (vertical) - { - if (pt.y < rect.top + arrowSize) return SCROLL_TOP_ARROW; - if (pt.y >= rect.bottom - arrowSize) return SCROLL_BOTTOM_ARROW; - if (!thumbPos) return SCROLL_TOP_RECT; - pt.y -= rect.top; - if (pt.y < thumbPos) return SCROLL_TOP_RECT; - if (pt.y >= thumbPos + thumbSize) return SCROLL_BOTTOM_RECT; - } - else /* horizontal */ - { - if (pt.x < rect.left + arrowSize) return SCROLL_TOP_ARROW; - if (pt.x >= rect.right - arrowSize) return SCROLL_BOTTOM_ARROW; - if (!thumbPos) return SCROLL_TOP_RECT; - pt.x -= rect.left; - if (pt.x < thumbPos) return SCROLL_TOP_RECT; - if (pt.x >= thumbPos + thumbSize) return SCROLL_BOTTOM_RECT; - } - return SCROLL_THUMB; -} - - /*********************************************************************** * SCROLL_DrawArrows * @@ -630,102 +319,6 @@ void WINAPI USER_ScrollBarDraw( HWND hwnd, HDC hdc, INT nBar, enum SCROLL_HITTES } }
-void WINAPI SCROLL_SetStandardScrollPainted( HWND hwnd, INT bar, BOOL painted ) -{ - LPSCROLLBAR_INFO info; - - if (bar != SB_HORZ && bar != SB_VERT) - return; - - info = SCROLL_GetInternalInfo( hwnd, bar, FALSE ); - if (info) - info->painted = painted; -} - -static BOOL SCROLL_IsStandardScrollPainted( HWND hwnd, INT bar ) -{ - LPSCROLLBAR_INFO info; - - if (bar != SB_HORZ && bar != SB_VERT) - return FALSE; - - info = SCROLL_GetInternalInfo( hwnd, bar, FALSE ); - return info ? info->painted : FALSE; -} - -/*********************************************************************** - * SCROLL_DrawScrollBar - * - * Redraw the whole scrollbar. - */ -void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, INT bar, enum SCROLL_HITTEST hit_test, - const struct SCROLL_TRACKING_INFO *tracking_info, BOOL draw_arrows, - BOOL draw_interior ) -{ - INT arrow_size, thumb_size, thumb_pos; - RECT rect, clip_box, intersect; - BOOL vertical; - DWORD style; - - if (!(hwnd = WIN_GetFullHandle( hwnd ))) - return; - - style = GetWindowLongW( hwnd, GWL_STYLE ); - if ((bar == SB_VERT && !(style & WS_VSCROLL)) || (bar == SB_HORZ && !(style & WS_HSCROLL))) - return; - - if (!WIN_IsWindowDrawable( hwnd, FALSE )) - return; - - SCROLL_GetScrollBarDrawInfo( hwnd, bar, tracking_info, &rect, &arrow_size, &thumb_size, - &thumb_pos, &vertical ); - /* do not draw if the scrollbar rectangle is empty */ - if (IsRectEmpty( &rect )) - return; - - TRACE("hwnd %p, hdc %p, bar %d, hit_test %d, tracking_info(win %p, bar %d, thumb_pos %d, " - "track_pos %d, vertical %d, hit_test %d), draw_arrows %d, draw_interior %d, rect %s, " - "arrow_size %d, thumb_pos %d, thumb_val %d, vertical %d, captured window %p\n", hwnd, hdc, - bar, hit_test, tracking_info->win, tracking_info->bar, tracking_info->thumb_pos, - tracking_info->thumb_val, tracking_info->vertical, tracking_info->hit_test, draw_arrows, - draw_interior, wine_dbgstr_rect(&rect), arrow_size, thumb_pos, thumb_size, vertical, - GetCapture()); - user_api->pScrollBarDraw( hwnd, hdc, bar, hit_test, tracking_info, draw_arrows, draw_interior, - &rect, arrow_size, thumb_pos, thumb_size, vertical ); - - if (bar == SB_HORZ || bar == SB_VERT) - { - GetClipBox( hdc, &clip_box ); - if (IntersectRect(&intersect, &rect, &clip_box)) - SCROLL_SetStandardScrollPainted( hwnd, bar, TRUE ); - } -} - -void SCROLL_DrawNCScrollBar( HWND hwnd, HDC hdc, BOOL draw_horizontal, BOOL draw_vertical ) -{ - if (draw_horizontal) - SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, g_tracking_info.hit_test, &g_tracking_info, TRUE, TRUE ); - if (draw_vertical) - SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, g_tracking_info.hit_test, &g_tracking_info, TRUE, TRUE ); -} - -/*********************************************************************** - * SCROLL_RefreshScrollBar - * - * Repaint the scroll bar interior after a SetScrollRange() or - * SetScrollPos() call. - */ -static void SCROLL_RefreshScrollBar( HWND hwnd, INT nBar, - BOOL arrows, BOOL interior ) -{ - HDC hdc = NtUserGetDCEx( hwnd, 0, DCX_CACHE | ((nBar == SB_CTL) ? 0 : DCX_WINDOW) ); - if (!hdc) return; - - SCROLL_DrawScrollBar( hwnd, hdc, nBar, g_tracking_info.hit_test, &g_tracking_info, arrows, interior ); - NtUserReleaseDC( hwnd, hdc ); -} - - /*********************************************************************** * SCROLL_HandleKbdEvent * @@ -762,507 +355,6 @@ static void SCROLL_HandleKbdEvent(HWND hwnd, WPARAM wParam, LPARAM lParam) }
-/*********************************************************************** - * SCROLL_HandleScrollEvent - * - * Handle a mouse or timer event for the scrollbar. - * 'pt' is the location of the mouse event in client (for SB_CTL) or - * windows coordinates. - */ -void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt ) -{ - /* Previous mouse position for timer events */ - static POINT prevPt; - /* Thumb position when tracking started. */ - static UINT trackThumbPos; - /* Position in the scroll-bar of the last button-down event. */ - static INT lastClickPos; - /* Position in the scroll-bar of the last mouse event. */ - static INT lastMousePos; - - enum SCROLL_HITTEST hittest; - HWND hwndOwner, hwndCtl; - TRACKMOUSEEVENT tme; - BOOL vertical; - INT arrowSize, thumbSize, thumbPos; - RECT rect; - HDC hdc; - - SCROLLBAR_INFO *infoPtr = SCROLL_GetInternalInfo( hwnd, nBar, FALSE ); - if (!infoPtr) return; - if ((g_tracking_info.hit_test == SCROLL_NOWHERE) - && (msg != WM_LBUTTONDOWN && msg != WM_MOUSEMOVE && msg != WM_MOUSELEAVE - && msg != WM_NCMOUSEMOVE && msg != WM_NCMOUSELEAVE)) - return; - - if (nBar == SB_CTL && (GetWindowLongW( hwnd, GWL_STYLE ) & (SBS_SIZEGRIP | SBS_SIZEBOX))) - { - switch(msg) - { - case WM_LBUTTONDOWN: /* Initialise mouse tracking */ - NtUserHideCaret( hwnd ); /* hide caret while holding down LBUTTON */ - NtUserSetCapture( hwnd ); - prevPt = pt; - g_tracking_info.hit_test = hittest = SCROLL_THUMB; - break; - case WM_MOUSEMOVE: - GetClientRect(GetParent(GetParent(hwnd)),&rect); - prevPt = pt; - break; - case WM_LBUTTONUP: - ReleaseCapture(); - g_tracking_info.hit_test = hittest = SCROLL_NOWHERE; - if (hwnd == GetFocus()) NtUserShowCaret( hwnd ); - break; - case WM_SYSTIMER: - pt = prevPt; - break; - } - return; - } - - hdc = NtUserGetDCEx( hwnd, 0, DCX_CACHE | ((nBar == SB_CTL) ? 0 : DCX_WINDOW)); - vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect, - &arrowSize, &thumbSize, &thumbPos ); - hwndOwner = (nBar == SB_CTL) ? GetParent(hwnd) : hwnd; - hwndCtl = (nBar == SB_CTL) ? hwnd : 0; - - switch(msg) - { - case WM_LBUTTONDOWN: /* Initialise mouse tracking */ - NtUserHideCaret( hwnd ); /* hide caret while holding down LBUTTON */ - g_tracking_info.vertical = vertical; - g_tracking_info.hit_test = hittest = SCROLL_HitTest( hwnd, nBar, pt, FALSE ); - lastClickPos = vertical ? (pt.y - rect.top) : (pt.x - rect.left); - lastMousePos = lastClickPos; - trackThumbPos = thumbPos; - prevPt = pt; - if (nBar == SB_CTL && (GetWindowLongW(hwnd, GWL_STYLE) & WS_TABSTOP)) NtUserSetFocus( hwnd ); - NtUserSetCapture( hwnd ); - break; - - case WM_MOUSEMOVE: - hittest = SCROLL_HitTest( hwnd, nBar, pt, vertical == g_tracking_info.vertical && GetCapture() == hwnd ); - prevPt = pt; - - if (nBar != SB_CTL) - break; - - tme.cbSize = sizeof(tme); - tme.dwFlags = TME_QUERY; - NtUserTrackMouseEvent( &tme ); - if (!(tme.dwFlags & TME_LEAVE) || tme.hwndTrack != hwnd) - { - tme.dwFlags = TME_LEAVE; - tme.hwndTrack = hwnd; - NtUserTrackMouseEvent( &tme ); - } - - break; - - case WM_NCMOUSEMOVE: - hittest = SCROLL_HitTest( hwnd, nBar, pt, vertical == g_tracking_info.vertical && GetCapture() == hwnd ); - prevPt = pt; - - if (nBar == SB_CTL) - break; - - tme.cbSize = sizeof(tme); - tme.dwFlags = TME_QUERY; - NtUserTrackMouseEvent( &tme ); - if (((tme.dwFlags & (TME_NONCLIENT | TME_LEAVE)) != (TME_NONCLIENT | TME_LEAVE)) || tme.hwndTrack != hwnd) - { - tme.dwFlags = TME_NONCLIENT | TME_LEAVE; - tme.hwndTrack = hwnd; - NtUserTrackMouseEvent( &tme ); - } - - break; - - case WM_NCMOUSELEAVE: - if (nBar == SB_CTL) - return; - - hittest = SCROLL_NOWHERE; - break; - - case WM_MOUSELEAVE: - if (nBar != SB_CTL) - return; - - hittest = SCROLL_NOWHERE; - break; - - case WM_LBUTTONUP: - hittest = SCROLL_NOWHERE; - ReleaseCapture(); - /* if scrollbar has focus, show back caret */ - if (hwnd == GetFocus()) NtUserShowCaret( hwnd ); - break; - - case WM_SYSTIMER: - pt = prevPt; - hittest = SCROLL_HitTest( hwnd, nBar, pt, FALSE ); - break; - - default: - return; /* Should never happen */ - } - - TRACE("Event: hwnd=%p bar=%d msg=%s pt=%ld,%ld hit=%d\n", - hwnd, nBar, SPY_GetMsgName(msg,hwnd), pt.x, pt.y, hittest ); - - switch (g_tracking_info.hit_test) - { - case SCROLL_NOWHERE: /* No tracking in progress */ - /* For standard scroll bars, hovered state gets painted only when the scroll bar was - * previously painted by DefWinProc(). If an application handles WM_NCPAINT by itself, then - * the scrollbar shouldn't be repainted here to avoid overwriting the application painted - * content */ - if (msg == WM_MOUSEMOVE || msg == WM_MOUSELEAVE - || ((msg == WM_NCMOUSEMOVE || msg == WM_NCMOUSELEAVE) - && SCROLL_IsStandardScrollPainted( hwnd, nBar))) - SCROLL_DrawScrollBar( hwnd, hdc, nBar, hittest, &g_tracking_info, TRUE, TRUE ); - break; - - case SCROLL_TOP_ARROW: - SCROLL_DrawScrollBar( hwnd, hdc, nBar, hittest, &g_tracking_info, TRUE, FALSE ); - if (hittest == g_tracking_info.hit_test) - { - if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER)) - { - SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL, - SB_LINEUP, (LPARAM)hwndCtl ); - } - - NtUserSetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ? - SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY ); - } - else KillSystemTimer( hwnd, SCROLL_TIMER ); - break; - - case SCROLL_TOP_RECT: - SCROLL_DrawScrollBar( hwnd, hdc, nBar, hittest, &g_tracking_info, FALSE, TRUE ); - if (hittest == g_tracking_info.hit_test) - { - if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER)) - { - SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL, - SB_PAGEUP, (LPARAM)hwndCtl ); - } - NtUserSetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ? - SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY ); - } - else KillSystemTimer( hwnd, SCROLL_TIMER ); - break; - - case SCROLL_THUMB: - if (msg == WM_LBUTTONDOWN) - { - g_tracking_info.win = hwnd; - g_tracking_info.bar = nBar; - g_tracking_info.thumb_pos = trackThumbPos + lastMousePos - lastClickPos; - g_tracking_info.thumb_val = SCROLL_GetThumbVal( hwnd, infoPtr, &rect, vertical, - g_tracking_info.thumb_pos ); - if (!SCROLL_MovingThumb) - { - SCROLL_MovingThumb = TRUE; - SCROLL_DrawScrollBar( hwnd, hdc, nBar, hittest, &g_tracking_info, FALSE, TRUE ); - } - } - else if (msg == WM_LBUTTONUP) - { - SCROLL_DrawScrollBar( hwnd, hdc, nBar, SCROLL_NOWHERE, &g_tracking_info, FALSE, TRUE ); - } - else if (msg == WM_MOUSEMOVE) - { - INT pos; - - if (!SCROLL_PtInRectEx( &rect, pt, vertical )) pos = lastClickPos; - else - { - pt = SCROLL_ClipPos( &rect, pt ); - pos = vertical ? (pt.y - rect.top) : (pt.x - rect.left); - } - if ( (pos != lastMousePos) || (!SCROLL_MovingThumb) ) - { - lastMousePos = pos; - g_tracking_info.thumb_pos = trackThumbPos + pos - lastClickPos; - g_tracking_info.thumb_val = SCROLL_GetThumbVal( hwnd, infoPtr, &rect, vertical, - g_tracking_info.thumb_pos ); - SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL, - MAKEWPARAM( SB_THUMBTRACK, g_tracking_info.thumb_val ), - (LPARAM)hwndCtl ); - SCROLL_MovingThumb = TRUE; - SCROLL_DrawScrollBar( hwnd, hdc, nBar, hittest, &g_tracking_info, FALSE, TRUE ); - } - } - break; - - case SCROLL_BOTTOM_RECT: - SCROLL_DrawScrollBar( hwnd, hdc, nBar, hittest, &g_tracking_info, FALSE, TRUE ); - if (hittest == g_tracking_info.hit_test) - { - if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER)) - { - SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL, - SB_PAGEDOWN, (LPARAM)hwndCtl ); - } - NtUserSetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ? - SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY ); - } - else KillSystemTimer( hwnd, SCROLL_TIMER ); - break; - - case SCROLL_BOTTOM_ARROW: - SCROLL_DrawScrollBar( hwnd, hdc, nBar, hittest, &g_tracking_info, TRUE, FALSE ); - if (hittest == g_tracking_info.hit_test) - { - if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER)) - { - SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL, - SB_LINEDOWN, (LPARAM)hwndCtl ); - } - - NtUserSetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ? - SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY ); - } - else KillSystemTimer( hwnd, SCROLL_TIMER ); - break; - } - - if (msg == WM_LBUTTONDOWN) - { - - if (hittest == SCROLL_THUMB) - { - UINT val = SCROLL_GetThumbVal( hwnd, infoPtr, &rect, vertical, - trackThumbPos + lastMousePos - lastClickPos ); - SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL, - MAKEWPARAM( SB_THUMBTRACK, val ), (LPARAM)hwndCtl ); - } - } - - if (msg == WM_LBUTTONUP) - { - hittest = g_tracking_info.hit_test; - g_tracking_info.hit_test = SCROLL_NOWHERE; /* Terminate tracking */ - - if (hittest == SCROLL_THUMB) - { - UINT val = SCROLL_GetThumbVal( hwnd, infoPtr, &rect, vertical, - trackThumbPos + lastMousePos - lastClickPos ); - SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL, - MAKEWPARAM( SB_THUMBPOSITION, val ), (LPARAM)hwndCtl ); - } - /* SB_ENDSCROLL doesn't report thumb position */ - SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL, - SB_ENDSCROLL, (LPARAM)hwndCtl ); - - /* Terminate tracking */ - g_tracking_info.win = 0; - SCROLL_MovingThumb = FALSE; - hittest = SCROLL_NOWHERE; - SCROLL_DrawScrollBar( hwnd, hdc, nBar, hittest, &g_tracking_info, TRUE, TRUE ); - } - - NtUserReleaseDC( hwnd, hdc ); -} - - -/*********************************************************************** - * SCROLL_TrackScrollBar - * - * Track a mouse button press on a scroll-bar. - * pt is in screen-coordinates for non-client scroll bars. - */ -void SCROLL_TrackScrollBar( HWND hwnd, INT scrollbar, POINT pt ) -{ - MSG msg; - RECT rect; - - if (scrollbar != SB_CTL) - { - WIN_GetRectangles( hwnd, COORDS_CLIENT, &rect, NULL ); - ScreenToClient( hwnd, &pt ); - pt.x -= rect.left; - pt.y -= rect.top; - } - else - rect.left = rect.top = 0; - - SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt ); - - do - { - if (!GetMessageW( &msg, 0, 0, 0 )) break; - if (NtUserCallMsgFilter( &msg, MSGF_SCROLLBAR )) continue; - if (msg.message == WM_LBUTTONUP || - msg.message == WM_MOUSEMOVE || - msg.message == WM_MOUSELEAVE || - msg.message == WM_NCMOUSEMOVE || - msg.message == WM_NCMOUSELEAVE || - (msg.message == WM_SYSTIMER && msg.wParam == SCROLL_TIMER)) - { - pt.x = (short)LOWORD(msg.lParam) - rect.left; - pt.y = (short)HIWORD(msg.lParam) - rect.top; - SCROLL_HandleScrollEvent( hwnd, scrollbar, msg.message, pt ); - } - else - { - TranslateMessage( &msg ); - DispatchMessageW( &msg ); - } - if (!IsWindow( hwnd )) - { - ReleaseCapture(); - break; - } - } while (msg.message != WM_LBUTTONUP && GetCapture() == hwnd); -} - - -/************************************************************************* - * SCROLL_GetScrollInfo - * - * 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 - * info [IO] fMask specifies which values to retrieve - * - * RETURNS - * FALSE if requested field not filled (f.i. scroll bar does not exist) - */ -static BOOL SCROLL_GetScrollInfo(HWND hwnd, INT nBar, LPSCROLLINFO info) -{ - LPSCROLLBAR_INFO infoPtr; - - /* handle invalid data structure */ - if (!SCROLL_ScrollInfoValid(info) - || !(infoPtr = SCROLL_GetInternalInfo(hwnd, nBar, FALSE))) - return FALSE; - - /* fill in the desired scroll info structure */ - if (info->fMask & SIF_PAGE) info->nPage = infoPtr->page; - if (info->fMask & SIF_POS) info->nPos = infoPtr->curVal; - if ((info->fMask & SIF_TRACKPOS) && (info->cbSize == sizeof(*info))) - info->nTrackPos = (g_tracking_info.win == WIN_GetFullHandle(hwnd)) ? g_tracking_info.thumb_val : infoPtr->curVal; - if (info->fMask & SIF_RANGE) - { - info->nMin = infoPtr->minVal; - info->nMax = infoPtr->maxVal; - } - - TRACE("cbSize %02x fMask %04x nMin %d nMax %d nPage %u nPos %d nTrackPos %d\n", - info->cbSize, info->fMask, info->nMin, info->nMax, info->nPage, - info->nPos, info->nTrackPos); - - return (info->fMask & SIF_ALL) != 0; -} - - -/************************************************************************* - * SCROLL_GetScrollBarInfo - * - * Internal helper for the API function - * - * PARAMS - * hwnd [I] Handle of window with scrollbar(s) - * idObject [I] One of OBJID_CLIENT, OBJID_HSCROLL, or OBJID_VSCROLL - * info [IO] cbSize specifies the size of the structure - * - * RETURNS - * FALSE if failed - */ -static BOOL SCROLL_GetScrollBarInfo(HWND hwnd, LONG idObject, LPSCROLLBARINFO info) -{ - LPSCROLLBAR_INFO infoPtr; - INT nBar; - INT nDummy; - DWORD style = GetWindowLongW(hwnd, GWL_STYLE); - BOOL pressed; - RECT rect; - - switch (idObject) - { - case OBJID_CLIENT: nBar = SB_CTL; break; - case OBJID_HSCROLL: nBar = SB_HORZ; break; - case OBJID_VSCROLL: nBar = SB_VERT; break; - default: return FALSE; - } - - /* handle invalid data structure */ - if (info->cbSize != sizeof(*info)) - return FALSE; - - SCROLL_GetScrollBarRect(hwnd, nBar, &info->rcScrollBar, &nDummy, - &info->dxyLineButton, &info->xyThumbTop); - /* rcScrollBar needs to be in screen coordinates */ - GetWindowRect(hwnd, &rect); - OffsetRect(&info->rcScrollBar, rect.left, rect.top); - - info->xyThumbBottom = info->xyThumbTop + info->dxyLineButton; - - infoPtr = SCROLL_GetInternalInfo(hwnd, nBar, TRUE); - if (!infoPtr) - return FALSE; - - /* Scroll bar state */ - info->rgstate[0] = 0; - if ((nBar == SB_HORZ && !(style & WS_HSCROLL)) - || (nBar == SB_VERT && !(style & WS_VSCROLL))) - info->rgstate[0] |= STATE_SYSTEM_INVISIBLE; - if (infoPtr->minVal >= infoPtr->maxVal - max(infoPtr->page - 1, 0)) - { - if (!(info->rgstate[0] & STATE_SYSTEM_INVISIBLE)) - info->rgstate[0] |= STATE_SYSTEM_UNAVAILABLE; - else - info->rgstate[0] |= STATE_SYSTEM_OFFSCREEN; - } - if (nBar == SB_CTL && !IsWindowEnabled(hwnd)) - info->rgstate[0] |= STATE_SYSTEM_UNAVAILABLE; - - pressed = ((nBar == SB_VERT) == g_tracking_info.vertical && GetCapture() == hwnd); - - /* Top/left arrow button state. MSDN says top/right, but I don't believe it */ - info->rgstate[1] = 0; - if (pressed && g_tracking_info.hit_test == SCROLL_TOP_ARROW) - info->rgstate[1] |= STATE_SYSTEM_PRESSED; - if (infoPtr->flags & ESB_DISABLE_LTUP) - info->rgstate[1] |= STATE_SYSTEM_UNAVAILABLE; - - /* Page up/left region state. MSDN says up/right, but I don't believe it */ - info->rgstate[2] = 0; - if (infoPtr->curVal == infoPtr->minVal) - info->rgstate[2] |= STATE_SYSTEM_INVISIBLE; - if (pressed && g_tracking_info.hit_test == SCROLL_TOP_RECT) - info->rgstate[2] |= STATE_SYSTEM_PRESSED; - - /* Thumb state */ - info->rgstate[3] = 0; - if (pressed && g_tracking_info.hit_test == SCROLL_THUMB) - info->rgstate[3] |= STATE_SYSTEM_PRESSED; - - /* Page down/right region state. MSDN says down/left, but I don't believe it */ - info->rgstate[4] = 0; - if (infoPtr->curVal >= infoPtr->maxVal - 1) - info->rgstate[4] |= STATE_SYSTEM_INVISIBLE; - if (pressed && g_tracking_info.hit_test == SCROLL_BOTTOM_RECT) - info->rgstate[4] |= STATE_SYSTEM_PRESSED; - - /* Bottom/right arrow button state. MSDN says bottom/left, but I don't believe it */ - info->rgstate[5] = 0; - if (pressed && g_tracking_info.hit_test == SCROLL_BOTTOM_ARROW) - info->rgstate[5] |= STATE_SYSTEM_PRESSED; - if (infoPtr->flags & ESB_DISABLE_RTDN) - info->rgstate[5] |= STATE_SYSTEM_UNAVAILABLE; - - return TRUE; -} - - /************************************************************************* * SCROLL_GetScrollPos * @@ -1305,77 +397,12 @@ static BOOL SCROLL_GetScrollRange(HWND hwnd, INT nBar, LPINT lpMin, LPINT lpMax) }
-/************************************************************************* - * SCROLL_SetScrollRange - * - * PARAMS - * hwnd [I] Handle of window with scrollbar(s) - * nBar [I] One of SB_HORZ, SB_VERT, or SB_CTL - * lpMin [I] Minimum value - * lpMax [I] Maximum value - * - */ -static BOOL SCROLL_SetScrollRange(HWND hwnd, INT nBar, INT minVal, INT maxVal) -{ - LPSCROLLBAR_INFO infoPtr = SCROLL_GetInternalInfo(hwnd, nBar, FALSE); - - TRACE("hwnd=%p nBar=%d min=%d max=%d\n", hwnd, nBar, minVal, maxVal); - - if (infoPtr) - { - infoPtr->minVal = minVal; - infoPtr->maxVal = maxVal; - } - return TRUE; -} - LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, BOOL unicode ) { if (!IsWindow( hwnd )) return 0;
switch(message) { - case WM_ENABLE: - { - SCROLLBAR_INFO *infoPtr; - if ((infoPtr = SCROLL_GetInternalInfo( hwnd, SB_CTL, FALSE ))) - { - infoPtr->flags = wParam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH; - SCROLL_RefreshScrollBar(hwnd, SB_CTL, TRUE, TRUE); - } - } - return 0; - - case WM_LBUTTONDBLCLK: - case WM_LBUTTONDOWN: - if (GetWindowLongW( hwnd, GWL_STYLE ) & SBS_SIZEGRIP) - { - SendMessageW( GetParent(hwnd), WM_SYSCOMMAND, - SC_SIZE + ((GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) ? - WMSZ_BOTTOMLEFT : WMSZ_BOTTOMRIGHT), lParam ); - } - else - { - POINT pt; - pt.x = (short)LOWORD(lParam); - pt.y = (short)HIWORD(lParam); - SCROLL_TrackScrollBar( hwnd, SB_CTL, pt ); - } - break; - case WM_LBUTTONUP: - case WM_NCMOUSEMOVE: - case WM_NCMOUSELEAVE: - case WM_MOUSEMOVE: - case WM_MOUSELEAVE: - case WM_SYSTIMER: - { - POINT pt; - pt.x = (short)LOWORD(lParam); - pt.y = (short)HIWORD(lParam); - SCROLL_HandleScrollEvent( hwnd, SB_CTL, message, pt ); - } - break; - case WM_KEYDOWN: SCROLL_HandleKbdEvent(hwnd, wParam, lParam); break; @@ -1384,21 +411,19 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA NtUserShowCaret( hwnd ); break;
+ case WM_ENABLE: case WM_SETFOCUS: case WM_KILLFOCUS: case WM_CREATE: case WM_ERASEBKGND: case WM_GETDLGCODE: - return NtUserMessageCall( hwnd, message, wParam, lParam, 0, NtUserScrollBarWndProc, !unicode ); - case WM_PAINT: - { - PAINTSTRUCT ps; - HDC hdc = wParam ? (HDC)wParam : NtUserBeginPaint( hwnd, &ps ); - SCROLL_DrawScrollBar( hwnd, hdc, SB_CTL, g_tracking_info.hit_test, &g_tracking_info, TRUE, TRUE ); - if (!wParam) NtUserEndPaint( hwnd, &ps ); - } - break; + case SBM_SETRANGEREDRAW: + case SBM_SETRANGE: + 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) @@ -1414,31 +439,11 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA case SBM_GETPOS: return SCROLL_GetScrollPos(hwnd, SB_CTL);
- case SBM_SETRANGEREDRAW: - case SBM_SETRANGE: - { - INT oldPos = SCROLL_GetScrollPos( hwnd, SB_CTL ); - SCROLL_SetScrollRange( hwnd, SB_CTL, wParam, lParam ); - if (message == SBM_SETRANGEREDRAW) - SCROLL_RefreshScrollBar( hwnd, SB_CTL, TRUE, TRUE ); - if (oldPos != SCROLL_GetScrollPos( hwnd, SB_CTL )) return oldPos; - } - return 0; - case SBM_GETRANGE: return SCROLL_GetScrollRange(hwnd, SB_CTL, (LPINT)wParam, (LPINT)lParam);
case SBM_ENABLE_ARROWS: - return EnableScrollBar( hwnd, SB_CTL, wParam ); - - case SBM_SETSCROLLINFO: - return SCROLL_SetScrollInfo( hwnd, SB_CTL, (SCROLLINFO *)lParam, wParam ); - - case SBM_GETSCROLLINFO: - return SCROLL_GetScrollInfo(hwnd, SB_CTL, (SCROLLINFO *)lParam); - - case SBM_GETSCROLLBARINFO: - return SCROLL_GetScrollBarInfo(hwnd, OBJID_CLIENT, (SCROLLBARINFO *)lParam); + return NtUserEnableScrollBar( hwnd, SB_CTL, wParam );
case 0x00e5: case 0x00e7: @@ -1471,186 +476,6 @@ LRESULT ScrollBarWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPar return user_api->pScrollBarWndProc( hwnd, msg, wParam, lParam, unicode ); }
-/************************************************************************* - * SetScrollInfo (USER32.@) - * - * SetScrollInfo can be used to set the position, upper bound, - * lower bound, and page size of a scrollbar control. - * - * PARAMS - * hwnd [I] Handle of window with scrollbar(s) - * nBar [I] One of SB_HORZ, SB_VERT, or SB_CTL - * info [I] Specifies what to change and new values - * bRedraw [I] Should scrollbar be redrawn afterwards? - * - * RETURNS - * Scrollbar position - * - * NOTE - * For 100 lines of text to be displayed in a window of 25 lines, - * one would for instance use info->nMin=0, info->nMax=75 - * (corresponding to the 76 different positions of the window on - * the text), and info->nPage=25. - */ -INT WINAPI DECLSPEC_HOTPATCH SetScrollInfo(HWND hwnd, INT nBar, const SCROLLINFO *info, BOOL bRedraw) -{ - TRACE("hwnd=%p nBar=%d info=%p, bRedraw=%d\n", hwnd, nBar, info, bRedraw); - - /* Refer SB_CTL requests to the window */ - if (nBar == SB_CTL) - return SendMessageW(hwnd, SBM_SETSCROLLINFO, bRedraw, (LPARAM)info); - else - return SCROLL_SetScrollInfo( hwnd, nBar, info, bRedraw ); -} - -static INT SCROLL_SetScrollInfo( HWND hwnd, INT nBar, LPCSCROLLINFO info, BOOL bRedraw ) -{ - /* Update the scrollbar state and set action flags according to - * what has to be done graphics wise. */ - - SCROLLBAR_INFO *infoPtr; - UINT new_flags; - INT action = 0; - - /* handle invalid data structure */ - if (!SCROLL_ScrollInfoValid(info) - || !(infoPtr = SCROLL_GetInternalInfo(hwnd, nBar, TRUE))) - return 0; - - if (TRACE_ON(scroll)) - { - TRACE("hwnd=%p bar=%d", hwnd, nBar); - if (info->fMask & SIF_PAGE) TRACE( " page=%d", info->nPage ); - if (info->fMask & SIF_POS) TRACE( " pos=%d", info->nPos ); - if (info->fMask & SIF_RANGE) TRACE( " min=%d max=%d", info->nMin, info->nMax ); - TRACE("\n"); - } - - /* Set the page size */ - - if (info->fMask & SIF_PAGE) - { - if( infoPtr->page != info->nPage ) - { - infoPtr->page = info->nPage; - action |= SA_SSI_REFRESH; - } - } - - /* Set the scroll pos */ - - if (info->fMask & SIF_POS) - { - if( infoPtr->curVal != info->nPos ) - { - infoPtr->curVal = info->nPos; - action |= SA_SSI_REFRESH; - } - } - - /* Set the scroll range */ - - if (info->fMask & SIF_RANGE) - { - /* Invalid range -> range is set to (0,0) */ - if ((info->nMin > info->nMax) || - ((UINT)(info->nMax - info->nMin) >= 0x80000000)) - { - action |= SA_SSI_REFRESH; - infoPtr->minVal = 0; - infoPtr->maxVal = 0; - } - else - { - if( infoPtr->minVal != info->nMin || - infoPtr->maxVal != info->nMax ) - { - action |= SA_SSI_REFRESH; - infoPtr->minVal = info->nMin; - infoPtr->maxVal = info->nMax; - } - } - } - - /* Make sure the page size is valid */ - if (infoPtr->page < 0) infoPtr->page = 0; - else if (infoPtr->page > infoPtr->maxVal - infoPtr->minVal + 1 ) - infoPtr->page = infoPtr->maxVal - infoPtr->minVal + 1; - - /* Make sure the pos is inside the range */ - - if (infoPtr->curVal < infoPtr->minVal) - infoPtr->curVal = infoPtr->minVal; - else if (infoPtr->curVal > infoPtr->maxVal - max( infoPtr->page-1, 0 )) - infoPtr->curVal = infoPtr->maxVal - max( infoPtr->page-1, 0 ); - - TRACE(" new values: page=%d pos=%d min=%d max=%d\n", - infoPtr->page, infoPtr->curVal, - infoPtr->minVal, infoPtr->maxVal ); - - /* don't change the scrollbar state if SetScrollInfo - * is just called with SIF_DISABLENOSCROLL - */ - if(!(info->fMask & SIF_ALL)) goto done; - - /* Check if the scrollbar should be hidden or disabled */ - - if (info->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL)) - { - new_flags = infoPtr->flags; - if (infoPtr->minVal >= infoPtr->maxVal - max( infoPtr->page-1, 0 )) - { - /* Hide or disable scroll-bar */ - if (info->fMask & SIF_DISABLENOSCROLL) - { - new_flags = ESB_DISABLE_BOTH; - action |= SA_SSI_REFRESH; - } - else if ((nBar != SB_CTL) && (action & SA_SSI_REFRESH)) - { - action = SA_SSI_HIDE; - } - } - else /* Show and enable scroll-bar only if no page only changed. */ - if (info->fMask != SIF_PAGE) - { - new_flags = ESB_ENABLE_BOTH; - if ((nBar != SB_CTL) && ( (action & SA_SSI_REFRESH) )) - action |= SA_SSI_SHOW; - } - - if (nBar == SB_CTL && bRedraw && IsWindowVisible(hwnd) && - (new_flags == ESB_ENABLE_BOTH || new_flags == ESB_DISABLE_BOTH)) - { - EnableWindow(hwnd, new_flags == ESB_ENABLE_BOTH); - } - - if (infoPtr->flags != new_flags) /* check arrow flags */ - { - infoPtr->flags = new_flags; - action |= SA_SSI_REPAINT_ARROWS; - } - } - -done: - if( action & SA_SSI_HIDE ) - SCROLL_ShowScrollBar( hwnd, nBar, FALSE, FALSE ); - else - { - if( action & SA_SSI_SHOW ) - if( SCROLL_ShowScrollBar( hwnd, nBar, TRUE, TRUE ) ) - return infoPtr->curVal; /* SetWindowPos() already did the painting */ - - if( bRedraw ) - SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, TRUE ); - else if( action & SA_SSI_REPAINT_ARROWS ) - SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, FALSE ); - } - - /* Return current position */ - return infoPtr->curVal; -} -
/************************************************************************* * GetScrollInfo (USER32.@) @@ -1678,33 +503,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH GetScrollInfo(HWND hwnd, INT nBar, LPSCROLLINFO in SendMessageW(hwnd, SBM_GETSCROLLINFO, 0, (LPARAM)info); return TRUE; } - return SCROLL_GetScrollInfo(hwnd, nBar, info); -} - - -/************************************************************************* - * GetScrollBarInfo (USER32.@) - * - * GetScrollBarInfo can be used to retrieve information about a scrollbar - * control. - * - * PARAMS - * hwnd [I] Handle of window with scrollbar(s) - * idObject [I] One of OBJID_CLIENT, OBJID_HSCROLL, or OBJID_VSCROLL - * info [IO] cbSize specifies the size of SCROLLBARINFO - * - * RETURNS - * TRUE if success - */ -BOOL WINAPI GetScrollBarInfo(HWND hwnd, LONG idObject, LPSCROLLBARINFO info) -{ - TRACE("hwnd=%p idObject=%ld info=%p\n", hwnd, idObject, info); - - /* Refer OBJID_CLIENT requests to the window */ - if (idObject == OBJID_CLIENT) - return SendMessageW(hwnd, SBM_GETSCROLLBARINFO, 0, (LPARAM)info); - else - return SCROLL_GetScrollBarInfo(hwnd, idObject, info); + return NtUserGetScrollInfo( hwnd, nBar, info ); }
@@ -1737,7 +536,7 @@ INT WINAPI DECLSPEC_HOTPATCH SetScrollPos( HWND hwnd, INT nBar, INT nPos, BOOL b info.cbSize = sizeof(info); info.nPos = nPos; info.fMask = SIF_POS; - SetScrollInfo( hwnd, nBar, &info, bRedraw ); + NtUserSetScrollInfo( hwnd, nBar, &info, bRedraw ); return oldPos; }
@@ -1799,7 +598,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH SetScrollRange(HWND hwnd, INT nBar, INT minVal, IN info.fMask = SIF_RANGE; info.nMin = minVal; info.nMax = maxVal; - SetScrollInfo( hwnd, nBar, &info, bRedraw ); + NtUserSetScrollInfo( hwnd, nBar, &info, bRedraw ); return TRUE; }
@@ -1830,84 +629,3 @@ BOOL WINAPI DECLSPEC_HOTPATCH GetScrollRange(HWND hwnd, INT nBar, LPINT lpMin, L
return TRUE; } - - -/************************************************************************* - * SCROLL_ShowScrollBar() - * - * Back-end for ShowScrollBar(). Returns FALSE if no action was taken. - */ -static BOOL SCROLL_ShowScrollBar( HWND hwnd, INT nBar, BOOL fShowH, BOOL fShowV ) -{ - ULONG old_style, set_bits = 0, clear_bits = 0; - - TRACE("hwnd=%p bar=%d horz=%d, vert=%d\n", hwnd, nBar, fShowH, fShowV ); - - switch(nBar) - { - case SB_CTL: - NtUserShowWindow( hwnd, fShowH ? SW_SHOW : SW_HIDE ); - return TRUE; - - case SB_BOTH: - case SB_HORZ: - if (fShowH) set_bits |= WS_HSCROLL; - else clear_bits |= WS_HSCROLL; - if( nBar == SB_HORZ ) break; - /* fall through */ - case SB_VERT: - if (fShowV) set_bits |= WS_VSCROLL; - else clear_bits |= WS_VSCROLL; - break; - - default: - return FALSE; /* Nothing to do! */ - } - - old_style = WIN_SetStyle( hwnd, set_bits, clear_bits ); - if ((old_style & clear_bits) != 0 || (old_style & set_bits) != set_bits) - { - /* frame has been changed, let the window redraw itself */ - NtUserSetWindowPos( hwnd, 0, 0, 0, 0, 0, - SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ); - return TRUE; - } - return FALSE; /* no frame changes */ -} - - -/************************************************************************* - * EnableScrollBar (USER32.@) - * - * Enables or disables the scroll bars. - */ -BOOL WINAPI DECLSPEC_HOTPATCH EnableScrollBar( HWND hwnd, UINT nBar, UINT flags ) -{ - BOOL bFineWithMe; - SCROLLBAR_INFO *infoPtr; - - flags &= ESB_DISABLE_BOTH; - - if (nBar == SB_BOTH) - { - if (!(infoPtr = SCROLL_GetInternalInfo( hwnd, SB_VERT, TRUE ))) return FALSE; - if (!(bFineWithMe = (infoPtr->flags == flags)) ) - { - infoPtr->flags = flags; - SCROLL_RefreshScrollBar( hwnd, SB_VERT, TRUE, TRUE ); - } - nBar = SB_HORZ; - } - else - bFineWithMe = nBar != SB_CTL; - - if (!(infoPtr = SCROLL_GetInternalInfo( hwnd, nBar, TRUE ))) return FALSE; - if (bFineWithMe && infoPtr->flags == flags) return FALSE; - infoPtr->flags = flags; - - if (nBar == SB_CTL && (flags == ESB_DISABLE_BOTH || flags == ESB_ENABLE_BOTH)) - EnableWindow(hwnd, flags == ESB_ENABLE_BOTH); - - SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, TRUE ); - return TRUE; -} diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index ce8365b1336..800dc4a9240 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -206,7 +206,7 @@ @ stdcall EnableMenuItem(long long long) NtUserEnableMenuItem @ stdcall EnableMouseInPointer(long) @ stdcall EnableNonClientDpiScaling(long) -@ stdcall EnableScrollBar(long long long) +@ stdcall -import EnableScrollBar(long long long) NtUserEnableScrollBar @ stdcall EnableWindow(long long) @ stdcall EndDeferWindowPos(long) @ stdcall EndDialog(long long) @@ -373,7 +373,7 @@ @ stdcall GetRawInputDeviceList(ptr ptr long) NtUserGetRawInputDeviceList # @ stub GetReasonTitleFromReasonCode @ stdcall GetRegisteredRawInputDevices(ptr ptr long) NtUserGetRegisteredRawInputDevices -@ stdcall GetScrollBarInfo(long long ptr) +@ stdcall GetScrollBarInfo(long long ptr) NtUserGetScrollBarInfo @ stdcall GetScrollInfo(long long ptr) @ stdcall GetScrollPos(long long) @ stdcall GetScrollRange(long long ptr ptr) @@ -699,7 +699,7 @@ @ stdcall SetPropW(long wstr long) @ stdcall SetRect(ptr long long long long) @ stdcall SetRectEmpty(ptr) -@ stdcall SetScrollInfo(long long ptr long) +@ stdcall -import SetScrollInfo(long long ptr long) NtUserSetScrollInfo @ stdcall SetScrollPos(long long long long) @ stdcall SetScrollRange(long long long long long) @ stdcall SetShellWindow(long) diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index 7a85a86d786..b6c8f26cec6 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -157,7 +157,6 @@ static const struct user_callbacks user_funcs = ImmProcessKey, ImmTranslateMessage, NtWaitForMultipleObjects, - SCROLL_DrawNCScrollBar, free_win_ptr, SCROLL_GetInternalInfo, notify_ime, @@ -174,6 +173,16 @@ static NTSTATUS WINAPI User32CopyImage( const struct copy_image_params *params, return HandleToUlong( ret ); }
+static NTSTATUS WINAPI User32DrawScrollBar( const struct draw_scroll_bar_params *params, ULONG size ) +{ + RECT rect = params->rect; + user_api->pScrollBarDraw( params->hwnd, params->hdc, params->bar, params->hit_test, + ¶ms->tracking_info, params->arrows, params->interior, + &rect, params->arrow_size, params->thumb_pos, + params->thumb_size, params->vertical ); + return 0; +} + static NTSTATUS WINAPI User32DrawText( const struct draw_text_params *params, ULONG size ) { size -= FIELD_OFFSET( struct draw_text_params, str ); @@ -220,6 +229,7 @@ static const void *kernel_callback_table[NtUserCallCount] = User32CallWindowProc, User32CallWindowsHook, User32CopyImage, + User32DrawScrollBar, User32DrawText, User32FreeCachedClipboardData, User32LoadDriver, diff --git a/dlls/user32/win.c b/dlls/user32/win.c index d1b25da0e68..8b5033ad821 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -1182,20 +1182,6 @@ BOOL WINAPI IsWindowVisible( HWND hwnd ) }
-/*********************************************************************** - * WIN_IsWindowDrawable - * - * hwnd is drawable when it is visible, all parents are not - * minimized, and it is itself not minimized unless we are - * trying to draw its default class icon. - */ -BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL icon ) -{ - /* FIXME: move callers to win32u */ - return NtUserCallHwndParam( hwnd, icon, NtUserIsWindowDrawable ); -} - - /******************************************************************* * GetTopWindow (USER32.@) */ diff --git a/dlls/user32/win.h b/dlls/user32/win.h index 59a7e0e2e38..8ef090fe983 100644 --- a/dlls/user32/win.h +++ b/dlls/user32/win.h @@ -44,7 +44,6 @@ extern HWND WIN_IsCurrentThread( HWND hwnd ) DECLSPEC_HIDDEN; extern ULONG WIN_SetStyle( HWND hwnd, ULONG set_bits, ULONG clear_bits ) DECLSPEC_HIDDEN; extern BOOL WIN_GetRectangles( HWND hwnd, enum coords_relative relative, RECT *rectWindow, RECT *rectClient ) DECLSPEC_HIDDEN; extern HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, BOOL unicode ) DECLSPEC_HIDDEN; -extern BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL ) DECLSPEC_HIDDEN; extern HWND *WIN_ListChildren( HWND hwnd ) DECLSPEC_HIDDEN; extern void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta, UINT *id ) DECLSPEC_HIDDEN; extern HDESK open_winstation_desktop( HWINSTA hwinsta, LPCWSTR name, DWORD flags, BOOL inherit, ACCESS_MASK access ) DECLSPEC_HIDDEN; diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index af51b933d49..702673e0cdd 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -922,6 +922,28 @@ static void sys_command_size_move( HWND hwnd, WPARAM wparam ) } }
+/*********************************************************************** + * track_nc_scroll_bar + * + * Track a mouse button press on the horizontal or vertical scroll-bar. + */ +static void track_nc_scroll_bar( HWND hwnd, WPARAM wparam, POINT pt ) +{ + int scrollbar; + + if ((wparam & 0xfff0) == SC_HSCROLL) + { + if ((wparam & 0x0f) != HTHSCROLL) return; + scrollbar = SB_HORZ; + } + else /* SC_VSCROLL */ + { + if ((wparam & 0x0f) != HTVSCROLL) return; + scrollbar = SB_VERT; + } + track_scroll_bar( hwnd, scrollbar, pt ); +} + static LRESULT handle_sys_command( HWND hwnd, WPARAM wparam, LPARAM lparam ) { TRACE( "hwnd %p WM_SYSCOMMAND %lx %lx\n", hwnd, wparam, lparam ); @@ -956,7 +978,13 @@ static LRESULT handle_sys_command( HWND hwnd, WPARAM wparam, LPARAM lparam )
case SC_VSCROLL: case SC_HSCROLL: - return 1; /* FIXME: handle on client side */ + { + POINT pt; + pt.x = (short)LOWORD( lparam ); + pt.y = (short)HIWORD( lparam ); + track_nc_scroll_bar( hwnd, wparam, pt ); + } + break;
case SC_MOUSEMENU: track_mouse_menu_bar( hwnd, wparam & 0x000F, (short)LOWORD(lparam), (short)HIWORD(lparam) ); @@ -1736,8 +1764,7 @@ static void nc_paint( HWND hwnd, HRGN clip ) draw_rect_edge( hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST, 1 );
/* Draw the scroll-bars */ - if (user_callbacks) - user_callbacks->draw_nc_scrollbar( hwnd, hdc, style & WS_HSCROLL, style & WS_VSCROLL ); + draw_nc_scrollbar( hwnd, hdc, style & WS_HSCROLL, style & WS_VSCROLL );
/* Draw the "size-box" */ if ((style & WS_VSCROLL) && (style & WS_HSCROLL)) @@ -2295,6 +2322,42 @@ static HBRUSH handle_control_color( HDC hdc, UINT type ) return get_sys_color_brush( COLOR_WINDOW ); }
+static LRESULT handle_nc_mouse_move( HWND hwnd, WPARAM wparam, LPARAM lparam ) +{ + RECT rect; + POINT pt; + + TRACE( "hwnd=%p wparam=%#lx lparam=%#lx\n", hwnd, wparam, lparam ); + + if (wparam != HTHSCROLL && wparam != HTVSCROLL) + return 0; + + get_window_rects( hwnd, COORDS_CLIENT, &rect, NULL, get_thread_dpi() ); + + pt.x = (short)LOWORD( lparam ); + pt.y = (short)HIWORD( lparam ); + screen_to_client( hwnd, &pt ); + pt.x -= rect.left; + pt.y -= rect.top; + handle_scroll_event( hwnd, wparam == HTHSCROLL ? SB_HORZ : SB_VERT, WM_NCMOUSEMOVE, pt ); + return 0; +} + +static LRESULT handle_nc_mouse_leave( HWND hwnd ) +{ + LONG style = get_window_long( hwnd, GWL_STYLE ); + POINT pt = {0, 0}; + + TRACE( "hwnd=%p\n", hwnd ); + + if (style & WS_HSCROLL) + handle_scroll_event( hwnd, SB_HORZ, WM_NCMOUSELEAVE, pt ); + if (style & WS_VSCROLL) + handle_scroll_event( hwnd, SB_VERT, WM_NCMOUSELEAVE, pt ); + return 0; +} + + LRESULT default_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi ) { LRESULT result = 0; @@ -2352,6 +2415,14 @@ LRESULT default_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, case WM_NCLBUTTONDBLCLK: return handle_nc_button_dbl_click( hwnd, wparam, lparam );
+ case WM_NCMOUSEMOVE: + result = handle_nc_mouse_move( hwnd, wparam, lparam ); + break; + + case WM_NCMOUSELEAVE: + result = handle_nc_mouse_leave( hwnd ); + break; + case WM_RBUTTONUP: { POINT pt; diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c index d843716e4c0..9aab651e551 100644 --- a/dlls/win32u/gdiobj.c +++ b/dlls/win32u/gdiobj.c @@ -1164,6 +1164,7 @@ static struct unix_funcs unix_funcs = NtUserDrawMenuBarTemp, NtUserEmptyClipboard, NtUserEnableMenuItem, + NtUserEnableScrollBar, NtUserEndDeferWindowPosEx, NtUserEndPaint, NtUserEnumDisplayDevices, @@ -1184,6 +1185,7 @@ static struct unix_funcs unix_funcs = NtUserGetMessage, NtUserGetPriorityClipboardFormat, NtUserGetQueueStatus, + NtUserGetScrollBarInfo, NtUserGetSystemMenu, NtUserGetUpdateRect, NtUserGetUpdateRgn, @@ -1226,6 +1228,7 @@ static struct unix_funcs unix_funcs = NtUserSetLayeredWindowAttributes, NtUserSetMenu, NtUserSetParent, + NtUserSetScrollInfo, NtUserSetSysColors, NtUserSetSystemMenu, NtUserSetWindowLong, diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 36c11a49c4e..b2765a70a3d 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -35,7 +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 *draw_nc_scrollbar)( HWND hwnd, HDC hdc, BOOL draw_horizontal, BOOL draw_vertical ); 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 ); diff --git a/dlls/win32u/scroll.c b/dlls/win32u/scroll.c index 14bec1e3b83..a51c7d3cf93 100644 --- a/dlls/win32u/scroll.c +++ b/dlls/win32u/scroll.c @@ -23,7 +23,7 @@ #pragma makedep unix #endif
-#include "win32u_private.h" +#include "ntgdi_private.h" #include "ntuser_private.h" #include "wine/debug.h"
@@ -41,6 +41,27 @@ WINE_DEFAULT_DEBUG_CHANNEL(scroll); /* Overlap between arrows and thumb */ #define SCROLL_ARROW_THUMB_OVERLAP 0
+/* Delay (in ms) before first repetition when holding the button down */ +#define SCROLL_FIRST_DELAY 200 + +/* Delay (in ms) between scroll repetitions */ +#define SCROLL_REPEAT_DELAY 50 + +/* Scroll timer id */ +#define SCROLL_TIMER 0 + +/* What to do after set_scroll_info() */ +#define SA_SSI_HIDE 0x0001 +#define SA_SSI_SHOW 0x0002 +#define SA_SSI_REFRESH 0x0004 +#define SA_SSI_REPAINT_ARROWS 0x0008 + +/* Scroll Bar tracking information */ +static struct SCROLL_TRACKING_INFO g_tracking_info; + +/* Is the moving thumb being displayed? */ +static BOOL scroll_moving_thumb = FALSE; + static struct scroll_info *get_scroll_info_ptr( HWND hwnd, int bar, BOOL alloc ) { struct scroll_info *ret = NULL; @@ -200,6 +221,856 @@ static BOOL get_scroll_bar_rect( HWND hwnd, int bar, RECT *rect, int *arrow_size return vertical; }
+/*********************************************************************** + * draw_scroll_bar + * + * Redraw the whole scrollbar. + */ +void draw_scroll_bar( HWND hwnd, HDC hdc, int bar, enum SCROLL_HITTEST hit_test, + const struct SCROLL_TRACKING_INFO *tracking_info, BOOL draw_arrows, + BOOL draw_interior ) +{ + struct draw_scroll_bar_params params; + struct scroll_info *info; + RECT clip_box, intersect; + DWORD style; + void *ret_ptr; + ULONG ret_len; + + if (!(hwnd = get_full_window_handle( hwnd ))) + return; + + style = get_window_long( hwnd, GWL_STYLE ); + if ((bar == SB_VERT && !(style & WS_VSCROLL)) || (bar == SB_HORZ && !(style & WS_HSCROLL))) + return; + + if (!is_window_drawable( hwnd, FALSE )) + return; + + if (!(info = get_scroll_info_ptr( hwnd, bar, TRUE ))) return; + params.enable_flags = info->flags; + release_scroll_info_ptr( info ); + + if (bar == SB_CTL && get_window_long( hwnd, GWL_STYLE ) & (SBS_SIZEGRIP | SBS_SIZEBOX)) + { + get_client_rect( hwnd, ¶ms.rect ); + params.arrow_size = 0; + params.thumb_pos = 0; + params.thumb_size = 0; + params.vertical = FALSE; + } + else + { + int pos, max_size; + + params.vertical = get_scroll_bar_rect( hwnd, bar, ¶ms.rect, ¶ms.arrow_size, + ¶ms.thumb_size, ¶ms.thumb_pos ); + + if (scroll_moving_thumb && tracking_info->win == hwnd && tracking_info->bar == bar) + { + max_size = params.vertical ? + params.rect.bottom - params.rect.top : params.rect.right - params.rect.left; + max_size -= params.arrow_size - SCROLL_ARROW_THUMB_OVERLAP + params.thumb_size; + + pos = tracking_info->thumb_pos; + if (pos < params.arrow_size - SCROLL_ARROW_THUMB_OVERLAP) + pos = params.arrow_size - SCROLL_ARROW_THUMB_OVERLAP; + else if (pos > max_size) + pos = max_size; + + params.thumb_pos = pos; + } + } + + /* do not draw if the scrollbar rectangle is empty */ + if (IsRectEmpty( ¶ms.rect )) + return; + + TRACE( "hwnd %p, hdc %p, bar %d, hit_test %d, tracking_info(win %p, bar %d, thumb_pos %d, " + "track_pos %d, vertical %d, hit_test %d), draw_arrows %d, draw_interior %d, rect %s, " + "arrow_size %d, thumb_pos %d, thumb_val %d, vertical %d, captured window %p\n", hwnd, hdc, + bar, hit_test, tracking_info->win, tracking_info->bar, tracking_info->thumb_pos, + tracking_info->thumb_val, tracking_info->vertical, tracking_info->hit_test, draw_arrows, + draw_interior, wine_dbgstr_rect(¶ms.rect), params.arrow_size, params.thumb_pos, + params.thumb_size, params.vertical, get_capture() ); + + params.hwnd = hwnd; + params.hdc = hdc; + params.bar = bar; + params.hit_test = hit_test; + params.arrows = draw_arrows; + params.interior = draw_interior; + KeUserModeCallback( NtUserDrawScrollBar, ¶ms, sizeof(params), &ret_ptr, &ret_len ); + + if (bar == SB_HORZ || bar == SB_VERT) + { + NtGdiGetAppClipBox( hdc, &clip_box ); + if (intersect_rect( &intersect, ¶ms.rect, &clip_box )) + set_standard_scroll_painted( hwnd, bar, TRUE ); + } +} + +void draw_nc_scrollbar( HWND hwnd, HDC hdc, BOOL draw_horizontal, BOOL draw_vertical ) +{ + if (draw_horizontal) + draw_scroll_bar( hwnd, hdc, SB_HORZ, g_tracking_info.hit_test, &g_tracking_info, TRUE, TRUE ); + if (draw_vertical) + draw_scroll_bar( hwnd, hdc, SB_VERT, g_tracking_info.hit_test, &g_tracking_info, TRUE, TRUE ); +} + +static void refresh_scroll_bar( HWND hwnd, int nBar, BOOL arrows, BOOL interior ) +{ + HDC hdc = NtUserGetDCEx( hwnd, 0, DCX_CACHE | (nBar == SB_CTL ? 0 : DCX_WINDOW) ); + if (!hdc) return; + + draw_scroll_bar( hwnd, hdc, nBar, g_tracking_info.hit_test, &g_tracking_info, arrows, interior ); + NtUserReleaseDC( hwnd, hdc ); +} + +static BOOL point_in_scroll_rect( RECT *r, POINT pt, BOOL vertical ) +{ + RECT rect = *r; + int width; + + /* Pad hit rect to allow mouse to be dragged outside of scrollbar and + * still be considered in the scrollbar. */ + if (vertical) + { + width = r->right - r->left; + InflateRect( &rect, width * 8, width * 2 ); + } + else + { + width = r->bottom - r->top; + InflateRect( &rect, width * 2, width * 8 ); + } + return PtInRect( &rect, pt ); +} + +/*********************************************************************** + * scroll_hit_test + * + * Scroll-bar hit testing (don't confuse this with WM_NCHITTEST!). + */ +static enum SCROLL_HITTEST scroll_hit_test( HWND hwnd, int bar, POINT pt, BOOL dragging ) +{ + int arrow_size, thumb_size, thumb_pos; + BOOL vertical; + RECT rect; + + vertical = get_scroll_bar_rect( hwnd, bar, &rect, &arrow_size, &thumb_size, &thumb_pos ); + + if ((dragging && !point_in_scroll_rect( &rect, pt, vertical )) || !PtInRect( &rect, pt )) + return SCROLL_NOWHERE; + + if (vertical) + { + if (pt.y < rect.top + arrow_size) return SCROLL_TOP_ARROW; + if (pt.y >= rect.bottom - arrow_size) return SCROLL_BOTTOM_ARROW; + if (!thumb_pos) return SCROLL_TOP_RECT; + pt.y -= rect.top; + if (pt.y < thumb_pos) return SCROLL_TOP_RECT; + if (pt.y >= thumb_pos + thumb_size) return SCROLL_BOTTOM_RECT; + } + else /* horizontal */ + { + if (pt.x < rect.left + arrow_size) return SCROLL_TOP_ARROW; + if (pt.x >= rect.right - arrow_size) return SCROLL_BOTTOM_ARROW; + if (!thumb_pos) return SCROLL_TOP_RECT; + pt.x -= rect.left; + if (pt.x < thumb_pos) return SCROLL_TOP_RECT; + if (pt.x >= thumb_pos + thumb_size) return SCROLL_BOTTOM_RECT; + } + return SCROLL_THUMB; +} + +static BOOL is_standard_scroll_painted( HWND hwnd, int bar ) +{ + struct scroll_info *info; + BOOL ret; + + if (bar != SB_HORZ && bar != SB_VERT) return FALSE; + if (!(info = get_scroll_info_ptr( hwnd, bar, FALSE ))) return FALSE; + ret = info->painted; + release_scroll_info_ptr( info ); + return ret; +} + +/*********************************************************************** + * get_thumb_val + * + * Compute the current scroll position based on the thumb position in pixels + * from the top of the scroll-bar. + */ +static UINT get_thumb_val( HWND hwnd, int bar, RECT *rect, BOOL vertical, int pos ) +{ + int thumb_size, min_thumb_size, pixels, range; + struct scroll_info *info; + UINT ret; + + pixels = vertical ? rect->bottom-rect->top : rect->right-rect->left; + pixels -= 2 * (get_system_metrics( SM_CXVSCROLL ) - SCROLL_ARROW_THUMB_OVERLAP); + if (!(info = get_scroll_info_ptr( hwnd, bar, FALSE ))) return 0; + ret = info->minVal; + if (pixels > 0) + { + if (info->page) + { + thumb_size = muldiv( pixels, info->page, info->maxVal - info->minVal + 1 ); + min_thumb_size = muldiv( SCROLL_MIN_THUMB, get_dpi_for_window( hwnd ), 96 ); + if (thumb_size < min_thumb_size) thumb_size = min_thumb_size; + } + else thumb_size = get_system_metrics( SM_CXVSCROLL ); + + if ((pixels -= thumb_size) > 0) + { + pos = max( 0, pos - (get_system_metrics( SM_CXVSCROLL ) - SCROLL_ARROW_THUMB_OVERLAP )); + if (pos > pixels) pos = pixels; + + if (!info->page) + range = info->maxVal - info->minVal; + else + range = info->maxVal - info->minVal - info->page + 1; + + ret = info->minVal + muldiv( pos, range, pixels ); + } + } + + release_scroll_info_ptr( info ); + return ret; +} + +static POINT clip_scroll_pos( RECT *rect, POINT pt ) +{ + if (pt.x < rect->left) + pt.x = rect->left; + else if (pt.x > rect->right) + pt.x = rect->right; + + if (pt.y < rect->top) + pt.y = rect->top; + else if (pt.y > rect->bottom) + pt.y = rect->bottom; + + return pt; +} + +/*********************************************************************** + * handle_scroll_event + * + * Handle a mouse or timer event for the scrollbar. + * 'pt' is the location of the mouse event in client (for SB_CTL) or + * windows coordinates. + */ +void handle_scroll_event( HWND hwnd, int bar, UINT msg, POINT pt ) +{ + /* Previous mouse position for timer events. */ + static POINT prev_pt; + /* Thumb position when tracking started. */ + static UINT track_thumb_pos; + /* Position in the scroll-bar of the last button-down event. */ + static int last_click_pos; + /* Position in the scroll-bar of the last mouse event. */ + static int last_mouse_pos; + + int arrow_size, thumb_size, thumb_pos; + enum SCROLL_HITTEST hittest; + HWND owner_hwnd, ctl_hwnd; + struct scroll_info *info; + TRACKMOUSEEVENT tme; + BOOL vertical; + RECT rect; + HDC hdc; + + if (!(info = get_scroll_info_ptr( hwnd, bar, FALSE ))) return; + release_scroll_info_ptr( info ); + + if (g_tracking_info.hit_test == SCROLL_NOWHERE && + (msg != WM_LBUTTONDOWN && msg != WM_MOUSEMOVE && msg != WM_MOUSELEAVE && + msg != WM_NCMOUSEMOVE && msg != WM_NCMOUSELEAVE)) + return; + + if (bar == SB_CTL && (get_window_long( hwnd, GWL_STYLE ) & (SBS_SIZEGRIP | SBS_SIZEBOX))) + { + switch (msg) + { + case WM_LBUTTONDOWN: /* Initialise mouse tracking */ + NtUserHideCaret( hwnd ); /* hide caret while holding down LBUTTON */ + NtUserSetCapture( hwnd ); + prev_pt = pt; + g_tracking_info.hit_test = hittest = SCROLL_THUMB; + break; + case WM_MOUSEMOVE: + get_client_rect( get_parent( get_parent( hwnd )), &rect ); + prev_pt = pt; + break; + case WM_LBUTTONUP: + release_capture(); + g_tracking_info.hit_test = hittest = SCROLL_NOWHERE; + if (hwnd == get_focus()) NtUserShowCaret( hwnd ); + break; + case WM_SYSTIMER: + pt = prev_pt; + break; + } + return; + } + + hdc = NtUserGetDCEx( hwnd, 0, DCX_CACHE | (bar == SB_CTL ? 0 : DCX_WINDOW)); + vertical = get_scroll_bar_rect( hwnd, bar, &rect, &arrow_size, &thumb_size, &thumb_pos ); + owner_hwnd = bar == SB_CTL ? get_parent( hwnd ) : hwnd; + ctl_hwnd = bar == SB_CTL ? hwnd : 0; + + switch (msg) + { + case WM_LBUTTONDOWN: /* Initialise mouse tracking */ + NtUserHideCaret( hwnd ); /* hide caret while holding down LBUTTON */ + g_tracking_info.vertical = vertical; + g_tracking_info.hit_test = hittest = scroll_hit_test( hwnd, bar, pt, FALSE ); + last_click_pos = vertical ? pt.y - rect.top : pt.x - rect.left; + last_mouse_pos = last_click_pos; + track_thumb_pos = thumb_pos; + prev_pt = pt; + if (bar == SB_CTL && (get_window_long( hwnd, GWL_STYLE ) & WS_TABSTOP)) + NtUserSetFocus( hwnd ); + NtUserSetCapture( hwnd ); + break; + + case WM_MOUSEMOVE: + hittest = scroll_hit_test( hwnd, bar, pt, + vertical == g_tracking_info.vertical && get_capture() == hwnd ); + prev_pt = pt; + + if (bar != SB_CTL) + break; + + tme.cbSize = sizeof(tme); + tme.dwFlags = TME_QUERY; + NtUserTrackMouseEvent( &tme ); + if (!(tme.dwFlags & TME_LEAVE) || tme.hwndTrack != hwnd) + { + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = hwnd; + NtUserTrackMouseEvent( &tme ); + } + break; + + case WM_NCMOUSEMOVE: + hittest = scroll_hit_test( hwnd, bar, pt, + vertical == g_tracking_info.vertical && get_capture() == hwnd ); + prev_pt = pt; + + if (bar == SB_CTL) + break; + + tme.cbSize = sizeof(tme); + tme.dwFlags = TME_QUERY; + NtUserTrackMouseEvent( &tme ); + if (((tme.dwFlags & (TME_NONCLIENT | TME_LEAVE)) != (TME_NONCLIENT | TME_LEAVE)) || + tme.hwndTrack != hwnd) + { + tme.dwFlags = TME_NONCLIENT | TME_LEAVE; + tme.hwndTrack = hwnd; + NtUserTrackMouseEvent( &tme ); + } + + break; + + case WM_NCMOUSELEAVE: + if (bar == SB_CTL) + return; + + hittest = SCROLL_NOWHERE; + break; + + case WM_MOUSELEAVE: + if (bar != SB_CTL) + return; + + hittest = SCROLL_NOWHERE; + break; + + case WM_LBUTTONUP: + hittest = SCROLL_NOWHERE; + release_capture(); + /* if scrollbar has focus, show back caret */ + if (hwnd == get_focus()) NtUserShowCaret( hwnd ); + break; + + case WM_SYSTIMER: + pt = prev_pt; + hittest = scroll_hit_test( hwnd, bar, pt, FALSE ); + break; + + default: + return; /* Should never happen */ + } + + TRACE( "Event: hwnd=%p bar=%d msg=%s pt=%d,%d hit=%d\n", + hwnd, bar, debugstr_msg_name( msg, hwnd ), pt.x, pt.y, hittest ); + + switch (g_tracking_info.hit_test) + { + case SCROLL_NOWHERE: /* No tracking in progress */ + /* For standard scroll bars, hovered state gets painted only when the scroll bar was + * previously painted by DefWinProc(). If an application handles WM_NCPAINT by itself, then + * the scrollbar shouldn't be repainted here to avoid overwriting the application painted + * content */ + if (msg == WM_MOUSEMOVE || msg == WM_MOUSELEAVE || + ((msg == WM_NCMOUSEMOVE || msg == WM_NCMOUSELEAVE) && + is_standard_scroll_painted( hwnd, bar ))) + draw_scroll_bar( hwnd, hdc, bar, hittest, &g_tracking_info, TRUE, TRUE ); + break; + + case SCROLL_TOP_ARROW: + draw_scroll_bar( hwnd, hdc, bar, hittest, &g_tracking_info, TRUE, FALSE ); + if (hittest == g_tracking_info.hit_test) + { + if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER)) + { + send_message( owner_hwnd, vertical ? WM_VSCROLL : WM_HSCROLL, + SB_LINEUP, (LPARAM)ctl_hwnd ); + } + + NtUserSetSystemTimer( hwnd, SCROLL_TIMER, + msg == WM_LBUTTONDOWN ? SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY ); + } + else NtUserKillSystemTimer( hwnd, SCROLL_TIMER ); + break; + + case SCROLL_TOP_RECT: + draw_scroll_bar( hwnd, hdc, bar, hittest, &g_tracking_info, FALSE, TRUE ); + if (hittest == g_tracking_info.hit_test) + { + if (msg == WM_LBUTTONDOWN || msg == WM_SYSTIMER) + { + send_message( owner_hwnd, vertical ? WM_VSCROLL : WM_HSCROLL, + SB_PAGEUP, (LPARAM)ctl_hwnd ); + } + NtUserSetSystemTimer( hwnd, SCROLL_TIMER, + msg == WM_LBUTTONDOWN ? SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY ); + } + else NtUserKillSystemTimer( hwnd, SCROLL_TIMER ); + break; + + case SCROLL_THUMB: + if (msg == WM_LBUTTONDOWN) + { + g_tracking_info.win = hwnd; + g_tracking_info.bar = bar; + g_tracking_info.thumb_pos = track_thumb_pos + last_mouse_pos - last_click_pos; + g_tracking_info.thumb_val = get_thumb_val( hwnd, bar, &rect, vertical, + g_tracking_info.thumb_pos ); + if (!scroll_moving_thumb) + { + scroll_moving_thumb = TRUE; + draw_scroll_bar( hwnd, hdc, bar, hittest, &g_tracking_info, FALSE, TRUE ); + } + } + else if (msg == WM_LBUTTONUP) + { + draw_scroll_bar( hwnd, hdc, bar, SCROLL_NOWHERE, &g_tracking_info, FALSE, TRUE ); + } + else if (msg == WM_MOUSEMOVE) + { + int pos; + + if (!point_in_scroll_rect( &rect, pt, vertical )) pos = last_click_pos; + else + { + pt = clip_scroll_pos( &rect, pt ); + pos = vertical ? pt.y - rect.top : pt.x - rect.left; + } + if (pos != last_mouse_pos || !scroll_moving_thumb) + { + last_mouse_pos = pos; + g_tracking_info.thumb_pos = track_thumb_pos + pos - last_click_pos; + g_tracking_info.thumb_val = get_thumb_val( hwnd, bar, &rect, vertical, + g_tracking_info.thumb_pos ); + send_message( owner_hwnd, vertical ? WM_VSCROLL : WM_HSCROLL, + MAKEWPARAM( SB_THUMBTRACK, g_tracking_info.thumb_val ), + (LPARAM)ctl_hwnd ); + scroll_moving_thumb = TRUE; + draw_scroll_bar( hwnd, hdc, bar, hittest, &g_tracking_info, FALSE, TRUE ); + } + } + break; + + case SCROLL_BOTTOM_RECT: + draw_scroll_bar( hwnd, hdc, bar, hittest, &g_tracking_info, FALSE, TRUE ); + if (hittest == g_tracking_info.hit_test) + { + if (msg == WM_LBUTTONDOWN || msg == WM_SYSTIMER) + { + send_message( owner_hwnd, vertical ? WM_VSCROLL : WM_HSCROLL, + SB_PAGEDOWN, (LPARAM)ctl_hwnd ); + } + NtUserSetSystemTimer( hwnd, SCROLL_TIMER, + msg == WM_LBUTTONDOWN ? SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY ); + } + else NtUserKillSystemTimer( hwnd, SCROLL_TIMER ); + break; + + case SCROLL_BOTTOM_ARROW: + draw_scroll_bar( hwnd, hdc, bar, hittest, &g_tracking_info, TRUE, FALSE ); + if (hittest == g_tracking_info.hit_test) + { + if (msg == WM_LBUTTONDOWN || msg == WM_SYSTIMER) + { + send_message( owner_hwnd, vertical ? WM_VSCROLL : WM_HSCROLL, + SB_LINEDOWN, (LPARAM)ctl_hwnd ); + } + + NtUserSetSystemTimer( hwnd, SCROLL_TIMER, + msg == WM_LBUTTONDOWN ? SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY ); + } + else NtUserKillSystemTimer( hwnd, SCROLL_TIMER ); + break; + } + + if (msg == WM_LBUTTONDOWN) + { + + if (hittest == SCROLL_THUMB) + { + UINT val = get_thumb_val( hwnd, bar, &rect, vertical, + track_thumb_pos + last_mouse_pos - last_click_pos ); + send_message( owner_hwnd, vertical ? WM_VSCROLL : WM_HSCROLL, + MAKEWPARAM( SB_THUMBTRACK, val ), (LPARAM)ctl_hwnd ); + } + } + + if (msg == WM_LBUTTONUP) + { + hittest = g_tracking_info.hit_test; + g_tracking_info.hit_test = SCROLL_NOWHERE; /* Terminate tracking */ + + if (hittest == SCROLL_THUMB) + { + UINT val = get_thumb_val( hwnd, bar, &rect, vertical, + track_thumb_pos + last_mouse_pos - last_click_pos ); + send_message( owner_hwnd, vertical ? WM_VSCROLL : WM_HSCROLL, + MAKEWPARAM( SB_THUMBPOSITION, val ), (LPARAM)ctl_hwnd ); + } + /* SB_ENDSCROLL doesn't report thumb position */ + send_message( owner_hwnd, vertical ? WM_VSCROLL : WM_HSCROLL, + SB_ENDSCROLL, (LPARAM)ctl_hwnd ); + + /* Terminate tracking */ + g_tracking_info.win = 0; + scroll_moving_thumb = FALSE; + hittest = SCROLL_NOWHERE; + draw_scroll_bar( hwnd, hdc, bar, hittest, &g_tracking_info, TRUE, TRUE ); + } + + NtUserReleaseDC( hwnd, hdc ); +} + +/*********************************************************************** + * track_scroll_bar + * + * Track a mouse button press on a scroll-bar. + * pt is in screen-coordinates for non-client scroll bars. + */ +void track_scroll_bar( HWND hwnd, int scrollbar, POINT pt ) +{ + MSG msg; + RECT rect; + + if (scrollbar != SB_CTL) + { + get_window_rects( hwnd, COORDS_CLIENT, &rect, NULL, get_thread_dpi() ); + screen_to_client( hwnd, &pt ); + pt.x -= rect.left; + pt.y -= rect.top; + } + else + rect.left = rect.top = 0; + + handle_scroll_event( hwnd, scrollbar, WM_LBUTTONDOWN, pt ); + + do + { + if (!NtUserGetMessage( &msg, 0, 0, 0 )) break; + if (NtUserCallMsgFilter( &msg, MSGF_SCROLLBAR )) continue; + if (msg.message == WM_LBUTTONUP || + msg.message == WM_MOUSEMOVE || + msg.message == WM_MOUSELEAVE || + msg.message == WM_NCMOUSEMOVE || + msg.message == WM_NCMOUSELEAVE || + (msg.message == WM_SYSTIMER && msg.wParam == SCROLL_TIMER)) + { + pt.x = (short)LOWORD( msg.lParam ) - rect.left; + pt.y = (short)HIWORD( msg.lParam ) - rect.top; + handle_scroll_event( hwnd, scrollbar, msg.message, pt ); + } + else + { + NtUserTranslateMessage( &msg, 0 ); + NtUserDispatchMessage( &msg ); + } + if (!is_window( hwnd )) + { + release_capture(); + break; + } + } while (msg.message != WM_LBUTTONUP && get_capture() == hwnd); +} + +/*********************************************************************** + * validate_scroll_info + * + * Determine if the supplied SCROLLINFO struct is valid. + */ +static inline BOOL validate_scroll_info( const SCROLLINFO *info ) +{ + return !(info->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL) || + (info->cbSize != sizeof(*info) && + info->cbSize != sizeof(*info) - sizeof(info->nTrackPos))); +} + + +BOOL get_scroll_info( HWND hwnd, int bar, SCROLLINFO *info ) +{ + struct scroll_info *scroll; + + /* handle invalid data structure */ + if (!validate_scroll_info( info ) || !(scroll = get_scroll_info_ptr( hwnd, bar, FALSE ))) + return FALSE; + + /* fill in the desired scroll info structure */ + if (info->fMask & SIF_PAGE) info->nPage = scroll->page; + if (info->fMask & SIF_POS) info->nPos = scroll->curVal; + if ((info->fMask & SIF_TRACKPOS) && (info->cbSize == sizeof(*info))) + info->nTrackPos = g_tracking_info.win == get_full_window_handle( hwnd ) ? + g_tracking_info.thumb_val : scroll->curVal; + if (info->fMask & SIF_RANGE) + { + info->nMin = scroll->minVal; + info->nMax = scroll->maxVal; + } + release_scroll_info_ptr( scroll ); + + TRACE( "cbSize %02x fMask %04x nMin %d nMax %d nPage %u nPos %d nTrackPos %d\n", + info->cbSize, info->fMask, info->nMin, info->nMax, info->nPage, + info->nPos, info->nTrackPos ); + + return (info->fMask & SIF_ALL) != 0; +} + +static int set_scroll_info( HWND hwnd, int bar, const SCROLLINFO *info, BOOL redraw ) +{ + struct scroll_info *scroll; + UINT new_flags; + int action = 0, ret; + + /* handle invalid data structure */ + if (!validate_scroll_info( info ) || + !(scroll = get_scroll_info_ptr( hwnd, bar, TRUE ))) + return 0; + + if (TRACE_ON(scroll)) + { + TRACE( "hwnd=%p bar=%d", hwnd, bar ); + if (info->fMask & SIF_PAGE) TRACE( " page=%d", info->nPage ); + if (info->fMask & SIF_POS) TRACE( " pos=%d", info->nPos ); + if (info->fMask & SIF_RANGE) TRACE( " min=%d max=%d", info->nMin, info->nMax ); + TRACE( "\n" ); + } + + /* Set the page size */ + if ((info->fMask & SIF_PAGE) && scroll->page != info->nPage) + { + scroll->page = info->nPage; + action |= SA_SSI_REFRESH; + } + + /* Set the scroll pos */ + if ((info->fMask & SIF_POS) && scroll->curVal != info->nPos) + { + scroll->curVal = info->nPos; + action |= SA_SSI_REFRESH; + } + + /* Set the scroll range */ + if (info->fMask & SIF_RANGE) + { + /* Invalid range -> range is set to (0,0) */ + if (info->nMin > info->nMax || (UINT)(info->nMax - info->nMin) >= 0x80000000) + { + action |= SA_SSI_REFRESH; + scroll->minVal = 0; + scroll->maxVal = 0; + } + else + { + if (scroll->minVal != info->nMin || scroll->maxVal != info->nMax) + { + action |= SA_SSI_REFRESH; + scroll->minVal = info->nMin; + scroll->maxVal = info->nMax; + } + } + } + + /* Make sure the page size is valid */ + if (scroll->page < 0) scroll->page = 0; + else if (scroll->page > scroll->maxVal - scroll->minVal + 1) + scroll->page = scroll->maxVal - scroll->minVal + 1; + + /* Make sure the pos is inside the range */ + if (scroll->curVal < scroll->minVal) + scroll->curVal = scroll->minVal; + else if (scroll->curVal > scroll->maxVal - max( scroll->page - 1, 0 )) + scroll->curVal = scroll->maxVal - max( scroll->page - 1, 0 ); + + TRACE( " new values: page=%d pos=%d min=%d max=%d\n", scroll->page, scroll->curVal, + scroll->minVal, scroll->maxVal ); + + /* don't change the scrollbar state if SetScrollInfo is just called with SIF_DISABLENOSCROLL */ + if(!(info->fMask & SIF_ALL)) goto done; + + /* Check if the scrollbar should be hidden or disabled */ + if (info->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL)) + { + new_flags = scroll->flags; + if (scroll->minVal >= scroll->maxVal - max( scroll->page - 1, 0 )) + { + /* Hide or disable scroll-bar */ + if (info->fMask & SIF_DISABLENOSCROLL) + { + new_flags = ESB_DISABLE_BOTH; + action |= SA_SSI_REFRESH; + } + else if (bar != SB_CTL && (action & SA_SSI_REFRESH)) + { + action = SA_SSI_HIDE; + } + } + else if (info->fMask != SIF_PAGE) + { + /* Show and enable scroll-bar only if no page only changed. */ + new_flags = ESB_ENABLE_BOTH; + if (bar != SB_CTL && (action & SA_SSI_REFRESH)) action |= SA_SSI_SHOW; + } + + if (bar == SB_CTL && redraw && is_window_visible( hwnd ) && + (new_flags == ESB_ENABLE_BOTH || new_flags == ESB_DISABLE_BOTH)) + { + release_scroll_info_ptr( scroll ); + enable_window( hwnd, new_flags == ESB_ENABLE_BOTH ); + if (!(scroll = get_scroll_info_ptr( hwnd, bar, FALSE ))) return 0; + } + + if (scroll->flags != new_flags) /* check arrow flags */ + { + scroll->flags = new_flags; + action |= SA_SSI_REPAINT_ARROWS; + } + } + +done: + ret = scroll->curVal; + release_scroll_info_ptr( scroll ); + if (action & SA_SSI_HIDE) + show_scroll_bar( hwnd, bar, FALSE, FALSE ); + else + { + if (action & SA_SSI_SHOW && show_scroll_bar( hwnd, bar, TRUE, TRUE )) + return ret; /* NtUserSetWindowPos() already did the painting */ + + if (redraw) + refresh_scroll_bar( hwnd, bar, TRUE, TRUE ); + else if (action & SA_SSI_REPAINT_ARROWS) + refresh_scroll_bar( hwnd, bar, TRUE, FALSE ); + } + + return ret; /* Return current position */ +} + +static BOOL get_scroll_bar_info( HWND hwnd, LONG id, SCROLLBARINFO *info ) +{ + struct scroll_info *scroll; + int bar, dummy; + DWORD style = get_window_long( hwnd, GWL_STYLE ); + BOOL pressed; + RECT rect; + + switch (id) + { + case OBJID_CLIENT: bar = SB_CTL; break; + case OBJID_HSCROLL: bar = SB_HORZ; break; + case OBJID_VSCROLL: bar = SB_VERT; break; + default: return FALSE; + } + + /* handle invalid data structure */ + if (info->cbSize != sizeof(*info)) return FALSE; + + get_scroll_bar_rect( hwnd, bar, &info->rcScrollBar, &dummy, + &info->dxyLineButton, &info->xyThumbTop ); + /* rcScrollBar needs to be in screen coordinates */ + get_window_rect( hwnd, &rect, get_thread_dpi() ); + OffsetRect( &info->rcScrollBar, rect.left, rect.top ); + + info->xyThumbBottom = info->xyThumbTop + info->dxyLineButton; + + if (!(scroll = get_scroll_info_ptr( hwnd, bar, TRUE ))) return FALSE; + + /* Scroll bar state */ + info->rgstate[0] = 0; + if ((bar == SB_HORZ && !(style & WS_HSCROLL)) || + (bar == SB_VERT && !(style & WS_VSCROLL))) + info->rgstate[0] |= STATE_SYSTEM_INVISIBLE; + if (scroll->minVal >= scroll->maxVal - max( scroll->page - 1, 0 )) + { + if (!(info->rgstate[0] & STATE_SYSTEM_INVISIBLE)) + info->rgstate[0] |= STATE_SYSTEM_UNAVAILABLE; + else + info->rgstate[0] |= STATE_SYSTEM_OFFSCREEN; + } + if (bar == SB_CTL && !is_window_enabled( hwnd )) + info->rgstate[0] |= STATE_SYSTEM_UNAVAILABLE; + + pressed = (bar == SB_VERT) == g_tracking_info.vertical && get_capture() == hwnd; + + /* Top/left arrow button state. MSDN says top/right, but I don't believe it */ + info->rgstate[1] = 0; + if (pressed && g_tracking_info.hit_test == SCROLL_TOP_ARROW) + info->rgstate[1] |= STATE_SYSTEM_PRESSED; + if (scroll->flags & ESB_DISABLE_LTUP) + info->rgstate[1] |= STATE_SYSTEM_UNAVAILABLE; + + /* Page up/left region state. MSDN says up/right, but I don't believe it */ + info->rgstate[2] = 0; + if (scroll->curVal == scroll->minVal) + info->rgstate[2] |= STATE_SYSTEM_INVISIBLE; + if (pressed && g_tracking_info.hit_test == SCROLL_TOP_RECT) + info->rgstate[2] |= STATE_SYSTEM_PRESSED; + + /* Thumb state */ + info->rgstate[3] = 0; + if (pressed && g_tracking_info.hit_test == SCROLL_THUMB) + info->rgstate[3] |= STATE_SYSTEM_PRESSED; + + /* Page down/right region state. MSDN says down/left, but I don't believe it */ + info->rgstate[4] = 0; + if (scroll->curVal >= scroll->maxVal - 1) + info->rgstate[4] |= STATE_SYSTEM_INVISIBLE; + if (pressed && g_tracking_info.hit_test == SCROLL_BOTTOM_RECT) + info->rgstate[4] |= STATE_SYSTEM_PRESSED; + + /* Bottom/right arrow button state. MSDN says bottom/left, but I don't believe it */ + info->rgstate[5] = 0; + if (pressed && g_tracking_info.hit_test == SCROLL_BOTTOM_ARROW) + info->rgstate[5] |= STATE_SYSTEM_PRESSED; + if (scroll->flags & ESB_DISABLE_RTDN) + info->rgstate[5] |= STATE_SYSTEM_UNAVAILABLE; + + release_scroll_info_ptr( scroll ); + return TRUE; +} + static void create_scroll_bar( HWND hwnd, CREATESTRUCTW *create ) { struct scroll_info *info = NULL; @@ -256,6 +1127,31 @@ static void create_scroll_bar( HWND hwnd, CREATESTRUCTW *create ) } }
+static int get_scroll_pos(HWND hwnd, int bar) +{ + struct scroll_info *scroll = get_scroll_info_ptr( hwnd, bar, FALSE ); + int ret; + if (!scroll) return 0; + ret = scroll->curVal; + release_scroll_info_ptr( scroll ); + return ret; +} + +static BOOL set_scroll_range( HWND hwnd, int bar, int min_val, int max_val ) +{ + struct scroll_info *scroll = get_scroll_info_ptr( hwnd, bar, FALSE ); + + TRACE( "hwnd=%p bar=%d min=%d max=%d\n", hwnd, bar, min_val, max_val ); + + if (scroll) + { + scroll->minVal = min_val; + scroll->maxVal = max_val; + release_scroll_info_ptr( scroll ); + } + return TRUE; +} + LRESULT scroll_bar_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi ) { switch (msg) @@ -264,6 +1160,49 @@ LRESULT scroll_bar_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara create_scroll_bar( hwnd, (CREATESTRUCTW *)lparam ); return 0;
+ case WM_LBUTTONDBLCLK: + case WM_LBUTTONDOWN: + if (get_window_long( hwnd, GWL_STYLE ) & SBS_SIZEGRIP) + { + send_message( get_parent(hwnd), WM_SYSCOMMAND, + SC_SIZE + ((get_window_long( hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) ? + WMSZ_BOTTOMLEFT : WMSZ_BOTTOMRIGHT), lparam ); + } + else + { + POINT pt; + pt.x = (short)LOWORD( lparam ); + pt.y = (short)HIWORD( lparam ); + track_scroll_bar( hwnd, SB_CTL, pt ); + } + return 0; + + case WM_LBUTTONUP: + case WM_NCMOUSEMOVE: + case WM_NCMOUSELEAVE: + case WM_MOUSEMOVE: + case WM_MOUSELEAVE: + case WM_SYSTIMER: + { + POINT pt; + pt.x = (short)LOWORD( lparam ); + pt.y = (short)HIWORD( lparam ); + handle_scroll_event( hwnd, SB_CTL, msg, pt ); + } + return 0; + + case WM_ENABLE: + { + struct scroll_info *scroll; + if ((scroll = get_scroll_info_ptr( hwnd, SB_CTL, FALSE ))) + { + scroll->flags = wparam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH; + release_scroll_info_ptr( scroll ); + refresh_scroll_bar( hwnd, SB_CTL, TRUE, TRUE ); + } + } + return 0; + case WM_SETFOCUS: { /* Create a caret when a ScrollBar get focus */ @@ -312,6 +1251,34 @@ LRESULT scroll_bar_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara case WM_GETDLGCODE: return DLGC_WANTARROWS; /* Windows returns this value */
+ case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hdc = wparam ? (HDC)wparam : NtUserBeginPaint( hwnd, &ps ); + draw_scroll_bar( hwnd, hdc, SB_CTL, g_tracking_info.hit_test, &g_tracking_info, TRUE, TRUE ); + if (!wparam) NtUserEndPaint( hwnd, &ps ); + } + return 0; + + case SBM_SETRANGEREDRAW: + case SBM_SETRANGE: + { + int old_pos = get_scroll_pos( hwnd, SB_CTL ); + set_scroll_range( hwnd, SB_CTL, wparam, lparam ); + if (msg == SBM_SETRANGEREDRAW) refresh_scroll_bar( hwnd, SB_CTL, TRUE, TRUE ); + if (old_pos != get_scroll_pos( hwnd, SB_CTL )) return old_pos; + } + return 0; + + case SBM_GETSCROLLINFO: + return get_scroll_info( hwnd, SB_CTL, (SCROLLINFO *)lparam ); + + case SBM_GETSCROLLBARINFO: + return get_scroll_bar_info( hwnd, OBJID_CLIENT, (SCROLLBARINFO *)lparam ); + + case SBM_SETSCROLLINFO: + return set_scroll_info( hwnd, SB_CTL, (SCROLLINFO *)lparam, wparam ); + default: return default_window_proc( hwnd, msg, wparam, lparam, ansi ); } @@ -341,3 +1308,66 @@ BOOL WINAPI NtUserShowScrollBar( HWND hwnd, INT bar, BOOL show ) show_scroll_bar( hwnd, bar, bar == SB_VERT ? 0 : show, bar == SB_HORZ ? 0 : show ); return TRUE; } + +/************************************************************************* + * NtUserGetScrollBarInfo (win32u.@) + */ +BOOL WINAPI NtUserGetScrollBarInfo( HWND hwnd, LONG id, SCROLLBARINFO *info ) +{ + TRACE( "hwnd=%p id=%d info=%p\n", hwnd, id, info ); + + /* Refer OBJID_CLIENT requests to the window */ + if (id == OBJID_CLIENT) + return send_message( hwnd, SBM_GETSCROLLBARINFO, 0, (LPARAM)info ); + return get_scroll_bar_info( hwnd, id, info ); +} + +/************************************************************************* + * NtUserEnableScrollBar (win32u.@) + */ +BOOL WINAPI NtUserEnableScrollBar( HWND hwnd, UINT bar, UINT flags ) +{ + struct scroll_info *scroll; + BOOL check_flags; + + flags &= ESB_DISABLE_BOTH; + + if (bar == SB_BOTH) + { + if (!(scroll = get_scroll_info_ptr( hwnd, SB_VERT, TRUE ))) return FALSE; + check_flags = scroll->flags == flags; + scroll->flags = flags; + release_scroll_info_ptr( scroll ); + if (!check_flags) refresh_scroll_bar( hwnd, SB_VERT, TRUE, TRUE ); + bar = SB_HORZ; + } + else + check_flags = bar != SB_CTL; + + if (!(scroll = get_scroll_info_ptr( hwnd, bar, TRUE ))) return FALSE; + if (check_flags) check_flags = scroll->flags == flags; + scroll->flags = flags; + release_scroll_info_ptr( scroll ); + if (check_flags) return FALSE; + + if (bar == SB_CTL && (flags == ESB_DISABLE_BOTH || flags == ESB_ENABLE_BOTH)) + NtUserEnableWindow( hwnd, flags == ESB_ENABLE_BOTH ); + + refresh_scroll_bar( hwnd, bar, TRUE, TRUE ); + return TRUE; +} + + +/************************************************************************* + * NtUserSetScrollInfo (win32u.@) + */ +INT WINAPI NtUserSetScrollInfo( HWND hwnd, int bar, const SCROLLINFO *info, BOOL redraw ) +{ + TRACE( "hwnd=%p bar=%d info=%p, redraw=%d\n", hwnd, bar, info, redraw ); + + /* Refer SB_CTL requests to the window */ + if (bar == SB_CTL) + return send_message( hwnd, SBM_SETSCROLLINFO, redraw, (LPARAM)info ); + + return set_scroll_info( hwnd, bar, info, redraw ); +} diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 428e8aadf1c..a2369364877 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -866,7 +866,7 @@ @ stub NtUserEnableMouseInputForCursorSuppression @ stub NtUserEnableNonClientDpiScaling @ stub NtUserEnableResizeLayoutSynchronization -@ stub NtUserEnableScrollBar +@ stdcall NtUserEnableScrollBar(long long long) @ stub NtUserEnableSoftwareCursorForScreenCapture @ stub NtUserEnableTouchPad @ stub NtUserEnableWindowGDIScaledDpiMessage @@ -991,7 +991,7 @@ @ stdcall -syscall NtUserGetRegisteredRawInputDevices(ptr ptr long) @ stub NtUserGetRequiredCursorSizes @ stub NtUserGetResizeDCompositionSynchronizationObject -@ stub NtUserGetScrollBarInfo +@ stdcall NtUserGetScrollBarInfo(long long ptr) @ stub NtUserGetSharedWindowData @ stdcall -syscall NtUserGetSystemDpiForProcess(long) @ stdcall NtUserGetSystemMenu(long long) @@ -1223,7 +1223,7 @@ @ stub NtUserSetProcessUIAccessZorder @ stdcall -syscall NtUserSetProcessWindowStation(long) @ stdcall -syscall NtUserSetProp(long wstr ptr) -@ stub NtUserSetScrollInfo +@ stdcall NtUserSetScrollInfo(long long ptr long) @ stub NtUserSetSensorPresence @ stub NtUserSetSharedWindowData @ stub NtUserSetShellWindowEx diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 49c81ea3bef..a690acadd8b 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -223,6 +223,7 @@ struct unix_funcs DWORD (WINAPI *pNtUserDrawMenuBarTemp)( HWND hwnd, HDC hdc, RECT *rect, HMENU handle, HFONT font ); BOOL (WINAPI *pNtUserEmptyClipboard)(void); BOOL (WINAPI *pNtUserEnableMenuItem)( HMENU handle, UINT id, UINT flags ); + BOOL (WINAPI *pNtUserEnableScrollBar)( HWND hwnd, UINT bar, UINT flags ); BOOL (WINAPI *pNtUserEndDeferWindowPosEx)( HDWP hdwp, BOOL async ); BOOL (WINAPI *pNtUserEndPaint)( HWND hwnd, const PAINTSTRUCT *ps ); NTSTATUS (WINAPI *pNtUserEnumDisplayDevices)( UNICODE_STRING *device, DWORD index, @@ -248,6 +249,7 @@ struct unix_funcs BOOL (WINAPI *pNtUserGetMessage)( MSG *msg, HWND hwnd, UINT first, UINT last ); INT (WINAPI *pNtUserGetPriorityClipboardFormat)( UINT *list, INT count ); DWORD (WINAPI *pNtUserGetQueueStatus)( UINT flags ); + BOOL (WINAPI *pNtUserGetScrollBarInfo)( HWND hwnd, LONG id, SCROLLBARINFO *info ); HMENU (WINAPI *pNtUserGetSystemMenu)( HWND hwnd, BOOL revert ); BOOL (WINAPI *pNtUserGetUpdateRect)( HWND hwnd, RECT *rect, BOOL erase ); INT (WINAPI *pNtUserGetUpdateRgn)( HWND hwnd, HRGN hrgn, BOOL erase ); @@ -300,6 +302,7 @@ struct unix_funcs BOOL (WINAPI *pNtUserSetLayeredWindowAttributes)( HWND hwnd, COLORREF key, BYTE alpha, DWORD flags ); BOOL (WINAPI *pNtUserSetMenu)( HWND hwnd, HMENU menu ); HWND (WINAPI *pNtUserSetParent)( HWND hwnd, HWND parent ); + INT (WINAPI *pNtUserSetScrollInfo)( HWND hwnd, INT bar, const SCROLLINFO *info, BOOL redraw ); BOOL (WINAPI *pNtUserSetSysColors)( INT count, const INT *colors, const COLORREF *values ); BOOL (WINAPI *pNtUserSetSystemMenu)( HWND hwnd, HMENU menu ); LONG (WINAPI *pNtUserSetWindowLong)( HWND hwnd, INT offset, LONG newval, BOOL ansi ); @@ -441,9 +444,13 @@ extern BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardwar extern BOOL rawinput_device_get_usages( HANDLE handle, USHORT *usage_page, USHORT *usage ) DECLSPEC_HIDDEN;
/* scroll.c */ +extern void draw_nc_scrollbar( HWND hwnd, HDC hdc, BOOL draw_horizontal, BOOL draw_vertical ) DECLSPEC_HIDDEN; +extern BOOL get_scroll_info( HWND hwnd, INT bar, SCROLLINFO *info ) DECLSPEC_HIDDEN; +extern void handle_scroll_event( HWND hwnd, INT bar, UINT msg, POINT pt ) DECLSPEC_HIDDEN; extern LRESULT scroll_bar_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi ) DECLSPEC_HIDDEN; extern void set_standard_scroll_painted( HWND hwnd, int bar, BOOL painted ) DECLSPEC_HIDDEN; +extern void track_scroll_bar( HWND hwnd, int scrollbar, POINT pt ) DECLSPEC_HIDDEN;
/* sysparams.c */ extern BOOL enable_thunk_lock DECLSPEC_HIDDEN; @@ -484,6 +491,7 @@ extern HDWP begin_defer_window_pos( INT count ) DECLSPEC_HIDDEN; extern BOOL client_to_screen( HWND hwnd, POINT *pt ) DECLSPEC_HIDDEN; extern void destroy_thread_windows(void) DECLSPEC_HIDDEN; extern LRESULT destroy_window( HWND hwnd ) DECLSPEC_HIDDEN; +extern BOOL enable_window( HWND hwnd, BOOL enable ) DECLSPEC_HIDDEN; extern BOOL get_client_rect( HWND hwnd, RECT *rect ) DECLSPEC_HIDDEN; extern HWND get_desktop_window(void) DECLSPEC_HIDDEN; extern UINT get_dpi_for_window( HWND hwnd ) DECLSPEC_HIDDEN; diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 4a6b321d391..de4779aee59 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -812,7 +812,7 @@ BOOL is_window_unicode( HWND hwnd ) }
/* see EnableWindow */ -static BOOL enable_window( HWND hwnd, BOOL enable ) +BOOL enable_window( HWND hwnd, BOOL enable ) { BOOL ret;
@@ -5442,6 +5442,12 @@ ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code ) case NtUserCallHwndParam_GetClientRect: return get_client_rect( hwnd, (RECT *)param );
+ case NtUserCallHwndParam_GetScrollInfo: + { + struct get_scroll_info_params *params = (void *)param; + return get_scroll_info( hwnd, params->bar, params->info ); + } + case NtUserCallHwndParam_GetWindowInfo: return get_window_info( hwnd, (WINDOWINFO *)param );
@@ -5501,9 +5507,6 @@ ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code ) return show_owned_popups( hwnd, param );
/* temporary exports */ - case NtUserIsWindowDrawable: - return is_window_drawable( hwnd, param ); - case NtUserSetWindowStyle: { STYLESTRUCT *style = (void *)param; diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c index e7ab66cadcb..ba6fa9ea0a0 100644 --- a/dlls/win32u/wrappers.c +++ b/dlls/win32u/wrappers.c @@ -887,6 +887,12 @@ BOOL WINAPI NtUserEnableMenuItem( HMENU handle, UINT id, UINT flags ) return unix_funcs->pNtUserEnableMenuItem( handle, id, flags ); }
+BOOL WINAPI NtUserEnableScrollBar( HWND hwnd, UINT bar, UINT flags ) +{ + if (!unix_funcs) return FALSE; + return unix_funcs->pNtUserEnableScrollBar( hwnd, bar, flags ); +} + BOOL WINAPI NtUserEndDeferWindowPosEx( HDWP hdwp, BOOL async ) { if (!unix_funcs) return FALSE; @@ -1048,6 +1054,12 @@ DWORD WINAPI NtUserGetQueueStatus( UINT flags ) return unix_funcs->pNtUserGetQueueStatus( flags ); }
+BOOL WINAPI NtUserGetScrollBarInfo( HWND hwnd, LONG id, SCROLLBARINFO *info ) +{ + if (!unix_funcs) return FALSE; + return unix_funcs->pNtUserGetScrollBarInfo( hwnd, id, info ); +} + BOOL WINAPI NtUserGetUpdatedClipboardFormats( UINT *formats, UINT size, UINT *out_size ) { if (!unix_funcs) return FALSE; @@ -1274,6 +1286,12 @@ HWND WINAPI NtUserSetParent( HWND hwnd, HWND parent ) return unix_funcs->pNtUserSetParent( hwnd, parent ); }
+INT WINAPI NtUserSetScrollInfo( HWND hwnd, INT bar, const SCROLLINFO *info, BOOL redraw ) +{ + if (!unix_funcs) return 0; + return unix_funcs->pNtUserSetScrollInfo( hwnd, bar, info, redraw ); +} + BOOL WINAPI NtUserSetSysColors( INT count, const INT *colors, const COLORREF *values ) { if (!unix_funcs) return FALSE; diff --git a/include/ntuser.h b/include/ntuser.h index 08a49cbd123..fecdbbbe253 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -33,6 +33,7 @@ enum NtUserCallWinProc, NtUserCallWindowsHook, NtUserCopyImage, + NtUserDrawScrollBar, NtUserDrawText, NtUserFreeCachedClipboardData, NtUserLoadDriver, @@ -336,6 +337,24 @@ struct set_clipboard_params UINT seqno; };
+/* NtUserDrawScrollBar params */ +struct draw_scroll_bar_params +{ + HWND hwnd; + HDC hdc; + INT bar; + UINT hit_test; + struct SCROLL_TRACKING_INFO tracking_info; + BOOL arrows; + BOOL interior; + RECT rect; + UINT enable_flags; + INT arrow_size; + INT thumb_pos; + INT thumb_size; + BOOL vertical; +}; + /* internal messages codes */ enum wine_internal_message { @@ -559,6 +578,7 @@ BOOL WINAPI NtUserDrawIconEx( HDC hdc, INT x0, INT y0, HICON icon, INT width, DWORD WINAPI NtUserDrawMenuBarTemp( HWND hwnd, HDC hdc, RECT *rect, HMENU handle, HFONT font ); BOOL WINAPI NtUserEmptyClipboard(void); BOOL WINAPI NtUserEnableMenuItem( HMENU handle, UINT id, UINT flags ); +BOOL WINAPI NtUserEnableScrollBar( HWND hwnd, UINT bar, UINT flags ); BOOL WINAPI NtUserEndDeferWindowPosEx( HDWP hdwp, BOOL async ); BOOL WINAPI NtUserEndMenu(void); BOOL WINAPI NtUserEndPaint( HWND hwnd, const PAINTSTRUCT *ps ); @@ -625,6 +645,7 @@ UINT WINAPI NtUserGetRawInputData( HRAWINPUT rawinput, UINT command, void *da UINT WINAPI NtUserGetRawInputDeviceInfo( HANDLE handle, UINT command, void *data, UINT *data_size ); UINT WINAPI NtUserGetRawInputDeviceList( RAWINPUTDEVICELIST *devices, UINT *device_count, UINT size ); UINT WINAPI NtUserGetRegisteredRawInputDevices( RAWINPUTDEVICE *devices, UINT *device_count, UINT size ); +BOOL WINAPI NtUserGetScrollBarInfo( HWND hwnd, LONG id, SCROLLBARINFO *info ); ULONG WINAPI NtUserGetSystemDpiForProcess( HANDLE process ); HMENU WINAPI NtUserGetSystemMenu( HWND hwnd, BOOL revert ); HDESK WINAPI NtUserGetThreadDesktop( DWORD thread ); @@ -701,6 +722,7 @@ HWND WINAPI NtUserSetParent( HWND hwnd, HWND parent ); BOOL WINAPI NtUserSetProcessDpiAwarenessContext( ULONG awareness, ULONG unknown ); BOOL WINAPI NtUserSetProcessWindowStation( HWINSTA handle ); BOOL WINAPI NtUserSetProp( HWND hwnd, const WCHAR *str, HANDLE handle ); +INT WINAPI NtUserSetScrollInfo( HWND hwnd, INT bar, const SCROLLINFO *info, BOOL redraw ); BOOL WINAPI NtUserSetSysColors( INT count, const INT *colors, const COLORREF *values ); BOOL WINAPI NtUserSetSystemMenu( HWND hwnd, HMENU menu ); UINT_PTR WINAPI NtUserSetSystemTimer( HWND hwnd, UINT_PTR id, UINT timeout ); @@ -1085,6 +1107,7 @@ enum NtUserCallHwndParam_GetClassLongPtrW, NtUserCallHwndParam_GetClassWord, NtUserCallHwndParam_GetClientRect, + NtUserCallHwndParam_GetScrollInfo, NtUserCallHwndParam_GetWindowInfo, NtUserCallHwndParam_GetWindowLongA, NtUserCallHwndParam_GetWindowLongW, @@ -1104,7 +1127,6 @@ enum NtUserCallHwndParam_SetWindowPixelFormat, NtUserCallHwndParam_ShowOwnedPopups, /* temporary exports */ - NtUserIsWindowDrawable, NtUserSetWindowStyle, NtUserSpyGetMsgName, }; @@ -1149,6 +1171,18 @@ static inline BOOL NtUserGetClientRect( HWND hwnd, RECT *rect ) return NtUserCallHwndParam( hwnd, (UINT_PTR)rect, NtUserCallHwndParam_GetClientRect ); }
+struct get_scroll_info_params +{ + int bar; + SCROLLINFO *info; +}; + +static inline BOOL NtUserGetScrollInfo( HWND hwnd, INT bar, SCROLLINFO *info ) +{ + struct get_scroll_info_params params = { .bar = bar, .info = info }; + return NtUserCallHwndParam( hwnd, (UINT_PTR)¶ms, NtUserCallHwndParam_GetScrollInfo ); +} + static inline BOOL NtUserGetWindowInfo( HWND hwnd, WINDOWINFO *info ) { return NtUserCallHwndParam( hwnd, (UINT_PTR)info, NtUserCallHwndParam_GetWindowInfo );
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/scroll.c | 30 +++++++++++------------------- dlls/user32/user_main.c | 2 +- dlls/user32/user_private.h | 4 ++-- dlls/uxtheme/scrollbar.c | 6 +++--- dlls/uxtheme/uxthemedll.h | 4 ++-- include/winuser.h | 4 ++-- 6 files changed, 21 insertions(+), 29 deletions(-)
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index bf0a7d3350a..e368a2feb70 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -125,7 +125,7 @@ SCROLLBAR_INFO *SCROLL_GetInternalInfo( HWND hwnd, INT nBar, BOOL alloc ) * * Draw the scroll bar arrows. */ -static void SCROLL_DrawArrows( HDC hdc, SCROLLBAR_INFO *infoPtr, +static void SCROLL_DrawArrows( HDC hdc, UINT flags, RECT *rect, INT arrowSize, BOOL vertical, BOOL top_pressed, BOOL bottom_pressed ) { @@ -140,7 +140,7 @@ static void SCROLL_DrawArrows( HDC hdc, SCROLLBAR_INFO *infoPtr, DrawFrameControl( hdc, &r, DFC_SCROLL, (vertical ? DFCS_SCROLLUP : DFCS_SCROLLLEFT) | (top_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0 ) - | (infoPtr->flags&ESB_DISABLE_LTUP ? DFCS_INACTIVE : 0 ) ); + | (flags & ESB_DISABLE_LTUP ? DFCS_INACTIVE : 0 ) );
r = *rect; if( vertical ) @@ -151,7 +151,7 @@ static void SCROLL_DrawArrows( HDC hdc, SCROLLBAR_INFO *infoPtr, DrawFrameControl( hdc, &r, DFC_SCROLL, (vertical ? DFCS_SCROLLDOWN : DFCS_SCROLLRIGHT) | (bottom_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0 ) - | (infoPtr->flags&ESB_DISABLE_RTDN ? DFCS_INACTIVE : 0) ); + | (flags & ESB_DISABLE_RTDN ? DFCS_INACTIVE : 0) ); }
/*********************************************************************** @@ -161,8 +161,7 @@ static void SCROLL_DrawArrows( HDC hdc, SCROLLBAR_INFO *infoPtr, */ static void SCROLL_DrawInterior( HWND hwnd, HDC hdc, INT nBar, RECT *rect, INT arrowSize, - INT thumbSize, INT thumbPos, - UINT flags, BOOL vertical, + INT thumbSize, INT thumbPos, BOOL vertical, BOOL top_selected, BOOL bottom_selected ) { RECT r; @@ -247,11 +246,9 @@ static void SCROLL_DrawInterior( HWND hwnd, HDC hdc, INT nBar,
void WINAPI USER_ScrollBarDraw( HWND hwnd, HDC hdc, INT nBar, enum SCROLL_HITTEST hit_test, const struct SCROLL_TRACKING_INFO *tracking_info, BOOL arrows, - BOOL interior, RECT *rect, INT arrowSize, INT thumbPos, - INT thumbSize, BOOL vertical ) + BOOL interior, RECT *rect, UINT enable_flags, INT arrowSize, + INT thumbPos, INT thumbSize, BOOL vertical ) { - SCROLLBAR_INFO *infoPtr; - if (nBar == SB_CTL) { DWORD style = GetWindowLongW( hwnd, GWL_STYLE ); @@ -274,34 +271,29 @@ void WINAPI USER_ScrollBarDraw( HWND hwnd, HDC hdc, INT nBar, enum SCROLL_HITTES } }
- if (!(infoPtr = SCROLL_GetInternalInfo( hwnd, nBar, TRUE ))) - return; - - /* Draw the arrows */ - + /* Draw the arrows */ if (arrows && arrowSize) { if (vertical == tracking_info->vertical && GetCapture() == hwnd) - SCROLL_DrawArrows( hdc, infoPtr, rect, arrowSize, vertical, + SCROLL_DrawArrows( hdc, enable_flags, rect, arrowSize, vertical, hit_test == tracking_info->hit_test && hit_test == SCROLL_TOP_ARROW, hit_test == tracking_info->hit_test && hit_test == SCROLL_BOTTOM_ARROW ); else - SCROLL_DrawArrows( hdc, infoPtr, rect, arrowSize, vertical, FALSE, FALSE ); + SCROLL_DrawArrows( hdc, enable_flags, rect, arrowSize, vertical, FALSE, FALSE ); }
if (interior) { if (vertical == tracking_info->vertical && GetCapture() == hwnd) { - SCROLL_DrawInterior( hwnd, hdc, nBar, rect, arrowSize, thumbSize, thumbPos, - infoPtr->flags, vertical, + SCROLL_DrawInterior( hwnd, hdc, nBar, rect, arrowSize, thumbSize, thumbPos, vertical, hit_test == tracking_info->hit_test && hit_test == SCROLL_TOP_RECT, hit_test == tracking_info->hit_test && hit_test == SCROLL_BOTTOM_RECT ); } else { SCROLL_DrawInterior( hwnd, hdc, nBar, rect, arrowSize, thumbSize, thumbPos, - infoPtr->flags, vertical, FALSE, FALSE ); + vertical, FALSE, FALSE ); } }
diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index b6c8f26cec6..fb9ce74736d 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -178,7 +178,7 @@ static NTSTATUS WINAPI User32DrawScrollBar( const struct draw_scroll_bar_params RECT rect = params->rect; user_api->pScrollBarDraw( params->hwnd, params->hdc, params->bar, params->hit_test, ¶ms->tracking_info, params->arrows, params->interior, - &rect, params->arrow_size, params->thumb_pos, + &rect, params->enable_flags, params->arrow_size, params->thumb_pos, params->thumb_size, params->vertical ); return 0; } diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index f34818ea258..3be5b84b41b 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -177,8 +177,8 @@ extern struct user_api_hook *user_api DECLSPEC_HIDDEN; LRESULT WINAPI USER_DefDlgProc(HWND, UINT, WPARAM, LPARAM, BOOL) DECLSPEC_HIDDEN; LRESULT WINAPI USER_ScrollBarProc(HWND, UINT, WPARAM, LPARAM, BOOL) DECLSPEC_HIDDEN; void WINAPI USER_ScrollBarDraw(HWND, HDC, INT, enum SCROLL_HITTEST, - const struct SCROLL_TRACKING_INFO *, BOOL, BOOL, RECT *, INT, INT, - INT, BOOL) DECLSPEC_HIDDEN; + const struct SCROLL_TRACKING_INFO *, BOOL, BOOL, RECT *, UINT, + INT, INT, INT, BOOL) DECLSPEC_HIDDEN; struct scroll_info *SCROLL_GetInternalInfo( HWND hwnd, INT nBar, BOOL alloc );
#endif /* __WINE_USER_PRIVATE_H */ diff --git a/dlls/uxtheme/scrollbar.c b/dlls/uxtheme/scrollbar.c index 719081ad5b8..4ae1b2a8724 100644 --- a/dlls/uxtheme/scrollbar.c +++ b/dlls/uxtheme/scrollbar.c @@ -34,8 +34,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(theme_scroll);
void WINAPI UXTHEME_ScrollBarDraw(HWND hwnd, HDC dc, INT bar, enum SCROLL_HITTEST hit_test, const struct SCROLL_TRACKING_INFO *tracking_info, - BOOL draw_arrows, BOOL draw_interior, RECT *rect, INT arrowsize, - INT thumbpos, INT thumbsize, BOOL vertical) + BOOL draw_arrows, BOOL draw_interior, RECT *rect, UINT enable_flags, + INT arrowsize, INT thumbpos, INT thumbsize, BOOL vertical) { BOOL disabled = !IsWindowEnabled(hwnd); HTHEME theme; @@ -49,7 +49,7 @@ void WINAPI UXTHEME_ScrollBarDraw(HWND hwnd, HDC dc, INT bar, enum SCROLL_HITTES if (!theme) { user_api.pScrollBarDraw(hwnd, dc, bar, hit_test, tracking_info, draw_arrows, draw_interior, - rect, arrowsize, thumbpos, thumbsize, vertical); + rect, enable_flags, arrowsize, thumbpos, thumbsize, vertical); return; }
diff --git a/dlls/uxtheme/uxthemedll.h b/dlls/uxtheme/uxthemedll.h index 67130774392..85b834e20e8 100644 --- a/dlls/uxtheme/uxthemedll.h +++ b/dlls/uxtheme/uxthemedll.h @@ -109,8 +109,8 @@ extern struct user_api_hook user_api DECLSPEC_HIDDEN; LRESULT WINAPI UXTHEME_DefDlgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL unicode) DECLSPEC_HIDDEN; void WINAPI UXTHEME_ScrollBarDraw(HWND hwnd, HDC dc, INT bar, enum SCROLL_HITTEST hit_test, const struct SCROLL_TRACKING_INFO *tracking_info, - BOOL draw_arrows, BOOL draw_interior, RECT *rect, INT arrowsize, - INT thumbpos, INT thumbsize, BOOL vertical) DECLSPEC_HIDDEN; + BOOL draw_arrows, BOOL draw_interior, RECT *rect, UINT enable_flags, + INT arrowsize, INT thumbpos, INT thumbsize, BOOL vertical) DECLSPEC_HIDDEN; LRESULT WINAPI UXTHEME_ScrollbarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode) DECLSPEC_HIDDEN;
diff --git a/include/winuser.h b/include/winuser.h index 4e43d6c1170..d2262b6d70a 100644 --- a/include/winuser.h +++ b/include/winuser.h @@ -4789,8 +4789,8 @@ struct user_api_hook { LRESULT (WINAPI *pDefDlgProc)(HWND, UINT, WPARAM, LPARAM, BOOL); void (WINAPI *pScrollBarDraw)(HWND, HDC, INT, enum SCROLL_HITTEST, - const struct SCROLL_TRACKING_INFO *, BOOL, BOOL, RECT *, INT, INT, - INT, BOOL); + const struct SCROLL_TRACKING_INFO *, BOOL, BOOL, RECT *, UINT, + INT, INT, INT, BOOL); LRESULT (WINAPI *pScrollBarWndProc)(HWND, UINT, WPARAM, LPARAM, BOOL); };
This merge request was approved by Huw Davies.