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;