Try 3: user32.dll fix and test ShowOwnedPopups

Vitaliy Margolen wine-patch at kievinfo.com
Mon May 16 11:42:08 CDT 2005


It looks like DefWinProc needs to be smarter about WM_SHOWWINDOW when lParam!=0.
Added more tests for WM_SHOWWINDOW to test that it could be used as
ShowOwnedPopup (for single window).

This time with input from Dmitry. Moved tests to msg.c

ShowOwnedPopups should handle none WS_POPUP style windows as well. DefWinProc
should do the same for WM_SHOWWINDOW.

Match names for WM_SHOWWINDOW status codes to MSDN

ShowWindow(hwnd, SW_HIDE) should change Z-order thus omit SWP_NOZORDER from call
to SetWindowPos, but only for none active windows also adding SWP_NOACTIVATE

Vitaliy Margolen

changelog:
  include/winuser.h
    Match names for WM_SHOWWINDOW status codes to MSDN
  dlls/user/win.c
    ShowOwnedPopups should handle none WS_POPUP style windows as well.
  dlls/user/defwnd.c
    WM_SHOWWINDOW should show/hide none WS_POPUP style windows as well.
  dlls/user/tests/msg.c
    Tests for ShowOwnedPopups
  dlls/x11drv/winpos.c
    Fix flags in ShowWindow(,SW_HIDE) for active/none active windows
