Alexandre Julliard : user32: Add support for finding HWND_MESSAGE windows in FindWindowEx.

Alexandre Julliard julliard at winehq.org
Wed Jun 25 16:43:51 CDT 2008


Module: wine
Branch: master
Commit: 612c0104312e81c21b0a1216edd181cd46687404
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=612c0104312e81c21b0a1216edd181cd46687404

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Jun 25 15:30:22 2008 +0200

user32: Add support for finding HWND_MESSAGE windows in FindWindowEx.

---

 dlls/user32/tests/win.c |   14 +++++++++-
 dlls/user32/win.c       |    9 +++++-
 server/window.c         |   68 +++++++++++++++++++++++++++++++++--------------
 3 files changed, 69 insertions(+), 22 deletions(-)

diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index 182a0b6..3a3a152 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -4709,7 +4709,7 @@ static void test_GetWindowModuleFileName(void)
 
 static void test_hwnd_message(void)
 {
-    HWND parent = 0, hwnd;
+    HWND parent = 0, hwnd, found;
     RECT rect;
 
     hwnd = CreateWindowExA(0, "MainWindowClass", "message window", WS_CAPTION | WS_VISIBLE,
@@ -4743,6 +4743,18 @@ static void test_hwnd_message(void)
     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 );
 
+    /* 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);
 }
 
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index 3ba4d76..9a21246 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -1578,7 +1578,9 @@ HWND WINAPI FindWindowExW( HWND parent, HWND child, LPCWSTR className, LPCWSTR t
     int i = 0, len = 0;
     WCHAR *buffer = NULL;
 
-    if (!parent) parent = GetDesktopWindow();
+    if (!parent && child) parent = GetDesktopWindow();
+    else if (parent == HWND_MESSAGE) parent = get_hwnd_message_parent();
+
     if (title)
     {
         len = strlenW(title) + 1;  /* one extra char to check for chars beyond the end */
@@ -2940,6 +2942,11 @@ HWND WINAPI GetLastActivePopup( HWND hwnd )
  */
 HWND *WIN_ListChildren( HWND hwnd )
 {
+    if (!hwnd)
+    {
+        SetLastError( ERROR_INVALID_WINDOW_HANDLE );
+        return NULL;
+    }
     return list_window_children( 0, hwnd, NULL, 0 );
 }
 
diff --git a/server/window.c b/server/window.c
index 53ea59f..ed8f042 100644
--- a/server/window.c
+++ b/server/window.c
@@ -639,6 +639,29 @@ static inline int is_point_in_window( struct window *win, int x, int y )
     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) */
 static struct window *child_window_from_point( struct window *parent, int x, int y )
 {
@@ -1932,46 +1955,51 @@ DECL_HANDLER(get_window_parents)
 /* get a list of the window children */
 DECL_HANDLER(get_window_children)
 {
-    struct window *ptr, *parent;
-    int total = 0;
+    struct window *parent = NULL;
+    unsigned int total;
     user_handle_t *data;
     data_size_t len;
     struct unicode_str cls_name;
     atom_t atom = req->atom;
+    struct desktop *desktop = NULL;
 
     if (req->desktop)
     {
-        struct desktop *desktop = get_desktop_obj( current->process, req->desktop, DESKTOP_ENUMERATE );
-        if (!desktop) return;
+        if (!(desktop = get_desktop_obj( current->process, req->desktop, DESKTOP_ENUMERATE ))) return;
         parent = desktop->top_window;
-        release_object( desktop );
     }
-    else parent = get_window( req->parent );
-
-    if (!parent) return;
+    else
+    {
+        if (req->parent && !(parent = get_window( req->parent ))) return;
+        if (!parent && !(desktop = get_thread_desktop( current, 0 ))) return;
+    }
 
     get_req_unicode_str( &cls_name );
     if (cls_name.len && !(atom = find_global_atom( NULL, &cls_name ))) return;
 
-    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 (parent)
+        total = get_children_windows( parent, atom, req->tid, NULL, 0 );
+    else
+        total = get_children_windows( desktop->top_window, atom, req->tid, NULL, 0 ) +
+                get_children_windows( desktop->msg_window, atom, req->tid, NULL, 0 );
+
     reply->count = total;
     len = min( get_reply_max_size(), total * sizeof(user_handle_t) );
     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;
-            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);
+            total = get_children_windows( desktop->top_window, atom, req->tid,
+                                          data, len / sizeof(user_handle_t) );
+            data += total;
+            len -= total * sizeof(user_handle_t);
+            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 );
 }
 
 




More information about the wine-cvs mailing list