From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/window.c | 85 +++++++----------------------- server/protocol.def | 33 ++++-------- server/window.c | 121 ++++++++++++++++++++++++++++--------------- 3 files changed, 108 insertions(+), 131 deletions(-)
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 0bdee8ec66a..6e542c8b2ac 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1013,27 +1013,12 @@ static LONG_PTR get_window_long_size( HWND hwnd, INT offset, UINT size, BOOL ans RtlSetLastWin32Error( ERROR_ACCESS_DENIED ); return 0; } - SERVER_START_REQ( set_window_info ) + SERVER_START_REQ( get_window_info ) { req->handle = wine_server_user_handle( hwnd ); - req->flags = 0; /* don't set anything, just retrieve */ - req->extra_offset = (offset >= 0) ? offset : -1; - req->extra_size = (offset >= 0) ? size : 0; - if (!wine_server_call_err( req )) - { - switch(offset) - { - case GWL_STYLE: retval = reply->old_style; break; - case GWL_EXSTYLE: retval = reply->old_ex_style; break; - case GWLP_ID: retval = reply->old_id; break; - case GWLP_HINSTANCE: retval = (ULONG_PTR)wine_server_get_ptr( reply->old_instance ); break; - case GWLP_USERDATA: retval = reply->old_user_data; break; - default: - if (offset >= 0) retval = get_win_data( &reply->old_extra_value, size ); - else RtlSetLastWin32Error( ERROR_INVALID_INDEX ); - break; - } - } + req->offset = offset; + req->size = size; + if (!wine_server_call_err( req )) retval = reply->info; } SERVER_END_REQ; return retval; @@ -1127,12 +1112,11 @@ UINT set_window_style_bits( HWND hwnd, UINT set_bits, UINT clear_bits ) 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; + req->offset = GWL_STYLE; + req->new_info = style.styleNew; if ((ok = !wine_server_call( req ))) { - style.styleOld = reply->old_style; + style.styleOld = reply->old_info; win->dwStyle = style.styleNew; } } @@ -1317,74 +1301,45 @@ LONG_PTR set_window_long( HWND hwnd, INT offset, UINT size, LONG_PTR newval, BOO break; }
+ if (offset == GWLP_WNDPROC) newval = !!(win->flags & WIN_ISUNICODE); + if (offset == GWLP_USERDATA && size == sizeof(WORD)) newval = MAKELONG( newval, win->userdata >> 16 ); + 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: - if (size == sizeof(WORD)) newval = MAKELONG( newval, win->userdata >> 16 ); - 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 ); - } + req->offset = offset; + req->new_info = newval; + req->size = size; if ((ok = !wine_server_call_err( req ))) { - switch(offset) + switch (offset) { case GWL_STYLE: win->dwStyle = newval; win->dwExStyle = fix_exstyle(win->dwStyle, win->dwExStyle); - retval = reply->old_style; + retval = reply->old_info; break; case GWL_EXSTYLE: win->dwExStyle = newval; - retval = reply->old_ex_style; + retval = reply->old_info; break; case GWLP_ID: win->wIDmenu = newval; - retval = reply->old_id; + retval = reply->old_info; break; case GWLP_HINSTANCE: win->hInstance = (HINSTANCE)newval; - retval = (ULONG_PTR)wine_server_get_ptr( reply->old_instance ); + retval = reply->old_info; break; case GWLP_WNDPROC: break; case GWLP_USERDATA: win->userdata = newval; - retval = reply->old_user_data; + retval = reply->old_info; break; default: - retval = get_win_data( (char *)win->wExtra + offset, size ); set_win_data( (char *)win->wExtra + offset, newval, size ); + retval = reply->old_info; break; } } diff --git a/server/protocol.def b/server/protocol.def index 2018f2049ae..dd9ace22b85 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2587,9 +2587,12 @@ enum message_type /* Get information from a window handle */ @REQ(get_window_info) user_handle_t handle; /* handle to the window */ + int offset; /* offset of the info */ + data_size_t size; /* size of the info value to read */ @REPLY user_handle_t last_active; /* last active popup */ int is_unicode; /* ANSI or unicode */ + lparam_t info; /* current window info value */ @END
@@ -2605,31 +2608,13 @@ enum message_type
/* Set some information in a window */ @REQ(set_window_info) - unsigned short flags; /* flags for fields to set (see below) */ - short int is_unicode; /* ANSI or unicode */ user_handle_t handle; /* handle to the window */ - unsigned int style; /* window style */ - unsigned int ex_style; /* window extended style */ - data_size_t extra_size; /* size to set in extra bytes */ - mod_handle_t instance; /* creator instance */ - lparam_t user_data; /* user-specific data */ - lparam_t extra_value; /* value to set in extra bytes or window id */ - int extra_offset; /* offset to set in extra bytes */ -@REPLY - unsigned int old_style; /* old window style */ - unsigned int old_ex_style; /* old window extended style */ - mod_handle_t old_instance; /* old creator instance */ - lparam_t old_user_data; /* old user-specific data */ - lparam_t old_extra_value; /* old value in extra bytes */ - lparam_t old_id; /* old window id */ -@END -#define SET_WIN_STYLE 0x01 -#define SET_WIN_EXSTYLE 0x02 -#define SET_WIN_ID 0x04 -#define SET_WIN_INSTANCE 0x08 -#define SET_WIN_USERDATA 0x10 -#define SET_WIN_EXTRA 0x20 -#define SET_WIN_UNICODE 0x40 + int offset; /* offset of the info */ + data_size_t size; /* size of the info value to write */ + lparam_t new_info; /* new window info value */ +@REPLY + lparam_t old_info; /* previous window info value */ +@END
/* Set the parent of a window */ diff --git a/server/window.c b/server/window.c index f1575b023fe..e2e9d5cc485 100644 --- a/server/window.c +++ b/server/window.c @@ -2177,6 +2177,22 @@ void free_window_handle( struct window *win ) release_object( win ); }
+static void fix_window_ex_style( struct window *win ) +{ + if (win->ex_style & WS_EX_DLGMODALFRAME) win->ex_style |= WS_EX_WINDOWEDGE; + else if (win->ex_style & WS_EX_STATICEDGE) win->ex_style &= ~WS_EX_WINDOWEDGE; + else if (win->style & (WS_DLGFRAME | WS_THICKFRAME)) win->ex_style |= WS_EX_WINDOWEDGE; + else win->ex_style &= ~WS_EX_WINDOWEDGE; +} + +static void set_window_ex_style( struct window *win, unsigned int ex_style ) +{ + /* WS_EX_TOPMOST can only be changed for unlinked windows */ + if (!win->is_linked) win->ex_style = ex_style; + else win->ex_style = (ex_style & ~WS_EX_TOPMOST) | (win->ex_style & WS_EX_TOPMOST); + if (!(win->ex_style & WS_EX_LAYERED)) win->is_layered = 0; +} +
/* create a window */ DECL_HANDLER(create_window) @@ -2343,14 +2359,32 @@ DECL_HANDLER(set_window_owner) /* get information from a window handle */ DECL_HANDLER(get_window_info) { - struct window *win = get_window( req->handle ); + struct window *win;
- if (!win) return; + if (!(win = get_window( req->handle ))) return;
reply->last_active = win->handle; reply->is_unicode = win->is_unicode; - if (get_user_object( win->last_active, NTUSER_OBJ_WINDOW )) reply->last_active = win->last_active; + + switch (req->offset) + { + case GWL_STYLE: reply->info = win->style; break; + case GWL_EXSTYLE: reply->info = win->ex_style; break; + case GWLP_ID: reply->info = win->id; break; + case GWLP_HINSTANCE: reply->info = win->instance; break; + case GWLP_WNDPROC: reply->info = win->is_unicode; break; + case GWLP_USERDATA: reply->info = win->user_data; break; + default: + if (req->size > sizeof(reply->info) || req->offset < 0 || + req->offset > win->nb_extra_bytes - (int)req->size) + { + set_win32_error( ERROR_INVALID_INDEX ); + break; + } + memcpy( &reply->info, win->extra_bytes + req->offset, req->size ); + break; + } }
@@ -2372,52 +2406,55 @@ DECL_HANDLER(init_window_info) /* set some information in a window */ DECL_HANDLER(set_window_info) { - struct window *win = get_window( req->handle ); + struct window *win;
- if (!win) return; - if (req->flags && is_desktop_window(win) && win->thread != current) + if (!(win = get_window( req->handle ))) return; + if (is_desktop_window( win ) && win->thread != current) { set_error( STATUS_ACCESS_DENIED ); return; } - if (req->extra_size > sizeof(req->extra_value) || - req->extra_offset < -1 || - req->extra_offset > win->nb_extra_bytes - (int)req->extra_size) - { - set_win32_error( ERROR_INVALID_INDEX ); - return; - } - if (req->extra_offset != -1) - { - memcpy( &reply->old_extra_value, win->extra_bytes + req->extra_offset, req->extra_size ); - } - else if (req->flags & SET_WIN_EXTRA) + + switch (req->offset) { - set_win32_error( ERROR_INVALID_INDEX ); - return; + case GWL_STYLE: + reply->old_info = win->style; + win->style = req->new_info; + fix_window_ex_style( win ); + /* changing window style triggers a non-client paint */ + win->paint_flags |= PAINT_NONCLIENT; + break; + case GWL_EXSTYLE: + reply->old_info = win->ex_style; + set_window_ex_style( win, req->new_info ); + break; + case GWLP_ID: + reply->old_info = win->id; + win->id = req->new_info; + break; + case GWLP_HINSTANCE: + reply->old_info = win->instance; + win->instance = req->new_info; + break; + case GWLP_WNDPROC: + reply->old_info = win->is_unicode; + win->is_unicode = req->new_info; + break; + case GWLP_USERDATA: + reply->old_info = win->user_data; + win->user_data = req->new_info; + break; + default: + if (req->size > sizeof(req->new_info) || req->offset < 0 || + req->offset > win->nb_extra_bytes - (int)req->size) + { + set_win32_error( ERROR_INVALID_INDEX ); + break; + } + memcpy( &reply->old_info, win->extra_bytes + req->offset, req->size ); + memcpy( win->extra_bytes + req->offset, &req->new_info, req->size ); + break; } - reply->old_style = win->style; - reply->old_ex_style = win->ex_style; - reply->old_id = win->id; - reply->old_instance = win->instance; - reply->old_user_data = win->user_data; - if (req->flags & SET_WIN_STYLE) win->style = req->style; - if (req->flags & SET_WIN_EXSTYLE) - { - /* WS_EX_TOPMOST can only be changed for unlinked windows */ - if (!win->is_linked) win->ex_style = req->ex_style; - else win->ex_style = (req->ex_style & ~WS_EX_TOPMOST) | (win->ex_style & WS_EX_TOPMOST); - if (!(win->ex_style & WS_EX_LAYERED)) win->is_layered = 0; - } - if (req->flags & SET_WIN_ID) win->id = req->extra_value; - if (req->flags & SET_WIN_INSTANCE) win->instance = req->instance; - if (req->flags & SET_WIN_UNICODE) win->is_unicode = req->is_unicode; - if (req->flags & SET_WIN_USERDATA) win->user_data = req->user_data; - if (req->flags & SET_WIN_EXTRA) memcpy( win->extra_bytes + req->extra_offset, - &req->extra_value, req->extra_size ); - - /* changing window style triggers a non-client paint */ - if (req->flags & SET_WIN_STYLE) win->paint_flags |= PAINT_NONCLIENT; }