-------------- next part --------------
Index: dlls/user/defwnd.c
===================================================================
RCS file: /home/wine/wine/dlls/user/defwnd.c,v
retrieving revision 1.2
diff -u -p -r1.2 defwnd.c
--- dlls/user/defwnd.c	27 Apr 2005 10:23:24 -0000	1.2
+++ dlls/user/defwnd.c	16 May 2005 16:22:20 -0000
@@ -580,11 +580,32 @@ static LRESULT DEFWND_DefWinProc( HWND h
     case WM_SHOWWINDOW:
         {
             LONG style = GetWindowLongW( hwnd, GWL_STYLE );
+            WND *pWnd;
             if (!lParam) return 0; /* sent from ShowWindow */
-            if (!(style & WS_POPUP)) return 0;
             if ((style & WS_VISIBLE) && wParam) return 0;
             if (!(style & WS_VISIBLE) && !wParam) return 0;
             if (!GetWindow( hwnd, GW_OWNER )) return 0;
+            if (!(pWnd = WIN_GetPtr( hwnd ))) return 0;
+            if (pWnd == WND_OTHER_PROCESS) return 0;
+            if (wParam)
+            {
+                if (pWnd->flags & WIN_NEEDS_SHOW_OWNEDPOPUP)
+                {
+                    pWnd->flags &= ~WIN_NEEDS_SHOW_OWNEDPOPUP;
+                    WIN_ReleasePtr( pWnd );
+                }
+                else
+                {
+                    WIN_ReleasePtr( pWnd );
+                    return 0;
+                }
+            }
+            else
+            {
+                pWnd->flags |= WIN_NEEDS_SHOW_OWNEDPOPUP;
+                WIN_ReleasePtr( pWnd );
+            }
+            
             ShowWindow( hwnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE );
             break;
         }
Index: dlls/user/win.c
===================================================================
RCS file: /home/wine/wine/dlls/user/win.c,v
retrieving revision 1.4
diff -u -p -r1.4 win.c
--- dlls/user/win.c	13 May 2005 13:58:17 -0000	1.4
+++ dlls/user/win.c	16 May 2005 16:22:21 -0000
@@ -2690,19 +2690,18 @@ BOOL WINAPI ShowOwnedPopups( HWND owner,
         if (!(pWnd = WIN_GetPtr( win_array[count] ))) continue;
         if (pWnd == WND_OTHER_PROCESS) continue;
 
-        if (pWnd->dwStyle & WS_POPUP)
+        /* Native does this for all owned windows, not just WS_POPUP */
         {
             if (fShow)
             {
                 if (pWnd->flags & WIN_NEEDS_SHOW_OWNEDPOPUP)
                 {
-                    pWnd->flags &= ~WIN_NEEDS_SHOW_OWNEDPOPUP;
                     WIN_ReleasePtr( pWnd );
                     /* In Windows, ShowOwnedPopups(TRUE) generates
                      * WM_SHOWWINDOW messages with SW_PARENTOPENING,
                      * regardless of the state of the owner
                      */
-                    SendMessageW(win_array[count], WM_SHOWWINDOW, SW_SHOW, SW_PARENTOPENING);
+                    SendMessageW(win_array[count], WM_SHOWWINDOW, SW_SHOWNORMAL, SW_PARENTOPENING);
                     continue;
                 }
             }
@@ -2710,7 +2709,6 @@ BOOL WINAPI ShowOwnedPopups( HWND owner,
             {
                 if (pWnd->dwStyle & WS_VISIBLE)
                 {
-                    pWnd->flags |= WIN_NEEDS_SHOW_OWNEDPOPUP;
                     WIN_ReleasePtr( pWnd );
                     /* In Windows, ShowOwnedPopups(FALSE) generates
                      * WM_SHOWWINDOW messages with SW_PARENTCLOSING,
Index: dlls/user/tests/msg.c
===================================================================
RCS file: /home/wine/wine/dlls/user/tests/msg.c,v
retrieving revision 1.84
diff -u -p -r1.84 msg.c
--- dlls/user/tests/msg.c	19 Apr 2005 09:48:44 -0000	1.84
+++ dlls/user/tests/msg.c	16 May 2005 16:22:21 -0000
@@ -5750,6 +5750,104 @@ static void test_DispatchMessage(void)
     }
 }
 
+/* ShowOwnedPopupsHide */
+static const struct message WmShowOwnedPopups_Hide[] = {
+    { WM_SHOWWINDOW, sent|wparam|lparam, SW_HIDE, SW_PARENTCLOSING },
+    { WM_SHOWWINDOW, sent|defwinproc|wparam|lparam, SW_HIDE, 0 },
+    { WM_WINDOWPOSCHANGING, sent|defwinproc|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE },
+    { WM_WINDOWPOSCHANGED, sent|defwinproc|wparam, SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE|SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE },
+    { 0 }
+};
+
+/* ShowOwnedPopupsHide_active */
+static const struct message WmShowOwnedPopups_Hide_active[] = {
+    { WM_SHOWWINDOW, sent|wparam|lparam, SW_HIDE, SW_PARENTCLOSING },
+    { WM_SHOWWINDOW, sent|defwinproc|wparam|lparam, SW_HIDE, 0 },
+    { WM_WINDOWPOSCHANGING, sent|defwinproc|wparam, SWP_HIDEWINDOW|SWP_NOMOVE|SWP_NOSIZE },
+    { WM_WINDOWPOSCHANGED, sent|defwinproc|wparam, SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE|SWP_HIDEWINDOW|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE  },
+    { HCBT_ACTIVATE, hook },
+    { WM_NCACTIVATE, sent|defwinproc|wparam, 0 },
+    { WM_ACTIVATE, sent|defwinproc|wparam, 0 },
+    { WM_WINDOWPOSCHANGING, sent|defwinproc|wparam, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE },
+    { HCBT_SETFOCUS, hook },
+    { WM_KILLFOCUS, sent|defwinproc },
+    { 0 }
+};
+
+/* ShowOwnedPopupsShow */
+static const struct message WmShowOwnedPopups_Show[] = {
+    { WM_SHOWWINDOW, sent|wparam|lparam, SW_SHOWNORMAL, SW_PARENTOPENING },
+    { WM_SHOWWINDOW, sent|defwinproc|wparam|lparam, SW_SHOWNORMAL, 0 },
+    { WM_WINDOWPOSCHANGING, sent|defwinproc|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE },
+    { WM_NCPAINT, sent|defwinproc|optional },
+    { WM_GETTEXT, sent|defwinproc|optional },
+    { WM_ERASEBKGND, sent|defwinproc|optional },
+    { WM_WINDOWPOSCHANGED, sent|defwinproc|wparam, SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE|SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE },
+    { 0 }
+};
+
+static void test_ShowOwnedPopups_helper(HWND owner, HWND owned)
+{
+    ok(ShowOwnedPopups(owner, TRUE), "Failed calling ShowOwnedPopups(%p, TRUE)\n", owner);
+    ok(!IsWindowVisible(owned), "Window %p should NOT be visible\n", owned);
+
+    ok(!SendMessageW(owned, WM_SHOWWINDOW, SW_SHOWNORMAL, SW_PARENTOPENING), "Failed sending message WM_SHOWWINDOW to %p\n", owned);
+    ok(!IsWindowVisible(owned), "Window %p should NOT be visible\n", owned);
+
+    ShowWindow(owner, SW_SHOW);
+    ShowWindow(owned, SW_SHOW);
+
+    flush_sequence();
+    ok(!SendMessageW(owned, WM_SHOWWINDOW, SW_HIDE, SW_PARENTCLOSING), "Failed sending message WM_SHOWWINDOW to %p\n", owned);
+    ok_sequence(WmShowOwnedPopups_Hide_active, "SendMessageW(owned, WM_SHOWWINDOW, SW_HIDE, SW_PARENTCLOSING)", 0);
+    ok(!IsWindowVisible(owned), "Window %p should NOT be visible\n", owned);
+
+    ok(ShowOwnedPopups(owner, TRUE), "Failed calling ShowOwnedPopups(%p, TRUE)\n", owner);
+    ok_sequence(WmShowOwnedPopups_Show, "ShowOwnedPopups(TRUE)", 0);
+    ok(IsWindowVisible(owned), "Window %p should be visible\n", owned);
+
+    flush_sequence();
+    ok(ShowOwnedPopups(owner, FALSE), "Failed calling ShowOwnedPopups(%p, FALSE)\n", owner);
+    ok_sequence(WmShowOwnedPopups_Hide, "ShowOwnedPopups(FALSE)", 0);
+    ok(!IsWindowVisible(owned), "Window %p should NOT be visible\n", owned);
+
+    ok(!SendMessageW(owned, WM_SHOWWINDOW, SW_SHOWNORMAL, SW_PARENTOPENING), "Failed sending message WM_SHOWWINDOW to %p\n", owned);
+    ok_sequence(WmShowOwnedPopups_Show, "SendMessageW(owned, WM_SHOWWINDOW, SW_SHOWNORMAL, SW_PARENTOPENING)", 0);
+    ok(IsWindowVisible(owned), "Window %p should be visible\n", owned);
+
+    ShowWindow(owned, SW_HIDE);
+    ok(!IsWindowVisible(owned), "Window %p should NOT be visible\n", owned);
+    ok(ShowOwnedPopups(owner, TRUE), "Failed calling ShowOwnedPopups(%p, TRUE)\n", owner);
+    ok(!IsWindowVisible(owned), "Window %p should NOT be visible\n", owned);
+
+    ok(!SendMessageW(owned, WM_SHOWWINDOW, SW_SHOWNORMAL, SW_PARENTOPENING), "Failed sending message WM_SHOWWINDOW to %p\n", owned);
+    ok(!IsWindowVisible(owned), "Window %p should NOT be visible\n", owned);
+}
+
+static void test_ShowOwnedPopups(void)
+{
+    HWND hwnd, hwnd1;
+    
+    hwnd = CreateWindowExA(0, "static", "Owner", WS_OVERLAPPEDWINDOW,
+			     100, 100, 200, 200, 0, 0, 0, NULL);
+    assert(hwnd != 0);
+    hwnd1 = CreateWindowExA(0, "TestWindowClass", "Owned", WS_OVERLAPPEDWINDOW,
+			     0, 0, 50, 50, hwnd, 0, 0, NULL);
+    assert(hwnd1 != 0);
+
+    test_ShowOwnedPopups_helper (hwnd, hwnd1);
+
+    DestroyWindow(hwnd1);
+    hwnd1 = CreateWindowExA(0, "TestWindowClass", NULL, WS_POPUPWINDOW,
+			     0, 0, 50, 50, hwnd, 0, 0, NULL);
+    assert(hwnd1 != 0);
+
+    ShowWindow(hwnd, SW_HIDE);
+    test_ShowOwnedPopups_helper (hwnd, hwnd1);
+
+    DestroyWindow(hwnd);
+    DestroyWindow(hwnd1);
+}
 
 START_TEST(msg)
 {
@@ -5804,6 +5902,7 @@ START_TEST(msg)
     test_set_hook();
     test_DestroyWindow();
     test_DispatchMessage();
+    test_ShowOwnedPopups();
 
     UnhookWindowsHookEx(hCBT_hook);
     if (pUnhookWinEvent)
Index: dlls/x11drv/winpos.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/winpos.c,v
retrieving revision 1.133
diff -u -p -r1.133 winpos.c
--- dlls/x11drv/winpos.c	25 Mar 2005 16:47:04 -0000	1.133
+++ dlls/x11drv/winpos.c	16 May 2005 16:22:21 -0000
@@ -934,7 +934,9 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT c
         case SW_HIDE:
             if (!wasVisible) return FALSE;
             showFlag = FALSE;
-            swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER;
+            swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE;
+            if (hwnd != GetActiveWindow())
+                swp |= SWP_NOACTIVATE | SWP_NOZORDER;
 	    break;
 
 	case SW_SHOWMINNOACTIVE:
Index: include/winuser.h
===================================================================
RCS file: /home/wine/wine/include/winuser.h,v
retrieving revision 1.215
diff -u -p -r1.215 winuser.h
--- include/winuser.h	14 Apr 2005 11:32:28 -0000	1.215
+++ include/winuser.h	16 May 2005 16:22:22 -0000
@@ -3010,11 +3010,11 @@ typedef struct {
     DWORD dwTimeout;
 } FLASHWINFO, *PFLASHWINFO;
 
-/* WM_SHOWWINDOW wParam codes */
+/* WM_SHOWWINDOW lParam codes */
 #define SW_PARENTCLOSING    1
-#define SW_OTHERMAXIMIZED   2
+#define SW_OTHERZOOM        2
 #define SW_PARENTOPENING    3
-#define SW_OTHERRESTORED    4
+#define SW_OTHERUNZOOM      4
 
 /* SetLayeredWindowAttributes() flags */
 #define LWA_COLORKEY        0x00000001


More information about the wine-patches mailing list