Commit a1ccb921 authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

Make message flow for MDI creation/activation/destruction more like in

Windows. Add a bunch of MDI message tests.
parent 8657ad87
......@@ -316,6 +316,14 @@ static const struct message WmShowChildSeq_3[] = {
{ 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 WmDestroyMDIchildVisibleMaxSeq2[] = {
{ 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();
......
......@@ -480,23 +480,33 @@ static void MDI_ChildGetMinMaxInfo( HWND client, HWND hwnd, MINMAXINFO* lpMinMax
* 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 parent, MDICLIENTINFO *ci,
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 parent, MDICLIENTINFO *ci,
/**********************************************************************
* 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 client, HWND child )
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 client, HWND child )
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( HWND hwnd, UINT message,
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( HWND hwnd, UINT message,
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 hwnd, UINT message,
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 hwnd, UINT message,
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 hwnd, UINT message,
return 0;
}
break;
case WM_DESTROY:
/* Remove itself from the Window menu */
MDI_RefreshMenu(ci);
break;
}
return DefWindowProcW(hwnd, message, wParam, lParam);
}
......
......@@ -1024,6 +1024,18 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
}
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( CREATESTRUCTA *cs, ATOM classAtom,
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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment