diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 27a83dc662b..5867b6b4009 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -1866,9 +1866,6 @@ LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar return ShowWindow( hwnd, wparam ); case WM_WINE_SETWINDOWLONG: return WIN_SetWindowLong( hwnd, (short)LOWORD(wparam), HIWORD(wparam), lparam, TRUE ); - case WM_WINE_SETSTYLE: - if (is_desktop_window( hwnd )) return 0; - return WIN_SetStyle(hwnd, wparam, lparam); default: { MSG m; diff --git a/dlls/user32/win.c b/dlls/user32/win.c index ca4697713d6..bb6df478b1b 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -668,51 +668,10 @@ static HWND WIN_SetOwner( HWND hwnd, HWND owner ) */ ULONG WIN_SetStyle( HWND hwnd, ULONG set_bits, ULONG clear_bits ) { - BOOL ok, made_visible = FALSE; - STYLESTRUCT style; - WND *win = WIN_GetPtr( hwnd ); - - if (!win || win == WND_DESKTOP) return 0; - if (win == WND_OTHER_PROCESS) - { - if (IsWindow(hwnd)) - return SendMessageW(hwnd, WM_WINE_SETSTYLE, set_bits, clear_bits); - return 0; - } - style.styleOld = win->dwStyle; - style.styleNew = (win->dwStyle | set_bits) & ~clear_bits; - if (style.styleNew == style.styleOld) - { - WIN_ReleasePtr( win ); - return style.styleNew; - } - SERVER_START_REQ( set_window_info ) - { - req->handle = wine_server_user_handle( hwnd ); - req->flags = SET_WIN_STYLE; - req->style = style.styleNew; - req->extra_offset = -1; - if ((ok = !wine_server_call( req ))) - { - style.styleOld = reply->old_style; - win->dwStyle = style.styleNew; - } - } - SERVER_END_REQ; - - if (ok && ((style.styleOld ^ style.styleNew) & WS_VISIBLE)) - { - made_visible = (style.styleNew & WS_VISIBLE) != 0; - invalidate_dce( win, NULL ); - } - WIN_ReleasePtr( win ); - - if (!ok) return 0; - - USER_Driver->pSetWindowStyle( hwnd, GWL_STYLE, &style ); - if (made_visible) update_window_state( hwnd ); - - return style.styleOld; + /* FIXME: Use SetWindowLong or move callers to win32u instead. + * We use STYLESTRUCT to pass params, but meaning of its field does not match our usage. */ + STYLESTRUCT style = { .styleNew = set_bits, .styleOld = clear_bits }; + return NtUserCallHwndParam( hwnd, (UINT_PTR)&style, NtUserSetWindowStyle ); } diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 56fce1c6496..afe44e1c4a3 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -1196,6 +1196,7 @@ static const struct user_driver_funcs lazy_load_driver = .pSetLayeredWindowAttributes = loaderdrv_SetLayeredWindowAttributes, .pSetParent = nulldrv_SetParent, .pSetWindowRgn = loaderdrv_SetWindowRgn, + .pSetWindowStyle = nulldrv_SetWindowStyle, .pMsgWaitForMultipleObjectsEx = nulldrv_MsgWaitForMultipleObjectsEx, .pReleaseDC = nulldrv_ReleaseDC, .pScrollDC = nulldrv_ScrollDC, diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 5582f627166..1f0d6e6c297 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -47,6 +47,9 @@ LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar case WM_WINE_SETPARENT: if (is_desktop_window( hwnd )) return 0; return HandleToUlong( NtUserSetParent( hwnd, UlongToHandle(wparam) )); + case WM_WINE_SETSTYLE: + if (is_desktop_window( hwnd )) return 0; + return set_window_style( hwnd, wparam, lparam ); case WM_WINE_SETACTIVEWINDOW: if (!wparam && NtUserGetForegroundWindow() == hwnd) return 0; return (LRESULT)NtUserSetActiveWindow( (HWND)wparam ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index ac40daa5d35..67df4490bf3 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -361,6 +361,7 @@ extern int map_window_points( HWND hwnd_from, HWND hwnd_to, POINT *points, UINT UINT dpi ) DECLSPEC_HIDDEN; extern void map_window_region( HWND from, HWND to, HRGN hrgn ) DECLSPEC_HIDDEN; extern BOOL set_window_pos( WINDOWPOS *winpos, int parent_x, int parent_y ) DECLSPEC_HIDDEN; +extern ULONG set_window_style( HWND hwnd, ULONG set_bits, ULONG clear_bits ) DECLSPEC_HIDDEN; extern void update_window_state( HWND hwnd ) DECLSPEC_HIDDEN; /* to release pointers retrieved by win_get_ptr */ diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index c3da53d08e4..01b1f15d158 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1050,6 +1050,60 @@ static WORD get_window_word( HWND hwnd, INT offset ) return get_window_long_size( hwnd, offset, sizeof(WORD), TRUE ); } +/*********************************************************************** + * set_window_style + * + * Change the style of a window. + */ +ULONG set_window_style( HWND hwnd, ULONG set_bits, ULONG clear_bits ) +{ + BOOL ok, made_visible = FALSE; + STYLESTRUCT style; + WND *win = get_win_ptr( hwnd ); + + if (!win || win == WND_DESKTOP) return 0; + if (win == WND_OTHER_PROCESS) + { + if (is_window(hwnd)) + return send_message( hwnd, WM_WINE_SETSTYLE, set_bits, clear_bits ); + return 0; + } + style.styleOld = win->dwStyle; + style.styleNew = (win->dwStyle | set_bits) & ~clear_bits; + if (style.styleNew == style.styleOld) + { + release_win_ptr( win ); + return style.styleNew; + } + SERVER_START_REQ( set_window_info ) + { + req->handle = wine_server_user_handle( hwnd ); + req->flags = SET_WIN_STYLE; + req->style = style.styleNew; + req->extra_offset = -1; + if ((ok = !wine_server_call( req ))) + { + style.styleOld = reply->old_style; + win->dwStyle = style.styleNew; + } + } + SERVER_END_REQ; + + if (ok && ((style.styleOld ^ style.styleNew) & WS_VISIBLE)) + { + made_visible = (style.styleNew & WS_VISIBLE) != 0; + invalidate_dce( win, NULL ); + } + release_win_ptr( win ); + + if (!ok) return 0; + + user_driver->pSetWindowStyle( hwnd, GWL_STYLE, &style ); + if (made_visible) update_window_state( hwnd ); + + return style.styleOld; +} + /*********************************************************************** * NtUserGetProp (win32u.@) * @@ -2954,6 +3008,11 @@ ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code ) /* temporary exports */ case NtUserIsWindowDrawable: return is_window_drawable( hwnd, param ); + case NtUserSetWindowStyle: + { + STYLESTRUCT *style = (void *)param; + return set_window_style( hwnd, style->styleNew, style->styleOld ); + } default: FIXME( "invalid code %u\n", code ); return 0; diff --git a/include/ntuser.h b/include/ntuser.h index f68f5481f90..96f61d2a07a 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -183,6 +183,7 @@ enum NtUserSetForegroundWindow, /* temporary exports */ NtUserIsWindowDrawable, + NtUserSetWindowStyle, }; /* NtUserMessageCall codes */