Commit 612c0104 authored by Alexandre Julliard's avatar Alexandre Julliard

user32: Add support for finding HWND_MESSAGE windows in FindWindowEx.

parent 9b9dbb20
...@@ -4709,7 +4709,7 @@ static void test_GetWindowModuleFileName(void) ...@@ -4709,7 +4709,7 @@ static void test_GetWindowModuleFileName(void)
static void test_hwnd_message(void) static void test_hwnd_message(void)
{ {
HWND parent = 0, hwnd; HWND parent = 0, hwnd, found;
RECT rect; RECT rect;
hwnd = CreateWindowExA(0, "MainWindowClass", "message window", WS_CAPTION | WS_VISIBLE, hwnd = CreateWindowExA(0, "MainWindowClass", "message window", WS_CAPTION | WS_VISIBLE,
...@@ -4743,6 +4743,18 @@ static void test_hwnd_message(void) ...@@ -4743,6 +4743,18 @@ static void test_hwnd_message(void)
ok( rect.left == 100 && rect.right == 300 && rect.top == 100 && rect.bottom == 300, ok( rect.left == 100 && rect.right == 300 && rect.top == 100 && rect.bottom == 300,
"wrong window rect %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom ); "wrong window rect %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
/* test FindWindow behavior */
found = FindWindowExA( 0, 0, 0, "message window" );
ok( found == hwnd, "didn't find message window %p/%p\n", found, hwnd );
found = FindWindowExA( GetDesktopWindow(), 0, 0, "message window" );
ok( found == 0, "found message window %p/%p\n", found, hwnd );
if (parent)
{
found = FindWindowExA( parent, 0, 0, "message window" );
ok( found == hwnd, "didn't find message window %p/%p\n", found, hwnd );
}
DestroyWindow(hwnd); DestroyWindow(hwnd);
} }
......
...@@ -1578,7 +1578,9 @@ HWND WINAPI FindWindowExW( HWND parent, HWND child, LPCWSTR className, LPCWSTR t ...@@ -1578,7 +1578,9 @@ HWND WINAPI FindWindowExW( HWND parent, HWND child, LPCWSTR className, LPCWSTR t
int i = 0, len = 0; int i = 0, len = 0;
WCHAR *buffer = NULL; WCHAR *buffer = NULL;
if (!parent) parent = GetDesktopWindow(); if (!parent && child) parent = GetDesktopWindow();
else if (parent == HWND_MESSAGE) parent = get_hwnd_message_parent();
if (title) if (title)
{ {
len = strlenW(title) + 1; /* one extra char to check for chars beyond the end */ len = strlenW(title) + 1; /* one extra char to check for chars beyond the end */
...@@ -2940,6 +2942,11 @@ HWND WINAPI GetLastActivePopup( HWND hwnd ) ...@@ -2940,6 +2942,11 @@ HWND WINAPI GetLastActivePopup( HWND hwnd )
*/ */
HWND *WIN_ListChildren( HWND hwnd ) HWND *WIN_ListChildren( HWND hwnd )
{ {
if (!hwnd)
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return NULL;
}
return list_window_children( 0, hwnd, NULL, 0 ); return list_window_children( 0, hwnd, NULL, 0 );
} }
......
...@@ -639,6 +639,29 @@ static inline int is_point_in_window( struct window *win, int x, int y ) ...@@ -639,6 +639,29 @@ static inline int is_point_in_window( struct window *win, int x, int y )
return 1; return 1;
} }
/* fill an array with the handles of the children of a specified window */
static unsigned int get_children_windows( struct window *parent, atom_t atom, thread_id_t tid,
user_handle_t *handles, unsigned int max_count )
{
struct window *ptr;
unsigned int count = 0;
if (!parent) return 0;
LIST_FOR_EACH_ENTRY( ptr, &parent->children, struct window, entry )
{
if (atom && get_class_atom(ptr->class) != atom) continue;
if (tid && get_thread_id(ptr->thread) != tid) continue;
if (handles)
{
if (count >= max_count) break;
handles[count] = ptr->handle;
}
count++;
}
return count;
}
/* find child of 'parent' that contains the given point (in parent-relative coords) */ /* find child of 'parent' that contains the given point (in parent-relative coords) */
static struct window *child_window_from_point( struct window *parent, int x, int y ) static struct window *child_window_from_point( struct window *parent, int x, int y )
{ {
...@@ -1932,46 +1955,51 @@ DECL_HANDLER(get_window_parents) ...@@ -1932,46 +1955,51 @@ DECL_HANDLER(get_window_parents)
/* get a list of the window children */ /* get a list of the window children */
DECL_HANDLER(get_window_children) DECL_HANDLER(get_window_children)
{ {
struct window *ptr, *parent; struct window *parent = NULL;
int total = 0; unsigned int total;
user_handle_t *data; user_handle_t *data;
data_size_t len; data_size_t len;
struct unicode_str cls_name; struct unicode_str cls_name;
atom_t atom = req->atom; atom_t atom = req->atom;
struct desktop *desktop = NULL;
if (req->desktop) if (req->desktop)
{ {
struct desktop *desktop = get_desktop_obj( current->process, req->desktop, DESKTOP_ENUMERATE ); if (!(desktop = get_desktop_obj( current->process, req->desktop, DESKTOP_ENUMERATE ))) return;
if (!desktop) return;
parent = desktop->top_window; parent = desktop->top_window;
release_object( desktop );
} }
else parent = get_window( req->parent ); else
{
if (!parent) return; if (req->parent && !(parent = get_window( req->parent ))) return;
if (!parent && !(desktop = get_thread_desktop( current, 0 ))) return;
}
get_req_unicode_str( &cls_name ); get_req_unicode_str( &cls_name );
if (cls_name.len && !(atom = find_global_atom( NULL, &cls_name ))) return; if (cls_name.len && !(atom = find_global_atom( NULL, &cls_name ))) return;
LIST_FOR_EACH_ENTRY( ptr, &parent->children, struct window, entry ) if (parent)
{ total = get_children_windows( parent, atom, req->tid, NULL, 0 );
if (atom && get_class_atom(ptr->class) != atom) continue; else
if (req->tid && get_thread_id(ptr->thread) != req->tid) continue; total = get_children_windows( desktop->top_window, atom, req->tid, NULL, 0 ) +
total++; get_children_windows( desktop->msg_window, atom, req->tid, NULL, 0 );
}
reply->count = total; reply->count = total;
len = min( get_reply_max_size(), total * sizeof(user_handle_t) ); len = min( get_reply_max_size(), total * sizeof(user_handle_t) );
if (len && ((data = set_reply_data_size( len )))) if (len && ((data = set_reply_data_size( len ))))
{ {
LIST_FOR_EACH_ENTRY( ptr, &parent->children, struct window, entry ) if (parent) get_children_windows( parent, atom, req->tid, data, len / sizeof(user_handle_t) );
else
{ {
if (len < sizeof(*data)) break; total = get_children_windows( desktop->top_window, atom, req->tid,
if (atom && get_class_atom(ptr->class) != atom) continue; data, len / sizeof(user_handle_t) );
if (req->tid && get_thread_id(ptr->thread) != req->tid) continue; data += total;
*data++ = ptr->handle; len -= total * sizeof(user_handle_t);
len -= sizeof(*data); if (len >= sizeof(user_handle_t))
get_children_windows( desktop->msg_window, atom, req->tid,
data, len / sizeof(user_handle_t) );
} }
} }
if (desktop) release_object( desktop );
} }
......
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