Make message flow for MDI creation/activation/destruction more like in Windows
Dmitry Timoshkov
dmitry at baikal.ru
Mon Sep 20 05:04:51 CDT 2004
Hello,
this patch adds another bunch of message tests for MDI children
and makes message flow for MDI creation/activation/destruction
more like in Windows. It's still not exactly the same as in Windows,
but it's close enough.
Changelog:
Dmitry Timoshkov <dmitry at codeweavers.com>
Make message flow for MDI creation/activation/destruction
more like in Windows. Add a bunch of MDI message tests.
diff -u cvs/hq/wine/dlls/user/tests/msg.c wine/dlls/user/tests/msg.c
--- cvs/hq/wine/dlls/user/tests/msg.c 2004-09-20 17:08:26.000000000 +0900
+++ wine/dlls/user/tests/msg.c 2004-09-20 18:21:30.000000000 +0900
@@ -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();
diff -u cvs/hq/wine/windows/mdi.c wine/windows/mdi.c
--- cvs/hq/wine/windows/mdi.c 2004-09-20 17:08:26.000000000 +0900
+++ wine/windows/mdi.c 2004-09-20 18:40:38.000000000 +0900
@@ -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);
}
diff -u cvs/hq/wine/windows/win.c wine/windows/win.c
--- cvs/hq/wine/windows/win.c 2004-09-20 17:09:15.000000000 +0900
+++ wine/windows/win.c 2004-09-20 18:21:30.000000000 +0900
@@ -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;
More information about the wine-patches
mailing list