Jacek Caban : server: Orphan child windows when unlinking them from parent.

Alexandre Julliard julliard at winehq.org
Wed Feb 9 16:03:49 CST 2022


Module: wine
Branch: master
Commit: 862d0eeff978c6a2294e0bf9d39febdd3ef98f46
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=862d0eeff978c6a2294e0bf9d39febdd3ef98f46

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Feb  8 13:13:28 2022 +0100

server: Orphan child windows when unlinking them from parent.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/user32/tests/win.c | 34 ++++++++++++++++++++++++++++++++++
 server/window.c         |  5 ++++-
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index d38ce382b86..a5848ac28da 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -12786,6 +12786,39 @@ static void test_DragDetect(void)
     ok(!(GetKeyState( VK_LBUTTON ) & 0x8000), "got VK_LBUTTON\n");
 }
 
+static LRESULT WINAPI ncdestroy_test_proc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
+{
+    unsigned int ret;
+    HWND parent;
+
+    switch (msg)
+    {
+    case WM_NCDESTROY:
+        SetLastError( 0xdeadbeef );
+        ret = SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 100, 100, SWP_NOSIZE|SWP_NOMOVE );
+        todo_wine
+        ok( !ret, "SetWindowPos succeeded\n" );
+        todo_wine
+        ok( GetLastError() == ERROR_INVALID_PARAMETER, "SetWindowPos returned error %u\n", GetLastError() );
+
+        SetLastError( 0xdeadbeef );
+        parent = SetParent( hwnd, hwndMain );
+        ok( parent == 0, "SetParent returned %p\n", parent );
+        ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %u\n", GetLastError() );
+        break;
+    }
+
+    return DefWindowProcW( hwnd, msg, wp, lp );
+}
+
+static void test_ncdestroy(void)
+{
+    HWND hwnd;
+    hwnd = create_tool_window( WS_POPUP, 0 );
+    SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (LONG_PTR)ncdestroy_test_proc );
+    DestroyWindow(hwnd);
+}
+
 START_TEST(win)
 {
     char **argv;
@@ -12900,6 +12933,7 @@ START_TEST(win)
     test_parent_owner();
     test_enum_thread_windows();
     test_thread_exit_destroy();
+    test_ncdestroy();
 
     test_icons();
     test_SetWindowPos(hwndMain, hwndMain2);
diff --git a/server/window.c b/server/window.c
index 6cc2f9d0f70..da05d024056 100644
--- a/server/window.c
+++ b/server/window.c
@@ -79,6 +79,7 @@ struct window
     unsigned int     is_unicode : 1;  /* ANSI or unicode */
     unsigned int     is_linked : 1;   /* is it linked into the parent z-order list? */
     unsigned int     is_layered : 1;  /* has layered info been set? */
+    unsigned int     is_orphan : 1;   /* is window orphaned */
     unsigned int     color_key;       /* color key for a layered window */
     unsigned int     alpha;           /* alpha value for a layered window */
     unsigned int     layered_flags;   /* flags for a layered window */
@@ -203,7 +204,7 @@ static inline int is_desktop_window( const struct window *win )
 /* check if window is orphaned */
 static int is_orphan_window( struct window *win )
 {
-    do if (!win->handle) return 1;
+    do if (win->is_orphan) return 1;
     while ((win = win->parent));
     return 0;
 }
@@ -347,6 +348,7 @@ static int set_parent_window( struct window *win, struct window *parent )
         list_remove( &win->entry );  /* unlink it from the previous location */
         list_add_head( &win->parent->unlinked, &win->entry );
         win->is_linked = 0;
+        win->is_orphan = 1;
     }
     return 1;
 }
@@ -566,6 +568,7 @@ static struct window *create_window( struct window *parent, struct window *owner
     win->is_unicode     = 1;
     win->is_linked      = 0;
     win->is_layered     = 0;
+    win->is_orphan      = 0;
     win->dpi_awareness  = DPI_AWARENESS_PER_MONITOR_AWARE;
     win->dpi            = 0;
     win->user_data      = 0;




More information about the wine-cvs mailing list