user32: Implemented EnumDesktopWindows.

This commit is contained in:
Alexandre Julliard 2008-03-18 15:17:40 +01:00
parent 5e463acef7
commit 34fe91bf2b
8 changed files with 46 additions and 25 deletions

View file

@ -212,7 +212,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, LPCWSTR class, DWORD tid )
static HWND *list_window_children( HDESK desktop, HWND hwnd, LPCWSTR class, DWORD tid )
{
HWND *list;
int size = 32;
@ -225,6 +225,7 @@ static HWND *list_window_children( HWND hwnd, LPCWSTR class, DWORD tid )
SERVER_START_REQ( get_window_children )
{
req->desktop = desktop;
req->parent = hwnd;
req->tid = tid;
if (!(req->atom = get_int_atom_value( class )) && class)
@ -1522,7 +1523,7 @@ HWND WINAPI FindWindowExW( HWND parent, HWND child, LPCWSTR className, LPCWSTR t
if (!(buffer = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) return 0;
}
if (!(list = list_window_children( parent, className, 0 ))) goto done;
if (!(list = list_window_children( 0, parent, className, 0 ))) goto done;
if (child)
{
@ -2862,7 +2863,7 @@ HWND WINAPI GetLastActivePopup( HWND hwnd )
*/
HWND *WIN_ListChildren( HWND hwnd )
{
return list_window_children( hwnd, NULL, 0 );
return list_window_children( 0, hwnd, NULL, 0 );
}
@ -2906,7 +2907,7 @@ BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam )
USER_CheckNotLock();
if (!(list = list_window_children( GetDesktopWindow(), NULL, id ))) return TRUE;
if (!(list = list_window_children( 0, GetDesktopWindow(), NULL, id ))) return TRUE;
/* Now call the callback function for every window */
@ -2917,6 +2918,25 @@ BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam )
}
/***********************************************************************
* EnumDesktopWindows (USER32.@)
*/
BOOL WINAPI EnumDesktopWindows( HDESK desktop, WNDENUMPROC func, LPARAM lparam )
{
HWND *list;
int i;
USER_CheckNotLock();
if (!(list = list_window_children( desktop, 0, NULL, 0 ))) return TRUE;
for (i = 0; list[i]; i++)
if (!func( list[i], lparam )) break;
HeapFree( GetProcessHeap(), 0, list );
return TRUE;
}
/**********************************************************************
* WIN_EnumChildWindows
*

View file

@ -454,16 +454,6 @@ HDESK WINAPI OpenInputDesktop( DWORD flags, BOOL inherit, ACCESS_MASK access )
}
/***********************************************************************
* EnumDesktopWindows (USER32.@)
*/
BOOL WINAPI EnumDesktopWindows( HDESK desktop, WNDENUMPROC func, LPARAM lparam )
{
FIXME( "(%p,%p,0x%lx): stub!\n", desktop, func, lparam );
return TRUE;
}
/***********************************************************************
* GetUserObjectInformationA (USER32.@)
*/

View file

@ -2901,6 +2901,7 @@ struct get_window_parents_reply
struct get_window_children_request
{
struct request_header __header;
obj_handle_t desktop;
user_handle_t parent;
atom_t atom;
thread_id_t tid;
@ -4994,6 +4995,6 @@ union generic_reply
struct add_fd_completion_reply add_fd_completion_reply;
};
#define SERVER_PROTOCOL_VERSION 337
#define SERVER_PROTOCOL_VERSION 338
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View file

@ -2139,6 +2139,7 @@ enum message_type
/* Get a list of the window children */
@REQ(get_window_children)
obj_handle_t desktop; /* handle to desktop */
user_handle_t parent; /* parent window */
atom_t atom; /* class atom for the listed children */
thread_id_t tid; /* thread owning the listed children */

View file

@ -2656,6 +2656,7 @@ static void dump_get_window_parents_reply( const struct get_window_parents_reply
static void dump_get_window_children_request( const struct get_window_children_request *req )
{
fprintf( stderr, " desktop=%p,", req->desktop );
fprintf( stderr, " parent=%p,", req->parent );
fprintf( stderr, " atom=%04x,", req->atom );
fprintf( stderr, " tid=%04x,", req->tid );

View file

@ -150,6 +150,7 @@ extern void *get_class_client_ptr( struct window_class *class );
/* windows station functions */
extern struct desktop *get_desktop_obj( struct process *process, obj_handle_t handle, unsigned int access );
extern struct winstation *get_process_winstation( struct process *process, unsigned int access );
extern struct desktop *get_thread_desktop( struct thread *thread, unsigned int access );
extern void connect_process_winstation( struct process *process, struct thread *parent );

View file

@ -1804,26 +1804,34 @@ DECL_HANDLER(get_window_parents)
/* get a list of the window children */
DECL_HANDLER(get_window_children)
{
struct window *ptr, *parent = get_window( req->parent );
struct window *ptr, *parent;
int total = 0;
user_handle_t *data;
data_size_t len;
atom_t atom = req->atom;
if (req->desktop)
{
struct desktop *desktop = get_desktop_obj( current->process, req->desktop, DESKTOP_ENUMERATE );
if (!desktop) return;
parent = desktop->top_window;
release_object( desktop );
}
else parent = get_window( req->parent );
if (!parent) return;
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 )
{
LIST_FOR_EACH_ENTRY( ptr, &parent->children, struct window, entry )
{
if (atom && get_class_atom(ptr->class) != atom) continue;
if (req->tid && get_thread_id(ptr->thread) != req->tid) continue;
total++;
}
if (atom && get_class_atom(ptr->class) != atom) continue;
if (req->tid && get_thread_id(ptr->thread) != req->tid) continue;
total++;
}
reply->count = total;
len = min( get_reply_max_size(), total * sizeof(user_handle_t) );

View file

@ -203,8 +203,7 @@ static WCHAR *build_desktop_name( const struct unicode_str *name,
}
/* retrieve a pointer to a desktop object */
static inline struct desktop *get_desktop_obj( struct process *process, obj_handle_t handle,
unsigned int access )
struct desktop *get_desktop_obj( struct process *process, obj_handle_t handle, unsigned int access )
{
return (struct desktop *)get_handle_obj( process, handle, access, &desktop_ops );
}