David Hedberg : user32: Fix return value when passing a non-sibling preceding window to SetWindowPos .

Alexandre Julliard julliard at winehq.org
Wed Mar 30 13:15:41 CDT 2011


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

Author: David Hedberg <dhedberg at codeweavers.com>
Date:   Tue Mar 22 02:40:46 2011 +0100

user32: Fix return value when passing a non-sibling preceding window to SetWindowPos.

Acrobat Reader relies on SetWindowPos, with hwndInsertAfter set to a
non-sibling window and no SWP_NOZORDER passed, to return true.

---

 dlls/user32/tests/win.c |   22 +++++++++-------------
 dlls/user32/winpos.c    |   43 ++++++++++++++++++++++++++-----------------
 2 files changed, 35 insertions(+), 30 deletions(-)

diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index 67601b1..278a282 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -2064,7 +2064,7 @@ static void test_SetWindowPos(HWND hwnd, HWND hwnd2)
 
     /* Returns TRUE also for windows that are not siblings */
     ret = SetWindowPos(hwnd_child, hwnd2, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
-    todo_wine ok(ret, "Got %d\n", ret);
+    ok(ret, "Got %d\n", ret);
     check_active_state(hwnd2, hwnd2, hwnd2);
 
     ret = SetWindowPos(hwnd2, hwnd_child, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
@@ -2074,7 +2074,7 @@ static void test_SetWindowPos(HWND hwnd, HWND hwnd2)
     /* Does not seem to do anything even without passing flags, still returns TRUE */
     GetWindowRect(hwnd_child, &rc1);
     ret = SetWindowPos(hwnd_child, hwnd2 , 1, 2, 3, 4, 0);
-    todo_wine ok(ret, "Got %d\n", ret);
+    ok(ret, "Got %d\n", ret);
     GetWindowRect(hwnd_child, &rc2);
     ok(rc1.left == rc2.left && rc1.top == rc2.top &&
        rc1.right == rc2.right && rc1.bottom == rc2.bottom,
@@ -2087,20 +2087,16 @@ static void test_SetWindowPos(HWND hwnd, HWND hwnd2)
     ret = SetWindowPos(hwnd2, hwnd_child, 1, 2, 3, 4, 0);
     ok(ret, "Got %d\n", ret);
     GetWindowRect(hwnd2, &rc2);
-    todo_wine
-        ok(rc1.left == rc2.left && rc1.top == rc2.top &&
-           rc1.right == rc2.right && rc1.bottom == rc2.bottom,
-           "(%d, %d, %d, %d) != (%d, %d, %d, %d)\n",
-           rc1.left, rc1.top, rc1.right, rc1.bottom, rc2.left, rc2.top, rc2.right, rc2.bottom);
+    ok(rc1.left == rc2.left && rc1.top == rc2.top &&
+       rc1.right == rc2.right && rc1.bottom == rc2.bottom,
+       "(%d, %d, %d, %d) != (%d, %d, %d, %d)\n",
+       rc1.left, rc1.top, rc1.right, rc1.bottom, rc2.left, rc2.top, rc2.right, rc2.bottom);
     check_active_state(hwnd2, hwnd2, hwnd2);
 
-    /* Restore window */
-    SetWindowPos(hwnd2, HWND_TOP, rc1.left, rc1.top, rc1.right-rc1.left, rc1.bottom-rc1.top, 0);
-
     /* .. and with these windows. */
     GetWindowRect(hwnd_grandchild, &rc1);
     ret = SetWindowPos(hwnd_grandchild, hwnd_child2, 1, 2, 3, 4, 0);
-    todo_wine ok(ret, "Got %d\n", ret);
+    ok(ret, "Got %d\n", ret);
     GetWindowRect(hwnd_grandchild, &rc2);
     ok(rc1.left == rc2.left && rc1.top == rc2.top &&
        rc1.right == rc2.right && rc1.bottom == rc2.bottom,
@@ -2154,8 +2150,8 @@ static void test_SetWindowPos(HWND hwnd, HWND hwnd2)
     check_active_state(hwnd2, hwnd2, hwnd2);
 
     ret = SetWindowPos(hwnd, hwnd_desktop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
-    todo_wine ok(!ret, "Got %d\n", ret);
-    todo_wine check_active_state(hwnd2, hwnd2, hwnd2);
+    ok(!ret, "Got %d\n", ret);
+    check_active_state(hwnd2, hwnd2, hwnd2);
 
     DestroyWindow(hwnd_grandchild);
     DestroyWindow(hwnd_child);
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c
index 789238f..57ccb81 100644
--- a/dlls/user32/winpos.c
+++ b/dlls/user32/winpos.c
@@ -1902,11 +1902,6 @@ static BOOL fixup_flags( WINDOWPOS *winpos )
     /* Check hwndInsertAfter */
     if (winpos->flags & SWP_NOZORDER) goto done;
 
-    /* fix sign extension */
-    if (winpos->hwndInsertAfter == (HWND)0xffff) winpos->hwndInsertAfter = HWND_TOPMOST;
-    else if (winpos->hwndInsertAfter == (HWND)0xfffe) winpos->hwndInsertAfter = HWND_NOTOPMOST;
-
-    /* hwndInsertAfter must be a sibling of the window */
     if (winpos->hwndInsertAfter == HWND_TOP)
     {
         if (GetWindow(winpos->hwnd, GW_HWNDFIRST) == winpos->hwnd)
@@ -1929,16 +1924,9 @@ static BOOL fixup_flags( WINDOWPOS *winpos )
     }
     else
     {
-        if (GetAncestor( winpos->hwndInsertAfter, GA_PARENT ) != parent) ret = FALSE;
-        else
-        {
-            /* don't need to change the Zorder of hwnd if it's already inserted
-             * after hwndInsertAfter or when inserting hwnd after itself.
-             */
-            if ((winpos->hwnd == winpos->hwndInsertAfter) ||
-                (winpos->hwnd == GetWindow( winpos->hwndInsertAfter, GW_HWNDNEXT )))
-                winpos->flags |= SWP_NOZORDER;
-        }
+        if ((winpos->hwnd == winpos->hwndInsertAfter) ||
+            (winpos->hwnd == GetWindow( winpos->hwndInsertAfter, GW_HWNDNEXT )))
+            winpos->flags |= SWP_NOZORDER;
     }
  done:
     WIN_ReleasePtr( wndPtr );
@@ -2033,8 +2021,29 @@ BOOL USER_SetWindowPos( WINDOWPOS * winpos )
     UINT orig_flags;
     
     orig_flags = winpos->flags;
-    
-    /* First make sure that coordinates are valid for WM_WINDOWPOSCHANGING */
+
+    /* First, check z-order arguments.  */
+    if (!(winpos->flags & SWP_NOZORDER))
+    {
+        /* fix sign extension */
+        if (winpos->hwndInsertAfter == (HWND)0xffff) winpos->hwndInsertAfter = HWND_TOPMOST;
+        else if (winpos->hwndInsertAfter == (HWND)0xfffe) winpos->hwndInsertAfter = HWND_NOTOPMOST;
+
+        if (!(winpos->hwndInsertAfter == HWND_TOP ||
+              winpos->hwndInsertAfter == HWND_BOTTOM ||
+              winpos->hwndInsertAfter == HWND_TOPMOST ||
+              winpos->hwndInsertAfter == HWND_NOTOPMOST))
+        {
+            HWND parent = GetAncestor( winpos->hwnd, GA_PARENT );
+            HWND insertafter_parent = GetAncestor( winpos->hwndInsertAfter, GA_PARENT );
+
+            /* hwndInsertAfter must be a sibling of the window */
+            if (!insertafter_parent) return FALSE;
+            if (insertafter_parent != parent) return TRUE;
+        }
+    }
+
+    /* Make sure that coordinates are valid for WM_WINDOWPOSCHANGING */
     if (!(winpos->flags & SWP_NOMOVE))
     {
         if (winpos->x < -32768) winpos->x = -32768;




More information about the wine-cvs mailing list