Commit in reactos/apps/tests/user32 on MAIN
dde.c+119added 1.1
class.c+8-81.2 -> 1.3
dialog.c+3-31.1 -> 1.2
input.c+14-41.2 -> 1.3
listbox.c+1-11.2 -> 1.3
makefile+2-11.2 -> 1.3
msg.c+756-1211.1 -> 1.2
resource.c+1-11.1 -> 1.2
sysparams.c+2091.2 -> 1.3
testlist.c+41.2 -> 1.3
win.c+538-31.2 -> 1.3
+1655-142
1 added + 10 modified, total 11 files
upgrading user32  test to Wine-20040527 - disabled a test in the 'msg' test because it fails on XP SP1.

reactos/apps/tests/user32
dde.c added at 1.1
diff -N dde.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ dde.c	28 May 2004 17:56:17 -0000	1.1
@@ -0,0 +1,119 @@
+/*
+ * Unit tests for DDE functions
+ *
+ * Copyright (c) 2004 Dmitry Timoshkov
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <assert.h>
+
+#include "wine/test.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "ddeml.h"
+#include "winerror.h"
+
+static HDDEDATA CALLBACK DdeCallback(UINT uType, UINT uFmt, HCONV hconv,
+                                     HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
+                                     ULONG_PTR dwData1, ULONG_PTR dwData2)
+{
+    return 0;
+}
+
+static void test_DdeCreateStringHandleW(DWORD dde_inst, int codepage)
+{
+    static const WCHAR dde_string[] = {'D','D','E',' ','S','t','r','i','n','g',0};
+    HSZ str_handle;
+    WCHAR bufW[256];
+    char buf[256];
+    int ret;
+
+    str_handle = DdeCreateStringHandleW(dde_inst, dde_string, codepage);
+    ok(str_handle != 0, "DdeCreateStringHandleW failed with error %08x\n",
+       DdeGetLastError(dde_inst));
+
+    ret = DdeQueryStringW(dde_inst, str_handle, NULL, 0, codepage);
+    if (codepage == CP_WINANSI)
+        ok(ret == 1, "DdeQueryStringW returned wrong length %d\n", ret);
+    else
+        ok(ret == lstrlenW(dde_string), "DdeQueryStringW returned wrong length %d\n", ret);
+
+    ret = DdeQueryStringW(dde_inst, str_handle, bufW, 256, codepage);
+    if (codepage == CP_WINANSI)
+    {
+        ok(ret == 1, "DdeQueryStringW returned wrong length %d\n", ret);
+        ok(!lstrcmpA("D", (LPCSTR)bufW), "DdeQueryStringW returned wrong string\n");
+    }
+    else
+    {
+        ok(ret == lstrlenW(dde_string), "DdeQueryStringW returned wrong length %d\n", ret);
+        ok(!lstrcmpW(dde_string, bufW), "DdeQueryStringW returned wrong string\n");
+    }
+
+    ret = DdeQueryStringA(dde_inst, str_handle, buf, 256, CP_WINANSI);
+    if (codepage == CP_WINANSI)
+    {
+        ok(ret == 1, "DdeQueryStringA returned wrong length %d\n", ret);
+        ok(!lstrcmpA("D", buf), "DdeQueryStringW returned wrong string\n");
+    }
+    else
+    {
+        ok(ret == lstrlenA("DDE String"), "DdeQueryStringA returned wrong length %d\n", ret);
+        ok(!lstrcmpA("DDE String", buf), "DdeQueryStringA returned wrong string %s\n", buf);
+    }
+
+    ret = DdeQueryStringA(dde_inst, str_handle, buf, 256, CP_WINUNICODE);
+    if (codepage == CP_WINANSI)
+    {
+        ok(ret == 1, "DdeQueryStringA returned wrong length %d\n", ret);
+        ok(!lstrcmpA("D", buf), "DdeQueryStringA returned wrong string %s\n", buf);
+    }
+    else
+    {
+        ok(ret == lstrlenA("DDE String"), "DdeQueryStringA returned wrong length %d\n", ret);
+        ok(!lstrcmpW(dde_string, (LPCWSTR)buf), "DdeQueryStringW returned wrong string\n");
+    }
+
+    ok(DdeFreeStringHandle(dde_inst, str_handle), "DdeFreeStringHandle failed\n");
+}
+
+START_TEST(dde)
+{
+    DWORD dde_inst, ret;
+
+    dde_inst = 0xdeadbeef;
+    SetLastError(0xdeadbeef);
+    ret = DdeInitializeW(&dde_inst, DdeCallback, APPCMD_CLIENTONLY, 0);
+    if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+    {
+        trace("Skipping the DDE test on a Win9x platform\n");
+        return;
+    }
+
+    ok(ret == DMLERR_INVALIDPARAMETER, "DdeInitializeW should fail, but got %04lx instead\n", ret);
+    ok(DdeGetLastError(dde_inst) == DMLERR_INVALIDPARAMETER, "expected DMLERR_INVALIDPARAMETER\n");
+
+    dde_inst = 0;
+    ret = DdeInitializeW(&dde_inst, DdeCallback, APPCMD_CLIENTONLY, 0);
+    ok(ret == DMLERR_NO_ERROR, "DdeInitializeW failed with error %04lx (%08x)\n",
+       ret, DdeGetLastError(dde_inst));
+
+    test_DdeCreateStringHandleW(dde_inst, 0);
+    test_DdeCreateStringHandleW(dde_inst, CP_WINUNICODE);
+    test_DdeCreateStringHandleW(dde_inst, CP_WINANSI);
+
+    ok(DdeUninitialize(dde_inst), "DdeUninitialize failed\n");
+}

reactos/apps/tests/user32
class.c 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- class.c	14 Feb 2004 20:13:04 -0000	1.2
+++ class.c	28 May 2004 17:56:17 -0000	1.3
@@ -20,9 +20,6 @@
 
 /* To get CS_DROPSHADOW with the MSVC headers */
 #define _WIN32_WINNT 0x0501
-#ifndef CS_DROPSHADOW
-#define CS_DROPSHADOW       0x00020000
-#endif
 
 #include <assert.h>
 #include <stdlib.h>
@@ -48,8 +45,8 @@
 static void ClassTest(HINSTANCE hInstance, BOOL global)
 {
     WNDCLASSW cls, wc;
-    WCHAR className[] = {'T','e','s','t','C','l','a','s','s',0};
-    WCHAR winName[]   = {'W','i','n','C','l','a','s','s','T','e','s','t',0};
+    static const WCHAR className[] = {'T','e','s','t','C','l','a','s','s',0};
+    static const WCHAR winName[]   = {'W','i','n','C','l','a','s','s','T','e','s','t',0};
     ATOM test_atom;
     HWND hTestWnd;
     DWORD i;
@@ -243,7 +240,7 @@
 
 static void check_instance( const char *name, HINSTANCE inst, HINSTANCE info_inst, HINSTANCE gcl_inst )
 {
-    WNDCLASS wc;
+    WNDCLASSA wc;
     HWND hwnd;
 
     ok( GetClassInfo( inst, name, &wc ), "Couldn't find class %s inst %p\n", name, inst );
@@ -251,9 +248,12 @@
         wc.hInstance, info_inst, name );
     hwnd = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, inst, 0 );
     ok( hwnd != NULL, "Couldn't create window for class %s inst %p\n", name, inst );
-    ok( (HINSTANCE)GetClassLong( hwnd, GCL_HMODULE ) == gcl_inst,
+    ok( (HINSTANCE)GetClassLongA( hwnd, GCL_HMODULE ) == gcl_inst,
         "Wrong GCL instance %p/%p for class %s\n",
-        (HINSTANCE)GetClassLong( hwnd, GCL_HMODULE ), gcl_inst, name );
+        (HINSTANCE)GetClassLongA( hwnd, GCL_HMODULE ), gcl_inst, name );
+    ok( (HINSTANCE)GetWindowLongA( hwnd, GWL_HINSTANCE ) == inst,
+        "Wrong GWL instance %p/%p for window %s\n",
+        (HINSTANCE)GetWindowLongA( hwnd, GWL_HINSTANCE ), inst, name );
     DestroyWindow(hwnd);
 }
 

reactos/apps/tests/user32
dialog.c 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- dialog.c	14 Feb 2004 20:13:04 -0000	1.1
+++ dialog.c	28 May 2004 17:56:17 -0000	1.2
@@ -365,9 +365,9 @@
         {   1,  23,    6,  68,   0,   0,  68},
         {   1,  24,    6,  25,   0,   1,  72},
         {   1,  25,    1,  70,   0,   0,  72},
-        {   0,  26,    1,  70,   0,   1,   3},
+        /*{   0,  26,    1,  70,   0,   1,   3}, Crashes Win95*/
         {   1,  27,    1,  70,   1,   0,  72},
-        {   0,  28,    1,  70,   1,   1,  61},
+        /*{   0,  28,    1,  70,   1,   1,  61}, Crashes Win95*/
 
         {   1,  29,    6,  67,   1,   0,  72},
         {   1,  30,    6,  72,   1,   1,  67},
@@ -515,4 +515,4 @@
 
     GetNextDlgItemTest();
     IsDialogMessageWTest();
-}
+}
\ No newline at end of file

reactos/apps/tests/user32
input.c 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- input.c	14 Feb 2004 20:13:04 -0000	1.2
+++ input.c	28 May 2004 17:56:17 -0000	1.3
@@ -46,9 +46,10 @@
 
 #define _WIN32_WINNT 0x401
 
+#include <windows.h>
 #include "wine/test.h"
-#include "winbase.h"
-#include "winuser.h"
+//#include "winbase.h"
+//#include "winuser.h"
 
 #include <assert.h>
 
@@ -56,6 +57,8 @@
 HWND hWndTest;
 long timetag = 0x10000000;
 
+static UINT (WINAPI *ptr_SendInput) (UINT, INPUT*, size_t);
+
 #define MAXKEYEVENTS 6
 #define MAXKEYMESSAGES MAXKEYEVENTS /* assuming a key event generates one
                                        and only one message */
@@ -203,12 +206,19 @@
  */
 void do_test( HWND hwnd, int seqnr, KEV td[] )
 {
+    HMODULE module;
     INPUT inputs[MAXKEYEVENTS];
     KMSG expmsg[MAXKEYEVENTS];
     MSG msg;
     char buf[100];
     UINT evtctr=0;
     int kmctr, i;
+
+    module = GetModuleHandleA("user32");
+    if (!module) return;
+    ptr_SendInput = (void *)GetProcAddress(module, "SendInput");
+    if (!ptr_SendInput) return;
+
     buf[0]='\0';
     TrackSysKey=0; /* see input.c */
     for( i = 0; i < MAXKEYEVENTS; i++) {
@@ -222,7 +232,7 @@
     for( kmctr = 0; kmctr < MAXKEYEVENTS && expmsg[kmctr].message; kmctr++)
         ;
     assert( evtctr <= MAXKEYEVENTS );
-    assert( evtctr == SendInput(evtctr, &inputs[0], sizeof(INPUT)));
+    assert( evtctr == ptr_SendInput(evtctr, &inputs[0], sizeof(INPUT)));
     i = 0;
     trace("======== key stroke sequence #%d: %s =============\n",
             seqnr + 1, buf);
@@ -352,4 +362,4 @@
         TranslateMessage( &msg );
         DispatchMessageA( &msg );
     }
-}
+}
\ No newline at end of file

reactos/apps/tests/user32
listbox.c 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- listbox.c	14 Feb 2004 20:13:04 -0000	1.2
+++ listbox.c	28 May 2004 17:56:17 -0000	1.3
@@ -170,4 +170,4 @@
   check (MS);
   trace (" ... with NOSEL\n");
   check (MS_NS);
-}
+}
\ No newline at end of file

reactos/apps/tests/user32
makefile 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- makefile	14 Feb 2004 20:13:04 -0000	1.2
+++ makefile	28 May 2004 17:56:17 -0000	1.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.2 2004/02/14 20:13:04 sedwards Exp $
+# $Id: makefile,v 1.3 2004/05/28 17:56:17 royce Exp $
 
 PATH_TO_TOP = ../../..
 
@@ -18,6 +18,7 @@
 TARGET_OBJECTS = \
 	testlist.o \
 	class.o \
+	dde.o \
 	dialog.o \
 	listbox.o \
 	msg.o \

reactos/apps/tests/user32
msg.c 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- msg.c	18 Nov 2003 22:24:42 -0000	1.1
+++ msg.c	28 May 2004 17:56:17 -0000	1.2
@@ -3,6 +3,7 @@
  *
  * Copyright 1999 Ove Kaaven
  * Copyright 2003 Dimitrie O. Paun
+ * Copyright 2004 Dmitry Timoshkov
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,9 +21,7 @@
  */
 
 #include <assert.h>
-#include <stdlib.h>
 #include <stdarg.h>
-#include <stdio.h>
 
 #include "windef.h"
 #include "winbase.h"
@@ -44,102 +43,246 @@
 
 typedef enum { 
     sent=0x1, posted=0x2, parent=0x4, wparam=0x8, lparam=0x10,
-    defwinproc=0x20
+    defwinproc=0x20, optional=0x40, hook=0x80
 } msg_flags_t;
 
 struct message {
     UINT message;          /* the WM_* code */
     msg_flags_t flags;     /* message props */
-    WPARAM wParam;         /* expacted value of wParam */
-    LPARAM lParam;         /* expacted value of lParam */
+    WPARAM wParam;         /* expected value of wParam */
+    LPARAM lParam;         /* expected value of lParam */
 };
 
 /* CreateWindow (for overlapped window, not initially visible) (16/32) */
-static struct message WmCreateOverlappedSeq[] = {
+static const struct message WmCreateOverlappedSeq[] = {
+    { HCBT_CREATEWND, hook },
     { WM_GETMINMAXINFO, sent },
     { WM_NCCREATE, sent },
     { WM_NCCALCSIZE, sent|wparam, 0 },
     { WM_CREATE, sent },
     { 0 }
 };
-/* ShowWindow (for overlapped window) (16/32) */
-static struct message WmShowOverlappedSeq[] = {
+/* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
+ * for a not visible overlapped window.
+ */
+static const struct message WmSWP_ShowOverlappedSeq[] = {
+    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
+    { WM_NCPAINT, sent|wparam|optional, 1 },
+    { WM_GETTEXT, sent|defwinproc|optional },
+    { WM_ERASEBKGND, sent|optional },
+    { HCBT_ACTIVATE, hook },
+    { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 },
+    { WM_WINDOWPOSCHANGING, sent|wparam|optional, 0 }, /* Win9x: SWP_NOSENDCHANGING */
+    { WM_ACTIVATEAPP, sent|wparam, 1 },
+    { WM_NCACTIVATE, sent|wparam, 1 },
+    { WM_GETTEXT, sent|defwinproc|optional },
+    { WM_ACTIVATE, sent|wparam, 1 },
+    { HCBT_SETFOCUS, hook },
+    { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
+    { WM_SETFOCUS, sent|wparam|defwinproc, 0 },
+    { WM_NCPAINT, sent|wparam|optional, 1 },
+    { WM_GETTEXT, sent|defwinproc|optional },
+    { WM_ERASEBKGND, sent|optional },
+    { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
+    { WM_NCCALCSIZE, sent|wparam|optional, 1 },
+    { WM_NCPAINT, sent|wparam|optional, 1 },
+    { WM_ERASEBKGND, sent|optional },
+    { 0 }
+};
+/* SetWindowPos(SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE)
+ * for a visible overlapped window.
+ */
+static const struct message WmSWP_HideOverlappedSeq[] = {
+    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
+    { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
+    { 0 }
+};
+/* ShowWindow(SW_SHOW) for a not visible overlapped window */
+static const struct message WmShowOverlappedSeq[] = {
     { WM_SHOWWINDOW, sent|wparam, 1 },
-    { WM_WINDOWPOSCHANGING, sent|wparam, /*FIXME: SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW*/ 0 },
-    /* FIXME: WM_QUERYNEWPALETTE, if in 256-color mode */
-    { WM_WINDOWPOSCHANGING, sent|wparam, /*FIXME: SWP_NOMOVE|SWP_NOSIZE*/ 0 },
+    { WM_NCPAINT, sent|wparam|optional, 1 },
+    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
+    { WM_NCPAINT, sent|wparam|optional, 1 },
+    { WM_GETTEXT, sent|defwinproc|optional },
+    { WM_ERASEBKGND, sent|optional },
+    { HCBT_ACTIVATE, hook },
+    { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 },
+    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
     { WM_ACTIVATEAPP, sent|wparam, 1 },
     { WM_NCACTIVATE, sent|wparam, 1 },
-    { WM_GETTEXT, sent|defwinproc },
+    { WM_GETTEXT, sent|defwinproc|optional },
     { WM_ACTIVATE, sent|wparam, 1 },
+    { HCBT_SETFOCUS, hook },
+    { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
     { WM_SETFOCUS, sent|wparam|defwinproc, 0 },
-    { WM_NCPAINT, sent|wparam, 1 },
-    { WM_GETTEXT, sent|defwinproc },
-    { WM_ERASEBKGND, sent },
-    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_SHOWWINDOW },
+    { WM_NCPAINT, sent|wparam|optional, 1 },
+    { WM_GETTEXT, sent|defwinproc|optional },
+    { WM_ERASEBKGND, sent|optional },
+    { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
+    { WM_NCCALCSIZE, sent|optional },
+    { WM_NCPAINT, sent|optional },
+    { WM_ERASEBKGND, sent|optional },
+#if 0 /* CreateWindow/ShowWindow(SW_SHOW) also generates WM_SIZE/WM_MOVE
+       * messages. Does that mean that CreateWindow doesn't set initial
+       * window dimensions for overlapped windows?
+       */
     { WM_SIZE, sent },
     { WM_MOVE, sent },
+#endif
     { 0 }
 };
-
-/* DestroyWindow (for overlapped window) (32) */
-static struct message WmDestroyOverlappedSeq[] = {
+/* ShowWindow(SW_HIDE) for a visible overlapped window */
+static const struct message WmHideOverlappedSeq[] = {
+    { WM_SHOWWINDOW, sent|wparam, 0 },
     { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
     { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
+    { WM_SIZE, sent },
+    { WM_MOVE, sent },
     { WM_NCACTIVATE, sent|wparam, 0 },
     { WM_ACTIVATE, sent|wparam, 0 },
     { WM_ACTIVATEAPP, sent|wparam, 0 },
     { WM_KILLFOCUS, sent|wparam, 0 },
+    { WM_IME_SETCONTEXT, sent|wparam|optional, 0 },
+    { 0 }
+};
+/* DestroyWindow for a visible overlapped window */
+static const struct message WmDestroyOverlappedSeq[] = {
+    { HCBT_DESTROYWND, hook },
+    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
+    { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
+    { WM_NCACTIVATE, sent|wparam, 0 },
+    { WM_ACTIVATE, sent|wparam, 0 },
+    { WM_ACTIVATEAPP, sent|wparam, 0 },
+    { WM_KILLFOCUS, sent|wparam, 0 },
+    { WM_IME_SETCONTEXT, sent|wparam|optional, 0 },
     { WM_DESTROY, sent },
     { WM_NCDESTROY, sent },
     { 0 }
 };
+/* CreateWindow (for a child popup window, not initially visible) */
+static const struct message WmCreateChildPopupSeq[] = {
+    { HCBT_CREATEWND, hook },
+    { WM_NCCREATE, sent }, 
+    { WM_NCCALCSIZE, sent|wparam, 0 },
+    { WM_CREATE, sent },
+    { WM_SIZE, sent },
+    { WM_MOVE, sent },
+    { 0 }
+};
+/* CreateWindow (for a popup window, not initially visible,
+ * which sets WS_VISIBLE in WM_CREATE handler)
+ */
+static const struct message WmCreateInvisiblePopupSeq[] = {
+    { HCBT_CREATEWND, hook },
+    { WM_NCCREATE, sent }, 
+    { WM_NCCALCSIZE, sent|wparam, 0 },
+    { WM_CREATE, sent },
+    { WM_STYLECHANGING, sent },
+    { WM_STYLECHANGED, sent },
+    { WM_SIZE, sent },
+    { WM_MOVE, sent },
+    { 0 }
+};
+/* ShowWindow (for a popup window with WS_VISIBLE style set) */
+static const struct message WmShowVisiblePopupSeq[] = {
+    { 0 }
+};
+/* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER)
+ * for a popup window with WS_VISIBLE style set
+ */
+static const struct message WmShowVisiblePopupSeq_2[] = {
+    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
+    { 0 }
+};
+/* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
+ * for a popup window with WS_VISIBLE style set
+ */
+static const struct message WmShowVisiblePopupSeq_3[] = {
+    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
+    { HCBT_ACTIVATE, hook },
+    { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 },
+    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
+    { WM_NCACTIVATE, sent|wparam, 1 },
+    { WM_ACTIVATE, sent|wparam, 1 },
+    { HCBT_SETFOCUS, hook },
+    { WM_KILLFOCUS, sent|parent },
+    { WM_IME_SETCONTEXT, sent|parent|wparam|optional, 0 },
+    { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
+    { WM_SETFOCUS, sent|defwinproc },
+    { 0 }
+};
 /* CreateWindow (for child window, not initially visible) */
-static struct message WmCreateChildSeq[] = {
+static const struct message WmCreateChildSeq[] = {
+    { HCBT_CREATEWND, hook },
     { WM_NCCREATE, sent }, 
     /* child is inserted into parent's child list after WM_NCCREATE returns */
     { WM_NCCALCSIZE, sent|wparam, 0 },
     { WM_CREATE, sent },
     { WM_SIZE, sent },
     { WM_MOVE, sent },
-    { WM_PARENTNOTIFY, sent|parent|wparam, 1 },
+    { WM_PARENTNOTIFY, sent|parent|wparam, WM_CREATE },
     { 0 }
 };
-/* ShowWindow (for child window) */
-static struct message WmShowChildSeq[] = {
+/* CreateWindow (for maximized child window, not initially visible) */
+static const struct message WmCreateMaximizedChildSeq[] = {
+    { HCBT_CREATEWND, hook },
+    { WM_NCCREATE, sent }, 
+    { WM_NCCALCSIZE, sent|wparam, 0 },
+    { WM_CREATE, sent },
+    { WM_SIZE, sent },
+    { WM_MOVE, sent },
+    { HCBT_MINMAX, hook|lparam, 0, SW_MAXIMIZE },
+    { WM_GETMINMAXINFO, sent },
+    { WM_WINDOWPOSCHANGING, sent },
+    { WM_NCCALCSIZE, sent },
+    { WM_WINDOWPOSCHANGED, sent },
+    { WM_SIZE, sent|defwinproc },
+    { WM_PARENTNOTIFY, sent|parent|wparam, WM_CREATE },
+    { 0 }
+};
+/* ShowWindow(SW_SHOW) for a not visible child window */
+static const struct message WmShowChildSeq[] = {
     { WM_SHOWWINDOW, sent|wparam, 1 },
     { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
-    { WM_ERASEBKGND, sent|parent },
+    { WM_ERASEBKGND, sent|parent|optional },
     { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
     { 0 }
 };
-/* DestroyWindow (for child window) */
-static struct message WmDestroyChildSeq[] = {
-    { WM_PARENTNOTIFY, sent|parent|wparam, 2 },
+/* DestroyWindow for a visible child window */
+static const struct message WmDestroyChildSeq[] = {
+    { HCBT_DESTROYWND, hook },
+    { WM_PARENTNOTIFY, sent|parent|wparam, WM_DESTROY },
     { WM_SHOWWINDOW, sent|wparam, 0 },
     { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
-    { WM_ERASEBKGND, sent|parent },
+    { WM_ERASEBKGND, sent|parent|optional },
     { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
+    { HCBT_SETFOCUS, hook }, /* set focus to a parent */
+    { WM_KILLFOCUS, sent },
+    { WM_IME_SETCONTEXT, sent|wparam|optional, 0 },
+    { WM_IME_SETCONTEXT, sent|wparam|parent|optional, 1 },
+    { WM_SETFOCUS, sent|parent },
     { WM_DESTROY, sent },
+    { WM_DESTROY, sent|optional }, /* a bug in win2k sp4 ? */
     { WM_NCDESTROY, sent },
+    { WM_NCDESTROY, sent|optional }, /* a bug in win2k sp4 ? */
     { 0 }
 };
 /* Moving the mouse in nonclient area */
-static struct message WmMouseMoveInNonClientAreaSeq[] = { /* FIXME: add */
+static const struct message WmMouseMoveInNonClientAreaSeq[] = { /* FIXME: add */
     { WM_NCHITTEST, sent },
     { WM_SETCURSOR, sent },
     { WM_NCMOUSEMOVE, posted },
     { 0 }
 };
 /* Moving the mouse in client area */
-static struct message WmMouseMoveInClientAreaSeq[] = { /* FIXME: add */
+static const struct message WmMouseMoveInClientAreaSeq[] = { /* FIXME: add */
     { WM_NCHITTEST, sent },
     { WM_SETCURSOR, sent },
     { WM_MOUSEMOVE, posted },
     { 0 }
 };
 /* Moving by dragging the title bar (after WM_NCHITTEST and WM_SETCURSOR) (outline move) */
-static struct message WmDragTitleBarSeq[] = { /* FIXME: add */
+static const struct message WmDragTitleBarSeq[] = { /* FIXME: add */
     { WM_NCLBUTTONDOWN, sent|wparam, HTCAPTION },
     { WM_SYSCOMMAND, sent|defwinproc|wparam, SC_MOVE+2 },
     { WM_GETMINMAXINFO, sent|defwinproc },
@@ -151,7 +294,7 @@
     { 0 }
 };
 /* Sizing by dragging the thick borders (after WM_NCHITTEST and WM_SETCURSOR) (outline move) */
-static struct message WmDragThinkBordersBarSeq[] = { /* FIXME: add */
+static const struct message WmDragThickBordersBarSeq[] = { /* FIXME: add */
     { WM_NCLBUTTONDOWN, sent|wparam, 0xd },
     { WM_SYSCOMMAND, sent|defwinproc|wparam, 0xf004 },
     { WM_GETMINMAXINFO, sent|defwinproc },
@@ -170,17 +313,17 @@
     { 0 }
 };
 /* Resizing child window with MoveWindow (32) */
-static struct message WmResizingChildWithMoveWindowSeq[] = {
+static const struct message WmResizingChildWithMoveWindowSeq[] = {
     { WM_WINDOWPOSCHANGING, sent },
     { WM_NCCALCSIZE, sent|wparam, 1 },
-    { WM_ERASEBKGND, sent },
+    { WM_ERASEBKGND, sent|optional },
     { WM_WINDOWPOSCHANGED, sent },
     { WM_MOVE, sent|defwinproc },
     { WM_SIZE, sent|defwinproc },
     { 0 }
 };
 /* Clicking on inactive button */
-static struct message WmClickInactiveButtonSeq[] = { /* FIXME: add */
+static const struct message WmClickInactiveButtonSeq[] = { /* FIXME: add */
     { WM_NCHITTEST, sent },
     { WM_PARENTNOTIFY, sent|parent|wparam, WM_LBUTTONDOWN },
     { WM_MOUSEACTIVATE, sent },
@@ -201,7 +344,7 @@
 };
 /* Reparenting a button (16/32) */
 /* The last child (button) reparented gets topmost for its new parent. */
-static struct message WmReparentButtonSeq[] = { /* FIXME: add */
+static const struct message WmReparentButtonSeq[] = { /* FIXME: add */
     { WM_SHOWWINDOW, sent|wparam, 0 },
     { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER },
     { WM_ERASEBKGND, sent|parent },
@@ -213,62 +356,147 @@
     { WM_SHOWWINDOW, sent|wparam, 1 },
     { 0 }
 };
-/* Creation of a modal dialog (32) */
-static struct message WmCreateModalDialogSeq[] = { /* FIXME: add */
+/* Creation of a custom dialog (32) */
+static const struct message WmCreateCustomDialogSeq[] = {
+    { HCBT_CREATEWND, hook },
+    { WM_GETMINMAXINFO, sent },
+    { WM_NCCREATE, sent },
+    { WM_NCCALCSIZE, sent|wparam, 0 },
+    { WM_CREATE, sent },
+    { WM_SHOWWINDOW, sent|wparam, 1 },
+    { HCBT_ACTIVATE, hook },
+    { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 },
+    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
+    { WM_NCACTIVATE, sent|wparam, 1 },
+    { WM_GETTEXT, sent|optional|defwinproc },
+    { WM_GETICON, sent|optional|defwinproc },
+    { WM_GETICON, sent|optional|defwinproc },
+    { WM_GETICON, sent|optional|defwinproc },
+    { WM_GETTEXT, sent|optional|defwinproc },
+    { WM_ACTIVATE, sent|wparam, 1 },
+    { WM_KILLFOCUS, sent|parent },
+    { WM_IME_SETCONTEXT, sent|parent|wparam|optional, 0 },
+    { WM_IME_SETCONTEXT, sent|wparam|optional, 1 },
+    { WM_SETFOCUS, sent },
+    { WM_GETDLGCODE, sent|defwinproc|wparam, 0 },
+    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
+    { WM_NCPAINT, sent|wparam, 1 },
+    { WM_GETTEXT, sent|optional|defwinproc },
+    { WM_GETICON, sent|optional|defwinproc },
+    { WM_GETICON, sent|optional|defwinproc },
+    { WM_GETICON, sent|optional|defwinproc },
+    { WM_GETTEXT, sent|optional|defwinproc },
+    { WM_ERASEBKGND, sent },
+    { WM_CTLCOLORDLG, sent|defwinproc },
+    { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
+    { WM_GETTEXT, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETTEXT, sent|optional },
+    { WM_NCCALCSIZE, sent|optional },
+    { WM_NCPAINT, sent|optional },
+    { WM_GETTEXT, sent|optional|defwinproc },
+    { WM_GETICON, sent|optional|defwinproc },
+    { WM_GETICON, sent|optional|defwinproc },
+    { WM_GETICON, sent|optional|defwinproc },
+    { WM_GETTEXT, sent|optional|defwinproc },
+    { WM_ERASEBKGND, sent|optional },
+    { WM_CTLCOLORDLG, sent|optional|defwinproc },
+    { WM_SIZE, sent },
+    { WM_MOVE, sent },
+    { 0 }
+};
+/* Calling EndDialog for a custom dialog (32) */
+static const struct message WmEndCustomDialogSeq[] = {
+    { WM_WINDOWPOSCHANGING, sent },
+    { WM_WINDOWPOSCHANGED, sent },
+    { WM_GETTEXT, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { HCBT_ACTIVATE, hook },
+    { WM_NCACTIVATE, sent|wparam, 0 },
+    { WM_GETTEXT, sent|optional|defwinproc },
+    { WM_GETICON, sent|optional|defwinproc },
+    { WM_GETICON, sent|optional|defwinproc },
+    { WM_GETICON, sent|optional|defwinproc },
+    { WM_GETTEXT, sent|optional|defwinproc },
+    { WM_ACTIVATE, sent|wparam, 0 },
+    { WM_WINDOWPOSCHANGING, sent|optional },
+    { HCBT_SETFOCUS, hook },
+    { WM_KILLFOCUS, sent },
+    { WM_IME_SETCONTEXT, sent|wparam|optional, 0 },
+    { WM_IME_SETCONTEXT, sent|parent|wparam|defwinproc|optional, 1 },
+    { WM_SETFOCUS, sent|parent|defwinproc },
+    { 0 }
+};
+/* Creation and destruction of a modal dialog (32) */
+static const struct message WmModalDialogSeq[] = {
     { WM_CANCELMODE, sent|parent },
     { WM_KILLFOCUS, sent|parent },
+    { WM_IME_SETCONTEXT, sent|parent|wparam|optional, 0 },
     { WM_ENABLE, sent|parent|wparam, 0 },
-    /* (window proc creation messages not tracked yet, because...) */
     { WM_SETFONT, sent },
     { WM_INITDIALOG, sent },
-    /* (...the window proc message hook was installed here, IsVisible still FALSE) */
-    { WM_NCACTIVATE, sent|parent|wparam, 0 },
-    { WM_GETTEXT, sent|defwinproc },
-    { WM_ACTIVATE, sent|parent|wparam, 0 },
+    { WM_CHANGEUISTATE, sent|optional },
+    { WM_SHOWWINDOW, sent },
     { WM_WINDOWPOSCHANGING, sent },
-    { WM_WINDOWPOSCHANGING, sent|parent },
     { WM_NCACTIVATE, sent|wparam, 1 },
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETTEXT, sent|optional },
     { WM_ACTIVATE, sent|wparam, 1 },
-    /* (setting focus) */
-    { WM_SHOWWINDOW, sent|wparam, 1 },
     { WM_WINDOWPOSCHANGING, sent },
     { WM_NCPAINT, sent },
-    { WM_GETTEXT, sent|defwinproc },
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETTEXT, sent|optional },
     { WM_ERASEBKGND, sent },
-    { WM_CTLCOLORDLG, sent|defwinproc },
+    { WM_CTLCOLORDLG, sent },
     { WM_WINDOWPOSCHANGED, sent },
-    { WM_PAINT, sent },
-    /* FIXME: (bunch of WM_CTLCOLOR* for each control) */
-    { WM_PAINT, sent|parent },
-    { WM_ENTERIDLE, sent|parent|wparam, 0},
-    { WM_SETCURSOR, sent|parent },
-    { 0 }
-};
-/* Destruction of a modal dialog (32) */
-static struct message WmDestroyModalDialogSeq[] = { /* FIXME: add */
-    /* (inside dialog proc: EndDialog is called) */
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETTEXT, sent|optional },
+    { WM_NCCALCSIZE, sent|optional },
+    { WM_NCPAINT, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETTEXT, sent|optional },
+    { WM_ERASEBKGND, sent|optional },
+    { WM_CTLCOLORDLG, sent|optional },
+    { WM_PAINT, sent|optional },
+    { WM_CTLCOLORBTN, sent },
+    { WM_ENTERIDLE, sent|parent },
+    { WM_TIMER, sent },
     { WM_ENABLE, sent|parent|wparam, 1 },
-    { WM_SETFOCUS, sent },
     { WM_WINDOWPOSCHANGING, sent },
-    { WM_NCPAINT, sent|parent },
-    { WM_GETTEXT, sent|defwinproc },
-    { WM_ERASEBKGND, sent|parent },
     { WM_WINDOWPOSCHANGED, sent },
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETTEXT, sent|optional },
+    { HCBT_ACTIVATE, hook },
     { WM_NCACTIVATE, sent|wparam, 0 },
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETTEXT, sent|optional },
     { WM_ACTIVATE, sent|wparam, 0 },
-    { WM_WINDOWPOSCHANGING, sent },
-    { WM_WINDOWPOSCHANGING, sent|parent },
-    { WM_NCACTIVATE, sent|parent|wparam, 1 },
-    { WM_GETTEXT, sent|defwinproc },
-    { WM_ACTIVATE, sent|parent|wparam, 1 },
-    { WM_KILLFOCUS, sent },
-    { WM_SETFOCUS, sent|parent },
+    { WM_WINDOWPOSCHANGING, sent|optional },
+    { HCBT_SETFOCUS, hook },
+    { WM_IME_SETCONTEXT, sent|parent|wparam|defwinproc|optional, 1 },
+    { WM_SETFOCUS, sent|parent|defwinproc },
     { WM_DESTROY, sent },
     { WM_NCDESTROY, sent },
     { 0 }
 };
 /* Creation of a modal dialog that is resized inside WM_INITDIALOG (32) */
-static struct message WmCreateModalDialogResizeSeq[] = { /* FIXME: add */
+static const struct message WmCreateModalDialogResizeSeq[] = { /* FIXME: add */
     /* (inside dialog proc, handling WM_INITDIALOG) */
     { WM_WINDOWPOSCHANGING, sent },
     { WM_NCCALCSIZE, sent },
@@ -296,37 +524,124 @@
     { WM_SETCURSOR, sent|parent },
     { 0 }
 };
+/* SetMenu for NonVisible windows with size change*/
+static const struct message WmSetMenuNonVisibleSizeChangeSeq[] = {
+    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
+    { WM_NCCALCSIZE, sent|wparam, 1 },
+    { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
+    { WM_MOVE, sent|defwinproc },
+    { WM_SIZE, sent|defwinproc },
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETICON, sent|optional },
+    { WM_GETTEXT, sent|optional },
+    { WM_NCCALCSIZE, sent|wparam|optional, 1 },
+    { 0 }
+};
+/* SetMenu for NonVisible windows with no size change */
+static const struct message WmSetMenuNonVisibleNoSizeChangeSeq[] = {
+    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
+    { WM_NCCALCSIZE, sent|wparam, 1 },
+    { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
+    { 0 }
+};
+/* SetMenu for Visible windows with size change */
+static const struct message WmSetMenuVisibleSizeChangeSeq[] = {
+    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
+    { WM_NCCALCSIZE, sent|wparam, 1 },
+    { WM_NCPAINT, sent|wparam, 1 },
+    { WM_GETTEXT, sent|defwinproc|optional },
+    { WM_ERASEBKGND, sent|optional },
+    { WM_ACTIVATE, sent|optional },
+    { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
+    { WM_MOVE, sent|defwinproc },
+    { WM_SIZE, sent|defwinproc },
+    { WM_NCCALCSIZE, sent|wparam|optional, 1 },
+    { WM_NCPAINT, sent|wparam|optional, 1 },
+    { WM_ERASEBKGND, sent|optional },
+    { 0 }
+};
+/* SetMenu for Visible windows with no size change */
+static const struct message WmSetMenuVisibleNoSizeChangeSeq[] = {
+    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
+    { WM_NCCALCSIZE, sent|wparam, 1 },
+    { WM_NCPAINT, sent|wparam, 1 },
+    { WM_GETTEXT, sent|defwinproc|optional },
+    { WM_ERASEBKGND, sent|optional },
+    { WM_ACTIVATE, sent|optional },
+    { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
+    { 0 }
+};
+/* DrawMenuBar for a visible window */
+static const struct message WmDrawMenuBarSeq[] =
+{
+    { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
+    { WM_NCCALCSIZE, sent|wparam, 1 },
+    { WM_NCPAINT, sent|wparam, 1 },
+    { WM_GETTEXT, sent|defwinproc|optional },
+    { WM_ERASEBKGND, sent|optional },
+    { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
+    { 0 }
+};
 
+static const struct message WmSetRedrawFalseSeq[] =
+{
+    { WM_SETREDRAW, sent|wparam, 0 },
+    { 0 }
+};
+
+static const struct message WmSetRedrawTrueSeq[] =
+{
+    { WM_SETREDRAW, sent|wparam, 1 },
+    { 0 }
+};
+
+static int after_end_dialog;
 static int sequence_cnt, sequence_size;
 static struct message* sequence;
 
-static void add_message(struct message msg)
+static void add_message(const struct message *msg)
 {
     if (!sequence) 
-	sequence = malloc ( (sequence_size = 10) * sizeof (struct message) );
+    {
+	sequence_size = 10;
+	sequence = HeapAlloc( GetProcessHeap(), 0, sequence_size * sizeof (struct message) );
+    }
     if (sequence_cnt == sequence_size) 
-	sequence = realloc ( sequence, (sequence_size *= 2) * sizeof (struct message) );
+    {
+	sequence_size *= 2;
+	sequence = HeapReAlloc( GetProcessHeap(), 0, sequence, sequence_size * sizeof (struct message) );
+    }
     assert(sequence);
-    sequence[sequence_cnt++] = msg;
+
+    sequence[sequence_cnt].message = msg->message;
+    sequence[sequence_cnt].flags = msg->flags;
+    sequence[sequence_cnt].wParam = msg->wParam;
+    sequence[sequence_cnt].lParam = msg->lParam;
+
+    sequence_cnt++;
 }
 
 static void flush_sequence()
 {
-    free(sequence);
+    HeapFree(GetProcessHeap(), 0, sequence);
     sequence = 0;
     sequence_cnt = sequence_size = 0;
 }
 
-static void ok_sequence(struct message *expected, const char *context)
+static void ok_sequence(const struct message *expected, const char *context)
 {
-    static struct message end_of_sequence = { 0, 0, 0, 0 };
-    struct message *actual = sequence;
+    static const struct message end_of_sequence = { 0, 0, 0, 0 };
+    const struct message *actual;
     
-    add_message(end_of_sequence);
+    add_message(&end_of_sequence);
 
-    /* naive sequence comparison. Would be nice to use a regexp engine here */
-    while (expected->message || actual->message)
+    actual = sequence;
+
+    while (expected->message && actual->message)
     {
+	trace("expected %04x - actual %04x\n", expected->message, actual->message);
+
 	if (expected->message == actual->message)
 	{
 	    if (expected->flags & wparam)
@@ -337,30 +652,23 @@
 		 ok (expected->lParam == actual->lParam,
 		     "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
 		     context, expected->message, expected->lParam, actual->lParam);
-	    /* FIXME: should we check defwinproc? */
+	    ok ((expected->flags & defwinproc) == (actual->flags & defwinproc),
+		"%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
+		context, expected->message, (expected->flags & defwinproc) ? "" : "NOT ");
 	    ok ((expected->flags & (sent|posted)) == (actual->flags & (sent|posted)),
 		"%s: the msg 0x%04x should have been %s\n",
 		context, expected->message, (expected->flags & posted) ? "posted" : "sent");
 	    ok ((expected->flags & parent) == (actual->flags & parent),
 		"%s: the msg 0x%04x was expected in %s\n",
 		context, expected->message, (expected->flags & parent) ? "parent" : "child");
+	    ok ((expected->flags & hook) == (actual->flags & hook),
+		"%s: the msg 0x%04x should have been sent by a hook\n",
+		context, expected->message);
 	    expected++;
 	    actual++;
 	}
-	else if (expected->message && ((expected + 1)->message == actual->message) )
-	{
-	  todo_wine {
-	    ok (FALSE, "%s: the msg 0x%04x was not received\n", context, expected->message);
+	else if (expected->flags & optional)
 	    expected++;
-	  }
-	}
-	else if (actual->message && (expected->message == (actual + 1)->message) )
-	{
-	  todo_wine {
-	    ok (FALSE, "%s: the msg 0x%04x was not expected\n", context, actual->message);
-	    actual++;
-	  }
-	}
 	else
 	{
 	  todo_wine {
@@ -372,31 +680,112 @@
 	}
     }
 
+    /* skip all optional trailing messages */
+    while (expected->message && (expected->flags & optional))
+	expected++;
+  // the next test was disabled because it fails in XP - Royce3
+  /*todo_wine {
+    if (expected->message || actual->message)
+	ok (FALSE, "%s: the msg sequence is not complete (got 0x%04x)\n", context, actual->message);
+  }*/
+
+    flush_sequence();
+}
+
+static void test_WM_SETREDRAW(HWND hwnd)
+{
+    DWORD style = GetWindowLongA(hwnd, GWL_STYLE);
+
+    flush_sequence();
+
+    SendMessageA(hwnd, WM_SETREDRAW, FALSE, 0);
+    ok_sequence(WmSetRedrawFalseSeq, "SetRedraw:FALSE");
+
+    ok(!(GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE), "WS_VISIBLE should NOT be set\n");
+    ok(!IsWindowVisible(hwnd), "IsWindowVisible() should return FALSE\n");
+
+    flush_sequence();
+    SendMessageA(hwnd, WM_SETREDRAW, TRUE, 0);
+    ok_sequence(WmSetRedrawTrueSeq, "SetRedraw:TRUE");
+
+    ok(GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
+    ok(IsWindowVisible(hwnd), "IsWindowVisible() should return TRUE\n");
+
+    /* restore original WS_VISIBLE state */
+    SetWindowLongA(hwnd, GWL_STYLE, style);
+
     flush_sequence();
 }
 
+static INT_PTR CALLBACK TestModalDlgProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    struct message msg;
+
+    trace("dialog: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
+
+    msg.message = message;
+    msg.flags = sent|wparam|lparam;
+    msg.wParam = wParam;
+    msg.lParam = lParam;
+    add_message(&msg);
+
+    if (message == WM_INITDIALOG) SetTimer( hwnd, 1, 100, NULL );
+    if (message == WM_TIMER) EndDialog( hwnd, 0 );
+    return 0;
+}
+
 /* test if we receive the right sequence of messages */
 static void test_messages(void)
 {
     HWND hwnd, hparent, hchild;
     HWND hchild2, hbutton;
+    HMENU hmenu;
 
     hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
                            100, 100, 200, 200, 0, 0, 0, NULL);
     ok (hwnd != 0, "Failed to create overlapped window\n");
     ok_sequence(WmCreateOverlappedSeq, "CreateWindow:overlapped");
+
+    /* test WM_SETREDRAW on a not visible top level window */
+    test_WM_SETREDRAW(hwnd);
+
+    SetWindowPos(hwnd, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);
+    ok_sequence(WmSWP_ShowOverlappedSeq, "SetWindowPos:SWP_SHOWWINDOW:overlapped");
+    ok(IsWindowVisible(hwnd), "window should be visible at this point\n");
+
+    ok(GetActiveWindow() == hwnd, "window should be active\n");
+    ok(GetFocus() == hwnd, "window should have input focus\n");
+    ShowWindow(hwnd, SW_HIDE);
+    ok_sequence(WmHideOverlappedSeq, "ShowWindow(SW_HIDE):overlapped");
     
-    ShowWindow(hwnd, TRUE);
-    ok_sequence(WmShowOverlappedSeq, "ShowWindow:overlapped");
+    ShowWindow(hwnd, SW_SHOW);
+    ok_sequence(WmShowOverlappedSeq, "ShowWindow(SW_SHOW):overlapped");
+
+    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");
+    ok(!IsWindowVisible(hwnd), "window should not be visible at this point\n");
+
+    /* test WM_SETREDRAW on a visible top level window */
+    ShowWindow(hwnd, SW_SHOW);
+    test_WM_SETREDRAW(hwnd);
 
     DestroyWindow(hwnd);
     ok_sequence(WmDestroyOverlappedSeq, "DestroyWindow:overlapped");
 
-    hparent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW,
+    hparent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                               100, 100, 200, 200, 0, 0, 0, NULL);
     ok (hparent != 0, "Failed to create parent window\n");
     flush_sequence();
 
+    hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD | WS_MAXIMIZE,
+                             0, 0, 10, 10, hparent, 0, 0, NULL);
+    ok (hchild != 0, "Failed to create child window\n");
+    ok_sequence(WmCreateMaximizedChildSeq, "CreateWindow:maximized child");
+    DestroyWindow(hchild);
+    flush_sequence();
+
     hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILDWINDOW,
                              0, 0, 10, 10, hparent, 0, 0, NULL);
     ok (hchild != 0, "Failed to create child window\n");
@@ -410,24 +799,247 @@
     hbutton = CreateWindowExA(0, "TestWindowClass", "Test button", WS_CHILDWINDOW,
                               0, 100, 50, 50, hchild, 0, 0, NULL);
     ok (hbutton != 0, "Failed to create button window\n");
-    flush_sequence();
 
-    ShowWindow(hchild, TRUE);
+    /* test WM_SETREDRAW on a not visible child window */
+    test_WM_SETREDRAW(hchild);
+
+    ShowWindow(hchild, SW_SHOW);
     ok_sequence(WmShowChildSeq, "ShowWindow:child");
 
+    /* test WM_SETREDRAW on a visible child window */
+    test_WM_SETREDRAW(hchild);
+
+    SetFocus(hchild);
+    flush_sequence();
+
     MoveWindow(hchild, 10, 10, 20, 20, TRUE);
     ok_sequence(WmResizingChildWithMoveWindowSeq, "MoveWindow:child");
 
     DestroyWindow(hchild);
     ok_sequence(WmDestroyChildSeq, "DestroyWindow:child");
+    DestroyWindow(hchild2);
+    DestroyWindow(hbutton);
+
+    flush_sequence();
+    hchild = CreateWindowExA(0, "TestWindowClass", "Test Child Popup", WS_CHILD | WS_POPUP,
+                             0, 0, 100, 100, hparent, 0, 0, NULL);
+    ok (hchild != 0, "Failed to create child popup window\n");
+    ok_sequence(WmCreateChildPopupSeq, "CreateWindow:child_popup");
+    DestroyWindow(hchild);
+
+    /* test what happens to a window which sets WS_VISIBLE in WM_CREATE */
+    flush_sequence();
+    hchild = CreateWindowExA(0, "TestPopupClass", "Test Popup", WS_POPUP,
+                             0, 0, 100, 100, hparent, 0, 0, NULL);
+    ok (hchild != 0, "Failed to create popup window\n");
+    ok_sequence(WmCreateInvisiblePopupSeq, "CreateWindow:invisible_popup");
+    ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
+    ok(IsWindowVisible(hchild), "IsWindowVisible() should return TRUE\n");
+    flush_sequence();
+    ShowWindow(hchild, SW_SHOW);
+    ok_sequence(WmShowVisiblePopupSeq, "CreateWindow:show_visible_popup");
+    flush_sequence();
+    SetWindowPos(hchild, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
+    ok_sequence(WmShowVisiblePopupSeq_2, "CreateWindow:show_visible_popup_2");
+    flush_sequence();
+    SetWindowPos(hchild, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);
+    ok_sequence(WmShowVisiblePopupSeq_3, "CreateWindow:show_visible_popup_3");
+    DestroyWindow(hchild);
+
+    /* this time add WS_VISIBLE for CreateWindowEx, but this fact actually
+     * changes nothing in message sequences.
+     */
+    flush_sequence();
+    hchild = CreateWindowExA(0, "TestPopupClass", "Test Popup", WS_POPUP | WS_VISIBLE,
+                             0, 0, 100, 100, hparent, 0, 0, NULL);
+    ok (hchild != 0, "Failed to create popup window\n");
+    ok_sequence(WmCreateInvisiblePopupSeq, "CreateWindow:invisible_popup");
+    ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
+    ok(IsWindowVisible(hchild), "IsWindowVisible() should return TRUE\n");
+    flush_sequence();
+    ShowWindow(hchild, SW_SHOW);
+    ok_sequence(WmShowVisiblePopupSeq, "CreateWindow:show_visible_popup");
+    flush_sequence();
+    SetWindowPos(hchild, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
+    ok_sequence(WmShowVisiblePopupSeq_2, "CreateWindow:show_visible_popup_2");
+    DestroyWindow(hchild);
+
+    flush_sequence();
+    hwnd = CreateWindowExA(WS_EX_DLGMODALFRAME, "TestDialogClass", NULL, WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_DLGFRAME,
+                           0, 0, 100, 100, hparent, 0, 0, NULL);
+    ok(hwnd != 0, "Failed to create custom dialog window\n");
+    ok_sequence(WmCreateCustomDialogSeq, "CreateCustomDialog");
+
+    flush_sequence();
+    after_end_dialog = 1;
+    EndDialog( hwnd, 0 );
+    ok_sequence(WmEndCustomDialogSeq, "EndCustomDialog");
+
+    DestroyWindow(hwnd);
+    after_end_dialog = 0;
+
+    flush_sequence();
+    DialogBoxA( 0, "TEST_DIALOG", hparent, TestModalDlgProcA );
+    ok_sequence(WmModalDialogSeq, "ModalDialog");
+
+    DestroyWindow(hparent);
+    flush_sequence();
+
+    /* Message sequence for SetMenu */
+    hmenu = CreateMenu();
+    ok (hmenu != 0, "Failed to create menu\n");
+    ok (InsertMenuA(hmenu, -1, MF_BYPOSITION, 0x1000, "foo"), "InsertMenu failed\n");
+    hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
+                           100, 100, 200, 200, 0, hmenu, 0, NULL);
+    ok_sequence(WmCreateOverlappedSeq, "CreateWindow:overlapped");
+    ok (SetMenu(hwnd, 0), "SetMenu\n");
+    ok_sequence(WmSetMenuNonVisibleSizeChangeSeq, "SetMenu:NonVisibleSizeChange");
+    ok (SetMenu(hwnd, 0), "SetMenu\n");
+    ok_sequence(WmSetMenuNonVisibleNoSizeChangeSeq, "SetMenu:NonVisibleNoSizeChange");
+    ShowWindow(hwnd, SW_SHOW);
+    flush_sequence();
+    ok (SetMenu(hwnd, 0), "SetMenu\n");
+    ok_sequence(WmSetMenuVisibleNoSizeChangeSeq, "SetMenu:VisibleNoSizeChange");
+    ok (SetMenu(hwnd, hmenu), "SetMenu\n");
+    ok_sequence(WmSetMenuVisibleSizeChangeSeq, "SetMenu:VisibleSizeChange");
+
+    ok(DrawMenuBar(hwnd), "DrawMenuBar\n");
+    ok_sequence(WmDrawMenuBarSeq, "DrawMenuBar");
+
+    DestroyWindow(hwnd);
 }
 
 static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
-    struct message msg = { message, sent|wparam|lparam, wParam, lParam };
+    static long defwndproc_counter = 0;
+    LRESULT ret;
+    struct message msg;
+
+    trace("%p, %04x, %08x, %08lx\n", 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);
+
+    if (message == WM_GETMINMAXINFO && (GetWindowLongA(hwnd, GWL_STYLE) & WS_CHILD))
+    {
+	HWND parent = GetParent(hwnd);
+	RECT rc;
+	MINMAXINFO *minmax = (MINMAXINFO *)lParam;
+
+	GetClientRect(parent, &rc);
+	trace("parent %p client size = (%ld x %ld)\n", parent, rc.right, rc.bottom);
+
+	trace("ptReserved = (%ld,%ld)\n"
+	      "ptMaxSize = (%ld,%ld)\n"
+	      "ptMaxPosition = (%ld,%ld)\n"
+	      "ptMinTrackSize = (%ld,%ld)\n"
+	      "ptMaxTrackSize = (%ld,%ld)\n",
+	      minmax->ptReserved.x, minmax->ptReserved.y,
+	      minmax->ptMaxSize.x, minmax->ptMaxSize.y,
+	      minmax->ptMaxPosition.x, minmax->ptMaxPosition.y,
+	      minmax->ptMinTrackSize.x, minmax->ptMinTrackSize.y,
+	      minmax->ptMaxTrackSize.x, minmax->ptMaxTrackSize.y);
+
+	ok(minmax->ptMaxSize.x == rc.right, "default width of maximized child %ld != %ld\n",
+	   minmax->ptMaxSize.x, rc.right);
+	ok(minmax->ptMaxSize.y == rc.bottom, "default height of maximized child %ld != %ld\n",
+	   minmax->ptMaxSize.y, rc.bottom);
+    }
+
+    defwndproc_counter++;
+    ret = DefWindowProcA(hwnd, message, wParam, lParam);
+    defwndproc_counter--;
 
-    add_message(msg);
-    return DefWindowProcA(hwnd, message, wParam, lParam);
+    return ret;
+}
+
+static LRESULT WINAPI PopupMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    static long defwndproc_counter = 0;
+    LRESULT ret;
+    struct message msg;
+
+    trace("popup: %p, %04x, %08x, %08lx\n", 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);
+
+    if (message == WM_CREATE)
+    {
+	DWORD style = GetWindowLongA(hwnd, GWL_STYLE) | WS_VISIBLE;
+	SetWindowLongA(hwnd, GWL_STYLE, style);
+    }
+
+    defwndproc_counter++;
+    ret = DefWindowProcA(hwnd, message, wParam, lParam);
+    defwndproc_counter--;
+
[truncated at 1000 lines; 144 more skipped]

reactos/apps/tests/user32
resource.c 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- resource.c	14 Feb 2004 20:13:04 -0000	1.1
+++ resource.c	28 May 2004 17:56:17 -0000	1.2
@@ -26,7 +26,7 @@
 test_LoadStringA (void)
 {
     HINSTANCE hInst = GetModuleHandle (NULL);
-    const char str[] = "String resource"; /* same in resource.rc */
+    static const char str[] = "String resource"; /* same in resource.rc */
     char buf[128];
     struct string_test {
         int bufsiz;

reactos/apps/tests/user32
sysparams.c 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- sysparams.c	14 Feb 2004 20:13:04 -0000	1.2
+++ sysparams.c	28 May 2004 17:56:17 -0000	1.3
@@ -78,6 +78,16 @@
 #define SPI_SETSHOWSOUNDS_VALNAME    "On"
 #define SPI_SETDRAGFULLWINDOWS_REGKEY           "Control Panel\\Desktop"
 #define SPI_SETDRAGFULLWINDOWS_VALNAME          "DragFullWindows"
+#define SPI_SETMOUSEHOVERWIDTH_REGKEY           "Control Panel\\Mouse"
+#define SPI_SETMOUSEHOVERWIDTH_VALNAME          "MouseHoverWidth"
+#define SPI_SETMOUSEHOVERHEIGHT_REGKEY          "Control Panel\\Mouse"
+#define SPI_SETMOUSEHOVERHEIGHT_VALNAME         "MouseHoverHeight"
+#define SPI_SETMOUSEHOVERTIME_REGKEY            "Control Panel\\Mouse"
+#define SPI_SETMOUSEHOVERTIME_VALNAME           "MouseHoverTime"
+#define SPI_SETMOUSESCROLLLINES_REGKEY          "Control Panel\\Desktop"
+#define SPI_SETMOUSESCROLLLINES_VALNAME         "WheelScrollLines"
+#define SPI_SETMENUSHOWDELAY_REGKEY             "Control Panel\\Desktop"
+#define SPI_SETMENUSHOWDELAY_VALNAME            "MenuShowDelay"
 #define SPI_SETDESKWALLPAPER_REGKEY		"Control Panel\\Desktop"
 #define SPI_SETDESKWALLPAPER_VALNAME		"Wallpaper"
 /* FIXME - don't have access to Windows with this action (W95, NT5.0). Set real values */
@@ -1028,6 +1038,200 @@
     /* TODO!!! - don't have version of Windows which has this */
 }
 
+static void test_SPI_SETMOUSEHOVERWIDTH( void )      /*     99 */
+{
+    BOOL rc;
+    UINT old_width;
+    const UINT vals[]={0,32767};
+    int i;
+
+    trace("testing SPI_{GET,SET}MOUSEHOVERWIDTH\n");
+    rc=SystemParametersInfoA( SPI_GETMOUSEHOVERWIDTH, 0, &old_width, 0 );
+    if (rc==0 && (GetLastError()==0 || GetLastError()==ERROR_INVALID_SPI_VALUE))
+    {
+        /* SPI_{GET,SET}MOUSEHOVERWIDTH does not seem to be supported on Win9x despite
+         * what MSDN states (Verified on Win98SE)
+         */
+        trace("SPI_{GET,SET}MOUSEHOVERWIDTH not supported on this platform\n");
+        return;
+    }
+    ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError());
+    
+    for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
+    {
+        UINT v;
+        char buf[10];
+
+        rc=SystemParametersInfoA( SPI_SETMOUSEHOVERWIDTH, vals[i], 0,
+                               SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
+        ok(rc!=0,"%d: rc=%d err=%ld\n",i,rc,GetLastError());
+        test_change_message( SPI_SETMOUSEHOVERWIDTH, 0 );
+        sprintf( buf, "%d", vals[i] );
+        test_reg_key( SPI_SETMOUSEHOVERWIDTH_REGKEY,
+                      SPI_SETMOUSEHOVERWIDTH_VALNAME, buf );
+
+        SystemParametersInfoA( SPI_GETMOUSEHOVERWIDTH, 0, &v, 0 );
+        ok(rc!=0,"%d: rc=%d err=%ld\n",i,rc,GetLastError());
+        eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERWIDTH", "%d" );
+    }
+
+    rc=SystemParametersInfoA( SPI_SETMOUSEHOVERWIDTH, old_width, 0,
+                              SPIF_UPDATEINIFILE );
+    ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError());
+}
+
+static void test_SPI_SETMOUSEHOVERHEIGHT( void )      /*     101 */
+{
+    BOOL rc;
+    UINT old_height;
+    const UINT vals[]={0,32767};
+    int i;
+
+    trace("testing SPI_{GET,SET}MOUSEHOVERHEIGHT\n");
+    rc=SystemParametersInfoA( SPI_GETMOUSEHOVERHEIGHT, 0, &old_height, 0 );
+    if (rc==0 && (GetLastError()==0 || GetLastError()==ERROR_INVALID_SPI_VALUE))
+    {
+        /* SPI_{GET,SET}MOUSEHOVERWIDTH does not seem to be supported on Win9x despite
+         * what MSDN states (Verified on Win98SE)
+         */
+        trace("SPI_{GET,SET}MOUSEHOVERHEIGHT not supported on this platform\n");
+        return;
+    }
+    ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError());
+    
+    for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
+    {
+        UINT v;
+        char buf[10];
+
+        rc=SystemParametersInfoA( SPI_SETMOUSEHOVERHEIGHT, vals[i], 0,
+                               SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
+        ok(rc!=0,"%d: rc=%d err=%ld\n",i,rc,GetLastError());
+        test_change_message( SPI_SETMOUSEHOVERHEIGHT, 0 );
+        sprintf( buf, "%d", vals[i] );
+        test_reg_key( SPI_SETMOUSEHOVERHEIGHT_REGKEY,
+                      SPI_SETMOUSEHOVERHEIGHT_VALNAME, buf );
+
+        SystemParametersInfoA( SPI_GETMOUSEHOVERHEIGHT, 0, &v, 0 );
+        ok(rc!=0,"%d: rc=%d err=%ld\n",i,rc,GetLastError());
+        eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERHEIGHT", "%d" );
+    }
+
+    rc=SystemParametersInfoA( SPI_SETMOUSEHOVERHEIGHT, old_height, 0,
+                              SPIF_UPDATEINIFILE );
+    ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError());
+}
+
+static void test_SPI_SETMOUSEHOVERTIME( void )      /*     103 */
+{
+    BOOL rc;
+    UINT old_time;
+    const UINT vals[]={0,32767};
+    int i;
+
+    trace("testing SPI_{GET,SET}MOUSEHOVERTIME\n");
+    rc=SystemParametersInfoA( SPI_GETMOUSEHOVERTIME, 0, &old_time, 0 );
+    if (rc==0 && (GetLastError()==0 || GetLastError()==ERROR_INVALID_SPI_VALUE))
+    {
+        /* SPI_{GET,SET}MOUSEHOVERWIDTH does not seem to be supported on Win9x despite
+         * what MSDN states (Verified on Win98SE)
+         */
+        trace("SPI_{GET,SET}MOUSEHOVERTIME not supported on this platform\n");
+        return;
+    }
+    ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError());
+    
+    for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
+    {
+        UINT v;
+        char buf[10];
+
+        rc=SystemParametersInfoA( SPI_SETMOUSEHOVERTIME, vals[i], 0,
+                               SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
+        ok(rc!=0,"%d: rc=%d err=%ld\n",i,rc,GetLastError());
+        test_change_message( SPI_SETMOUSEHOVERTIME, 0 );
+        sprintf( buf, "%d", vals[i] );
+        test_reg_key( SPI_SETMOUSEHOVERTIME_REGKEY,
+                      SPI_SETMOUSEHOVERTIME_VALNAME, buf );
+
+        SystemParametersInfoA( SPI_GETMOUSEHOVERTIME, 0, &v, 0 );
+        ok(rc!=0,"%d: rc=%d err=%ld\n",i,rc,GetLastError());
+        eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERTIME", "%d" );
+    }
+
+    rc=SystemParametersInfoA( SPI_SETMOUSEHOVERTIME, old_time, 0,
+                              SPIF_UPDATEINIFILE );
+    ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError());
+}
+
+static void test_SPI_SETWHEELSCROLLLINES( void )      /*     105 */
+{
+    BOOL rc;
+    UINT old_lines;
+    const UINT vals[]={0,32767};
+    int i;
+
+    trace("testing SPI_{GET,SET}WHEELSCROLLLINES\n");
+    rc=SystemParametersInfoA( SPI_GETWHEELSCROLLLINES, 0, &old_lines, 0 );
+    ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError());
+
+    for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
+    {
+        UINT v;
+        char buf[10];
+
+        rc=SystemParametersInfoA( SPI_SETWHEELSCROLLLINES, vals[i], 0,
+                               SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
+        ok(rc!=0,"%d: rc=%d err=%ld\n",i,rc,GetLastError());
+        test_change_message( SPI_SETWHEELSCROLLLINES, 0 );
+        sprintf( buf, "%d", vals[i] );
+        test_reg_key( SPI_SETMOUSESCROLLLINES_REGKEY,
+                      SPI_SETMOUSESCROLLLINES_VALNAME, buf );
+
+        SystemParametersInfoA( SPI_GETWHEELSCROLLLINES, 0, &v, 0 );
+        ok(rc!=0,"%d: rc=%d err=%ld\n",i,rc,GetLastError());
+        eq( v, vals[i], "SPI_{GET,SET}MOUSESCROLLLINES", "%d" );
+    }
+
+    rc=SystemParametersInfoA( SPI_SETWHEELSCROLLLINES, old_lines, 0,
+                              SPIF_UPDATEINIFILE );
+    ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError());
+}
+
+static void test_SPI_SETMENUSHOWDELAY( void )      /*     107 */
+{
+    BOOL rc;
+    UINT old_delay;
+    const UINT vals[]={0,32767};
+    int i;
+
+    trace("testing SPI_{GET,SET}MENUSHOWDELAY\n");
+    rc=SystemParametersInfoA( SPI_GETMENUSHOWDELAY, 0, &old_delay, 0 );
+    ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError());
+
+    for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
+    {
+        UINT v;
+        char buf[10];
+
+        rc=SystemParametersInfoA( SPI_SETMENUSHOWDELAY, vals[i], 0,
+                               SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
+        ok(rc!=0,"%d: rc=%d err=%ld\n",i,rc,GetLastError());
+        test_change_message( SPI_SETMENUSHOWDELAY, 0 );
+        sprintf( buf, "%d", vals[i] );
+        test_reg_key( SPI_SETMENUSHOWDELAY_REGKEY,
+                      SPI_SETMENUSHOWDELAY_VALNAME, buf );
+
+        SystemParametersInfoA( SPI_GETMENUSHOWDELAY, 0, &v, 0 );
+        ok(rc!=0,"%d: rc=%d err=%ld\n",i,rc,GetLastError());
+        eq( v, vals[i], "SPI_{GET,SET}MENUSHOWDELAY", "%d" );
+    }
+
+    rc=SystemParametersInfoA( SPI_SETMENUSHOWDELAY, old_delay, 0,
+                              SPIF_UPDATEINIFILE );
+    ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError());
+}
+
 static void test_SPI_SETWALLPAPER( void )              /*   115 */
 {
     BOOL rc;
@@ -1088,6 +1292,11 @@
     test_SPI_SETSHOWSOUNDS();                   /*     57 */
     test_SPI_SETKEYBOARDPREF();                 /*     69 */
     test_SPI_SETSCREENREADER();                 /*     71 */
+    test_SPI_SETMOUSEHOVERWIDTH();              /*     99 */
+    test_SPI_SETMOUSEHOVERHEIGHT();             /*    101 */
+    test_SPI_SETMOUSEHOVERTIME();               /*    103 */
+    test_SPI_SETWHEELSCROLLLINES();             /*    105 */
+    test_SPI_SETMENUSHOWDELAY();                /*    107 */
     test_SPI_SETWALLPAPER();                    /*    115 */
     SendMessageA( ghTestWnd, WM_DESTROY, 0, 0 );
     return 0;

reactos/apps/tests/user32
testlist.c 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- testlist.c	14 Feb 2004 20:13:04 -0000	1.2
+++ testlist.c	28 May 2004 17:56:17 -0000	1.3
@@ -7,7 +7,9 @@
 #include "winbase.h"
 
 extern void func_class(void);
+extern void func_dde(void);
 extern void func_dialog(void);
+//extern void func_input(void);
 extern void func_listbox(void);
 extern void func_msg(void);
 extern void func_resource(void);
@@ -24,7 +26,9 @@
 static const struct test winetest_testlist[] =
 {
     { "class", func_class },
+    { "dde", func_dde },
     { "dialog", func_dialog },
+    //{ "input", func_input },
     { "listbox", func_listbox },
     { "msg", func_msg },
     { "resource", func_resource },

reactos/apps/tests/user32
win.c 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- win.c	14 Feb 2004 20:13:04 -0000	1.2
+++ win.c	28 May 2004 17:56:17 -0000	1.3
@@ -43,7 +43,9 @@
 #define ULONG_PTR UINT_PTR
 
 static HWND (WINAPI *pGetAncestor)(HWND,UINT);
+static BOOL (WINAPI *pGetWindowInfo)(HWND,WINDOWINFO*);
 
+static HWND hwndMessage;
 static HWND hwndMain, hwndMain2;
 static HHOOK hhook;
 
@@ -443,6 +445,41 @@
 	    SetWindowLongA(hwnd, GWL_USERDATA, 0x20031021);
 	    break;
 	}
+	case WM_WINDOWPOSCHANGING:
+	{
+	    BOOL is_win9x = GetWindowLongW(hwnd, GWL_WNDPROC) == 0;
+	    WINDOWPOS *winpos = (WINDOWPOS *)lparam;
+	    trace("main: WM_WINDOWPOSCHANGING\n");
+	    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);
+	    if (!(winpos->flags & SWP_NOMOVE))
+	    {
+		ok(winpos->x >= -32768 && winpos->x <= 32767, "bad winpos->x %d\n", winpos->x);
+		ok(winpos->y >= -32768 && winpos->y <= 32767, "bad winpos->y %d\n", winpos->y);
+	    }
+	    /* Win9x does not fixup cx/xy for WM_WINDOWPOSCHANGING */
+	    if (!(winpos->flags & SWP_NOSIZE) && !is_win9x)
+	    {
+		ok(winpos->cx >= 0 && winpos->cx <= 32767, "bad winpos->cx %d\n", winpos->cx);
+		ok(winpos->cy >= 0 && winpos->cy <= 32767, "bad winpos->cy %d\n", winpos->cy);
+	    }
+	    break;
+	}
+	case WM_WINDOWPOSCHANGED:
+	{
+	    WINDOWPOS *winpos = (WINDOWPOS *)lparam;
+	    trace("main: WM_WINDOWPOSCHANGED\n");
+	    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);
+	    ok(winpos->x >= -32768 && winpos->x <= 32767, "bad winpos->x %d\n", winpos->x);
+	    ok(winpos->y >= -32768 && winpos->y <= 32767, "bad winpos->y %d\n", winpos->y);
+
+	    ok(winpos->cx >= 0 && winpos->cx <= 32767, "bad winpos->cx %d\n", winpos->cx);
+	    ok(winpos->cy >= 0 && winpos->cy <= 32767, "bad winpos->cy %d\n", winpos->cy);
+	    break;
+	}
 	case WM_NCCREATE:
 	{
 	    BOOL got_getminmaxinfo = GetWindowLongA(hwnd, GWL_USERDATA) == 0x20031021;
@@ -535,6 +572,43 @@
     return TRUE;
 }
 
+static void verify_window_info(HWND hwnd, const WINDOWINFO *info, BOOL test_borders)
+{
+    RECT rcWindow, rcClient;
+    INT border;
+    DWORD status;
+
+    ok(IsWindow(hwnd), "bad window handle\n");
+
+    GetWindowRect(hwnd, &rcWindow);
+    ok(EqualRect(&rcWindow, &info->rcWindow), "wrong rcWindow\n");
+
+    GetClientRect(hwnd, &rcClient);
+    /* translate to screen coordinates */
+    MapWindowPoints(hwnd, 0, (LPPOINT)&rcClient, 2);
+    ok(EqualRect(&rcClient, &info->rcClient), "wrong rcClient\n");
+
+    ok(info->dwStyle == GetWindowLongA(hwnd, GWL_STYLE), "wrong dwStyle\n");
+    ok(info->dwExStyle == GetWindowLongA(hwnd, GWL_EXSTYLE), "wrong dwExStyle\n");
+    status = (GetActiveWindow() == hwnd) ? WS_ACTIVECAPTION : 0;
+    ok(info->dwWindowStatus == status, "wrong dwWindowStatus\n");
+
+    if (test_borders && !IsRectEmpty(&rcWindow))
+    {
+	trace("rcWindow: %ld,%ld - %ld,%ld\n", rcWindow.left, rcWindow.top, rcWindow.right, rcWindow.bottom);
+	trace("rcClient: %ld,%ld - %ld,%ld\n", rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
+
+	ok(info->cxWindowBorders == rcClient.left - rcWindow.left,
+	    "wrong cxWindowBorders %d != %ld\n", info->cxWindowBorders, rcClient.left - rcWindow.left);
+	border = min(rcWindow.bottom - rcClient.bottom, rcClient.top - rcWindow.top);
+	ok(info->cyWindowBorders == border,
+	   "wrong cyWindowBorders %d != %d\n", info->cyWindowBorders, border);
+    }
+
+    ok(info->atomWindowType == GetClassLongA(hwnd, GCW_ATOM), "wrong atomWindowType\n");
+    ok(info->wCreatorVersion == 0x0400, "wrong wCreatorVersion %04x\n", info->wCreatorVersion);
+}
+
 static LRESULT CALLBACK cbt_hook_proc(int nCode, WPARAM wParam, LPARAM lParam) 
 { 
     static const char *CBT_code_name[10] = {
@@ -556,7 +630,11 @@
     {
 	case HCBT_CREATEWND:
 	{
-	    DWORD style;
+#if 0 /* Uncomment this once the test succeeds in all cases */
+	    static const RECT rc_null;
+	    RECT rc;
+#endif
+	    LONG style;
 	    CBT_CREATEWNDA *createwnd = (CBT_CREATEWNDA *)lParam;
 	    trace("HCBT_CREATEWND: hwnd %p, parent %p, style %08lx\n",
 		  (HWND)wParam, createwnd->lpcs->hwndParent, createwnd->lpcs->style);
@@ -567,8 +645,69 @@
 	    ok(style == GetWindowLongA((HWND)wParam, GWL_STYLE),
 		"style of hwnd and style in the CREATESTRUCT do not match: %08lx != %08lx\n",
 		GetWindowLongA((HWND)wParam, GWL_STYLE), style);
+
+#if 0 /* Uncomment this once the test succeeds in all cases */
+	    if ((style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
+	    {
+		ok(GetParent((HWND)wParam) == hwndMessage,
+		   "wrong result from GetParent %p: message window %p\n",
+		   GetParent((HWND)wParam), hwndMessage);
+	    }
+	    else
+		ok(!GetParent((HWND)wParam), "GetParent should return 0 at this point\n");
+
+	    ok(!GetWindow((HWND)wParam, GW_OWNER), "GW_OWNER should be set to 0 at this point\n");
+#endif
+#if 0	    /* while NT assigns GW_HWNDFIRST/LAST some values at this point,
+	     * Win9x still has them set to 0.
+	     */
+	    ok(GetWindow((HWND)wParam, GW_HWNDFIRST) != 0, "GW_HWNDFIRST should not be set to 0 at this point\n");
+	    ok(GetWindow((HWND)wParam, GW_HWNDLAST) != 0, "GW_HWNDLAST should not be set to 0 at this point\n");
+#endif
+	    ok(!GetWindow((HWND)wParam, GW_HWNDPREV), "GW_HWNDPREV should be set to 0 at this point\n");
+	    ok(!GetWindow((HWND)wParam, GW_HWNDNEXT), "GW_HWNDNEXT should be set to 0 at this point\n");
+
+#if 0 /* Uncomment this once the test succeeds in all cases */
+	    if (pGetAncestor)
+	    {
+		ok(pGetAncestor((HWND)wParam, GA_PARENT) == hwndMessage, "GA_PARENT should be set to hwndMessage at this point\n");
+		ok(pGetAncestor((HWND)wParam, GA_ROOT) == (HWND)wParam,
+		   "GA_ROOT is set to %p, expected %p\n", pGetAncestor((HWND)wParam, GA_ROOT), (HWND)wParam);
+
+		if ((style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
+		    ok(pGetAncestor((HWND)wParam, GA_ROOTOWNER) == hwndMessage,
+		       "GA_ROOTOWNER should be set to hwndMessage at this point\n");
+		else
+		    ok(pGetAncestor((HWND)wParam, GA_ROOTOWNER) == (HWND)wParam,
+		       "GA_ROOTOWNER is set to %p, expected %p\n", pGetAncestor((HWND)wParam, GA_ROOTOWNER), (HWND)wParam);
+            }
+
+	    ok(GetWindowRect((HWND)wParam, &rc), "GetWindowRect failed\n");
+	    ok(EqualRect(&rc, &rc_null), "window rect should be set to 0 HCBT_CREATEWND\n");
+	    ok(GetClientRect((HWND)wParam, &rc), "GetClientRect failed\n");
+	    ok(EqualRect(&rc, &rc_null), "client rect should be set to 0 on HCBT_CREATEWND\n");
+#endif
 	    break;
 	}
+
+	case HCBT_DESTROYWND:
+	case HCBT_SETFOCUS:
+	    if (wParam && pGetWindowInfo)
+	    {
+		WINDOWINFO info;
+
+		info.cbSize = 0;
+		ok(pGetWindowInfo((HWND)wParam, &info), "GetWindowInfo should not fail\n");
+		/* win2k SP4 returns broken border info if GetWindowInfo
+		 * is being called from HCBT_DESTROYWND hook proc.
+		 */
+		verify_window_info((HWND)wParam, &info, nCode != HCBT_DESTROYWND);
+
+		info.cbSize = sizeof(WINDOWINFO) + 1;
+		ok(pGetWindowInfo((HWND)wParam, &info), "GetWindowInfo should not fail\n");
+		verify_window_info((HWND)wParam, &info, nCode != HCBT_DESTROYWND);
+	    }
+	    break;
     }
 
     return CallNextHookEx(hhook, nCode, wParam, lParam);
@@ -878,6 +1017,62 @@
                                 (LPVOID)mdi_lParam_test_message);
     ok(mdi_child != 0, "MDI child creation failed\n");
     DestroyWindow(mdi_child);
+
+    /* maximized child */
+    mdi_child = CreateWindowExA(0, "MDI_child_Class_2", "MDI child",
+                                WS_CHILD | WS_MAXIMIZE,
+                                CW_USEDEFAULT, CW_USEDEFAULT,
+                                CW_USEDEFAULT, CW_USEDEFAULT,
+                                mdi_client, 0, GetModuleHandle(0),
+                                (LPVOID)mdi_lParam_test_message);
+    ok(mdi_child != 0, "MDI child creation failed\n");
+    DestroyWindow(mdi_child);
+
+    trace("Creating maximized child with a caption\n");
+    mdi_child = CreateWindowExA(0, "MDI_child_Class_2", "MDI child",
+                                WS_CHILD | WS_MAXIMIZE | WS_CAPTION,
+                                CW_USEDEFAULT, CW_USEDEFAULT,
+                                CW_USEDEFAULT, CW_USEDEFAULT,
+                                mdi_client, 0, GetModuleHandle(0),
+                                (LPVOID)mdi_lParam_test_message);
+    ok(mdi_child != 0, "MDI child creation failed\n");
+    DestroyWindow(mdi_child);
+
+    trace("Creating maximized child with a caption and a thick frame\n");
+    mdi_child = CreateWindowExA(0, "MDI_child_Class_2", "MDI child",
+                                WS_CHILD | WS_MAXIMIZE | WS_CAPTION | WS_THICKFRAME,
+                                CW_USEDEFAULT, CW_USEDEFAULT,
+                                CW_USEDEFAULT, CW_USEDEFAULT,
+                                mdi_client, 0, GetModuleHandle(0),
+                                (LPVOID)mdi_lParam_test_message);
+    ok(mdi_child != 0, "MDI child creation failed\n");
+    DestroyWindow(mdi_child);
+}
+
+/**********************************************************************
+ * MDI_ChildGetMinMaxInfo (copied from windows/mdi.c)
+ *
+ * Note: The rule here is that client rect of the maximized MDI child
+ *	 is equal to the client rect of the MDI client window.
+ */
+static void MDI_ChildGetMinMaxInfo( HWND client, HWND hwnd, MINMAXINFO* lpMinMax )
+{
+    RECT rect;
+
+    GetClientRect( client, &rect );
+    AdjustWindowRectEx( &rect, GetWindowLongA( hwnd, GWL_STYLE ),
+                        0, GetWindowLongA( hwnd, GWL_EXSTYLE ));
+
+    rect.right -= rect.left;
+    rect.bottom -= rect.top;
+    lpMinMax->ptMaxSize.x = rect.right;
+    lpMinMax->ptMaxSize.y = rect.bottom;
+
+    lpMinMax->ptMaxPosition.x = rect.left;
+    lpMinMax->ptMaxPosition.y = rect.top;
+
+    trace("max rect (%ld,%ld - %ld, %ld)\n",
+           rect.left, rect.top, rect.right, rect.bottom);
 }
 
 static LRESULT WINAPI mdi_child_wnd_proc_1(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
@@ -919,12 +1114,13 @@
 
             if (GetWindowLongA(cs->hwndParent, GWL_STYLE) & MDIS_ALLCHILDSTYLES)
             {
-                ok(cs->style == (mdi_cs->style | WS_CHILD | WS_CLIPSIBLINGS),
+                LONG style = mdi_cs->style | WS_CHILD | WS_CLIPSIBLINGS;
+                ok(cs->style == style,
                    "cs->style does not match (%08lx)\n", cs->style);
             }
             else
             {
-                DWORD style = mdi_cs->style;
+                LONG style = mdi_cs->style;
                 style &= ~WS_POPUP;
                 style |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION |
                     WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
@@ -933,6 +1129,69 @@
             }
             break;
         }
+
+        case WM_GETMINMAXINFO:
+        {
+            HWND client = GetParent(hwnd);
+            RECT rc;
+            MINMAXINFO *minmax = (MINMAXINFO *)lparam;
+            MINMAXINFO my_minmax;
+            LONG style, exstyle;
+
+            style = GetWindowLongA(hwnd, GWL_STYLE);
+            exstyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
+
+            GetWindowRect(client, &rc);
+            trace("MDI client %p window size = (%ld x %ld)\n", client, rc.right-rc.left, rc.bottom-rc.top);
+            GetClientRect(client, &rc);
+            trace("MDI client %p client size = (%ld x %ld)\n", client, rc.right, rc.bottom);
+            trace("screen size: %d x %d\n", GetSystemMetrics(SM_CXSCREEN),
+                                            GetSystemMetrics(SM_CYSCREEN));
+
+            GetClientRect(client, &rc);
+            if ((style & WS_CAPTION) == WS_CAPTION)
+                style &= ~WS_BORDER; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER */
+            AdjustWindowRectEx(&rc, style, 0, exstyle);
+            trace("MDI child: calculated max window size = (%ld x %ld)\n", rc.right-rc.left, rc.bottom-rc.top);
+
+            trace("ptReserved = (%ld,%ld)\n"
+                  "ptMaxSize = (%ld,%ld)\n"
+                  "ptMaxPosition = (%ld,%ld)\n"
+                  "ptMinTrackSize = (%ld,%ld)\n"
+                  "ptMaxTrackSize = (%ld,%ld)\n",
+                  minmax->ptReserved.x, minmax->ptReserved.y,
+                  minmax->ptMaxSize.x, minmax->ptMaxSize.y,
+                  minmax->ptMaxPosition.x, minmax->ptMaxPosition.y,
+                  minmax->ptMinTrackSize.x, minmax->ptMinTrackSize.y,
+                  minmax->ptMaxTrackSize.x, minmax->ptMaxTrackSize.y);
+
+            ok(minmax->ptMaxSize.x == rc.right - rc.left, "default width of maximized child %ld != %ld\n",
+               minmax->ptMaxSize.x, rc.right - rc.left);
+            ok(minmax->ptMaxSize.y == rc.bottom - rc.top, "default height of maximized child %ld != %ld\n",
+               minmax->ptMaxSize.y, rc.bottom - rc.top);
+
+            DefMDIChildProcA(hwnd, msg, wparam, lparam);
+
+            trace("DefMDIChildProc returned:\n"
+                  "ptReserved = (%ld,%ld)\n"
+                  "ptMaxSize = (%ld,%ld)\n"
+                  "ptMaxPosition = (%ld,%ld)\n"
+                  "ptMinTrackSize = (%ld,%ld)\n"
+                  "ptMaxTrackSize = (%ld,%ld)\n",
+                  minmax->ptReserved.x, minmax->ptReserved.y,
+                  minmax->ptMaxSize.x, minmax->ptMaxSize.y,
+                  minmax->ptMaxPosition.x, minmax->ptMaxPosition.y,
+                  minmax->ptMinTrackSize.x, minmax->ptMinTrackSize.y,
+                  minmax->ptMaxTrackSize.x, minmax->ptMaxTrackSize.y);
+
+            MDI_ChildGetMinMaxInfo(client, hwnd, &my_minmax);
+            ok(minmax->ptMaxSize.x == my_minmax.ptMaxSize.x, "default width of maximized child %ld != %ld\n",
+               minmax->ptMaxSize.x, my_minmax.ptMaxSize.x);
+            ok(minmax->ptMaxSize.y == my_minmax.ptMaxSize.y, "default height of maximized child %ld != %ld\n",
+               minmax->ptMaxSize.y, my_minmax.ptMaxSize.y);
+
+            return 1;
+        }
     }
     return DefMDIChildProcA(hwnd, msg, wparam, lparam);
 }
@@ -946,6 +1205,9 @@
         {
             CREATESTRUCTA *cs = (CREATESTRUCTA *)lparam;
 
+            trace("%s\n", (msg == WM_NCCREATE) ? "WM_NCCREATE" : "WM_CREATE");
+            trace("x %d, y %d, cx %d, cy %d\n", cs->x, cs->y, cs->cx, cs->cy);
+
             ok(!(cs->dwExStyle & WS_EX_MDICHILD), "WS_EX_MDICHILD should not be set\n");
             ok(cs->lpCreateParams == mdi_lParam_test_message, "wrong cs->lpCreateParams\n");
 
@@ -963,6 +1225,68 @@
             ok(cs->cy == 0, "%d != 0\n", cs->cy);
             break;
         }
+
+        case WM_GETMINMAXINFO:
+        {
+            HWND parent = GetParent(hwnd);
+            RECT rc;
+            MINMAXINFO *minmax = (MINMAXINFO *)lparam;
+            LONG style, exstyle;
+
+            trace("WM_GETMINMAXINFO\n");
+
+            style = GetWindowLongA(hwnd, GWL_STYLE);
+            exstyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
+
+            GetClientRect(parent, &rc);
+            trace("parent %p client size = (%ld x %ld)\n", parent, rc.right, rc.bottom);
+
+            GetClientRect(parent, &rc);
+            if ((style & WS_CAPTION) == WS_CAPTION)
+                style &= ~WS_BORDER; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER */
+            AdjustWindowRectEx(&rc, style, 0, exstyle);
+            trace("calculated max child window size = (%ld x %ld)\n", rc.right-rc.left, rc.bottom-rc.top);
+
+            trace("ptReserved = (%ld,%ld)\n"
+                  "ptMaxSize = (%ld,%ld)\n"
+                  "ptMaxPosition = (%ld,%ld)\n"
+                  "ptMinTrackSize = (%ld,%ld)\n"
+                  "ptMaxTrackSize = (%ld,%ld)\n",
+                  minmax->ptReserved.x, minmax->ptReserved.y,
+                  minmax->ptMaxSize.x, minmax->ptMaxSize.y,
+                  minmax->ptMaxPosition.x, minmax->ptMaxPosition.y,
+                  minmax->ptMinTrackSize.x, minmax->ptMinTrackSize.y,
+                  minmax->ptMaxTrackSize.x, minmax->ptMaxTrackSize.y);
+
+            ok(minmax->ptMaxSize.x == rc.right - rc.left, "default width of maximized child %ld != %ld\n",
+               minmax->ptMaxSize.x, rc.right - rc.left);
+            ok(minmax->ptMaxSize.y == rc.bottom - rc.top, "default height of maximized child %ld != %ld\n",
+               minmax->ptMaxSize.y, rc.bottom - rc.top);
+            break;
+        }
+
+        case WM_WINDOWPOSCHANGING:
+        case WM_WINDOWPOSCHANGED:
+        {
+            WINDOWPOS *winpos = (WINDOWPOS *)lparam;
+            WINDOWPOS my_winpos = *winpos;
+
+            trace("%s\n", (msg == 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);
+
+            DefWindowProcA(hwnd, msg, wparam, lparam);
+
+            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);
+
+            ok(!memcmp(&my_winpos, winpos, sizeof(WINDOWPOS)),
+               "DefWindowProc should not change WINDOWPOS values\n");
+
+            return 1;
+        }
     }
     return DefWindowProcA(hwnd, msg, wparam, lparam);
 }
@@ -1131,9 +1455,214 @@
     ok( res == icon2, "wrong big icon after set %p/%p\n", res, icon2 );
 }
 
+static void test_SetWindowPos(HWND hwnd)
+{
+    SetWindowPos(hwnd, 0, -32769, -40000, -32769, -90000, SWP_NOMOVE);
+    SetWindowPos(hwnd, 0, 32768, 40000, 32768, 40000, SWP_NOMOVE);
+
+    SetWindowPos(hwnd, 0, -32769, -40000, -32769, -90000, SWP_NOSIZE);
+    SetWindowPos(hwnd, 0, 32768, 40000, 32768, 40000, SWP_NOSIZE);
+}
+
+static void test_SetMenu(HWND parent)
+{
+    HWND child;
+    HMENU hMenu, ret;
+
+    hMenu = CreateMenu();
+    assert(hMenu);
+
+    /* parent */
+    ret = GetMenu(parent);
+    ok(ret == 0, "unexpected menu id %p\n", ret);
+
+    ok(!SetMenu(parent, (HMENU)20), "SetMenu with invalid menu handle should fail\n");
+    ret = GetMenu(parent);
+    ok(ret == 0, "unexpected menu id %p\n", ret);
+
+    ok(SetMenu(parent, hMenu), "SetMenu on a top level window should not fail\n");
+    ret = GetMenu(parent);
+    ok(ret == (HMENU)hMenu, "unexpected menu id %p\n", ret);
+
+    ok(SetMenu(parent, 0), "SetMenu(0) on a top level window should not fail\n");
+    ret = GetMenu(parent);
+    ok(ret == 0, "unexpected menu id %p\n", ret);
+ 
+    /* child */
+    child = CreateWindowExA(0, "static", NULL, WS_CHILD, 0, 0, 0, 0, parent, (HMENU)10, 0, NULL);
+    assert(child);
+
+    ret = GetMenu(child);
+    ok(ret == (HMENU)10, "unexpected menu id %p\n", ret);
+
+    ok(!SetMenu(child, (HMENU)20), "SetMenu with invalid menu handle should fail\n");
+    ret = GetMenu(child);
+    ok(ret == (HMENU)10, "unexpected menu id %p\n", ret);
+
+    ok(!SetMenu(child, hMenu), "SetMenu on a child window should fail\n");
+    ret = GetMenu(child);
+    ok(ret == (HMENU)10, "unexpected menu id %p\n", ret);
+
+    ok(!SetMenu(child, 0), "SetMenu(0) on a child window should fail\n");
+    ret = GetMenu(child);
+    ok(ret == (HMENU)10, "unexpected menu id %p\n", ret);
+
+    DestroyWindow(child);
+    DestroyMenu(hMenu);
+}
+
+static void test_window_tree(HWND parent, const DWORD *style, const int *order, int total)
+{
+    HWND child[5], hwnd;
+    int i;
+
+    assert(total <= 5);
+
+    hwnd = GetWindow(parent, GW_CHILD);
+    ok(!hwnd, "have to start without children to perform the test\n");
+
+    for (i = 0; i < total; i++)
+    {
+        child[i] = CreateWindowExA(0, "static", "", style[i], 0,0,10,10,
+                                   parent, 0, 0, NULL);
+        trace("child[%d] = %p\n", i, child[i]);
+        ok(child[i] != 0, "CreateWindowEx failed to create child window\n");
+    }
+
+    hwnd = GetWindow(parent, GW_CHILD);
+    ok(hwnd != 0, "GetWindow(GW_CHILD) failed\n");
+    ok(hwnd == GetWindow(child[total - 1], GW_HWNDFIRST), "GW_HWNDFIRST is wrong\n");
+    ok(child[order[total - 1]] == GetWindow(child[0], GW_HWNDLAST), "GW_HWNDLAST is wrong\n");
+
+    for (i = 0; i < total; i++)
+    {
+        trace("hwnd[%d] = %p\n", i, hwnd);
+        ok(child[order[i]] == hwnd, "Z order of child #%d is wrong\n", i);
+
+        hwnd = GetWindow(hwnd, GW_HWNDNEXT);
+    }
+
+    for (i = 0; i < total; i++)
+        ok(DestroyWindow(child[i]), "DestroyWindow failed\n");
+}
+
+static void test_children_zorder(HWND parent)
+{
+    const DWORD simple_style[5] = { WS_CHILD, WS_CHILD, WS_CHILD, WS_CHILD,
+                                    WS_CHILD };
+    const int simple_order[5] = { 0, 1, 2, 3, 4 };
+
+    const DWORD complex_style[5] = { WS_CHILD, WS_CHILD | WS_MAXIMIZE,
+                             WS_CHILD | WS_VISIBLE, WS_CHILD,
+                             WS_CHILD | WS_MAXIMIZE | WS_VISIBLE };
+    const int complex_order_1[1] = { 0 };
+    const int complex_order_2[2] = { 1, 0 };
+    const int complex_order_3[3] = { 1, 0, 2 };
+    const int complex_order_4[4] = { 1, 0, 2, 3 };
+    const int complex_order_5[5] = { 4, 1, 0, 2, 3 };
+
+    /* simple WS_CHILD */
+    test_window_tree(parent, simple_style, simple_order, 5);
+
+    /* complex children styles */
+    test_window_tree(parent, complex_style, complex_order_1, 1);
+    test_window_tree(parent, complex_style, complex_order_2, 2);
+    test_window_tree(parent, complex_style, complex_order_3, 3);
+    test_window_tree(parent, complex_style, complex_order_4, 4);
+    test_window_tree(parent, complex_style, complex_order_5, 5);
+}
+
+static void test_SetFocus(HWND hwnd)
+{
+    HWND child;
+
+    /* check if we can set focus to non-visible windows */
+
+    ShowWindow(hwnd, SW_SHOW);
+    SetFocus(0);
+    SetFocus(hwnd);
+    ok( GetFocus() == hwnd, "Failed to set focus to visible window %p\n", hwnd );
+    ok( GetWindowLong(hwnd,GWL_STYLE) & WS_VISIBLE, "Window %p not visible\n", hwnd );
+    ShowWindow(hwnd, SW_HIDE);
+    SetFocus(0);
+    SetFocus(hwnd);
+    ok( GetFocus() == hwnd, "Failed to set focus to invisible window %p\n", hwnd );
+    ok( !(GetWindowLong(hwnd,GWL_STYLE) & WS_VISIBLE), "Window %p still visible\n", hwnd );
+    child = CreateWindowExA(0, "static", NULL, WS_CHILD, 0, 0, 0, 0, hwnd, 0, 0, NULL);
+    assert(child);
+    SetFocus(child);
+    ok( GetFocus() == child, "Failed to set focus to invisible child %p\n", child );
+    ok( !(GetWindowLong(child,GWL_STYLE) & WS_VISIBLE), "Child %p is visible\n", child );
+    ShowWindow(child, SW_SHOW);
+    ok( GetWindowLong(child,GWL_STYLE) & WS_VISIBLE, "Child %p is not visible\n", child );
+    ok( GetFocus() == child, "Focus no longer on child %p\n", child );
+    ShowWindow(child, SW_HIDE);
+    ok( !(GetWindowLong(child,GWL_STYLE) & WS_VISIBLE), "Child %p is visible\n", child );
+    ok( GetFocus() == hwnd, "Focus should be on parent %p, not %p\n", hwnd, GetFocus() );
+    ShowWindow(child, SW_SHOW);
+    SetFocus(child);
+    ok( GetFocus() == child, "Focus should be on child %p\n", child );
+    SetWindowPos(child,0,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_HIDEWINDOW);
+    ok( GetFocus() == child, "Focus should still be on child %p\n", child );
+
+    ShowWindow(child, SW_HIDE);
+    SetFocus(hwnd);
+    ok( GetFocus() == hwnd, "Focus should be on parent %p, not %p\n", hwnd, GetFocus() );
+    SetWindowPos(child,0,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW);
+    ok( GetFocus() == hwnd, "Focus should still be on parent %p, not %p\n", hwnd, GetFocus() );
+    ShowWindow(child, SW_HIDE);
+    ok( GetFocus() == hwnd, "Focus should still be on parent %p, not %p\n", hwnd, GetFocus() );
+
+    DestroyWindow( child );
+}
+
+static void test_SetActiveWindow(HWND hwnd)
+{
+    HWND hwnd2;
+
+    ShowWindow(hwnd, SW_SHOW);
+    SetActiveWindow(0);
+    SetActiveWindow(hwnd);
+    ok( GetActiveWindow() == hwnd, "Failed to set focus to visible window %p\n", hwnd );
+    SetWindowPos(hwnd,0,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_HIDEWINDOW);
+    ok( GetActiveWindow() == hwnd, "Window %p no longer active\n", hwnd );
+    SetWindowPos(hwnd,0,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_SHOWWINDOW);
+    ShowWindow(hwnd, SW_HIDE);
+    ok( GetActiveWindow() != hwnd, "Window %p is still active\n", hwnd );
+    ShowWindow(hwnd, SW_SHOW);
+
+    hwnd2 = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0, hwnd, 0, 0, NULL);
+    ok( GetActiveWindow() == hwnd2, "Window %p is not active\n", hwnd2 );
+    DestroyWindow(hwnd2);
+    ok( GetActiveWindow() != hwnd2, "Window %p is still active\n", hwnd2 );
+
+    hwnd2 = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0, hwnd, 0, 0, NULL);
+    ok( GetActiveWindow() == hwnd2, "Window %p is not active\n", hwnd2 );
+    SetWindowPos(hwnd2,0,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_HIDEWINDOW);
+    ok( GetActiveWindow() == hwnd2, "Window %p no longer active (%p)\n", hwnd2, GetActiveWindow() );
+    DestroyWindow(hwnd2);
+    ok( GetActiveWindow() != hwnd2, "Window %p is still active\n", hwnd2 );
+}
+
 START_TEST(win)
 {
     pGetAncestor = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" );
+    pGetWindowInfo = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetWindowInfo" );
+
+    hwndMain = CreateWindowExA(0, "static", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, NULL);
+    if (hwndMain)
+    {
+        ok(!GetParent(hwndMain), "GetParent should return 0 for message only windows\n");
+        if (pGetAncestor)
+        {
+            hwndMessage = pGetAncestor(hwndMain, GA_PARENT);
+            ok(hwndMessage != 0, "GetAncestor(GA_PARENT) should not return 0 for message only windows\n");
+            trace("hwndMessage %p\n", hwndMessage);
+        }
+        DestroyWindow(hwndMain);
+    }
+    else
+        trace("CreateWindowExA with parent HWND_MESSAGE failed\n");
 
     if (!RegisterWindowClasses()) assert(0);
 
@@ -1158,6 +1687,12 @@
 
     test_mdi();
     test_icons();
+    test_SetWindowPos(hwndMain);
+    test_SetMenu(hwndMain);
+    test_SetFocus(hwndMain);
+    test_SetActiveWindow(hwndMain);
+
+    test_children_zorder(hwndMain);
 
     UnhookWindowsHookEx(hhook);
 }
CVSspam 0.2.8