[PATCH] user32: Fix messages sent on a window without WS_CHILD, but with an invisible parent, when it is shown.

Gabriel Ivăncescu gabrielopcode at gmail.com
Thu Feb 13 07:45:55 CST 2020


Some applications depend on the fact that WM_WINDOWPOSCHANGING is sent
after WM_SHOWWINDOW when SetParent is called, even if the window ends up
not visible because its parent is not visible, and occurs when the window
itself does not have the WS_CHILD style set.

This also fixes a TODO message sequence, so that Wine matches Windows.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=40262
Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
 dlls/user32/tests/msg.c |  3 ++-
 dlls/user32/winpos.c    | 11 +++++++----
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 935e437..7c83d10 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -16359,6 +16359,7 @@ static const struct message WmSetParentSeq_2[] = {
     { HCBT_ACTIVATE, hook|optional },
     { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
     { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE },
+    { WM_QUERYNEWPALETTE, sent|optional },
     { WM_NCACTIVATE, sent|wparam|optional, 1 },
     { WM_ACTIVATE, sent|wparam|optional, 1 },
     { HCBT_SETFOCUS, hook|optional },
@@ -16429,7 +16430,7 @@ static void test_SetParent(void)
 
     SetParent(popup, child);
     flush_events();
-    ok_sequence(WmSetParentSeq_2, "SetParent() visible WS_POPUP", TRUE);
+    ok_sequence(WmSetParentSeq_2, "SetParent() visible WS_POPUP", FALSE);
 
     ok(GetWindowLongA(popup, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
     ok(!IsWindowVisible(popup), "IsWindowVisible() should return FALSE\n");
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c
index b92a20d..0caff03 100644
--- a/dlls/user32/winpos.c
+++ b/dlls/user32/winpos.c
@@ -1122,8 +1122,8 @@ static BOOL show_window( HWND hwnd, INT cmd )
 
     swp = USER_Driver->pShowWindow( hwnd, cmd, &newPos, swp );
 
-    parent = GetAncestor( hwnd, GA_PARENT );
-    if (parent && !IsWindowVisible( parent ) && !(swp & SWP_STATECHANGED))
+    if ((style & WS_CHILD) && (parent = GetAncestor( hwnd, GA_PARENT )) &&
+        !IsWindowVisible( parent ) && !(swp & SWP_STATECHANGED))
     {
         /* if parent is not visible simply toggle WS_VISIBLE and return */
         if (showFlag) WIN_SetStyle( hwnd, WS_VISIBLE, 0 );
@@ -1955,8 +1955,11 @@ static BOOL fixup_flags( WINDOWPOS *winpos, const RECT *old_window_rect, int par
     if (winpos->cy < 0) winpos->cy = 0;
     else if (winpos->cy > 32767) winpos->cy = 32767;
 
-    parent = GetAncestor( winpos->hwnd, GA_PARENT );
-    if (!IsWindowVisible( parent )) winpos->flags |= SWP_NOREDRAW;
+    if (wndPtr->dwStyle & WS_CHILD)
+    {
+        parent = GetAncestor( winpos->hwnd, GA_PARENT );
+        if (!IsWindowVisible( parent )) winpos->flags |= SWP_NOREDRAW;
+    }
 
     if (wndPtr->dwStyle & WS_VISIBLE) winpos->flags &= ~SWP_SHOWWINDOW;
     else
-- 
2.21.0




More information about the wine-devel mailing list