[PATCH 0/2] MR11064: user32: Set FNID for the builtin scrollbar window class.
This adds a todo_wine on the comctl32 scrollbar test as the comctl32 class is supposed to be duplicated from the user32 class instead of reusing it. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11064
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/class.c | 2 +- dlls/win32u/ntuser_private.h | 6 ------ dlls/win32u/scroll.c | 33 ++++++++++++--------------------- 3 files changed, 13 insertions(+), 28 deletions(-) diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 3d050dfed87..bc8d6a9d5d2 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -69,7 +69,7 @@ static struct builtin_class_descr builtin_classes[] = { .name = "ScrollBar", .style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC, - .extra = sizeof(struct scroll_bar_win_data), + .extra = sizeof(struct scroll_info *), .cursor = IDC_ARROW, }, [NTUSER_WNDPROC_MESSAGE] = diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 1929a7e2cd6..45545dcd554 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -157,12 +157,6 @@ struct scroll_info BOOL painted; /* Whether the scroll bar is painted by DefWinProc() */ }; -struct scroll_bar_win_data -{ - DWORD magic; - struct scroll_info info; -}; - #define WINPROC_HANDLE (~0u >> 16) #define BUILTIN_WINPROC(index) ((WNDPROC)(ULONG_PTR)((index) | (WINPROC_HANDLE << 16))) diff --git a/dlls/win32u/scroll.c b/dlls/win32u/scroll.c index 052a571194f..d572ea94ed5 100644 --- a/dlls/win32u/scroll.c +++ b/dlls/win32u/scroll.c @@ -29,8 +29,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(scroll); +static struct scroll_info *get_control_state( HWND hwnd ) +{ + return (struct scroll_info *)NtUserGetPrivateData( hwnd, 0, sizeof(struct scroll_info *) ); +} -#define SCROLLBAR_MAGIC 0x5c6011ba +static struct scroll_info *set_control_state( HWND hwnd, struct scroll_info *state ) +{ + return (struct scroll_info *)NtUserSetPrivateData( hwnd, 0, sizeof(struct scroll_info *), (LONG_PTR)state ); +} /* Minimum size of the rectangle between the arrows */ #define SCROLL_MIN_RECT 4 @@ -72,8 +79,6 @@ struct win_scroll_bar_info struct scroll_info vert; }; -#define SCROLLBAR_MAGIC 0x5c6011ba - static struct scroll_info *get_scroll_info_ptr( HWND hwnd, int bar, BOOL alloc ) { @@ -91,12 +96,7 @@ static struct scroll_info *get_scroll_info_ptr( HWND hwnd, int bar, BOOL alloc ) if (win->pScroll) info = &win->pScroll->vert; break; case SB_CTL: - if (win->cbWndExtra >= sizeof(struct scroll_bar_win_data)) - { - struct scroll_bar_win_data *data = (struct scroll_bar_win_data *)win->wExtra; - if (data->magic == SCROLLBAR_MAGIC) info = &data->info; - } - if (!info) WARN( "window is not a scrollbar control\n" ); + if (!(info = get_control_state( hwnd ))) WARN( "window is not a scrollbar control\n" ); break; case SB_BOTH: WARN( "with SB_BOTH\n" ); @@ -1130,21 +1130,12 @@ static BOOL get_scroll_bar_info( HWND hwnd, LONG id, SCROLLBARINFO *info ) static void create_scroll_bar( HWND hwnd, CREATESTRUCTW *create ) { - struct scroll_info *info = NULL; - WND *win; + struct scroll_info *info; 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 (!(info = calloc( 1, sizeof(*info) ))) return; + set_control_state( hwnd, info ); if (create->style & WS_DISABLED) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11064
From: Rémi Bernon <rbernon@codeweavers.com> This adds a todo_wine on the comctl32 scrollbar test as the comctl32 class is supposed to be duplicated from the user32 class instead of reusing it. --- dlls/comctl32/tests/misc.c | 8 +++++--- dlls/user32/tests/class.c | 2 +- dlls/win32u/scroll.c | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/dlls/comctl32/tests/misc.c b/dlls/comctl32/tests/misc.c index 83dc93eaed3..8f578e7fca8 100644 --- a/dlls/comctl32/tests/misc.c +++ b/dlls/comctl32/tests/misc.c @@ -430,7 +430,9 @@ static void check_real_class_name_( int line, HWND hwnd, const char *expect ) ok_(__FILE__, line)( len == wcslen( expectW ), "got %ld\n", len ); } -static void check_class( const char *name, int must_exist, UINT style, UINT ignore, BOOL v6, DWORD classnameidx, BOOL classnameidx_todo ) +#define check_class( a, b, c, d, e, f, g ) check_class_( a, b, c, d, e, f, g, FALSE ) +static void check_class_( const char *name, int must_exist, UINT style, UINT ignore, BOOL v6, + DWORD classnameidx, BOOL classnameidx_todo, BOOL name_todo ) { WNDCLASSA wc; @@ -476,7 +478,7 @@ static void check_class( const char *name, int must_exist, UINT style, UINT igno RegisterClassA( &wc ); hwnd = CreateWindowA( wc.lpszClassName, 0, 0, 0, 0, 0, 0, 0, NULL, GetModuleHandleA( NULL ), 0 ); - check_real_class_name( hwnd, wc.lpszClassName ); + todo_wine_if( name_todo ) check_real_class_name( hwnd, wc.lpszClassName ); DestroyWindow( hwnd ); UnregisterClassA( wc.lpszClassName, GetModuleHandleA( NULL ) ); @@ -495,7 +497,7 @@ static void test_builtin_classes(void) check_class( "ComboBox", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS, 0, FALSE, 0x10005, FALSE ); check_class( "Edit", 1, CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS, 0, FALSE, 0x10004, FALSE ); check_class( "ListBox", 1, CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS, 0, FALSE, 0x10000, FALSE ); - check_class( "ScrollBar", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS, 0, FALSE, 0x1000a, FALSE ); + check_class_( "ScrollBar", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS, 0, FALSE, 0x1000a, FALSE, TRUE ); check_class( "Static", 1, CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS, 0, FALSE, 0x10003, FALSE ); check_class( "ComboLBox", 1, CS_SAVEBITS | CS_DBLCLKS | CS_DROPSHADOW | CS_GLOBALCLASS, CS_DROPSHADOW, FALSE, 0x10000, FALSE ); } diff --git a/dlls/user32/tests/class.c b/dlls/user32/tests/class.c index a554891f4a6..aa9a8e5003e 100644 --- a/dlls/user32/tests/class.c +++ b/dlls/user32/tests/class.c @@ -2524,7 +2524,7 @@ static const struct real_class_test class_tests[] = { "ComboBox", "ComboBox", FALSE, TRUE, TRUE, TRUE, FALSE }, { "Edit", "Edit", FALSE, FALSE, TRUE, TRUE, FALSE }, { "ListBox", "ListBox", FALSE, TRUE, TRUE, TRUE, FALSE }, - { "ScrollBar", "ScrollBar", FALSE, TRUE, FALSE, TRUE, TRUE }, + { "ScrollBar", "ScrollBar", FALSE, TRUE, FALSE, TRUE, FALSE }, { "Static", "Static", TRUE, TRUE, TRUE, TRUE, FALSE }, { "ComboLBox", "ListBox", FALSE, TRUE, TRUE, TRUE, FALSE }, { "MDIClient", "MDIClient", TRUE, TRUE, TRUE, TRUE, FALSE }, diff --git a/dlls/win32u/scroll.c b/dlls/win32u/scroll.c index d572ea94ed5..00450c20709 100644 --- a/dlls/win32u/scroll.c +++ b/dlls/win32u/scroll.c @@ -1135,6 +1135,7 @@ static void create_scroll_bar( HWND hwnd, CREATESTRUCTW *create ) TRACE( "hwnd=%p create=%p\n", hwnd, create ); if (!(info = calloc( 1, sizeof(*info) ))) return; + NtUserSetWindowFNID( hwnd, MAKE_FNID(NTUSER_WNDPROC_SCROLLBAR) ); set_control_state( hwnd, info ); if (create->style & WS_DISABLED) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11064
Fwiw the FNID is actually already set since 2c742fc061edb36280e7615efd50cf8dfe886b1d by the builtin class registration, it worked because wExtra was accessed directly from the window data, bypassing the private control info size checks. This first make sure we use NtUser(Get|Set)PrivateData instead. Regarding comctl32, I wasn't sure how to copy the class to comctl32_v6, it looks complicated, perhaps with some interactions with uxtheme. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11064#note_142185
This merge request was approved by Zhiyi Zhang. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11064
participants (3)
-
Rémi Bernon -
Rémi Bernon (@rbernon) -
Zhiyi Zhang (@zhiyi)