From a54a990b3b68a126e02ef6805d01f314fa5896e3 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 2 Nov 2007 15:26:49 +0100 Subject: [PATCH] server: Allow to specify the class name instead of the atom to find a window. --- dlls/user32/win.c | 76 ++++++++++++---------------------- include/wine/server_protocol.h | 3 +- server/protocol.def | 1 + server/trace.c | 4 +- server/window.c | 11 ++++- 5 files changed, 41 insertions(+), 54 deletions(-) diff --git a/dlls/user32/win.c b/dlls/user32/win.c index 023115e6506..72f3cfcf15b 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -211,7 +211,7 @@ static WND *free_window_handle( HWND hwnd ) * Build an array of the children of a given window. The array must be * freed with HeapFree. Returns NULL when no windows are found. */ -static HWND *list_window_children( HWND hwnd, ATOM atom, DWORD tid ) +static HWND *list_window_children( HWND hwnd, LPCWSTR class, DWORD tid ) { HWND *list; int size = 32; @@ -225,8 +225,9 @@ static HWND *list_window_children( HWND hwnd, ATOM atom, DWORD tid ) SERVER_START_REQ( get_window_children ) { req->parent = hwnd; - req->atom = atom; req->tid = tid; + if (!(req->atom = get_int_atom_value( class )) && class) + wine_server_add_data( req, class, strlenW(class)*sizeof(WCHAR) ); wine_server_set_reply( req, list, (size-1) * sizeof(HWND) ); if (!wine_server_call( req )) count = reply->count; } @@ -1398,11 +1399,9 @@ BOOL WINAPI OpenIcon( HWND hwnd ) /*********************************************************************** - * WIN_FindWindow - * - * Implementation of FindWindow() and FindWindowEx(). + * FindWindowExW (USER32.@) */ -static HWND WIN_FindWindow( HWND parent, HWND child, ATOM className, LPCWSTR title ) +HWND WINAPI FindWindowExW( HWND parent, HWND child, LPCWSTR className, LPCWSTR title ) { HWND *list = NULL; HWND retvalue = 0; @@ -1458,57 +1457,34 @@ HWND WINAPI FindWindowA( LPCSTR className, LPCSTR title ) /*********************************************************************** * FindWindowExA (USER32.@) */ -HWND WINAPI FindWindowExA( HWND parent, HWND child, - LPCSTR className, LPCSTR title ) +HWND WINAPI FindWindowExA( HWND parent, HWND child, LPCSTR className, LPCSTR title ) { - ATOM atom = 0; - LPWSTR buffer; - HWND hwnd; - INT len; + LPWSTR titleW = NULL; + HWND hwnd = 0; - if (className) + if (title) { - /* If the atom doesn't exist, then no class */ - /* with this name exists either. */ - if (!(atom = GlobalFindAtomA( className ))) - { - SetLastError (ERROR_CANNOT_FIND_WND_CLASS); - return 0; - } + DWORD len = MultiByteToWideChar( CP_ACP, 0, title, -1, NULL, 0 ); + if (!(titleW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return 0; + MultiByteToWideChar( CP_ACP, 0, title, -1, titleW, len ); } - if (!title) return WIN_FindWindow( parent, child, atom, NULL ); - len = MultiByteToWideChar( CP_ACP, 0, title, -1, NULL, 0 ); - if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return 0; - MultiByteToWideChar( CP_ACP, 0, title, -1, buffer, len ); - hwnd = WIN_FindWindow( parent, child, atom, buffer ); - HeapFree( GetProcessHeap(), 0, buffer ); + if (!IS_INTRESOURCE(className)) + { + WCHAR classW[256]; + if (MultiByteToWideChar( CP_ACP, 0, className, -1, classW, sizeof(classW)/sizeof(WCHAR) )) + hwnd = FindWindowExW( parent, child, classW, titleW ); + } + else + { + hwnd = FindWindowExW( parent, child, (LPCWSTR)className, titleW ); + } + + HeapFree( GetProcessHeap(), 0, titleW ); return hwnd; } -/*********************************************************************** - * FindWindowExW (USER32.@) - */ -HWND WINAPI FindWindowExW( HWND parent, HWND child, - LPCWSTR className, LPCWSTR title ) -{ - ATOM atom = 0; - - if (className) - { - /* If the atom doesn't exist, then no class */ - /* with this name exists either. */ - if (!(atom = GlobalFindAtomW( className ))) - { - SetLastError (ERROR_CANNOT_FIND_WND_CLASS); - return 0; - } - } - return WIN_FindWindow( parent, child, atom, title ); -} - - /*********************************************************************** * FindWindowW (USER32.@) */ @@ -2774,7 +2750,7 @@ HWND WINAPI GetLastActivePopup( HWND hwnd ) */ HWND *WIN_ListChildren( HWND hwnd ) { - return list_window_children( hwnd, 0, 0 ); + return list_window_children( hwnd, NULL, 0 ); } @@ -2818,7 +2794,7 @@ BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam ) USER_CheckNotLock(); - if (!(list = list_window_children( GetDesktopWindow(), 0, id ))) return TRUE; + if (!(list = list_window_children( GetDesktopWindow(), NULL, id ))) return TRUE; /* Now call the callback function for every window */ diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 1643070f957..913f2a168fd 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -2888,6 +2888,7 @@ struct get_window_children_request user_handle_t parent; atom_t atom; thread_id_t tid; + /* VARARG(class,unicode_str); */ }; struct get_window_children_reply { @@ -4884,6 +4885,6 @@ union generic_reply struct set_completion_info_reply set_completion_info_reply; }; -#define SERVER_PROTOCOL_VERSION 327 +#define SERVER_PROTOCOL_VERSION 328 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/protocol.def b/server/protocol.def index 5cb951d51a3..90e943b1b32 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2131,6 +2131,7 @@ enum message_type user_handle_t parent; /* parent window */ atom_t atom; /* class atom for the listed children */ thread_id_t tid; /* thread owning the listed children */ + VARARG(class,unicode_str); /* class name */ @REPLY int count; /* total count of children */ VARARG(children,user_handles); /* children handles */ diff --git a/server/trace.c b/server/trace.c index 2460cdeac22..7275e6566bb 100644 --- a/server/trace.c +++ b/server/trace.c @@ -2635,7 +2635,9 @@ static void dump_get_window_children_request( const struct get_window_children_r { fprintf( stderr, " parent=%p,", req->parent ); fprintf( stderr, " atom=%04x,", req->atom ); - fprintf( stderr, " tid=%04x", req->tid ); + fprintf( stderr, " tid=%04x,", req->tid ); + fprintf( stderr, " class=" ); + dump_varargs_unicode_str( cur_size ); } static void dump_get_window_children_reply( const struct get_window_children_reply *req ) diff --git a/server/window.c b/server/window.c index 3e8219b06e1..8cf8001eb5a 100644 --- a/server/window.c +++ b/server/window.c @@ -1757,12 +1757,19 @@ DECL_HANDLER(get_window_children) int total = 0; user_handle_t *data; data_size_t len; + atom_t atom = req->atom; + + if (get_req_data_size()) + { + atom = find_global_atom( NULL, get_req_data(), get_req_data_size() / sizeof(WCHAR) ); + if (!atom) return; + } if (parent) { LIST_FOR_EACH_ENTRY( ptr, &parent->children, struct window, entry ) { - if (req->atom && get_class_atom(ptr->class) != req->atom) continue; + if (atom && get_class_atom(ptr->class) != atom) continue; if (req->tid && get_thread_id(ptr->thread) != req->tid) continue; total++; } @@ -1774,7 +1781,7 @@ DECL_HANDLER(get_window_children) LIST_FOR_EACH_ENTRY( ptr, &parent->children, struct window, entry ) { if (len < sizeof(*data)) break; - if (req->atom && get_class_atom(ptr->class) != req->atom) continue; + if (atom && get_class_atom(ptr->class) != atom) continue; if (req->tid && get_thread_id(ptr->thread) != req->tid) continue; *data++ = ptr->handle; len -= sizeof(*data);