From f839a179a2136984fda1ec704b57befdd7dbd563 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Wed, 17 May 2006 16:35:26 +0900 Subject: [PATCH] user32: Make all the recently added ShowWindow tests pass in Wine. --- dlls/user/tests/msg.c | 39 +++++++++++++++++++++++---------- dlls/x11drv/winpos.c | 50 ++++++++++++++++++++++++++++++++----------- 2 files changed, 66 insertions(+), 23 deletions(-) diff --git a/dlls/user/tests/msg.c b/dlls/user/tests/msg.c index 5febf3f884b..02194612b1e 100644 --- a/dlls/user/tests/msg.c +++ b/dlls/user/tests/msg.c @@ -643,6 +643,9 @@ static const struct message WmShowChildInvisibleParentSeq_1[] = { { WM_MOVE, sent|defwinproc }, { WM_SIZE, sent|defwinproc }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, + /* FIXME: Wine creates an icon/title window while Windows doesn't */ + { WM_PARENTNOTIFY, sent|parent|wparam|optional, WM_CREATE }, + { WM_GETTEXT, sent|optional }, { 0 } }; /* repeated ShowWindow(SW_MINIMIZE) for child with invisible parent */ @@ -677,6 +680,9 @@ static const struct message WmShowChildInvisibleParentSeq_3[] = { { WM_MOVE, sent|defwinproc }, { WM_SIZE, sent|defwinproc }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, + /* FIXME: Wine creates an icon/title window while Windows doesn't */ + { WM_PARENTNOTIFY, sent|parent|wparam|optional, WM_CREATE }, + { WM_GETTEXT, sent|optional }, { 0 } }; /* repeated ShowWindow(SW_SHOWMINIMIZED) for child with invisible parent */ @@ -693,6 +699,9 @@ static const struct message WmShowChildInvisibleParentSeq_4[] = { { WM_MOVE, sent|defwinproc }, { WM_SIZE, sent|defwinproc }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, + /* FIXME: Wine creates an icon/title window while Windows doesn't */ + { WM_PARENTNOTIFY, sent|parent|wparam|optional, WM_CREATE }, + { WM_GETTEXT, sent|optional }, { 0 } }; /* repeated ShowWindow(SW_SHOWMINNOACTIVE) for child with invisible parent */ @@ -3281,6 +3290,7 @@ static void test_showwindow(void) hwnd = CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP | WS_MAXIMIZE, 100, 100, 200, 200, 0, 0, 0, NULL); ok (hwnd != 0, "Failed to create popup window\n"); + ok(IsZoomed(hwnd), "window should be maximized\n"); ok_sequence(WmCreateInvisibleMaxPopupSeq, "CreateWindow(WS_MAXIMIZED):popup", FALSE); trace("done\n"); @@ -3291,10 +3301,12 @@ static void test_showwindow(void) rc.left, rc.top, rc.right, rc.bottom); /* Reset window's size & position */ SetWindowPos(hwnd, 0, 10, 10, 200, 200, SWP_NOZORDER | SWP_NOACTIVATE); + ok(IsZoomed(hwnd), "window should be maximized\n"); flush_sequence(); - trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible popup window\n"); + trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible maximized popup window\n"); ShowWindow(hwnd, SW_SHOWMAXIMIZED); + ok(IsZoomed(hwnd), "window should be maximized\n"); ok_sequence(WmShowMaxPopupResizedSeq, "ShowWindow(SW_SHOWMAXIMIZED):popup", FALSE); trace("done\n"); @@ -3314,11 +3326,13 @@ static void test_showwindow(void) hwnd = CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP | WS_MAXIMIZE, 100, 100, 200, 200, 0, 0, 0, NULL); ok (hwnd != 0, "Failed to create popup window\n"); + ok(IsZoomed(hwnd), "window should be maximized\n"); ok_sequence(WmCreateInvisibleMaxPopupSeq, "CreateWindow(WS_MAXIMIZED):popup", FALSE); trace("done\n"); - trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible popup window\n"); + trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible maximized popup window\n"); ShowWindow(hwnd, SW_SHOWMAXIMIZED); + ok(IsZoomed(hwnd), "window should be maximized\n"); ok_sequence(WmShowMaxPopupSeq, "ShowWindow(SW_SHOWMAXIMIZED):popup", FALSE); trace("done\n"); DestroyWindow(hwnd); @@ -3331,6 +3345,7 @@ static void test_showwindow(void) hwnd = CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP | WS_MAXIMIZE | WS_VISIBLE, 100, 100, 200, 200, 0, 0, 0, NULL); ok (hwnd != 0, "Failed to create popup window\n"); + ok(IsZoomed(hwnd), "window should be maximized\n"); ok_sequence(WmCreateMaxPopupSeq, "CreateWindow(WS_MAXIMIZED):popup", FALSE); trace("done\n"); DestroyWindow(hwnd); @@ -3344,11 +3359,13 @@ static void test_showwindow(void) hwnd = CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP | WS_VISIBLE, 100, 100, 200, 200, 0, 0, 0, NULL); ok (hwnd != 0, "Failed to create popup window\n"); + ok(!IsZoomed(hwnd), "window should NOT be maximized\n"); ok_sequence(WmCreatePopupSeq, "CreateWindow(WS_VISIBLE):popup", TRUE); trace("done\n"); trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for visible popup window\n"); ShowWindow(hwnd, SW_SHOWMAXIMIZED); + ok(IsZoomed(hwnd), "window should be maximized\n"); ok_sequence(WmShowVisMaxPopupSeq, "ShowWindow(SW_SHOWMAXIMIZED):popup", TRUE); trace("done\n"); DestroyWindow(hwnd); @@ -3740,14 +3757,14 @@ static void invisible_parent_tests(void) ok_sequence(WmCreateChildSeq, "CreateWindow:child", FALSE); ShowWindow( hchild, SW_MINIMIZE ); - ok_sequence(WmShowChildInvisibleParentSeq_1, "ShowWindow(SW_MINIMIZE) child with invisible parent", TRUE); + ok_sequence(WmShowChildInvisibleParentSeq_1, "ShowWindow(SW_MINIMIZE) child with invisible parent", FALSE); ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n"); ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n"); /* repeat */ flush_events(); ShowWindow( hchild, SW_MINIMIZE ); - ok_sequence(WmShowChildInvisibleParentSeq_1r, "ShowWindow(SW_MINIMIZE) child with invisible parent", TRUE); + ok_sequence(WmShowChildInvisibleParentSeq_1r, "ShowWindow(SW_MINIMIZE) child with invisible parent", FALSE); DestroyWindow(hchild); hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD, @@ -3755,14 +3772,14 @@ static void invisible_parent_tests(void) flush_sequence(); ShowWindow( hchild, SW_MAXIMIZE ); - ok_sequence(WmShowChildInvisibleParentSeq_2, "ShowWindow(SW_MAXIMIZE) child with invisible parent", TRUE); + ok_sequence(WmShowChildInvisibleParentSeq_2, "ShowWindow(SW_MAXIMIZE) child with invisible parent", FALSE); ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n"); ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n"); /* repeat */ flush_events(); ShowWindow( hchild, SW_MAXIMIZE ); - ok_sequence(WmShowChildInvisibleParentSeq_2r, "ShowWindow(SW_MAXIMIZE) child with invisible parent", TRUE); + ok_sequence(WmShowChildInvisibleParentSeq_2r, "ShowWindow(SW_MAXIMIZE) child with invisible parent", FALSE); DestroyWindow(hchild); hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD, @@ -3770,14 +3787,14 @@ static void invisible_parent_tests(void) flush_sequence(); ShowWindow( hchild, SW_SHOWMINIMIZED ); - ok_sequence(WmShowChildInvisibleParentSeq_3, "ShowWindow(SW_SHOWMINIMIZED) child with invisible parent", TRUE); + ok_sequence(WmShowChildInvisibleParentSeq_3, "ShowWindow(SW_SHOWMINIMIZED) child with invisible parent", FALSE); ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n"); ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n"); /* repeat */ flush_events(); ShowWindow( hchild, SW_SHOWMINIMIZED ); - ok_sequence(WmShowChildInvisibleParentSeq_3r, "ShowWindow(SW_SHOWMINIMIZED) child with invisible parent", TRUE); + ok_sequence(WmShowChildInvisibleParentSeq_3r, "ShowWindow(SW_SHOWMINIMIZED) child with invisible parent", FALSE); DestroyWindow(hchild); hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD, @@ -3786,7 +3803,7 @@ static void invisible_parent_tests(void) /* same as ShowWindow( hchild, SW_MAXIMIZE ); */ ShowWindow( hchild, SW_SHOWMAXIMIZED ); - ok_sequence(WmShowChildInvisibleParentSeq_2, "ShowWindow(SW_SHOWMAXIMIZED) child with invisible parent", TRUE); + ok_sequence(WmShowChildInvisibleParentSeq_2, "ShowWindow(SW_SHOWMAXIMIZED) child with invisible parent", FALSE); ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n"); ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n"); @@ -3796,14 +3813,14 @@ static void invisible_parent_tests(void) flush_sequence(); ShowWindow( hchild, SW_SHOWMINNOACTIVE ); - ok_sequence(WmShowChildInvisibleParentSeq_4, "ShowWindow(SW_SHOWMINNOACTIVE) child with invisible parent", TRUE); + ok_sequence(WmShowChildInvisibleParentSeq_4, "ShowWindow(SW_SHOWMINNOACTIVE) child with invisible parent", FALSE); ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n"); ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n"); /* repeat */ flush_events(); ShowWindow( hchild, SW_SHOWMINNOACTIVE ); - ok_sequence(WmShowChildInvisibleParentSeq_4r, "ShowWindow(SW_SHOWMINNOACTIVE) child with invisible parent", TRUE); + ok_sequence(WmShowChildInvisibleParentSeq_4r, "ShowWindow(SW_SHOWMINNOACTIVE) child with invisible parent", FALSE); DestroyWindow(hchild); hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD, diff --git a/dlls/x11drv/winpos.c b/dlls/x11drv/winpos.c index 5fdde83d5cd..bc19aa84949 100644 --- a/dlls/x11drv/winpos.c +++ b/dlls/x11drv/winpos.c @@ -852,13 +852,23 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect ) if (IsIconic( hwnd )) { - if (cmd == SW_MINIMIZE) return SWP_NOSIZE | SWP_NOMOVE; + switch (cmd) + { + case SW_SHOWMINNOACTIVE: + case SW_SHOWMINIMIZED: + case SW_FORCEMINIMIZE: + case SW_MINIMIZE: + return SWP_NOSIZE | SWP_NOMOVE; + } if (!SendMessageW( hwnd, WM_QUERYOPEN, 0, 0 )) return SWP_NOSIZE | SWP_NOMOVE; swpFlags |= SWP_NOCOPYBITS; } switch( cmd ) { + case SW_SHOWMINNOACTIVE: + case SW_SHOWMINIMIZED: + case SW_FORCEMINIMIZE: case SW_MINIMIZE: if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0; if( wndPtr->dwStyle & WS_MAXIMIZE) wndPtr->flags |= WIN_RESTORE_MAX; @@ -877,6 +887,9 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect ) break; case SW_MAXIMIZE: + old_style = GetWindowLongW( hwnd, GWL_STYLE ); + if ((old_style & WS_MAXIMIZE) && (old_style & WS_CHILD)) return SWP_NOSIZE | SWP_NOMOVE; + WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL ); old_style = WIN_SetStyle( hwnd, WS_MAXIMIZE, WS_MINIMIZE ); @@ -933,7 +946,7 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT cmd ) HWND parent; LONG style = GetWindowLongW( hwnd, GWL_STYLE ); BOOL wasVisible = (style & WS_VISIBLE) != 0; - BOOL showFlag = TRUE; + BOOL showFlag = TRUE, state_change = FALSE; RECT newPos = {0, 0, 0, 0}; UINT swp = 0; @@ -949,23 +962,24 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT cmd ) swp |= SWP_NOACTIVATE | SWP_NOZORDER; break; + case SW_MINIMIZE: case SW_SHOWMINNOACTIVE: swp |= SWP_NOACTIVATE | SWP_NOZORDER; /* fall through */ case SW_SHOWMINIMIZED: case SW_FORCEMINIMIZE: /* FIXME: Does not work if thread is hung. */ - swp |= SWP_SHOWWINDOW; + swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED; /* fall through */ - case SW_MINIMIZE: - swp |= SWP_FRAMECHANGED; - if( !(style & WS_MINIMIZE) ) - swp |= WINPOS_MinMaximize( hwnd, SW_MINIMIZE, &newPos ); - else swp |= SWP_NOSIZE | SWP_NOMOVE; + swp |= WINPOS_MinMaximize( hwnd, cmd, &newPos ); + if (style & WS_MINIMIZE) return wasVisible; + state_change = TRUE; break; case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */ swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED; swp |= WINPOS_MinMaximize( hwnd, SW_MAXIMIZE, &newPos ); + if ((style & WS_MAXIMIZE) && (style & WS_CHILD)) return wasVisible; + state_change = TRUE; break; case SW_SHOWNA: @@ -979,6 +993,7 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT cmd ) case SW_RESTORE: swp |= SWP_FRAMECHANGED; + state_change = TRUE; /* fall through */ case SW_SHOWNOACTIVATE: swp |= SWP_NOACTIVATE | SWP_NOZORDER; @@ -993,14 +1008,14 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT cmd ) break; } - if ((showFlag != wasVisible || cmd == SW_SHOWNA) && cmd != SW_SHOWMAXIMIZED) + if ((showFlag != wasVisible || cmd == SW_SHOWNA) && !state_change) { SendMessageW( hwnd, WM_SHOWWINDOW, showFlag, 0 ); if (!IsWindow( hwnd )) return wasVisible; } parent = GetAncestor( hwnd, GA_PARENT ); - if (parent && !IsWindowVisible( parent )) + if (parent && !IsWindowVisible( parent ) && !state_change) { /* if parent is not visible simply toggle WS_VISIBLE and return */ if (showFlag) WIN_SetStyle( hwnd, WS_VISIBLE, 0 ); @@ -1009,8 +1024,19 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT cmd ) else { /* ShowWindow won't activate a not being maximized child window */ - if ((style & WS_CHILD) && cmd != SW_MAXIMIZE) - swp |= SWP_NOACTIVATE | SWP_NOZORDER; + if (style & WS_CHILD) + { + if (!state_change) + swp |= SWP_NOACTIVATE | SWP_NOZORDER; + else + { + /* it appears that Windows always adds an undocumented 0x8000 + * flag if the state of a window changes. + * FIXME: real SWP_xxxx name? + */ + swp |= 0x8000; + } + } SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top, newPos.right, newPos.bottom, LOWORD(swp) );