win32u: Move NtUsetSetWindowLong implementation from user32.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2022-03-16 15:35:25 +01:00 committed by Alexandre Julliard
parent 895ef97bc0
commit 1b847dff82
14 changed files with 369 additions and 316 deletions

View file

@ -95,10 +95,6 @@ static void CDECL nulldrv_SetWindowIcon( HWND hwnd, UINT type, HICON icon )
{
}
static void CDECL nulldrv_SetWindowStyle( HWND hwnd, INT offset, STYLESTRUCT *style )
{
}
static void CDECL nulldrv_SetWindowText( HWND hwnd, LPCWSTR text )
{
}
@ -190,7 +186,7 @@ static struct user_driver_funcs lazy_load_driver =
NULL,
NULL,
nulldrv_SetWindowIcon,
nulldrv_SetWindowStyle,
NULL,
nulldrv_SetWindowText,
nulldrv_ShowWindow,
nulldrv_SysCommand,
@ -230,7 +226,6 @@ void CDECL __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT v
SET_USER_FUNC(DestroyWindow);
SET_USER_FUNC(MsgWaitForMultipleObjectsEx);
SET_USER_FUNC(SetWindowIcon);
SET_USER_FUNC(SetWindowStyle);
SET_USER_FUNC(SetWindowText);
SET_USER_FUNC(ShowWindow);
SET_USER_FUNC(SysCommand);

View file

