ChangeSet ID: 13853 CVSROOT: /opt/cvs-commit Module name: wine Changes by: julliard@wine.codeweavers.com 2004/09/20 19:24:22 Modified files: windows : win.c mdi.c dlls/user/tests: msg.c Log message: Dmitry Timoshkov Make message flow for MDI creation/activation/destruction more like in Windows. Add a bunch of MDI message tests. Patch: http://cvs.winehq.org/patch.py?id=13853 Old revision New revision Changes Path 1.247 1.248 +23 -16 wine/windows/win.c 1.132 1.133 +51 -70 wine/windows/mdi.c 1.39 1.40 +186 -8 wine/dlls/user/tests/msg.c Index: wine/windows/win.c diff -u -p wine/windows/win.c:1.247 wine/windows/win.c:1.248 --- wine/windows/win.c:1.247 Wed May 22 20:49:23 2013 +++ wine/windows/win.c Wed May 22 20:49:23 2013 @@ -1024,6 +1024,18 @@ static HWND WIN_CreateWindowEx( CREATEST } top_child = GetWindow(cs->hwndParent, GW_CHILD); + + if (top_child) + { + /* Restore current maximized child */ + if((cs->style & WS_VISIBLE) && IsZoomed(top_child)) + { + TRACE("Restoring current maximized child %p\n", top_child); + SendMessageW( top_child, WM_SETREDRAW, FALSE, 0 ); + ShowWindow(top_child, SW_RESTORE); + SendMessageW( top_child, WM_SETREDRAW, TRUE, 0 ); + } + } } /* Find the parent window */ @@ -1167,24 +1179,22 @@ static HWND WIN_CreateWindowEx( CREATEST send_parent_notify( hwnd, WM_CREATE ); if (!IsWindow( hwnd )) return 0; - if (cs->dwExStyle & WS_EX_MDICHILD) + if (cs->style & WS_VISIBLE) { - if (top_child) + if (cs->style & WS_MAXIMIZE) + sw = SW_SHOWMAXIMIZED; + else if (cs->style & WS_MINIMIZE) + sw = SW_SHOWMINIMIZED; + + ShowWindow( hwnd, sw ); + if (cs->dwExStyle & WS_EX_MDICHILD) { - /* Restore current maximized child */ - if((cs->style & WS_VISIBLE) && IsZoomed(top_child)) - { - TRACE("Restoring current maximized child %p\n", top_child); - ShowWindow(top_child, SW_SHOWNOACTIVATE); - } + SendMessageW(cs->hwndParent, WM_MDIREFRESHMENU, 0, 0); + /* ShowWindow won't activate child windows */ + SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE ); } - - SendMessageW(cs->hwndParent, WM_MDIREFRESHMENU, 0, 0); } - if (cs->style & WS_VISIBLE) - ShowWindow( hwnd, sw ); - /* Call WH_SHELL hook */ if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) && !GetWindow( hwnd, GW_OWNER )) @@ -1432,9 +1442,6 @@ BOOL WINAPI DestroyWindow( HWND hwnd ) TRACE("(%p)\n", hwnd); - if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD) - SendMessageW(GetAncestor(hwnd, GA_PARENT), WM_MDIREFRESHMENU, 0, 0); - /* Call hooks */ if (HOOK_CallHooks( WH_CBT, HCBT_DESTROYWND, (WPARAM)hwnd, 0, TRUE )) return FALSE; Index: wine/windows/mdi.c diff -u -p wine/windows/mdi.c:1.132 wine/windows/mdi.c:1.133 --- wine/windows/mdi.c:1.132 Wed May 22 20:49:23 2013 +++ wine/windows/mdi.c Wed May 22 20:49:23 2013 @@ -480,23 +480,33 @@ static void MDI_ChildGetMinMaxInfo( HWND * Note: SetWindowPos sends WM_CHILDACTIVATE to the child window that is * being activated */ -static void MDI_SwitchActiveChild( HWND clientHwnd, HWND childHwnd, - BOOL bNextWindow ) +static void MDI_SwitchActiveChild( MDICLIENTINFO *ci, HWND hwndTo ) { - HWND hwndTo = 0; - HWND hwndPrev = 0; - MDICLIENTINFO *ci = get_client_info( clientHwnd ); + HWND hwndPrev; - hwndTo = MDI_GetWindow(ci, childHwnd, bNextWindow, 0); hwndPrev = ci->hwndActiveChild; - TRACE("from %p, to %p\n",childHwnd,hwndTo); + TRACE("from %p, to %p\n", hwndPrev, hwndTo); - if ( !hwndTo ) - MDI_ChildActivate( clientHwnd, 0 ); - else if ( hwndTo != hwndPrev ) - SetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE ); + if ( hwndTo != hwndPrev ) + { + BOOL was_zoomed = IsZoomed(hwndPrev); + + if (was_zoomed) + { + /* restore old MDI child */ + SendMessageW( hwndPrev, WM_SETREDRAW, FALSE, 0 ); + ShowWindow( hwndPrev, SW_RESTORE ); + SendMessageW( hwndPrev, WM_SETREDRAW, TRUE, 0 ); + + /* activate new MDI child */ + SetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE ); + /* maximize new MDI child */ + ShowWindow( hwndTo, SW_MAXIMIZE ); + } + /* activate new MDI child */ + SetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE ); + } } @@ -512,8 +522,8 @@ static LRESULT MDIDestroyChild( HWND par if( child == ci->hwndActiveChild ) { - MDI_SwitchActiveChild(parent, child, TRUE); - ShowWindow(child, SW_HIDE); + HWND next = MDI_GetWindow(ci, child, TRUE, 0); + MDI_SwitchActiveChild(ci, next); } for (i = 0; i < ci->nActiveChildren; i++) @@ -546,7 +556,7 @@ static LRESULT MDIDestroyChild( HWND par /********************************************************************** * MDI_ChildActivate * - * Note: hWndChild is NULL when last child is being destroyed + * Called in response to WM_CHILDACTIVATE */ static LONG MDI_ChildActivate( HWND client, HWND child ) { @@ -554,18 +564,16 @@ static LONG MDI_ChildActivate( HWND clie HWND prevActiveWnd, frame; BOOL isActiveFrameWnd; - if (child && (!IsWindowEnabled( child ))) return 0; - clientInfo = get_client_info( client ); + if (clientInfo->hwndActiveChild == child) return 0; + TRACE("%p\n", child); frame = GetParent(client); isActiveFrameWnd = (GetActiveWindow() == frame); prevActiveWnd = clientInfo->hwndActiveChild; - if (prevActiveWnd == child) return 0; - /* deactivate prev. active child */ if(prevActiveWnd) { @@ -575,39 +583,13 @@ static LONG MDI_ChildActivate( HWND clie clientInfo->hwndActiveChild = child; - /* set appearance */ - if (IsZoomed(prevActiveWnd) && prevActiveWnd != child) - { - if( child ) - { - INT cmd = SW_SHOWNORMAL; - HMENU hSysMenu = GetSystemMenu(child, FALSE); - UINT state = 0; - if (hSysMenu) - state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND); - if (state != 0xFFFFFFFF && !(state & (MF_DISABLED | MF_GRAYED))) - cmd = SW_SHOWMAXIMIZED; - - ShowWindow( child, cmd ); - } - else - MDI_RestoreFrameMenu(frame, child); - } - - MDI_UpdateFrameText(frame, client, NULL); - - /* check if we have any children left */ - if( !child ) - { - if( isActiveFrameWnd ) - SetFocus( client ); - return 0; - } - MDI_RefreshMenu(clientInfo); if( isActiveFrameWnd ) + { SendMessageW( child, WM_NCACTIVATE, TRUE, 0L); + SetFocus(child); + } SendMessageW( child, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, (LPARAM)child ); return TRUE; @@ -1060,8 +1042,7 @@ static LRESULT MDIClientWndProc_common( case WM_MDIACTIVATE: { - if( ci->hwndActiveChild != (HWND)wParam ) - SetWindowPos((HWND)wParam, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE); + MDI_SwitchActiveChild( ci, (HWND)wParam ); return 0; } @@ -1111,8 +1092,11 @@ static LRESULT MDIClientWndProc_common( return 0; case WM_MDINEXT: /* lParam != 0 means previous window */ - MDI_SwitchActiveChild( hwnd, WIN_GetFullHandle( (HWND)wParam ), !lParam ); + { + HWND next = MDI_GetWindow( ci, WIN_GetFullHandle( (HWND)wParam ), !lParam, 0 ); + MDI_SwitchActiveChild( ci, next ); break; + } case WM_MDIRESTORE: SendMessageW( (HWND)wParam, WM_SYSCOMMAND, SC_RESTORE, 0); @@ -1399,6 +1383,7 @@ LRESULT WINAPI DefMDIChildProcA( HWND hw case WM_SIZE: case WM_NEXTMENU: case WM_SYSCHAR: + case WM_DESTROY: return DefMDIChildProcW( hwnd, message, wParam, lParam ); } return DefWindowProcA(hwnd, message, wParam, lParam); @@ -1472,29 +1457,20 @@ LRESULT WINAPI DefMDIChildProcW( HWND hw break; case WM_SIZE: - if (wParam == SIZE_MAXIMIZED && !IsWindowVisible(hwnd)) - wParam = SIZE_RESTORED; - - if( hwnd == ci->hwndActiveChild && wParam != SIZE_MAXIMIZED ) - { - MDI_RestoreFrameMenu( GetParent(client), hwnd ); - MDI_UpdateFrameText( GetParent(client), client, NULL ); - } - - if( wParam == SIZE_MAXIMIZED ) + if( hwnd == ci->hwndActiveChild ) { - TRACE("maximizing child %p\n", hwnd ); + if( wParam == SIZE_MAXIMIZED ) + { + TRACE("maximizing child %p\n", hwnd ); - MDI_AugmentFrameMenu( GetParent(client), hwnd ); - MDI_UpdateFrameText( GetParent(client), client, NULL ); + MDI_AugmentFrameMenu( GetParent(client), hwnd ); + } + else + MDI_RestoreFrameMenu( GetParent(client), hwnd ); } - if( wParam == SIZE_MINIMIZED ) - { - HWND switchTo = MDI_GetWindow(ci, hwnd, TRUE, WS_MINIMIZE); - - if (switchTo) SendMessageW( switchTo, WM_CHILDACTIVATE, 0, 0); - } + MDI_UpdateFrameText( GetParent(client), client, NULL ); + MDI_RefreshMenu(ci); MDI_PostUpdate(client, ci, SB_BOTH+1); break; @@ -1524,6 +1500,11 @@ LRESULT WINAPI DefMDIChildProcW( HWND hw return 0; } break; + + case WM_DESTROY: + /* Remove itself from the Window menu */ + MDI_RefreshMenu(ci); + break; } return DefWindowProcW(hwnd, message, wParam, lParam); } Index: wine/dlls/user/tests/msg.c diff -u -p wine/dlls/user/tests/msg.c:1.39 wine/dlls/user/tests/msg.c:1.40 --- wine/dlls/user/tests/msg.c:1.39 Wed May 22 20:49:24 2013 +++ wine/dlls/user/tests/msg.c Wed May 22 20:49:24 2013 @@ -316,6 +316,14 @@ static const struct message WmShowChildS { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, { 0 } }; +/* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE) + * for a visible child window with a caption + */ +static const struct message WmShowChildSeq_4[] = { + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE }, + { WM_CHILDACTIVATE, sent }, + { 0 } +}; /* ShowWindow(SW_SHOW) for child with invisible parent */ static const struct message WmShowChildInvisibleParentSeq[] = { { WM_SHOWWINDOW, sent|wparam, 1 }, @@ -1268,6 +1276,76 @@ static const struct message WmDestroyMDI { WM_NCDESTROY, sent|defwinproc }, { 0 } }; +/* ShowWindow(SW_MAXIMIZE) for a not visible MDI child window */ +static const struct message WmMaximizeMDIchildInvisibleSeq[] = { + { HCBT_MINMAX, hook }, + { WM_GETMINMAXINFO, sent }, + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|0x8000 }, + { WM_NCCALCSIZE, sent|wparam, 1 }, + { WM_CHILDACTIVATE, sent|wparam|lparam, 0, 0 }, + + { WM_WINDOWPOSCHANGING, sent|wparam|defwinproc, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, + { WM_NCACTIVATE, sent|wparam|defwinproc, 1 }, + { HCBT_SETFOCUS, hook }, + { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */ + { WM_SETFOCUS, sent }, /* in MDI client */ + { HCBT_SETFOCUS, hook }, + { WM_KILLFOCUS, sent }, /* in MDI client */ + { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, /* in MDI client */ + { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 }, + { WM_SETFOCUS, sent|defwinproc }, + { WM_MDIACTIVATE, sent|defwinproc }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|0x8000 }, + { WM_SIZE, sent|defwinproc }, + /* in MDI frame */ + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER }, + { WM_NCCALCSIZE, sent|wparam, 1 }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { 0 } +}; +/* ShowWindow(SW_MAXIMIZE) for a visible MDI child window */ +static const struct message WmMaximizeMDIchildVisibleSeq[] = { + { HCBT_MINMAX, hook }, + { WM_GETMINMAXINFO, sent }, + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|0x8000 }, + { WM_NCCALCSIZE, sent|wparam, 1 }, + { WM_CHILDACTIVATE, sent|wparam|lparam, 0, 0 }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|0x8000 }, + { WM_SIZE, sent|defwinproc }, + /* in MDI frame */ + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER }, + { WM_NCCALCSIZE, sent|wparam, 1 }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { 0 } +}; +/* ShowWindow(SW_RESTORE) for a visible MDI child window */ +static const struct message WmRestoreMDIchildVisibleSeq[] = { + { HCBT_MINMAX, hook }, + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|0x8000 }, + { WM_NCCALCSIZE, sent|wparam, 1 }, + { WM_CHILDACTIVATE, sent|wparam|lparam, 0, 0 }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|0x8000 }, + { WM_SIZE, sent|defwinproc }, + /* in MDI frame */ + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER }, + { WM_NCCALCSIZE, sent|wparam, 1 }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { 0 } +}; +/* ShowWindow(SW_RESTORE) for a not visible MDI child window */ +static const struct message WmRestoreMDIchildInisibleSeq[] = { + { HCBT_MINMAX, hook }, + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|0x8000 }, + { WM_NCCALCSIZE, sent|wparam, 1 }, + { WM_CHILDACTIVATE, sent|wparam|lparam, 0, 0 }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|0x8000 }, + { WM_SIZE, sent|defwinproc }, + /* in MDI frame */ + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER }, + { WM_NCCALCSIZE, sent|wparam, 1 }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { 0 } +}; static HWND mdi_client; static WNDPROC old_mdi_client_proc; @@ -1462,6 +1540,9 @@ static void test_mdi_messages(void) assert(mdi_frame); ok_sequence(WmCreateMDIframeSeq, "Create MDI frame window", TRUE); + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == mdi_frame, "wrong focus window %p\n", GetFocus()); + trace("creating MDI client window\n"); client_cs.hWindowMenu = 0; client_cs.idFirstChild = MDI_FIRST_CHILD_ID; @@ -1473,6 +1554,7 @@ static void test_mdi_messages(void) assert(mdi_client); ok_sequence(WmCreateMDIclientSeq, "Create visible MDI client window", FALSE); + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); ok(GetFocus() == mdi_frame, "input focus should be on MDI frame not on %p\n", GetFocus()); active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed); @@ -1493,6 +1575,9 @@ static void test_mdi_messages(void) ok(GetWindowLongA(mdi_child, GWL_STYLE) & WS_VISIBLE, "MDI child should be visible\n"); ok(IsWindowVisible(mdi_child), "MDI child should be visible\n"); + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == mdi_child, "wrong focus window %p\n", GetFocus()); + active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed); ok(active_child == mdi_child, "wrong active MDI child %p\n", active_child); ok(!zoomed, "wrong zoomed state %d\n", zoomed); @@ -1501,6 +1586,9 @@ static void test_mdi_messages(void) DestroyWindow(mdi_child); ok_sequence(WmDestroyMDIchildVisibleSeq, "Destroy visible MDI child window", TRUE); + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus()); + /* Win2k: MDI client still returns a just destroyed child as active * Win9x: MDI client returns 0 */ @@ -1510,7 +1598,6 @@ static void test_mdi_messages(void) "wrong active MDI child %p\n", active_child); ok(!zoomed, "wrong zoomed state %d\n", zoomed); - SetFocus(0); flush_sequence(); trace("creating invisible MDI child window\n"); @@ -1519,11 +1606,14 @@ static void test_mdi_messages(void) 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, mdi_client, 0, GetModuleHandleA(0), NULL); assert(mdi_child2); - ok_sequence(WmCreateMDIchildInvisibleSeq, "Create invisible MDI child window", TRUE); + ok_sequence(WmCreateMDIchildInvisibleSeq, "Create invisible MDI child window", FALSE); ok(!(GetWindowLongA(mdi_child2, GWL_STYLE) & WS_VISIBLE), "MDI child should not be visible\n"); ok(!IsWindowVisible(mdi_child2), "MDI child should not be visible\n"); + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus()); + /* Win2k: MDI client still returns a just destroyed child as active * Win9x: MDI client returns mdi_child2 */ @@ -1534,15 +1624,79 @@ static void test_mdi_messages(void) ok(!zoomed, "wrong zoomed state %d\n", zoomed); flush_sequence(); + ShowWindow(mdi_child2, SW_MAXIMIZE); + ok_sequence(WmMaximizeMDIchildInvisibleSeq, "ShowWindow(SW_MAXIMIZE):invisible MDI child", TRUE); + + ok(GetWindowLongA(mdi_child2, GWL_STYLE) & WS_VISIBLE, "MDI child should be visible\n"); + ok(IsWindowVisible(mdi_child2), "MDI child should be visible\n"); + + active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed); + ok(active_child == mdi_child2, "wrong active MDI child %p\n", active_child); + ok(zoomed, "wrong zoomed state %d\n", zoomed); + flush_sequence(); + + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == mdi_child2 || /* win2k */ + GetFocus() == 0, /* win9x */ + "wrong focus window %p\n", GetFocus()); + + SetFocus(0); + flush_sequence(); + + ShowWindow(mdi_child2, SW_HIDE); + ok_sequence(WmHideChildSeq, "ShowWindow(SW_HIDE):MDI child", FALSE); + + ShowWindow(mdi_child2, SW_RESTORE); + ok_sequence(WmRestoreMDIchildInisibleSeq, "ShowWindow(SW_RESTORE):invisible MDI child", TRUE); + flush_sequence(); + + ok(GetWindowLongA(mdi_child2, GWL_STYLE) & WS_VISIBLE, "MDI child should be visible\n"); + ok(IsWindowVisible(mdi_child2), "MDI child should be visible\n"); + + active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed); + ok(active_child == mdi_child2, "wrong active MDI child %p\n", active_child); + ok(!zoomed, "wrong zoomed state %d\n", zoomed); + flush_sequence(); + + SetFocus(0); + flush_sequence(); + + ShowWindow(mdi_child2, SW_HIDE); + ok_sequence(WmHideChildSeq, "ShowWindow(SW_HIDE):MDI child", FALSE); + ShowWindow(mdi_child2, SW_SHOW); ok_sequence(WmShowChildSeq, "ShowWindow(SW_SHOW):MDI child", TRUE); + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus()); + + ShowWindow(mdi_child2, SW_MAXIMIZE); + ok_sequence(WmMaximizeMDIchildVisibleSeq, "ShowWindow(SW_MAXIMIZE):MDI child", TRUE); + + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus()); + + ShowWindow(mdi_child2, SW_RESTORE); + ok_sequence(WmRestoreMDIchildVisibleSeq, "ShowWindow(SW_RESTORE):MDI child", TRUE); + + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus()); + + SetFocus(0); + flush_sequence(); + ShowWindow(mdi_child2, SW_HIDE); ok_sequence(WmHideChildSeq, "ShowWindow(SW_HIDE):MDI child", FALSE); + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus()); + DestroyWindow(mdi_child2); ok_sequence(WmDestroyMDIchildInvisibleSeq, "Destroy invisible MDI child window", TRUE); + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus()); + /* test for maximized MDI children */ trace("creating maximized visible MDI child window 1\n"); mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_class", "MDI child", @@ -1553,6 +1707,11 @@ static void test_mdi_messages(void) ok_sequence(WmCreateMDIchildVisibleMaxSeq1, "Create maximized visible 1st MDI child window", TRUE); ok(IsZoomed(mdi_child), "1st MDI child should be maximized\n"); + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == mdi_child || /* win2k */ + GetFocus() == 0, /* win9x */ + "wrong focus window %p\n", GetFocus()); + active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed); ok(active_child == mdi_child, "wrong active MDI child %p\n", active_child); ok(zoomed, "wrong zoomed state %d\n", zoomed); @@ -1568,16 +1727,22 @@ static void test_mdi_messages(void) ok(IsZoomed(mdi_child2), "2nd MDI child should be maximized\n"); ok(!IsZoomed(mdi_child), "1st MDI child should NOT be maximized\n"); + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == mdi_child2, "wrong focus window %p\n", GetFocus()); + active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed); ok(active_child == mdi_child2, "wrong active MDI child %p\n", active_child); ok(zoomed, "wrong zoomed state %d\n", zoomed); flush_sequence(); + trace("destroying maximized visible MDI child window 2\n"); DestroyWindow(mdi_child2); ok_sequence(WmDestroyMDIchildVisibleSeq, "Destroy visible MDI child window", TRUE); ok(!IsZoomed(mdi_child), "1st MDI child should NOT be maximized\n"); - ok(GetFocus() == 0, "GetFocus() = %p\n", GetFocus()); + + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus()); /* Win2k: MDI client still returns a just destroyed child as active * Win9x: MDI client returns 0 @@ -1592,6 +1757,9 @@ static void test_mdi_messages(void) ok(IsZoomed(mdi_child), "1st MDI child should be maximized\n"); flush_sequence(); + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == mdi_child, "wrong focus window %p\n", GetFocus()); + trace("re-creating maximized visible MDI child window 2\n"); mdi_child2 = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_class", "MDI child", WS_CHILD | WS_VISIBLE | WS_MAXIMIZEBOX | WS_MAXIMIZE, @@ -1602,6 +1770,9 @@ static void test_mdi_messages(void) ok(IsZoomed(mdi_child2), "2nd MDI child should be maximized\n"); ok(!IsZoomed(mdi_child), "1st MDI child should NOT be maximized\n"); + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == mdi_child2, "wrong focus window %p\n", GetFocus()); + active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed); ok(active_child == mdi_child2, "wrong active MDI child %p\n", active_child); ok(zoomed, "wrong zoomed state %d\n", zoomed); @@ -1612,9 +1783,8 @@ static void test_mdi_messages(void) ok(!IsWindow(mdi_child2), "MDI child 2 should be destroyed\n"); ok(IsZoomed(mdi_child), "1st MDI child should be maximized\n"); -todo_wine { - ok(GetFocus() == mdi_child, "GetFocus() = %p\n", GetFocus()); -} + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == mdi_child, "wrong focus window %p\n", GetFocus()); active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed); ok(active_child == mdi_child, "wrong active MDI child %p\n", active_child); @@ -1624,6 +1794,9 @@ todo_wine { DestroyWindow(mdi_child); ok_sequence(WmDestroyMDIchildVisibleSeq, "Destroy visible MDI child window", TRUE); + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus()); + /* Win2k: MDI client still returns a just destroyed child as active * Win9x: MDI client returns 0 */ @@ -1884,7 +2057,7 @@ static void test_messages(void) ok(GetActiveWindow() == hwnd, "window should be active\n"); ok(GetFocus() == hwnd, "window should have input focus\n"); SetWindowPos(hwnd, 0,0,0,0,0, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE); - ok_sequence(WmSWP_HideOverlappedSeq, "SetWindowPos:SWP_HIDEWINDOW:overlapped", FALSE); + ok_sequence(WmSWP_HideOverlappedSeq, "SetWindowPos:SWP_HIDEWINDOW:overlapped", TRUE); ok(!IsWindowVisible(hwnd), "window should not be visible at this point\n"); /* test WM_SETREDRAW on a visible top level window */ @@ -1909,7 +2082,9 @@ static void test_messages(void) DestroyWindow(hchild); flush_sequence(); - hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD | WS_VISIBLE, + /* visible child window with a caption */ + hchild = CreateWindowExA(0, "TestWindowClass", "Test child", + WS_CHILD | WS_VISIBLE | WS_CAPTION, 0, 0, 10, 10, hparent, 0, 0, NULL); ok (hchild != 0, "Failed to create child window\n"); ok_sequence(WmCreateVisibleChildSeq, "CreateWindow:visible child", FALSE); @@ -1917,6 +2092,9 @@ static void test_messages(void) trace("testing scroll APIs on a visible child window %p\n", hchild); test_scroll_messages(hchild); + SetWindowPos(hchild, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE); + ok_sequence(WmShowChildSeq_4, "SetWindowPos(SWP_SHOWWINDOW):child with a caption", FALSE); + DestroyWindow(hchild); flush_sequence();