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