@ -1864,8 +1864,6 @@ LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
case WM_WINE_SHOWWINDOW:
if (is_desktop_window( hwnd )) return 0;
return ShowWindow( hwnd, wparam );
case WM_WINE_SETWINDOWLONG:
return WIN_SetWindowLong( hwnd, (short)LOWORD(wparam), HIWORD(wparam), lparam, TRUE );
default:
{
MSG m;

View file

@ -730,7 +730,7 @@
@ stdcall SetWindowStationUser(long long)
@ stdcall SetWindowTextA(long str)
@ stdcall SetWindowTextW(long wstr)
@ stdcall SetWindowWord(long long long)
@ stdcall SetWindowWord(long long long) NtUserSetWindowWord
@ stdcall SetWindowsHookA(long ptr)
@ stdcall SetWindowsHookExA(long long long long)
@ stdcall SetWindowsHookExW(long long long long)

View file

@ -39,51 +39,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(win);
static DWORD process_layout = ~0u;
/**********************************************************************/
/* helper for Get/SetWindowLong */
static inline LONG_PTR get_win_data( const void *ptr, UINT size )
{
if (size == sizeof(WORD))
{
WORD ret;
memcpy( &ret, ptr, sizeof(ret) );
return ret;
}
else if (size == sizeof(DWORD))
{
DWORD ret;
memcpy( &ret, ptr, sizeof(ret) );
return ret;
}
else
{
LONG_PTR ret;
memcpy( &ret, ptr, sizeof(ret) );
return ret;
}
}
/* helper for Get/SetWindowLong */
static inline void set_win_data( void *ptr, LONG_PTR val, UINT size )
{
if (size == sizeof(WORD))
{
WORD newval = val;
memcpy( ptr, &newval, sizeof(newval) );
}
else if (size == sizeof(DWORD))
{
DWORD newval = val;
memcpy( ptr, &newval, sizeof(newval) );
}
else
{
memcpy( ptr, &val, sizeof(val) );
}
}
/***********************************************************************
* alloc_user_handle
*/
@ -1994,236 +1949,6 @@ UINT WINAPI GetDpiForWindow( HWND hwnd )
}
/**********************************************************************
* WIN_SetWindowLong
*
* Helper function for SetWindowLong().
*
* 0 is the failure code. However, in the case of failure SetLastError
* must be set to distinguish between a 0 return value and a failure.
*/
LONG_PTR WIN_SetWindowLong( HWND hwnd, INT offset, UINT size, LONG_PTR newval, BOOL unicode )
{
STYLESTRUCT style;
BOOL ok, made_visible = FALSE;
LONG_PTR retval = 0;
WND *wndPtr;
TRACE( "%p %d %lx %c\n", hwnd, offset, newval, unicode ? 'W' : 'A' );
if (is_broadcast(hwnd))
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (!(wndPtr = WIN_GetPtr( hwnd )))
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
if (wndPtr == WND_DESKTOP)
{
/* can't change anything on the desktop window */
SetLastError( ERROR_ACCESS_DENIED );
return 0;
}
if (wndPtr == WND_OTHER_PROCESS)
{
if (offset == GWLP_WNDPROC)
{
SetLastError( ERROR_ACCESS_DENIED );
return 0;
}
if (offset > 32767 || offset < -32767)
{
SetLastError( ERROR_INVALID_INDEX );
return 0;
}
return SendMessageW( hwnd, WM_WINE_SETWINDOWLONG, MAKEWPARAM( offset, size ), newval );
}
/* first some special cases */
switch( offset )
{
case GWL_STYLE:
style.styleOld = wndPtr->dwStyle;
style.styleNew = newval;
WIN_ReleasePtr( wndPtr );
SendMessageW( hwnd, WM_STYLECHANGING, GWL_STYLE, (LPARAM)&style );
if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
newval = style.styleNew;
/* WS_CLIPSIBLINGS can't be reset on top-level windows */
if (wndPtr->parent == GetDesktopWindow()) newval |= WS_CLIPSIBLINGS;
/* WS_MINIMIZE can't be reset */
if (wndPtr->dwStyle & WS_MINIMIZE) newval |= WS_MINIMIZE;
break;
case GWL_EXSTYLE:
style.styleOld = wndPtr->dwExStyle;
style.styleNew = newval;
WIN_ReleasePtr( wndPtr );
SendMessageW( hwnd, WM_STYLECHANGING, GWL_EXSTYLE, (LPARAM)&style );
if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
/* WS_EX_TOPMOST can only be changed through SetWindowPos */
newval = (style.styleNew & ~WS_EX_TOPMOST) | (wndPtr->dwExStyle & WS_EX_TOPMOST);
newval = fix_exstyle(wndPtr->dwStyle, newval);
break;
case GWLP_HWNDPARENT:
if (wndPtr->parent == GetDesktopWindow())
{
WIN_ReleasePtr( wndPtr );
return (ULONG_PTR)WIN_SetOwner( hwnd, (HWND)newval );
}
else
{
WIN_ReleasePtr( wndPtr );
return (ULONG_PTR)NtUserSetParent( hwnd, (HWND)newval );
}
case GWLP_WNDPROC:
{
WNDPROC proc;
UINT old_flags = wndPtr->flags;
retval = unicode ? GetWindowLongPtrW( hwnd, offset ) : GetWindowLongPtrA( hwnd, offset );
proc = WINPROC_AllocProc( (WNDPROC)newval, unicode );
if (proc) wndPtr->winproc = proc;
if (WINPROC_IsUnicode( proc, unicode )) wndPtr->flags |= WIN_ISUNICODE;
else wndPtr->flags &= ~WIN_ISUNICODE;
if (!((old_flags ^ wndPtr->flags) & WIN_ISUNICODE))
{
WIN_ReleasePtr( wndPtr );
return retval;
}
/* update is_unicode flag on the server side */
break;
}
case GWLP_ID:
case GWLP_HINSTANCE:
case GWLP_USERDATA:
break;
case DWLP_DLGPROC:
if ((wndPtr->cbWndExtra - sizeof(LONG_PTR) >= DWLP_DLGPROC) &&
(size == sizeof(LONG_PTR)) && wndPtr->dlgInfo)
{
WNDPROC *ptr = (WNDPROC *)((char *)wndPtr->wExtra + DWLP_DLGPROC);
retval = (ULONG_PTR)WINPROC_GetProc( *ptr, unicode );
*ptr = WINPROC_AllocProc( (WNDPROC)newval, unicode );
WIN_ReleasePtr( wndPtr );
return retval;
}
/* fall through */
default:
if (offset < 0 || offset > (int)(wndPtr->cbWndExtra - size))
{
WARN("Invalid offset %d\n", offset );
WIN_ReleasePtr( wndPtr );
SetLastError( ERROR_INVALID_INDEX );
return 0;
}
else if (get_win_data( (char *)wndPtr->wExtra + offset, size ) == newval)
{
/* already set to the same value */
WIN_ReleasePtr( wndPtr );
return newval;
}
break;
}
SERVER_START_REQ( set_window_info )
{
req->handle = wine_server_user_handle( hwnd );
req->extra_offset = -1;
switch(offset)
{
case GWL_STYLE:
req->flags = SET_WIN_STYLE | SET_WIN_EXSTYLE;
req->style = newval;
req->ex_style = fix_exstyle(newval, wndPtr->dwExStyle);
break;
case GWL_EXSTYLE:
req->flags = SET_WIN_EXSTYLE;
req->ex_style = newval;
break;
case GWLP_ID:
req->flags = SET_WIN_ID;
req->extra_value = newval;
break;
case GWLP_HINSTANCE:
req->flags = SET_WIN_INSTANCE;
req->instance = wine_server_client_ptr( (void *)newval );
break;
case GWLP_WNDPROC:
req->flags = SET_WIN_UNICODE;
req->is_unicode = (wndPtr->flags & WIN_ISUNICODE) != 0;
break;
case GWLP_USERDATA:
req->flags = SET_WIN_USERDATA;
req->user_data = newval;
break;
default:
req->flags = SET_WIN_EXTRA;
req->extra_offset = offset;
req->extra_size = size;
set_win_data( &req->extra_value, newval, size );
}
if ((ok = !wine_server_call_err( req )))
{
switch(offset)
{
case GWL_STYLE:
wndPtr->dwStyle = newval;
wndPtr->dwExStyle = fix_exstyle(wndPtr->dwStyle, wndPtr->dwExStyle);
retval = reply->old_style;
break;
case GWL_EXSTYLE:
wndPtr->dwExStyle = newval;
retval = reply->old_ex_style;
break;
case GWLP_ID:
wndPtr->wIDmenu = newval;
retval = reply->old_id;
break;
case GWLP_HINSTANCE:
wndPtr->hInstance = (HINSTANCE)newval;
retval = (ULONG_PTR)wine_server_get_ptr( reply->old_instance );
break;
case GWLP_WNDPROC:
break;
case GWLP_USERDATA:
wndPtr->userdata = newval;
retval = reply->old_user_data;
break;
default:
retval = get_win_data( (char *)wndPtr->wExtra + offset, size );
set_win_data( (char *)wndPtr->wExtra + offset, newval, size );
break;
}
}
}
SERVER_END_REQ;
if ((offset == GWL_STYLE && ((style.styleOld ^ style.styleNew) & WS_VISIBLE)) ||
(offset == GWL_EXSTYLE && ((style.styleOld ^ style.styleNew) & WS_EX_LAYERED)))
{
made_visible = (wndPtr->dwStyle & WS_VISIBLE) != 0;
invalidate_dce( wndPtr, NULL );
}
WIN_ReleasePtr( wndPtr );
if (!ok) return 0;
if (offset == GWL_STYLE || offset == GWL_EXSTYLE)
{
style.styleOld = retval;
style.styleNew = newval;
USER_Driver->pSetWindowStyle( hwnd, offset, &style );
if (made_visible) update_window_state( hwnd );
SendMessageW( hwnd, WM_STYLECHANGED, offset, (LPARAM)&style );
}
return retval;
}
/**********************************************************************
* GetWindowWord (USER32.@)
*/
@ -2275,30 +2000,6 @@ LONG WINAPI GetWindowLongW( HWND hwnd, INT offset )
}
/**********************************************************************
* SetWindowWord (USER32.@)
*/
WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval )
{
switch(offset)
{
case GWLP_ID:
case GWLP_HINSTANCE:
case GWLP_HWNDPARENT:
break;
default:
if (offset < 0)
{
WARN("Invalid offset %d\n", offset );
SetLastError( ERROR_INVALID_INDEX );
return 0;
}
break;
}
return WIN_SetWindowLong( hwnd, offset, sizeof(WORD), newval, FALSE );
}
/**********************************************************************
* SetWindowLongA (USER32.@)
*
@ -2317,7 +2018,7 @@ LONG WINAPI DECLSPEC_HOTPATCH SetWindowLongA( HWND hwnd, INT offset, LONG newval
return 0;
#endif
default:
return WIN_SetWindowLong( hwnd, offset, sizeof(LONG), newval, FALSE );
return NtUserSetWindowLong( hwnd, offset, newval, TRUE );
}
}
@ -2405,7 +2106,7 @@ LONG WINAPI DECLSPEC_HOTPATCH SetWindowLongW(
return 0;
#endif
default:
return WIN_SetWindowLong( hwnd, offset, sizeof(LONG), newval, TRUE );
return NtUserSetWindowLong( hwnd, offset, newval, FALSE );
}
}
@ -3185,7 +2886,7 @@ LONG_PTR WINAPI GetWindowLongPtrA( HWND hwnd, INT offset )
*/
LONG_PTR WINAPI SetWindowLongPtrW( HWND hwnd, INT offset, LONG_PTR newval )
{
return WIN_SetWindowLong( hwnd, offset, sizeof(LONG_PTR), newval, TRUE );
return NtUserSetWindowLongPtr( hwnd, offset, newval, FALSE );
}
/*****************************************************************************
@ -3193,7 +2894,7 @@ LONG_PTR WINAPI SetWindowLongPtrW( HWND hwnd, INT offset, LONG_PTR newval )
*/
LONG_PTR WINAPI SetWindowLongPtrA( HWND hwnd, INT offset, LONG_PTR newval )
{
return WIN_SetWindowLong( hwnd, offset, sizeof(LONG_PTR), newval, FALSE );
return NtUserSetWindowLongPtr( hwnd, offset, newval, TRUE );
}
/*****************************************************************************

View file

@ -50,7 +50,6 @@ extern void destroy_thread_windows(void) 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 LONG_PTR WIN_SetWindowLong( HWND hwnd, INT offset, UINT size, LONG_PTR newval, BOOL unicode ) 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;

View file

@ -152,6 +152,17 @@ WNDPROC get_winproc( WNDPROC proc, BOOL ansi )
}
}
/* Return the window procedure type, or the default value if not a winproc handle. */
BOOL is_winproc_unicode( WNDPROC proc, BOOL def_val )
{
WINDOWPROC *ptr = get_winproc_ptr( proc );
if (!ptr) return def_val;
if (ptr == WINPROC_PROC16) return FALSE; /* 16-bit is always A */
if (ptr->procA && ptr->procW) return def_val; /* can be both */
return ptr->procW != NULL;
}
/***********************************************************************
* NtUserInitializeClientPfnArrays (win32u.@)
*/

