Commit a54a990b authored by Alexandre Julliard's avatar Alexandre Julliard

server: Allow to specify the class name instead of the atom to find a window.

parent 1fc461f9
...@@ -211,7 +211,7 @@ static WND *free_window_handle( HWND hwnd ) ...@@ -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 * Build an array of the children of a given window. The array must be
* freed with HeapFree. Returns NULL when no windows are found. * 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; HWND *list;
int size = 32; int size = 32;
...@@ -225,8 +225,9 @@ static HWND *list_window_children( HWND hwnd, ATOM atom, DWORD tid ) ...@@ -225,8 +225,9 @@ static HWND *list_window_children( HWND hwnd, ATOM atom, DWORD tid )
SERVER_START_REQ( get_window_children ) SERVER_START_REQ( get_window_children )
{ {
req->parent = hwnd; req->parent = hwnd;
req->atom = atom;
req->tid = tid; 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) ); wine_server_set_reply( req, list, (size-1) * sizeof(HWND) );
if (!wine_server_call( req )) count = reply->count; if (!wine_server_call( req )) count = reply->count;
} }
...@@ -1398,11 +1399,9 @@ BOOL WINAPI OpenIcon( HWND hwnd ) ...@@ -1398,11 +1399,9 @@ BOOL WINAPI OpenIcon( HWND hwnd )
/*********************************************************************** /***********************************************************************
* WIN_FindWindow * FindWindowExW (USER32.@)
*
* Implementation of FindWindow() and FindWindowEx().
*/ */
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 *list = NULL;
HWND retvalue = 0; HWND retvalue = 0;
...@@ -1458,54 +1457,31 @@ HWND WINAPI FindWindowA( LPCSTR className, LPCSTR title ) ...@@ -1458,54 +1457,31 @@ HWND WINAPI FindWindowA( LPCSTR className, LPCSTR title )
/*********************************************************************** /***********************************************************************
* FindWindowExA (USER32.@) * FindWindowExA (USER32.@)
*/ */
HWND WINAPI FindWindowExA( HWND parent, HWND child, HWND WINAPI FindWindowExA( HWND parent, HWND child, LPCSTR className, LPCSTR title )
LPCSTR className, LPCSTR title )
{ {
ATOM atom = 0; LPWSTR titleW = NULL;
LPWSTR buffer; HWND hwnd = 0;
HWND hwnd;
INT len;
if (className) if (title)
{ {
/* If the atom doesn't exist, then no class */ DWORD len = MultiByteToWideChar( CP_ACP, 0, title, -1, NULL, 0 );
/* with this name exists either. */ if (!(titleW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return 0;
if (!(atom = GlobalFindAtomA( className ))) MultiByteToWideChar( CP_ACP, 0, title, -1, titleW, len );
{
SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
return 0;
}
} }
if (!title) return WIN_FindWindow( parent, child, atom, NULL );
len = MultiByteToWideChar( CP_ACP, 0, title, -1, NULL, 0 ); if (!IS_INTRESOURCE(className))
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 );
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 */ WCHAR classW[256];
/* with this name exists either. */ if (MultiByteToWideChar( CP_ACP, 0, className, -1, classW, sizeof(classW)/sizeof(WCHAR) ))
if (!(atom = GlobalFindAtomW( className ))) hwnd = FindWindowExW( parent, child, classW, titleW );
{ }
SetLastError (ERROR_CANNOT_FIND_WND_CLASS); else
return 0; {
} hwnd = FindWindowExW( parent, child, (LPCWSTR)className, titleW );
} }
return WIN_FindWindow( parent, child, atom, title );
HeapFree( GetProcessHeap(), 0, titleW );
return hwnd;
} }
...@@ -2774,7 +2750,7 @@ HWND WINAPI GetLastActivePopup( HWND hwnd ) ...@@ -2774,7 +2750,7 @@ HWND WINAPI GetLastActivePopup( HWND hwnd )
*/ */
HWND *WIN_ListChildren( 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 ) ...@@ -2818,7 +2794,7 @@ BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam )
USER_CheckNotLock(); 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 */ /* Now call the callback function for every window */
......
...@@ -2888,6 +2888,7 @@ struct get_window_children_request ...@@ -2888,6 +2888,7 @@ struct get_window_children_request
user_handle_t parent; user_handle_t parent;
atom_t atom; atom_t atom;
thread_id_t tid; thread_id_t tid;
/* VARARG(class,unicode_str); */
}; };
struct get_window_children_reply struct get_window_children_reply
{ {
...@@ -4884,6 +4885,6 @@ union generic_reply ...@@ -4884,6 +4885,6 @@ union generic_reply
struct set_completion_info_reply set_completion_info_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 */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -2131,6 +2131,7 @@ enum message_type ...@@ -2131,6 +2131,7 @@ enum message_type
user_handle_t parent; /* parent window */ user_handle_t parent; /* parent window */
atom_t atom; /* class atom for the listed children */ atom_t atom; /* class atom for the listed children */
thread_id_t tid; /* thread owning the listed children */ thread_id_t tid; /* thread owning the listed children */
VARARG(class,unicode_str); /* class name */
@REPLY @REPLY
int count; /* total count of children */ int count; /* total count of children */
VARARG(children,user_handles); /* children handles */ VARARG(children,user_handles); /* children handles */
......
...@@ -2635,7 +2635,9 @@ static void dump_get_window_children_request( const struct get_window_children_r ...@@ -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, " parent=%p,", req->parent );
fprintf( stderr, " atom=%04x,", req->atom ); 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 ) static void dump_get_window_children_reply( const struct get_window_children_reply *req )
......
...@@ -1757,12 +1757,19 @@ DECL_HANDLER(get_window_children) ...@@ -1757,12 +1757,19 @@ DECL_HANDLER(get_window_children)
int total = 0; int total = 0;
user_handle_t *data; user_handle_t *data;
data_size_t len; 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) if (parent)
{ {
LIST_FOR_EACH_ENTRY( ptr, &parent->children, struct window, entry ) 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; if (req->tid && get_thread_id(ptr->thread) != req->tid) continue;
total++; total++;
} }
...@@ -1774,7 +1781,7 @@ DECL_HANDLER(get_window_children) ...@@ -1774,7 +1781,7 @@ DECL_HANDLER(get_window_children)
LIST_FOR_EACH_ENTRY( ptr, &parent->children, struct window, entry ) LIST_FOR_EACH_ENTRY( ptr, &parent->children, struct window, entry )
{ {
if (len < sizeof(*data)) break; 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; if (req->tid && get_thread_id(ptr->thread) != req->tid) continue;
*data++ = ptr->handle; *data++ = ptr->handle;
len -= sizeof(*data); len -= sizeof(*data);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment