user32: Add a message test for various ShowWindow() calls, fix some failures

Dmitry Timoshkov dmitry at codeweavers.com
Fri Dec 22 04:32:04 CST 2006


Hello,

I started to write this set of tests with the only single intention -
to figure out in which cases WM_SHOWWINDOW message should really be sent,
and probably improve or eliminate looking suspiciously/wrong test in
dlls/winex11.drv/winpos.c,X11DRV_ShowWindow(). Started in win.c this test
finally was moved into msg.c, and with time the test grew to what I'm sending
now.

This test passes under XP and Win98 SE, so it should be good enough to cover
most interesting cases.

Now just need to find time to start making the not passing tests succeed
without breaking existing tests.

Changelog:
    user32: Add a message test for various ShowWindow() calls, fix some failures.

---
 dlls/user32/tests/msg.c   |  425 ++++++++++++++++++++++++++++++++++++++++++++-
 dlls/winex11.drv/winpos.c |    6 +-
 2 files changed, 426 insertions(+), 5 deletions(-)

diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 8e4e611..b072fd9 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -3433,7 +3433,7 @@ static void test_showwindow(void)
     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);
+    ok_sequence(WmShowMaxPopupResizedSeq, "ShowWindow(SW_SHOWMAXIMIZED):invisible maximized and resized popup", FALSE);
     trace("done\n");
 
     GetWindowRect(hwnd, &rc);
@@ -3459,7 +3459,7 @@ static void test_showwindow(void)
     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);
+    ok_sequence(WmShowMaxPopupSeq, "ShowWindow(SW_SHOWMAXIMIZED):invisible maximized popup", FALSE);
     trace("done\n");
     DestroyWindow(hwnd);
     flush_sequence();
@@ -5848,6 +5848,115 @@ static LRESULT WINAPI TestDlgProcA(HWND hwnd, UINT message, WPARAM wParam, LPARA
     return ret;
 }
 
+static void dump_winpos_flags(UINT flags)
+{
+    if (!winetest_debug) return;
+
+    if (flags & SWP_SHOWWINDOW) printf("|SWP_SHOWWINDOW");
+    if (flags & SWP_HIDEWINDOW) printf("|SWP_HIDEWINDOW");
+    if (flags & SWP_NOACTIVATE) printf("|SWP_NOACTIVATE");
+    if (flags & SWP_FRAMECHANGED) printf("|SWP_FRAMECHANGED");
+    if (flags & SWP_NOCOPYBITS) printf("|SWP_NOCOPYBITS");
+    if (flags & SWP_NOOWNERZORDER) printf("|SWP_NOOWNERZORDER");
+    if (flags & SWP_NOSENDCHANGING) printf("|SWP_NOSENDCHANGING");
+    if (flags & SWP_DEFERERASE) printf("|SWP_DEFERERASE");
+    if (flags & SWP_ASYNCWINDOWPOS) printf("|SWP_ASYNCWINDOWPOS");
+    if (flags & SWP_NOZORDER) printf("|SWP_NOZORDER");
+    if (flags & SWP_NOREDRAW) printf("|SWP_NOREDRAW");
+    if (flags & SWP_NOSIZE) printf("|SWP_NOSIZE");
+    if (flags & SWP_NOMOVE) printf("|SWP_NOMOVE");
+    if (flags & SWP_NOCLIENTSIZE) printf("|SWP_NOCLIENTSIZE");
+    if (flags & SWP_NOCLIENTMOVE) printf("|SWP_NOCLIENTMOVE");
+
+#define DUMPED_FLAGS \
+    (SWP_NOSIZE | \
+    SWP_NOMOVE | \
+    SWP_NOZORDER | \
+    SWP_NOREDRAW | \
+    SWP_NOACTIVATE | \
+    SWP_FRAMECHANGED | \
+    SWP_SHOWWINDOW | \
+    SWP_HIDEWINDOW | \
+    SWP_NOCOPYBITS | \
+    SWP_NOOWNERZORDER | \
+    SWP_NOSENDCHANGING | \
+    SWP_DEFERERASE | \
+    SWP_ASYNCWINDOWPOS | \
+    SWP_NOCLIENTSIZE | \
+    SWP_NOCLIENTMOVE)
+
+    if(flags & ~DUMPED_FLAGS) printf("|0x%04x", flags & ~DUMPED_FLAGS);
+    printf("\n");
+#undef DUMPED_FLAGS
+}
+
+static LRESULT WINAPI ShowWindowProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    static long defwndproc_counter = 0;
+    LRESULT ret;
+    struct message msg;
+
+    /* log only specific messages we are interested in */
+    switch (message)
+    {
+#if 0 /* probably log these as well */
+    case WM_ACTIVATE:
+    case WM_SETFOCUS:
+    case WM_KILLFOCUS:
+#endif
+    case WM_SHOWWINDOW:
+        trace("WM_SHOWWINDOW %d\n", wParam);
+        break;
+    case WM_SIZE:
+        trace("WM_SIZE %d\n", wParam);
+        break;
+    case WM_MOVE:
+        trace("WM_MOVE\n");
+        break;
+    case WM_GETMINMAXINFO:
+        trace("WM_GETMINMAXINFO\n");
+        break;
+
+    case WM_WINDOWPOSCHANGING:
+    case WM_WINDOWPOSCHANGED:
+    {
+        WINDOWPOS *winpos = (WINDOWPOS *)lParam;
+
+        trace("%s\n", (message == WM_WINDOWPOSCHANGING) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
+        trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
+              winpos->hwnd, winpos->hwndInsertAfter,
+              winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags);
+        trace("flags: ");
+        dump_winpos_flags(winpos->flags);
+
+        /* Log only documented flags, win2k uses 0x1000 and 0x2000
+         * in the high word for internal purposes
+         */
+        wParam = winpos->flags & 0xffff;
+        /* I'm not interested in the flags that don't match under XP and Win9x */
+        wParam &= ~(SWP_NOZORDER);
+        break;
+    }
+
+    default: /* ignore */
+        /*trace("showwindow: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);*/
+        return DefWindowProcA(hwnd, message, wParam, lParam);
+    }
+
+    msg.message = message;
+    msg.flags = sent|wparam|lparam;
+    if (defwndproc_counter) msg.flags |= defwinproc;
+    msg.wParam = wParam;
+    msg.lParam = lParam;
+    add_message(&msg);
+
+    defwndproc_counter++;
+    ret = DefWindowProcA(hwnd, message, wParam, lParam);
+    defwndproc_counter--;
+
+    return ret;
+}
+
 static BOOL RegisterWindowClasses(void)
 {
     WNDCLASSA cls;
@@ -5864,6 +5973,10 @@ static BOOL RegisterWindowClasses(void)
     cls.lpszClassName = "TestWindowClass";
     if(!RegisterClassA(&cls)) return FALSE;
 
+    cls.lpfnWndProc = ShowWindowProcA;
+    cls.lpszClassName = "ShowWindowClass";
+    if(!RegisterClassA(&cls)) return FALSE;
+
     cls.lpfnWndProc = PopupMsgCheckProcA;
     cls.lpszClassName = "TestPopupClass";
     if(!RegisterClassA(&cls)) return FALSE;
@@ -5948,6 +6061,7 @@ static LRESULT CALLBACK cbt_hook_proc(int nCode, WPARAM wParam, LPARAM lParam)
     if (GetClassNameA(hwnd, buf, sizeof(buf)))
     {
 	if (!lstrcmpiA(buf, "TestWindowClass") ||
+	    !lstrcmpiA(buf, "ShowWindowClass") ||
 	    !lstrcmpiA(buf, "TestParentClass") ||
 	    !lstrcmpiA(buf, "TestPopupClass") ||
 	    !lstrcmpiA(buf, "SimpleWindowClass") ||
@@ -8211,6 +8325,311 @@ static void test_SetWindowRgn(void)
     DestroyWindow( hwnd );
 }
 
+/*************************** ShowWindow() test ******************************/
+static const struct message WmShowNormal[] = {
+    { WM_SHOWWINDOW, sent|wparam, 1 },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE },
+    { HCBT_ACTIVATE, hook },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE|SWP_NOMOVE },
+    { HCBT_SETFOCUS, hook },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
+    { 0 }
+};
+static const struct message WmShow[] = {
+    { WM_SHOWWINDOW, sent|wparam, 1 },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE },
+    { HCBT_ACTIVATE, hook },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE|SWP_NOMOVE },
+    { HCBT_SETFOCUS, hook },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
+    { 0 }
+};
+static const struct message WmShowNoActivate_1[] = {
+    { HCBT_MINMAX, hook },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|0x8000 },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|0x8000 },
+    { WM_MOVE, sent|defwinproc },
+    { WM_SIZE, sent|wparam|defwinproc, SIZE_RESTORED },
+    { 0 }
+};
+static const struct message WmShowNoActivate_2[] = {
+    { HCBT_MINMAX, hook },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { WM_MOVE, sent|defwinproc },
+    { WM_SIZE, sent|wparam|defwinproc, SIZE_RESTORED },
+    { HCBT_SETFOCUS, hook },
+    { HCBT_ACTIVATE, hook },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE|SWP_NOMOVE },
+    { HCBT_SETFOCUS, hook },
+    { 0 }
+};
+static const struct message WmShowNA_1[] = {
+    { WM_SHOWWINDOW, sent|wparam, 1 },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
+    { 0 }
+};
+static const struct message WmShowNA_2[] = {
+    { WM_SHOWWINDOW, sent|wparam, 1 },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE },
+    { 0 }
+};
+static const struct message WmRestore_1[] = {
+    { HCBT_MINMAX, hook },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { HCBT_ACTIVATE, hook },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE|SWP_NOMOVE },
+    { HCBT_SETFOCUS, hook },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { WM_MOVE, sent|defwinproc },
+    { WM_SIZE, sent|wparam|defwinproc, SIZE_RESTORED },
+    { 0 }
+};
+static const struct message WmRestore_2[] = {
+    { WM_SHOWWINDOW, sent|wparam, 1 },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
+    { 0 }
+};
+static const struct message WmRestore_3[] = {
+    { HCBT_MINMAX, hook },
+    { WM_GETMINMAXINFO, sent },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { HCBT_ACTIVATE, hook },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE|SWP_NOMOVE },
+    { HCBT_SETFOCUS, hook },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { WM_MOVE, sent|defwinproc },
+    { WM_SIZE, sent|wparam|defwinproc, SIZE_MAXIMIZED },
+    { 0 }
+};
+static const struct message WmRestore_4[] = {
+    { HCBT_MINMAX, hook },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|0x8000 },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|0x8000 },
+    { WM_MOVE, sent|defwinproc },
+    { WM_SIZE, sent|wparam|defwinproc, SIZE_RESTORED },
+    { 0 }
+};
+static const struct message WmHide_1[] = {
+    { WM_SHOWWINDOW, sent|wparam, 0 },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
+    { 0 }
+};
+static const struct message WmHide_2[] = {
+    { WM_SHOWWINDOW, sent|wparam, 0 },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
+    { 0 }
+};
+static const struct message WmHide_3[] = {
+    { WM_SHOWWINDOW, sent|wparam, 0 },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
+    { HCBT_SETFOCUS, hook },
+    { 0 }
+};
+static const struct message WmShowMinimized_1[] = {
+    { HCBT_MINMAX, hook },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { HCBT_ACTIVATE, hook },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE|SWP_NOMOVE },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { WM_MOVE, sent|defwinproc },
+    { WM_SIZE, sent|wparam|defwinproc, SIZE_MINIMIZED },
+    { 0 }
+};
+static const struct message WmMinimize_1[] = {
+    { HCBT_MINMAX, hook },
+    { HCBT_SETFOCUS, hook },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { WM_MOVE, sent|defwinproc },
+    { WM_SIZE, sent|wparam|defwinproc, SIZE_MINIMIZED },
+    { 0 }
+};
+static const struct message WmMinimize_2[] = {
+    { HCBT_MINMAX, hook },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { WM_MOVE, sent|defwinproc },
+    { WM_SIZE, sent|wparam|defwinproc, SIZE_MINIMIZED },
+    { 0 }
+};
+static const struct message WmMinimize_3[] = {
+    { HCBT_MINMAX, hook },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { WM_MOVE, sent|defwinproc },
+    { WM_SIZE, sent|wparam|defwinproc, SIZE_MINIMIZED },
+    { 0 }
+};
+static const struct message WmShowMinNoActivate[] = {
+    { HCBT_MINMAX, hook },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
+    { 0 }
+};
+static const struct message WmMinMax[] = {
+    { HCBT_MINMAX, hook },
+    { 0 }
+};
+static const struct message WmShowMaximized_1[] = {
+    { HCBT_MINMAX, hook },
+    { WM_GETMINMAXINFO, sent },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { HCBT_ACTIVATE, hook },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE|SWP_NOMOVE },
+    { HCBT_SETFOCUS, hook },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { WM_MOVE, sent|defwinproc },
+    { WM_SIZE, sent|wparam|defwinproc, SIZE_MAXIMIZED },
+    { 0 }
+};
+static const struct message WmShowMaximized_2[] = {
+    { HCBT_MINMAX, hook },
+    { WM_GETMINMAXINFO, sent },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE|SWP_NOMOVE },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
+    { WM_MOVE, sent|optional }, /* Win9x doesn't send it */
+    { WM_SIZE, sent|wparam|optional, SIZE_MAXIMIZED }, /* Win9x doesn't send it */
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOCOPYBITS|0x8000 },
+    { WM_MOVE, sent|defwinproc },
+    { WM_SIZE, sent|wparam|defwinproc, SIZE_MAXIMIZED },
+    { HCBT_SETFOCUS, hook },
+    { 0 }
+};
+static const struct message WmShowMaximized_3[] = {
+    { HCBT_MINMAX, hook },
+    { WM_GETMINMAXINFO, sent },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|0x8000 },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|0x8000 },
+    { WM_MOVE, sent|defwinproc },
+    { WM_SIZE, sent|wparam|defwinproc, SIZE_MAXIMIZED },
+    { 0 }
+};
+
+static void test_ShowWindow(void)
+{
+    /* ShowWindow commands in random order */
+    static const struct
+    {
+        INT cmd; /* ShowWindow command */
+        LPARAM ret; /* ShowWindow return value */
+        DWORD style; /* window style after the command */
+        const struct message *msg; /* message sequence the command produces */
+        BOOL todo_msg; /* message sequence doesn't match what Wine does */
+    } sw[] =
+    {
+/*  1 */ { SW_SHOWNORMAL, FALSE, WS_VISIBLE, WmShowNormal, TRUE },
+/*  2 */ { SW_SHOWNORMAL, TRUE, WS_VISIBLE, WmEmptySeq, TRUE },
+/*  3 */ { SW_HIDE, TRUE, 0, WmHide_1, FALSE },
+/*  4 */ { SW_HIDE, FALSE, 0, WmEmptySeq, FALSE },
+/*  5 */ { SW_SHOWMINIMIZED, FALSE, WS_VISIBLE|WS_MINIMIZE, WmShowMinimized_1, TRUE },
+/*  6 */ { SW_SHOWMINIMIZED, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax, FALSE },
+/*  7 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_1, FALSE },
+/*  8 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq, FALSE },
+/*  9 */ { SW_SHOWMAXIMIZED, FALSE, WS_VISIBLE|WS_MAXIMIZE, WmShowMaximized_1, TRUE },
+/* 10 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmMinMax, FALSE },
+/* 11 */ { SW_HIDE, TRUE, WS_MAXIMIZE, WmHide_1, FALSE },
+/* 12 */ { SW_HIDE, FALSE, WS_MAXIMIZE, WmEmptySeq, FALSE },
+/* 13 */ { SW_SHOWNOACTIVATE, FALSE, WS_VISIBLE, WmShowNoActivate_1, FALSE },
+/* 14 */ { SW_SHOWNOACTIVATE, TRUE, WS_VISIBLE, WmEmptySeq, TRUE },
+/* 15 */ { SW_HIDE, TRUE, 0, WmHide_2, TRUE },
+/* 16 */ { SW_HIDE, FALSE, 0, WmEmptySeq, FALSE },
+/* 17 */ { SW_SHOW, FALSE, WS_VISIBLE, WmShow, TRUE },
+/* 18 */ { SW_SHOW, TRUE, WS_VISIBLE, WmEmptySeq, FALSE },
+/* 19 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_1, TRUE },
+/* 20 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax, FALSE },
+/* 21 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2, TRUE },
+/* 22 */ { SW_SHOWMINNOACTIVE, FALSE, WS_VISIBLE|WS_MINIMIZE, WmShowMinNoActivate, TRUE },
+/* 23 */ { SW_SHOWMINNOACTIVE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax, FALSE },
+/* 24 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2, FALSE },
+/* 25 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq, FALSE },
+/* 26 */ { SW_SHOWNA, FALSE, WS_VISIBLE|WS_MINIMIZE, WmShowNA_1, FALSE },
+/* 27 */ { SW_SHOWNA, TRUE, WS_VISIBLE|WS_MINIMIZE, WmShowNA_2, FALSE },
+/* 28 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2, FALSE },
+/* 29 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq, FALSE },
+/* 30 */ { SW_RESTORE, FALSE, WS_VISIBLE, WmRestore_1, TRUE },
+/* 31 */ { SW_RESTORE, TRUE, WS_VISIBLE, WmEmptySeq, TRUE },
+/* 32 */ { SW_HIDE, TRUE, 0, WmHide_3, TRUE },
+/* 33 */ { SW_HIDE, FALSE, 0, WmEmptySeq, FALSE },
+/* 34 */ { SW_NORMALNA, FALSE, 0, WmEmptySeq, TRUE }, /* what does this mean?! */
+/* 35 */ { SW_NORMALNA, FALSE, 0, WmEmptySeq, TRUE },
+/* 36 */ { SW_HIDE, FALSE, 0, WmEmptySeq, FALSE },
+/* 37 */ { SW_RESTORE, FALSE, WS_VISIBLE, WmRestore_2, TRUE },
+/* 38 */ { SW_RESTORE, TRUE, WS_VISIBLE, WmEmptySeq, TRUE },
+/* 39 */ { SW_SHOWNOACTIVATE, TRUE, WS_VISIBLE, WmEmptySeq, TRUE },
+/* 40 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_2, TRUE },
+/* 41 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax, FALSE },
+/* 42 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmShowMaximized_2, TRUE },
+/* 43 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmMinMax, FALSE },
+/* 44 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_1, TRUE },
+/* 45 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax, FALSE },
+/* 46 */ { SW_RESTORE, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmRestore_3, TRUE },
+/* 47 */ { SW_RESTORE, TRUE, WS_VISIBLE, WmRestore_4, FALSE },
+/* 48 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmShowMaximized_3, FALSE },
+/* 49 */ { SW_SHOW, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmEmptySeq, FALSE },
+/* 50 */ { SW_SHOWNORMAL, TRUE, WS_VISIBLE, WmRestore_4, FALSE },
+/* 51 */ { SW_SHOWNORMAL, TRUE, WS_VISIBLE, WmEmptySeq, TRUE },
+/* 52 */ { SW_HIDE, TRUE, 0, WmHide_1, FALSE },
+/* 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, TRUE },
+/* 56 */ { SW_SHOWNOACTIVATE, FALSE, WS_VISIBLE, WmShowNoActivate_2, TRUE },
+/* 57 */ { SW_SHOW, TRUE, WS_VISIBLE, WmEmptySeq, FALSE }
+    };
+    HWND hwnd;
+    DWORD style;
+    LPARAM ret;
+    INT i;
+
+#define WS_BASE (WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_POPUP|WS_CLIPSIBLINGS)
+    hwnd = CreateWindowEx(0, "ShowWindowClass", NULL, WS_BASE,
+                          120, 120, 90, 90,
+                          0, 0, 0, NULL);
+    assert(hwnd);
+
+    style = GetWindowLong(hwnd, GWL_STYLE) & ~WS_BASE;
+    ok(style == 0, "expected style 0, got %08x\n", style);
+
+    flush_events();
+    flush_sequence();
+
+    for (i = 0; i < sizeof(sw)/sizeof(sw[0]); i++)
+    {
+        static const char * const sw_cmd_name[13] =
+        {
+            "SW_HIDE", "SW_SHOWNORMAL", "SW_SHOWMINIMIZED", "SW_SHOWMAXIMIZED",
+            "SW_SHOWNOACTIVATE", "SW_SHOW", "SW_MINIMIZE", "SW_SHOWMINNOACTIVE",
+            "SW_SHOWNA", "SW_RESTORE", "SW_SHOWDEFAULT", "SW_FORCEMINIMIZE",
+            "SW_NORMALNA" /* 0xCC */
+        };
+        char comment[64];
+        INT idx; /* index into the above array of names */
+
+        idx = (sw[i].cmd == SW_NORMALNA) ? 12 : sw[i].cmd;
+
+        style = GetWindowLong(hwnd, GWL_STYLE);
+        trace("%d: sending %s, current window style %08x\n", i+1, sw_cmd_name[idx], style);
+        ret = ShowWindow(hwnd, sw[i].cmd);
+        ok(!ret == !sw[i].ret, "%d: cmd %s: expected ret %lu, got %lu\n", i+1, sw_cmd_name[idx], sw[i].ret, ret);
+        style = GetWindowLong(hwnd, GWL_STYLE) & ~WS_BASE;
+        ok(style == sw[i].style, "%d: expected style %08x, got %08x\n", i+1, sw[i].style, style);
+
+        sprintf(comment, "%d: ShowWindow(%s)", i+1, sw_cmd_name[idx]);
+        ok_sequence(sw[i].msg, comment, sw[i].todo_msg);
+
+        flush_events();
+        flush_sequence();
+    }
+
+    DestroyWindow(hwnd);
+}
+
 START_TEST(msg)
 {
     BOOL ret;
@@ -8257,6 +8676,7 @@ START_TEST(msg)
     hEvent_hook = 0;
 #endif
 
+    test_ShowWindow();
     test_PeekMessage();
     test_scrollwindowex();
     test_messages();
@@ -8291,3 +8711,4 @@ START_TEST(msg)
            "unexpected error %d\n", GetLastError());
     }
 }
+
diff --git a/dlls/winex11.drv/winpos.c b/dlls/winex11.drv/winpos.c
index b1690df..3c41b65 100644
--- a/dlls/winex11.drv/winpos.c
+++ b/dlls/winex11.drv/winpos.c
@@ -594,14 +594,14 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT cmd )
 	case SW_SHOWMINIMIZED:
             swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
             swp |= WINPOS_MinMaximize( hwnd, cmd, &newPos );
-            if (style & WS_MINIMIZE) return wasVisible;
+            if ((style & WS_MINIMIZE) && wasVisible) return TRUE;
 	    break;
 
 	case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
             if (!wasVisible) swp |= SWP_SHOWWINDOW;
             swp |= SWP_FRAMECHANGED;
             swp |= WINPOS_MinMaximize( hwnd, SW_MAXIMIZE, &newPos );
-            if ((style & WS_MAXIMIZE) && wasVisible) return wasVisible;
+            if ((style & WS_MAXIMIZE) && wasVisible) return TRUE;
             break;
 
 	case SW_SHOWNA:
@@ -769,7 +769,7 @@ void X11DRV_UnmapNotify( HWND hwnd, XEvent *event )
     {
         if (win->dwStyle & WS_MAXIMIZE)
             win->flags |= WIN_RESTORE_MAX;
-        else
+        else if (!(win->dwStyle & WS_MINIMIZE))
             win->flags &= ~WIN_RESTORE_MAX;
 
         WIN_SetStyle( hwnd, WS_MINIMIZE, WS_MAXIMIZE );
-- 
1.4.4.2






More information about the wine-patches mailing list