View file

@ -1203,8 +1203,11 @@ static struct unix_funcs unix_funcs =
NtUserSetLayeredWindowAttributes,
NtUserSetParent,
NtUserSetSysColors,
NtUserSetWindowLong,
NtUserSetWindowLongPtr,
NtUserSetWindowPos,
NtUserSetWindowRgn,
NtUserSetWindowWord,
NtUserShowCursor,
NtUserSystemParametersInfo,
NtUserSystemParametersInfoForDpi,

View file

@ -47,6 +47,8 @@ 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_SETWINDOWLONG:
return set_window_long( hwnd, (short)LOWORD(wparam), HIWORD(wparam), lparam, FALSE );
case WM_WINE_SETSTYLE:
if (is_desktop_window( hwnd )) return 0;
return set_window_style( hwnd, wparam, lparam );

View file

@ -245,6 +245,7 @@ typedef struct tagCLASS
/* class.c */
WNDPROC alloc_winproc( WNDPROC func, BOOL ansi ) DECLSPEC_HIDDEN;
WINDOWPROC *get_winproc_ptr( WNDPROC handle ) DECLSPEC_HIDDEN;
BOOL is_winproc_unicode( WNDPROC proc, BOOL def_val ) DECLSPEC_HIDDEN;
DWORD get_class_long( HWND hwnd, INT offset, BOOL ansi ) DECLSPEC_HIDDEN;
ULONG_PTR get_class_long_ptr( HWND hwnd, INT offset, BOOL ansi ) DECLSPEC_HIDDEN;
WORD get_class_word( HWND hwnd, INT offset ) DECLSPEC_HIDDEN;

