diff --git a/dlls/user32/mdi.c b/dlls/user32/mdi.c index dace1e8f64d..23dd8e920aa 100644 --- a/dlls/user32/mdi.c +++ b/dlls/user32/mdi.c @@ -1559,8 +1559,8 @@ LRESULT WINAPI DefMDIChildProcW( HWND hwnd, UINT message, { HWND switchTo = MDI_GetWindow( ci, hwnd, TRUE, WS_MINIMIZE ); - if( switchTo ) - SendMessageW( switchTo, WM_CHILDACTIVATE, 0, 0 ); + if (!switchTo) switchTo = hwnd; + SendMessageW( switchTo, WM_CHILDACTIVATE, 0, 0 ); } MDI_PostUpdate(client, ci, SB_BOTH+1); diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 7e63e73e30f..8a21146e7f2 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -1589,7 +1589,9 @@ static const struct message WmCreateMDIclientSeq[] = { { HCBT_CREATEWND, hook }, { WM_NCCREATE, sent }, { WM_NCCALCSIZE, sent|wparam, 0 }, + { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam|optional, 0, 0 }, { WM_CREATE, sent }, + { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam|optional, 0, 0 }, { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 }, { WM_SIZE, sent|wparam, SIZE_RESTORED }, { WM_MOVE, sent }, @@ -1612,7 +1614,8 @@ static const struct message WmShowMDIclientSeq[] = { static const struct message WmHideMDIclientSeq[] = { { WM_SHOWWINDOW, sent|wparam, 0 }, { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, - { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 }, + { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam|optional, 0, 0 }, /* win2000 */ + { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* XP */ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, { 0 } }; @@ -1676,6 +1679,7 @@ static const struct message WmCreateMDIchildInvisibleParentSeq[] = { { WM_GETMINMAXINFO, sent }, { WM_NCCREATE, sent }, { WM_NCCALCSIZE, sent|wparam, 0 }, + { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam|optional, 0, 0 }, { WM_CREATE, sent }, { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 }, { WM_SIZE, sent|wparam, SIZE_RESTORED }, @@ -1801,6 +1805,8 @@ static const struct message WmDestroyMDIchildInvisibleSeq[] = { { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 }, { WM_DESTROY, sent }, { WM_NCDESTROY, sent }, + /* FIXME: Wine destroys an icon/title window while Windows doesn't */ + { WM_PARENTNOTIFY, sent|wparam|optional, WM_DESTROY }, /* MDI client */ { 0 } }; /* CreateWindow for the 1st MDI child window, initially visible and maximized */ @@ -1990,7 +1996,7 @@ static const struct message WmCreateMDIchildVisibleMaxSeq3[] = { { WM_SETFOCUS, sent|optional }, /* in MDI client */ { HCBT_SETFOCUS, hook }, /* in MDI client */ { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */ - { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, + { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, { WM_SETFOCUS, sent|optional }, /* in MDI client */ { HCBT_SETFOCUS, hook|optional }, { WM_KILLFOCUS, sent }, /* in MDI client */ @@ -2379,7 +2385,7 @@ static const struct message WmMaximizeMDIchildInvisibleParentSeq[] = { { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|0x8000 }, { WM_GETMINMAXINFO, sent|defwinproc }, { WM_NCCALCSIZE, sent|wparam, 1 }, - { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 }, + { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam|optional, 0, 0 }, /* XP doesn't send it */ { WM_CHILDACTIVATE, sent|wparam|lparam, 0, 0 }, { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOREDRAW|0x8000 }, { WM_MOVE, sent|defwinproc }, @@ -2389,13 +2395,15 @@ static const struct message WmMaximizeMDIchildInvisibleParentSeq[] = { { WM_NCCALCSIZE, sent|wparam|defwinproc, 1 }, { WM_WINDOWPOSCHANGED, sent|wparam|defwinproc, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOREDRAW|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, { WM_NCCALCSIZE, sent|wparam|defwinproc|optional, 1 }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI child XP */ + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI client XP */ /* in MDI frame */ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, { WM_NCCALCSIZE, sent|wparam, 1 }, { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, { WM_MOVE, sent|defwinproc }, { WM_SIZE, sent|defwinproc|wparam, SIZE_RESTORED }, - { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */ + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI frame win2000 */ /* in MDI client */ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOACTIVATE }, { WM_NCCALCSIZE, sent|wparam, 1 }, @@ -2407,10 +2415,16 @@ static const struct message WmMaximizeMDIchildInvisibleParentSeq[] = { { WM_NCCALCSIZE, sent|wparam|defwinproc, 1 }, { WM_WINDOWPOSCHANGED, sent|wparam|defwinproc, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOREDRAW|SWP_NOCLIENTMOVE }, { WM_SIZE, sent|defwinproc|wparam, SIZE_MAXIMIZED }, - { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */ + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI child win2000 */ { WM_NCCALCSIZE, sent|wparam|defwinproc|optional, 1 }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI child XP */ + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI child XP */ + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI client XP */ /* in MDI frame */ { WM_NCCALCSIZE, sent|wparam|optional, 1 }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI frame XP */ + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI frame XP */ + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI child XP */ { 0 } }; /* ShowWindow(SW_MAXIMIZE) for a visible MDI child window */ @@ -2430,7 +2444,7 @@ static const struct message WmMaximizeMDIchildVisibleSeq[] = { { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */ { 0 } }; -/* ShowWindow(SW_RESTORE) for a visible MDI child window */ +/* ShowWindow(SW_RESTORE) for a visible maximized MDI child window */ static const struct message WmRestoreMDIchildVisibleSeq[] = { { HCBT_MINMAX, hook|lparam, 0, SW_RESTORE }, { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|0x8000 }, @@ -2446,6 +2460,40 @@ static const struct message WmRestoreMDIchildVisibleSeq[] = { { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */ { 0 } }; +/* ShowWindow(SW_RESTORE) for a visible minimized MDI child window */ +static const struct message WmRestoreMDIchildVisibleSeq_2[] = { + { HCBT_MINMAX, hook|lparam, 0, SW_RESTORE }, + { WM_QUERYOPEN, sent|wparam|lparam, 0, 0 }, + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 }, + { WM_NCCALCSIZE, sent|wparam, 1 }, + { WM_CHILDACTIVATE, sent|wparam|lparam, 0, 0 }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_NOCLIENTSIZE|0x8000 }, + { WM_MOVE, sent|defwinproc }, + { WM_SIZE, sent|defwinproc|wparam, SIZE_RESTORED }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */ + { EVENT_SYSTEM_MINIMIZEEND, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */ + { HCBT_SETFOCUS, hook }, + { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, + { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, + { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, + { WM_SETFOCUS, sent }, + { 0 } +}; +/* ShowWindow(SW_MINIMIZE) for a visible restored MDI child window */ +static const struct message WmMinimizeMDIchildVisibleSeq[] = { + { HCBT_MINMAX, hook|lparam, 0, SW_MINIMIZE }, + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOCOPYBITS|0x8000 }, + { WM_NCCALCSIZE, sent|wparam, 1 }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOCLIENTSIZE|0x8000 }, + { WM_MOVE, sent|defwinproc }, + { WM_SIZE, sent|defwinproc|wparam, SIZE_MINIMIZED }, + { WM_CHILDACTIVATE, sent|wparam|lparam|defwinproc, 0, 0 }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */ + { EVENT_SYSTEM_MINIMIZESTART, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */ + /* FIXME: Wine creates an icon/title window while Windows doesn't */ + { WM_PARENTNOTIFY, sent|parent|wparam|optional, WM_CREATE }, /* MDI client */ + { 0 } +}; /* ShowWindow(SW_RESTORE) for a not visible MDI child window */ static const struct message WmRestoreMDIchildInisibleSeq[] = { { HCBT_MINMAX, hook|lparam, 0, SW_RESTORE }, @@ -2875,11 +2923,33 @@ static void test_mdi_messages(void) ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus()); ShowWindow(mdi_child2, SW_RESTORE); - ok_sequence(WmRestoreMDIchildVisibleSeq, "ShowWindow(SW_RESTORE):MDI child", FALSE); + ok_sequence(WmRestoreMDIchildVisibleSeq, "ShowWindow(SW_RESTORE):maximized MDI child", FALSE); ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus()); + ShowWindow(mdi_child2, SW_MINIMIZE); + ok_sequence(WmMinimizeMDIchildVisibleSeq, "ShowWindow(SW_MINIMIZE):MDI child", TRUE); + + ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow()); + ok(GetFocus() == 0, "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(); + + ShowWindow(mdi_child2, SW_RESTORE); + ok_sequence(WmRestoreMDIchildVisibleSeq_2, "ShowWindow(SW_RESTORE):minimized MDI child", TRUE); + + 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(); + SetFocus(0); flush_sequence(); @@ -8693,7 +8763,7 @@ static void test_ShowWindow(void) /* 53 */ { SW_HIDE, FALSE, 0, WmEmptySeq, FALSE }, /* 54 */ { SW_MINIMIZE, FALSE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_3, TRUE }, /* 55 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2, FALSE }, -/* 56 */ { SW_SHOWNOACTIVATE, FALSE, WS_VISIBLE, WmShowNoActivate_2, TRUE }, +/* 56 */ { SW_SHOWNOACTIVATE, FALSE, WS_VISIBLE, WmShowNoActivate_2, FALSE }, /* 57 */ { SW_SHOW, TRUE, WS_VISIBLE, WmEmptySeq, FALSE } }; HWND hwnd; diff --git a/dlls/winex11.drv/winpos.c b/dlls/winex11.drv/winpos.c index 95afc402361..0b10c145f5f 100644 --- a/dlls/winex11.drv/winpos.c +++ b/dlls/winex11.drv/winpos.c @@ -718,6 +718,9 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT cmd ) } else WIN_ReleasePtr( wndPtr ); + /* if previous state was minimized Windows sets focus to the window */ + if (style & WS_MINIMIZE) SetFocus( hwnd ); + return wasVisible; }