diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index 700e60db17..f4896052cc 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -3013,6 +3013,93 @@ static void test_popup_zorder(HWND hwnd_D, HWND hwnd_E, DWORD style)
     DestroyWindow(hwnd_F);
 }
 
+static void test_child_topmost_zorder(HWND hwnd_D)
+{
+    HWND hwnd_A, hwnd_B, hwnd_C;
+
+    BOOL is_wine = !strcmp(winetest_platform, "wine");
+
+    hwnd_C = CreateWindowExA(0, "MainWindowClass", NULL,
+                             WS_CHILD,
+                             100, 100, 100, 100,
+                             hwnd_D, 0, GetModuleHandleA(NULL), NULL);
+    check_z_order(hwnd_C, 0, 0, 0, FALSE);
+
+    hwnd_B = CreateWindowExA(0, "MainWindowClass", NULL,
+                             WS_CHILD,
+                             100, 100, 100, 100,
+                             hwnd_D, 0, GetModuleHandleA(NULL), NULL);
+    check_z_order(hwnd_C, hwnd_B, 0, 0, FALSE);
+    check_z_order(hwnd_B, 0, hwnd_C, 0, FALSE);
+
+    hwnd_A = CreateWindowExA(WS_EX_TOPMOST, "MainWindowClass", NULL,
+                             WS_CHILD,
+                             100, 100, 100, 100,
+                             hwnd_D, 0, GetModuleHandleA(NULL), NULL);
+    check_z_order(hwnd_C, hwnd_B, 0, 0, FALSE);
+    check_z_order(hwnd_B, hwnd_A, hwnd_C, 0, FALSE);
+if (!is_wine) /* FIXME: remove once Wine is fixed */
+    check_z_order(hwnd_A, 0, hwnd_B, 0, TRUE);
+
+    SetWindowPos(hwnd_A, HWND_TOP, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE);
+    check_z_order(hwnd_C, hwnd_B, hwnd_A, 0, FALSE);
+    check_z_order(hwnd_B, 0, hwnd_C, 0, FALSE);
+if (!is_wine) /* FIXME: remove once Wine is fixed */
+    check_z_order(hwnd_A, hwnd_C, 0, 0, TRUE);
+
+    SetWindowPos(hwnd_B, HWND_TOP, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE);
+    check_z_order(hwnd_C, 0, hwnd_A, 0, FALSE);
+    check_z_order(hwnd_B, hwnd_A, 0, 0, FALSE);
+if (!is_wine) /* FIXME: remove once Wine is fixed */
+    check_z_order(hwnd_A, hwnd_C, hwnd_B, 0, TRUE);
+
+    SetWindowPos(hwnd_C, HWND_TOP, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE);
+    check_z_order(hwnd_C, hwnd_B, 0, 0, FALSE);
+    check_z_order(hwnd_B, hwnd_A, hwnd_C, 0, FALSE);
+if (!is_wine) /* FIXME: remove once Wine is fixed */
+    check_z_order(hwnd_A, 0, hwnd_B, 0, TRUE);
+
+    SetWindowPos(hwnd_A, HWND_TOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE);
+    check_z_order(hwnd_C, hwnd_B, 0, 0, FALSE);
+    check_z_order(hwnd_B, hwnd_A, hwnd_C, 0, FALSE);
+if (!is_wine) /* FIXME: remove once Wine is fixed */
+    check_z_order(hwnd_A, 0, hwnd_B, 0, TRUE);
+
+    SetWindowPos(hwnd_B, HWND_TOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE);
+    check_z_order(hwnd_C, hwnd_B, 0, 0, FALSE);
+    check_z_order(hwnd_B, hwnd_A, hwnd_C, 0, FALSE);
+if (!is_wine) /* FIXME: remove once Wine is fixed */
+    check_z_order(hwnd_A, 0, hwnd_B, 0, TRUE);
+
+    SetWindowPos(hwnd_C, HWND_TOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE);
+    check_z_order(hwnd_C, hwnd_B, 0, 0, FALSE);
+    check_z_order(hwnd_B, hwnd_A, hwnd_C, 0, FALSE);
+if (!is_wine) /* FIXME: remove once Wine is fixed */
+    check_z_order(hwnd_A, 0, hwnd_B, 0, TRUE);
+
+    SetWindowPos(hwnd_A, HWND_TOP, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE);
+    check_z_order(hwnd_C, hwnd_B, 0, 0, FALSE);
+    check_z_order(hwnd_B, hwnd_A, hwnd_C, 0, FALSE);
+if (!is_wine) /* FIXME: remove once Wine is fixed */
+    check_z_order(hwnd_A, 0, hwnd_B, 0, TRUE);
+
+    SetWindowPos(hwnd_B, HWND_TOP, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE);
+    check_z_order(hwnd_C, hwnd_B, 0, 0, FALSE);
+    check_z_order(hwnd_B, hwnd_A, hwnd_C, 0, FALSE);
+if (!is_wine) /* FIXME: remove once Wine is fixed */
+    check_z_order(hwnd_A, 0, hwnd_B, 0, TRUE);
+
+    SetWindowPos(hwnd_C, HWND_TOP, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE);
+    check_z_order(hwnd_C, hwnd_B, 0, 0, FALSE);
+    check_z_order(hwnd_B, hwnd_A, hwnd_C, 0, FALSE);
+if (!is_wine) /* FIXME: remove once Wine is fixed */
+    check_z_order(hwnd_A, 0, hwnd_B, 0, TRUE);
+
+    DestroyWindow(hwnd_A);
+    DestroyWindow(hwnd_B);
+    DestroyWindow(hwnd_C);
+}
+
 static void test_vis_rgn( HWND hwnd )
 {
     RECT win_rect, rgn_rect;
@@ -11971,6 +12058,7 @@ START_TEST(win)
     test_children_zorder(hwndMain);
     test_popup_zorder(hwndMain2, hwndMain, WS_POPUP);
     test_popup_zorder(hwndMain2, hwndMain, 0);
+    test_child_topmost_zorder(hwndMain);
     test_GetLastActivePopup();
     test_keyboard_input(hwndMain);
     test_mouse_input(hwndMain);
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c
index b92a20df18..3588ee8394 100644
--- a/dlls/user32/winpos.c
+++ b/dlls/user32/winpos.c
@@ -2083,6 +2083,12 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags,
     RECT visible_rect, old_visible_rect, old_window_rect, old_client_rect, extra_rects[3];
     struct window_surface *old_surface, *new_surface = NULL;
 
+    if ((GetWindowLongW( hwnd, GWL_STYLE ) & (WS_CHILD | WS_POPUP)) == WS_CHILD
+        && insert_after == HWND_TOPMOST )
+    {
+        swp_flags |= SWP_NOZORDER;
+    }
+
     if (!parent || parent == GetDesktopWindow())
     {
         new_surface = &dummy_surface;  /* provide a default surface for top-level windows */
-- 
2.20.1