View file

@ -1246,15 +1246,15 @@
@ stub NtUserSetWindowFNID
@ stub NtUserSetWindowFeedbackSetting
@ stub NtUserSetWindowGroup
@ stub NtUserSetWindowLong
@ stub NtUserSetWindowLongPtr
@ stdcall NtUserSetWindowLong(long long long long)
@ stdcall NtUserSetWindowLongPtr(long long long long)
@ stub NtUserSetWindowPlacement
@ stdcall NtUserSetWindowPos(long long long long long long long)
@ stdcall NtUserSetWindowRgn(long long long)
@ stub NtUserSetWindowRgnEx
@ stub NtUserSetWindowShowState
@ stub NtUserSetWindowStationUser
@ stub NtUserSetWindowWord
@ stdcall NtUserSetWindowWord(long long long)
@ stub NtUserSetWindowsHookAW
@ stdcall -syscall NtUserSetWindowsHookEx(ptr ptr long long ptr long)
@ stub NtUserShowCaret

View file

@ -251,8 +251,11 @@ struct unix_funcs
BOOL (WINAPI *pNtUserSetLayeredWindowAttributes)( HWND hwnd, COLORREF key, BYTE alpha, DWORD flags );
HWND (WINAPI *pNtUserSetParent)( HWND hwnd, HWND parent );
BOOL (WINAPI *pNtUserSetSysColors)( INT count, const INT *colors, const COLORREF *values );
LONG (WINAPI *pNtUserSetWindowLong)( HWND hwnd, INT offset, LONG newval, BOOL ansi );
LONG_PTR (WINAPI *pNtUserSetWindowLongPtr)( HWND hwnd, INT offset, LONG_PTR newval, BOOL ansi );
BOOL (WINAPI *pNtUserSetWindowPos)( HWND hwnd, HWND after, INT x, INT y, INT cx, INT cy, UINT flags );
int (WINAPI *pNtUserSetWindowRgn)( HWND hwnd, HRGN hrgn, BOOL redraw );
WORD (WINAPI *pNtUserSetWindowWord)( HWND hwnd, INT offset, WORD newval );
INT (WINAPI *pNtUserShowCursor)( BOOL show );
BOOL (WINAPI *pNtUserSystemParametersInfo)( UINT action, UINT val, PVOID ptr, UINT winini );
BOOL (WINAPI *pNtUserSystemParametersInfoForDpi)( UINT action, UINT val, PVOID ptr,
@ -360,6 +363,8 @@ extern HWND *list_window_children( HDESK desktop, HWND hwnd, UNICODE_STRING *cla
extern int map_window_points( HWND hwnd_from, HWND hwnd_to, POINT *points, UINT count,
UINT dpi ) DECLSPEC_HIDDEN;
extern void map_window_region( HWND from, HWND to, HRGN hrgn ) DECLSPEC_HIDDEN;
extern LONG_PTR set_window_long( HWND hwnd, INT offset, UINT size, LONG_PTR newval,
BOOL ansi ) 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;

View file

@ -892,6 +892,25 @@ static LONG_PTR get_win_data( const void *ptr, UINT size )
}
}
/* helper for set_window_long */
static inline void set_win_data( void *ptr, LONG_PTR val, UINT size )
{
if (size == sizeof(WORD))
{
WORD newval = val;
memcpy( ptr, &newval, sizeof(newval) );
}
else if (size == sizeof(DWORD))
{
DWORD newval = val;
memcpy( ptr, &newval, sizeof(newval) );
}
else
{
memcpy( ptr, &val, sizeof(val) );
}
}
BOOL is_iconic( HWND hwnd )
{
return (get_window_long( hwnd, GWL_STYLE ) & WS_MINIMIZE) != 0;
@ -1104,6 +1123,304 @@ ULONG set_window_style( HWND hwnd, ULONG set_bits, ULONG clear_bits )
return style.styleOld;
}
static DWORD fix_exstyle( DWORD style, DWORD exstyle )
{
if ((exstyle & WS_EX_DLGMODALFRAME) ||
(!(exstyle & WS_EX_STATICEDGE) && (style & (WS_DLGFRAME | WS_THICKFRAME))))
exstyle |= WS_EX_WINDOWEDGE;
else
exstyle &= ~WS_EX_WINDOWEDGE;
return exstyle;
}
/* Change the owner of a window. */
static HWND set_window_owner( HWND hwnd, HWND owner )
{
WND *win = get_win_ptr( hwnd );
HWND ret = 0;
if (!win || win == WND_DESKTOP) return 0;
if (win == WND_OTHER_PROCESS)
{
if (is_window(hwnd)) ERR( "cannot set owner %p on other process window %p\n", owner, hwnd );
return 0;
}
SERVER_START_REQ( set_window_owner )
{
req->handle = wine_server_user_handle( hwnd );
req->owner = wine_server_user_handle( owner );
if (!wine_server_call( req ))
{
win->owner = wine_server_ptr_handle( reply->full_owner );
ret = wine_server_ptr_handle( reply->prev_owner );
}
}
SERVER_END_REQ;
release_win_ptr( win );
return ret;
}
/* Helper function for SetWindowLong(). */
LONG_PTR set_window_long( HWND hwnd, INT offset, UINT size, LONG_PTR newval, BOOL ansi )
{
BOOL ok, made_visible = FALSE;
LONG_PTR retval = 0;
STYLESTRUCT style;
WND *win;
TRACE( "%p %d %lx %c\n", hwnd, offset, newval, ansi ? 'A' : 'W' );
if (is_broadcast(hwnd))
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (!(win = get_win_ptr( hwnd )))
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
if (win == WND_DESKTOP)
{
/* can't change anything on the desktop window */
SetLastError( ERROR_ACCESS_DENIED );
return 0;
}
if (win == WND_OTHER_PROCESS)
{
if (offset == GWLP_WNDPROC)
{
SetLastError( ERROR_ACCESS_DENIED );
return 0;
}
if (offset > 32767 || offset < -32767)
{
SetLastError( ERROR_INVALID_INDEX );
return 0;
}
return send_message( hwnd, WM_WINE_SETWINDOWLONG, MAKEWPARAM( offset, size ), newval );
}
/* first some special cases */
switch( offset )
{
case GWL_STYLE:
style.styleOld = win->dwStyle;
style.styleNew = newval;
release_win_ptr( win );
send_message( hwnd, WM_STYLECHANGING, GWL_STYLE, (LPARAM)&style );
if (!(win = get_win_ptr( hwnd )) || win == WND_OTHER_PROCESS) return 0;
newval = style.styleNew;
/* WS_CLIPSIBLINGS can't be reset on top-level windows */
if (win->parent == get_desktop_window()) newval |= WS_CLIPSIBLINGS;
/* WS_MINIMIZE can't be reset */
if (win->dwStyle & WS_MINIMIZE) newval |= WS_MINIMIZE;
break;
case GWL_EXSTYLE:
style.styleOld = win->dwExStyle;
style.styleNew = newval;
release_win_ptr( win );
send_message( hwnd, WM_STYLECHANGING, GWL_EXSTYLE, (LPARAM)&style );
if (!(win = get_win_ptr( hwnd )) || win == WND_OTHER_PROCESS) return 0;
/* WS_EX_TOPMOST can only be changed through SetWindowPos */
newval = (style.styleNew & ~WS_EX_TOPMOST) | (win->dwExStyle & WS_EX_TOPMOST);
newval = fix_exstyle(win->dwStyle, newval);
break;
case GWLP_HWNDPARENT:
if (win->parent == get_desktop_window())
{
release_win_ptr( win );
return (ULONG_PTR)set_window_owner( hwnd, (HWND)newval );
}
else
{
release_win_ptr( win );
return (ULONG_PTR)NtUserSetParent( hwnd, (HWND)newval );
}
case GWLP_WNDPROC:
{
WNDPROC proc;
UINT old_flags = win->flags;
retval = get_window_long_ptr( hwnd, offset, ansi );
proc = alloc_winproc( (WNDPROC)newval, ansi );
if (proc) win->winproc = proc;
if (is_winproc_unicode( proc, !ansi )) win->flags |= WIN_ISUNICODE;
else win->flags &= ~WIN_ISUNICODE;
if (!((old_flags ^ win->flags) & WIN_ISUNICODE))
{
release_win_ptr( win );
return retval;
}
/* update is_unicode flag on the server side */
break;
}
case GWLP_ID:
case GWLP_HINSTANCE:
case GWLP_USERDATA:
break;
case DWLP_DLGPROC:
if ((win->cbWndExtra - sizeof(LONG_PTR) >= DWLP_DLGPROC) &&
(size == sizeof(LONG_PTR)) && win->dlgInfo)
{
WNDPROC *ptr = (WNDPROC *)((char *)win->wExtra + DWLP_DLGPROC);
retval = (ULONG_PTR)get_winproc( *ptr, ansi );
*ptr = alloc_winproc( (WNDPROC)newval, ansi );
release_win_ptr( win );
return retval;
}
/* fall through */
default:
if (offset < 0 || offset > (int)(win->cbWndExtra - size))
{
WARN("Invalid offset %d\n", offset );
release_win_ptr( win );
SetLastError( ERROR_INVALID_INDEX );
return 0;
}
else if (get_win_data( (char *)win->wExtra + offset, size ) == newval)
{
/* already set to the same value */
release_win_ptr( win );
return newval;
}
break;
}
SERVER_START_REQ( set_window_info )
{
req->handle = wine_server_user_handle( hwnd );
req->extra_offset = -1;
switch(offset)
{
case GWL_STYLE:
req->flags = SET_WIN_STYLE | SET_WIN_EXSTYLE;
req->style = newval;
req->ex_style = fix_exstyle(newval, win->dwExStyle);
break;
case GWL_EXSTYLE:
req->flags = SET_WIN_EXSTYLE;
req->ex_style = newval;
break;
case GWLP_ID:
req->flags = SET_WIN_ID;
req->extra_value = newval;
break;
case GWLP_HINSTANCE:
req->flags = SET_WIN_INSTANCE;
req->instance = wine_server_client_ptr( (void *)newval );
break;
case GWLP_WNDPROC:
req->flags = SET_WIN_UNICODE;
req->is_unicode = (win->flags & WIN_ISUNICODE) != 0;
break;
case GWLP_USERDATA:
req->flags = SET_WIN_USERDATA;
req->user_data = newval;
break;
default:
req->flags = SET_WIN_EXTRA;
req->extra_offset = offset;
req->extra_size = size;
set_win_data( &req->extra_value, newval, size );
}
if ((ok = !wine_server_call_err( req )))
{
switch(offset)
{
case GWL_STYLE:
win->dwStyle = newval;
win->dwExStyle = fix_exstyle(win->dwStyle, win->dwExStyle);
retval = reply->old_style;
break;
case GWL_EXSTYLE:
win->dwExStyle = newval;
retval = reply->old_ex_style;
break;
case GWLP_ID:
win->wIDmenu = newval;
retval = reply->old_id;
break;
case GWLP_HINSTANCE:
win->hInstance = (HINSTANCE)newval;
retval = (ULONG_PTR)wine_server_get_ptr( reply->old_instance );
break;
case GWLP_WNDPROC:
break;
case GWLP_USERDATA:
win->userdata = newval;
retval = reply->old_user_data;
break;
default:
retval = get_win_data( (char *)win->wExtra + offset, size );
set_win_data( (char *)win->wExtra + offset, newval, size );
break;
}
}
}
SERVER_END_REQ;
if ((offset == GWL_STYLE && ((style.styleOld ^ style.styleNew) & WS_VISIBLE)) ||
(offset == GWL_EXSTYLE && ((style.styleOld ^ style.styleNew) & WS_EX_LAYERED)))
{
made_visible = (win->dwStyle & WS_VISIBLE) != 0;
invalidate_dce( win, NULL );
}
release_win_ptr( win );
if (!ok) return 0;
if (offset == GWL_STYLE || offset == GWL_EXSTYLE)
{
style.styleOld = retval;
style.styleNew = newval;
user_driver->pSetWindowStyle( hwnd, offset, &style );
if (made_visible) update_window_state( hwnd );
send_message( hwnd, WM_STYLECHANGED, offset, (LPARAM)&style );
}
return retval;
}
/**********************************************************************
* NtUserSetWindowWord (win32u.@)
*/
WORD WINAPI NtUserSetWindowWord( HWND hwnd, INT offset, WORD newval )
{
switch(offset)
{
case GWLP_ID:
case GWLP_HINSTANCE:
case GWLP_HWNDPARENT:
break;
default:
if (offset < 0)
{
WARN("Invalid offset %d\n", offset );
SetLastError( ERROR_INVALID_INDEX );
return 0;
}
break;
}
return set_window_long( hwnd, offset, sizeof(WORD), newval, TRUE );
}
/**********************************************************************
* NtUserSetWindowLong (win32u.@)
*/
LONG WINAPI NtUserSetWindowLong( HWND hwnd, INT offset, LONG newval, BOOL ansi )
{
return set_window_long( hwnd, offset, sizeof(LONG), newval, ansi );
}
/*****************************************************************************
* NtUserSetWindowLongPtr (win32u.@)
*/
LONG_PTR WINAPI NtUserSetWindowLongPtr( HWND hwnd, INT offset, LONG_PTR newval, BOOL ansi )
{
return set_window_long( hwnd, offset, sizeof(LONG_PTR), newval, ansi );
}
/***********************************************************************
* NtUserGetProp (win32u.@)
*

View file

@ -1033,6 +1033,18 @@ BOOL WINAPI NtUserSetSysColors( INT count, const INT *colors, const COLORREF *va
return unix_funcs->pNtUserSetSysColors( count, colors, values );
}
LONG WINAPI NtUserSetWindowLong( HWND hwnd, INT offset, LONG newval, BOOL ansi )
{
if (!unix_funcs) return 0;
return unix_funcs->pNtUserSetWindowLong( hwnd, offset, newval, ansi );
}
LONG_PTR WINAPI NtUserSetWindowLongPtr( HWND hwnd, INT offset, LONG_PTR newval, BOOL ansi )
{
if (!unix_funcs) return 0;
return unix_funcs->pNtUserSetWindowLongPtr( hwnd, offset, newval, ansi );
}
BOOL WINAPI NtUserSetWindowPos( HWND hwnd, HWND after, INT x, INT y, INT cx, INT cy, UINT flags )
{
if (!unix_funcs) return 0;
@ -1045,6 +1057,12 @@ int WINAPI NtUserSetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
return unix_funcs->pNtUserSetWindowRgn( hwnd, hrgn, redraw );
}
WORD WINAPI NtUserSetWindowWord( HWND hwnd, INT offset, WORD newval )
{
if (!unix_funcs) return 0;
return unix_funcs->pNtUserSetWindowWord( hwnd, offset, newval );
}
INT WINAPI NtUserShowCursor( BOOL show )
{
if (!unix_funcs) return 0;

View file

@ -402,8 +402,11 @@ BOOL WINAPI NtUserSetProcessWindowStation( HWINSTA handle );
BOOL WINAPI NtUserSetProp( HWND hwnd, const WCHAR *str, HANDLE handle );
BOOL WINAPI NtUserSetSysColors( INT count, const INT *colors, const COLORREF *values );
BOOL WINAPI NtUserSetThreadDesktop( HDESK handle );
LONG WINAPI NtUserSetWindowLong( HWND hwnd, INT offset, LONG newval, BOOL ansi );
LONG_PTR WINAPI NtUserSetWindowLongPtr( HWND hwnd, INT offset, LONG_PTR newval, BOOL ansi );
BOOL WINAPI NtUserSetWindowPos( HWND hwnd, HWND after, INT x, INT y, INT cx, INT cy, UINT flags );
int WINAPI NtUserSetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw );
WORD WINAPI NtUserSetWindowWord( HWND hwnd, INT offset, WORD newval );
HHOOK WINAPI NtUserSetWindowsHookEx( HINSTANCE inst, UNICODE_STRING *module, DWORD tid, INT id,
HOOKPROC proc, BOOL ansi );
HWINEVENTHOOK WINAPI NtUserSetWinEventHook( DWORD event_min, DWORD event_max, HMODULE inst,