Release 970914

Thu Sep 11 18:24:56 1997  Philippe De Muyter  <phdm@info.ucl.ac.be>

	* [objects/dc.c]
	In DC_SetupGCForPatBlt, replace R2_NOT by GXxor with (black xor white).

Tue Sep  9 23:04:02 1997  U. Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>

	* [memory/virtual.c] 
	Do not write debugging info unconditionally to stderr.

	* [files/profile.c]
	Call PROFILE_GetSection in PROFILE_GetString for key_name "" too.

	* [misc/crtdll.c]
	Many new functions.

	* [include/windows.h] [windows/winpos.c]
	ClientToScreen16 doesn't have a return value.

Sun Sep  7 10:06:39 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [misc/main.c] [AUTHORS]
	Update the list of contributors. Please let me know if I forgot
	someone.

	* [if1632/*.spec] [if1632/builtin.c] [tools/build.c]
	Ordinal base for Win32 DLLs is now computed automatically from the
	lowest ordinal found.

	* [include/wintypes.h]
	WINAPI is now defined as attribute((stdcall)). This will require
	gcc to compile.

	* [if1632/thunk.c]
	Removed Win32 thunks (no longer needed with stdcall).

	* [if1632/crtdll.spec] [misc/crtdll.c]
	Make sure we only reference cdecl functions in the spec file.

	* [objects/dc.c]
	Use CapNotLast drawing style for 1-pixel wide lines.

	* [tools/build.c]
	Added 'double' argument type.
	Added 'varargs' function type for Win32.
	Made CallTo16_xxx functions stdcall.

Fri Sep  5 14:50:49 1997  Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [tools/build.c] [windows/win.c] [windows/event.c] [windows/message.c]
	More fixes to get message exchange closer to the original.

	* [misc/spy.c]
	Message logs now contain window names.

	* [loader/resource.c] [loader/ne_resource.c] [loader/task.c]
	  [objects/cursoricon.c] [windows/user.c]
	Added some obscure features to fix memory leaks.

Fri Sep  5 00:46:28 1997  Jan Willamowius <jan@janhh.shnet.org>

	* [if1632/kernel32.spec] [win32/newfns.c]
	Added stub for UTRegister() and UTUnRegister().

Thu Sep  4 12:03:12 1997  Frans van Dorsselaer <dorssel@rulhmpc49.LeidenUniv.nl>
	* [controls/edit.c]
	Allow ASCII codes > 127 in WM_CHAR.

Mon Sep  1 17:23:24 1997  Dimitrie O. Paun  <dimi@mail.cs.toronto.edu>

	* [controls/widgets.c]
	In InitCommonControls, remember the name of the class
	because lpszClassName was made to point to a local array
	Added the ProgressBar to the list of implemented controls.
	Call InitCommonControls from WIDGETS_Init to register all
	implemented Common Controls.
	
	* [include/commctrl.h]
	Added misc decl for the Progress Bar.

	* [controls/progress.c] [include/progress.h]
	First attempt at implementiong the Progress Bar class.

	* [objects/brush.h]
	Implementation for GetSysColorBrush[16|32]

	* [controls/status.c]
	Use DrawEdge to draw the borders and fill the background

	* [controls/uitools.c]
	Added DrawDiagEdge32 and DrawRectEdge32

	* [graphics/painting.c]
	Implement DrawEdge[16|32]
	Started DrawFrameControl32

Mon Sep  1 10:07:09 1997  Lawson Whitney <lawson_whitney@juno.com>

	* [misc/comm.c] [include/windows.h]
	SetCommEventMask returns a SEGPTR.

Sun Aug 31 23:28:32 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [loader/pe_image.c][loader/module.c][include/pe_image.h]
	  [include/module.h]
	Cleaned up the whole Win32 library mess (a bit).

	* [debugger/stabs.c]
	If 'wine' has no absolute path and isn't found, check $PATH too.

	* [misc/ole2nls.c]
	Some fixes.

	* [misc/ver.c]
	Added support for PE style version resources.

	* [memory/string.c]
	Check for NULL pointers to _lstr* functions, just as Windows95 does.

	* [multimedia/time.c]
	Made list of timers a simple linked list.

	* [loader/resource.c]
	Netscape 3 seems to pass NEGATIVE resource Ids (in an
	unsigned int, yes). Don't know why, fixed it anyway.

	* [objects/bitmap.c]
	LoadImageW added.

	* [include/win.h][windows/win.c]
	Change wIDmenu from UINT16 to UINT32 and changed the
	SetWindow(Long|Word) accordingly.

Thu Aug 28 19:30:08 1997  Morten Welinder  <terra@diku.dk>

	* [include/windows.h]
	Add a few more colors defined for Win95.
	Add a few more brush styles.

	* [windows/syscolor.c]
 	Add error checks for SYSCOLOR_SetColor, SYSCOLOR_Init,
	GetSysColor16, GetSysColor32.  Add support for above colors.

Sun Aug 24 16:22:57 1997  Andrew Taylor <andrew@riscan.com>

	* [multimedia/mmsystem.c]
	Changed mmioDescend to use mmio functions for file I/O, neccessary
	for memory files.
diff --git a/windows/class.c b/windows/class.c
index e6422e9..ca349f0 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -210,14 +210,13 @@
  *           CLASS_FindClassByAtom
  *
  * Return a pointer to the class.
+ * hinstance has been normalized by the caller.
  */
-CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE16 hinstance )
+CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE32 hinstance )
 {
     CLASS * class;
 
-    if (hinstance != 0xffff) hinstance = GetExePtr(hinstance);
-
-      /* First search task-specific classes */
+    /* First search task-specific classes */
 
     for (class = firstClass; (class); class = class->next)
     {
@@ -308,8 +307,7 @@
 {
     ATOM atom;
     CLASS *classPtr;
-
-    HINSTANCE32 hInstance = (HINSTANCE32)GetExePtr( wc->hInstance );
+    HINSTANCE16 hInstance=GetExePtr(wc->hInstance);
 
     if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
@@ -347,11 +345,8 @@
     ATOM atom;
     CLASS *classPtr;
 
-    /* FIXME: this should not be necessary for Win32 */
-    HINSTANCE32 hInstance = (HINSTANCE32)GetExePtr( wc->hInstance );
-
     if (!(atom = GlobalAddAtom32A( wc->lpszClassName ))) return 0;
-    if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
+    if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
                                           wc->cbClsExtra, wc->cbWndExtra,
                                           (WNDPROC16)wc->lpfnWndProc,
                                           WIN_PROC_32A )))
@@ -362,7 +357,7 @@
 
     dprintf_class( stddeb, "RegisterClass32A: atom=%04x wndproc=%08lx
 hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
-                   atom, (DWORD)wc->lpfnWndProc, hInstance,
+                   atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
                    wc->hbrBackground, wc->style, wc->cbClsExtra,
                    wc->cbWndExtra, classPtr,
                    HIWORD(wc->lpszClassName) ? wc->lpszClassName : "" );
@@ -384,11 +379,8 @@
     ATOM atom;
     CLASS *classPtr;
 
-    /* FIXME: this should not be necessary for Win32 */
-    HINSTANCE32 hInstance = (HINSTANCE32)GetExePtr( wc->hInstance );
-
     if (!(atom = GlobalAddAtom32W( wc->lpszClassName ))) return 0;
-    if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
+    if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
                                           wc->cbClsExtra, wc->cbWndExtra,
                                           (WNDPROC16)wc->lpfnWndProc,
                                           WIN_PROC_32W )))
@@ -398,7 +390,7 @@
     }
 
     dprintf_class( stddeb, "RegisterClass32W: atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
-                   atom, (DWORD)wc->lpfnWndProc, hInstance,
+                   atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
                    wc->hbrBackground, wc->style, wc->cbClsExtra,
                    wc->cbWndExtra, classPtr );
     
@@ -418,8 +410,7 @@
 {
     ATOM atom;
     CLASS *classPtr;
-
-    HINSTANCE32 hInstance = (HINSTANCE32)GetExePtr( wc->hInstance );
+    HINSTANCE16 hInstance = GetExePtr( wc->hInstance );
 
     if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
@@ -454,11 +445,8 @@
     ATOM atom;
     CLASS *classPtr;
 
-    /* FIXME: this should not be necessary for Win32 */
-    HINSTANCE32 hInstance = (HINSTANCE32)GetExePtr( wc->hInstance );
-
     if (!(atom = GlobalAddAtom32A( wc->lpszClassName ))) return 0;
-    if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
+    if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
                                           wc->cbClsExtra, wc->cbWndExtra,
                                           (WNDPROC16)wc->lpfnWndProc,
                                           WIN_PROC_32A )))
@@ -468,7 +456,7 @@
     }
 
     dprintf_class( stddeb, "RegisterClassEx32A: atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
-                   atom, (DWORD)wc->lpfnWndProc, hInstance,
+                   atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
                    wc->hbrBackground, wc->style, wc->cbClsExtra,
                    wc->cbWndExtra, classPtr );
     
@@ -489,11 +477,8 @@
     ATOM atom;
     CLASS *classPtr;
 
-    /* FIXME: this should not be necessary for Win32 */
-    HINSTANCE32 hInstance = (HINSTANCE32)GetExePtr( wc->hInstance );
-
     if (!(atom = GlobalAddAtom32W( wc->lpszClassName ))) return 0;
-    if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
+    if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
                                           wc->cbClsExtra, wc->cbWndExtra,
                                           (WNDPROC16)wc->lpfnWndProc,
                                           WIN_PROC_32W )))
@@ -503,7 +488,7 @@
     }
 
     dprintf_class( stddeb, "RegisterClassEx32W: atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
-                   atom, (DWORD)wc->lpfnWndProc, hInstance,
+                   atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
                    wc->hbrBackground, wc->style, wc->cbClsExtra,
                    wc->cbWndExtra, classPtr );
     
@@ -540,7 +525,6 @@
     CLASS *classPtr;
     ATOM atom;
 
-    hInstance = GetExePtr( hInstance );  /* FIXME: not needed in Win32 */
     if (!(atom = GlobalFindAtom32A( className ))) return FALSE;
     if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
         (classPtr->hInstance != hInstance)) return FALSE;
@@ -556,7 +540,6 @@
     CLASS *classPtr;
     ATOM atom;
 
-    hInstance = GetExePtr( hInstance );  /* FIXME: not needed in Win32 */
     if (!(atom = GlobalFindAtom32W( className ))) return FALSE;
     if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
         (classPtr->hInstance != hInstance)) return FALSE;
@@ -910,7 +893,6 @@
     ATOM atom;
     CLASS *classPtr;
 
-    hInstance = GetExePtr( hInstance );  /* FIXME: not needed in Win32 */
     if (!(atom = GlobalFindAtom32A( name )) ||
         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
 	(classPtr->hInstance && (hInstance != classPtr->hInstance)))
@@ -940,7 +922,6 @@
     ATOM atom;
     CLASS *classPtr;
 
-    hInstance = GetExePtr( hInstance );  /* FIXME: not needed in Win32 */
     if (!(atom = GlobalFindAtom32W( name )) ||
         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
 	(classPtr->hInstance && (hInstance != classPtr->hInstance)))
@@ -1003,7 +984,6 @@
     ATOM atom;
     CLASS *classPtr;
 
-    hInstance = GetExePtr( hInstance );  /* FIXME: not needed in Win32 */
     if (!(atom = GlobalFindAtom32A( name )) ||
         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
         (hInstance != classPtr->hInstance)) return FALSE;
@@ -1032,7 +1012,6 @@
     ATOM atom;
     CLASS *classPtr;
 
-    hInstance = GetExePtr( hInstance );  /* FIXME: not needed in Win32 */
     if (!(atom = GlobalFindAtom32W( name )) ||
         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
         (hInstance != classPtr->hInstance)) return FALSE;
diff --git a/windows/defwnd.c b/windows/defwnd.c
index a5b5af4..8a2a7b3 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -418,7 +418,7 @@
         break;
     }
 
-    SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, result );
+    SPY_ExitMessage( SPY_RESULT_DEFWND16, hwnd, msg, result );
     return result;
 }
 
@@ -479,7 +479,7 @@
         break;
     }
 
-    SPY_ExitMessage( SPY_RESULT_OK32, hwnd, msg, result );
+    SPY_ExitMessage( SPY_RESULT_DEFWND32, hwnd, msg, result );
     return result;
 }
 
diff --git a/windows/dialog.c b/windows/dialog.c
index 21ef5b0..31cd880 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -486,11 +486,14 @@
 
       /* Load menu */
 
-    if (template.menuName)
-    {
-        LPSTR str = SEGPTR_STRDUP( template.menuName );  /* FIXME: win32 */
-        hMenu = LoadMenu16( hInst, SEGPTR_GET(str) );
-        SEGPTR_FREE( str );
+    if (template.menuName) {
+	if (!HIWORD(hInst)) /* win32 modules always have hiword set */
+        {
+            LPSTR str = SEGPTR_STRDUP( template.menuName );
+	    hMenu = LoadMenu16( hInst, SEGPTR_GET(str) );
+            SEGPTR_FREE( str );
+	} else /* win32 modules always have hiword set */
+	    hMenu = LoadMenu32A( hInst, template.menuName );
     }
 
       /* Create custom font if needed */
@@ -566,7 +569,7 @@
                                  rect.left, rect.top, rect.right, rect.bottom,
                                  owner, hMenu, hInst, NULL );
     else
-        hwnd = CreateWindowEx16(template.exStyle, template.className,
+        hwnd = CreateWindowEx32A(template.exStyle, template.className,
                                 template.caption, template.style & ~WS_VISIBLE,
                                 rect.left, rect.top, rect.right, rect.bottom,
                                 owner, hMenu, hInst, NULL );
@@ -602,12 +605,17 @@
     {
        /* Send initialisation messages and set focus */
 
-       dlgInfo->hwndFocus = GetNextDlgTabItem32( hwnd, 0, FALSE );
-       if (SendMessage32A( hwnd, WM_INITDIALOG,
-                           (WPARAM32)dlgInfo->hwndFocus, param ))
-           SetFocus32( dlgInfo->hwndFocus );
-       if (template.style & WS_VISIBLE) ShowWindow32( hwnd, SW_SHOW );
-       return hwnd;
+	dlgInfo->hwndFocus = GetNextDlgTabItem32( hwnd, 0, FALSE );
+
+	if (SendMessage32A( hwnd, WM_INITDIALOG, (WPARAM32)dlgInfo->hwndFocus, param ))
+            SetFocus32( dlgInfo->hwndFocus );
+
+	if (template.style & WS_VISIBLE && !(wndPtr->dwStyle & WS_VISIBLE)) 
+	{
+	   ShowWindow32( hwnd, SW_SHOWNORMAL );	/* SW_SHOW doesn't always work */
+	   UpdateWindow32( hwnd );
+	}
+	return hwnd;
     }
 
     if( IsWindow32(hwnd) ) DestroyWindow32( hwnd );
diff --git a/windows/event.c b/windows/event.c
index 541bd46..c843ec9 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -290,6 +290,25 @@
    while( XCheckWindowEvent(display, pWnd->window, NoEventMask, &xe) );
 }
 
+
+/***********************************************************************
+ *           IsUserIdle		(USER.333)
+ *
+ * Check if we have pending X events.
+ */
+BOOL16 WINAPI IsUserIdle(void)
+{
+    struct timeval timeout = {0, 0};
+    fd_set check_set;
+
+    FD_ZERO(&check_set);
+    FD_SET(__event_x_connection, &check_set);
+    if( select(__event_x_connection + 1, &check_set, NULL, NULL, &timeout) > 0 )
+	return TRUE;
+    return FALSE;
+}
+
+
 /***********************************************************************
  *           EVENT_WaitNetEvent
  *
diff --git a/windows/hook.c b/windows/hook.c
index 7166bad..55e5785 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -88,16 +88,18 @@
 
 	case WH_CALLWNDPROC:
 	{
-	    INT32	(*localMap)(UINT16, WPARAM16, UINT32*, WPARAM32*, LPARAM*)
-			  = (bA) ? WINPROC_MapMsg16To32A : WINPROC_MapMsg16To32W;
 	    LPCWPSTRUCT16   lpcwp16 = PTR_SEG_TO_LIN(*plParam);
 	    LPCWPSTRUCT32   lpcwp32 = HeapAlloc( SystemHeap, 0, sizeof(*lpcwp32) );
 	    
 	    lpcwp32->hwnd = lpcwp16->hwnd;
 	    lpcwp32->lParam = lpcwp16->lParam;
 	    
-	    (*localMap)(lpcwp16->message, lpcwp16->wParam, 
-		       &lpcwp32->message, &lpcwp32->wParam, &lpcwp32->lParam );
+            if (bA) WINPROC_MapMsg16To32A( lpcwp16->message, lpcwp16->wParam, 
+                                           &lpcwp32->message, &lpcwp32->wParam,
+                                           &lpcwp32->lParam );
+            else WINPROC_MapMsg16To32W( lpcwp16->message, lpcwp16->wParam, 
+                                        &lpcwp32->message, &lpcwp32->wParam,
+                                        &lpcwp32->lParam );
 	    break;
 	}
 
@@ -264,11 +266,11 @@
 
 	case WH_CALLWNDPROC:
 	{
-            void          (*localUnMap)(UINT32, WPARAM32, LPARAM)
-                            = (bA) ? WINPROC_UnmapMsg16To32A : WINPROC_UnmapMsg16To32W;
             LPCWPSTRUCT32   lpcwp32 = (LPCWPSTRUCT32)lParam;
-
-            (*localUnMap)(lpcwp32->message, lpcwp32->wParam, lpcwp32->lParam );
+            if (bA) WINPROC_UnmapMsg16To32A( lpcwp32->message, lpcwp32->wParam,
+                                             lpcwp32->lParam );
+            else WINPROC_UnmapMsg16To32W( lpcwp32->message, lpcwp32->wParam,
+                                          lpcwp32->lParam );
 	    HeapFree( SystemHeap, 0, lpcwp32 );
             break;
 	}
@@ -392,16 +394,18 @@
 
       case WH_CALLWNDPROC:
       {
-          INT32       (*localMap)(UINT32, WPARAM32, UINT16*, WPARAM16*, LPARAM*)
-                          = (bA) ? WINPROC_MapMsg32ATo16 : WINPROC_MapMsg32WTo16;
           LPCWPSTRUCT32   lpcwp32 = (LPCWPSTRUCT32)*plParam;
 	  LPCWPSTRUCT16   lpcwp16 = SEGPTR_NEW( CWPSTRUCT16 );
 
           lpcwp16->hwnd = lpcwp32->hwnd;
           lpcwp16->lParam = lpcwp32->lParam;
 
-         (*localMap)(lpcwp32->message, lpcwp32->wParam,
-                    &lpcwp16->message, &lpcwp16->wParam, &lpcwp16->lParam );
+          if (bA) WINPROC_MapMsg32ATo16( lpcwp32->message, lpcwp32->wParam,
+                                         &lpcwp16->message, &lpcwp16->wParam,
+                                         &lpcwp16->lParam );
+          else WINPROC_MapMsg32WTo16( lpcwp32->message, lpcwp32->wParam,
+                                      &lpcwp16->message, &lpcwp16->wParam,
+                                      &lpcwp16->lParam );
 	  *plParam = (LPARAM)SEGPTR_GET( lpcwp16 );
           break;
       }
@@ -575,13 +579,14 @@
 
       case WH_CALLWNDPROC:
       {
-          void          (*localUnMap)(UINT32, WPARAM32, LPARAM, MSGPARAM16* )
-                          = (bA) ? WINPROC_UnmapMsg32ATo16 : WINPROC_UnmapMsg32WTo16;
           LPCWPSTRUCT16   lpcwp16 = (LPCWPSTRUCT16)PTR_SEG_TO_LIN(lParam);
 	  LPCWPSTRUCT32   lpcwp32 = (LPCWPSTRUCT32)lParamOrig;
 	  MSGPARAM16	  mp16 = { lpcwp16->wParam, lpcwp16->lParam, 0 };
 
-          (*localUnMap)(lpcwp32->message, lpcwp32->wParam, lpcwp32->lParam, &mp16 );
+          if (bA) WINPROC_UnmapMsg32ATo16( lpcwp32->message, lpcwp32->wParam,
+                                           lpcwp32->lParam, &mp16 );
+          else WINPROC_UnmapMsg32WTo16( lpcwp32->message, lpcwp32->wParam,
+                                        lpcwp32->lParam, &mp16 );
 	  SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
           break;
       }
@@ -691,6 +696,7 @@
 	}
 	else
 	  lpcbtcwW->lpcs->lpszClass = (LPCWSTR)lpcbtcwA->lpcs->lpszClass;
+	*plParam = lpcbtcwW;
     }
     return;
 }
@@ -744,6 +750,7 @@
                                                    lpcbtcwW->lpcs->lpszClass );
 	else
 	  lpcbtcwA->lpcs->lpszClass = (LPSTR)lpcbtcwW->lpcs->lpszClass;
+	*plParam = lpcbtcwA;
     }
     return;
 }
@@ -840,11 +847,13 @@
     HQUEUE16 hQueue = 0;
 
     if ((id < WH_MINHOOK) || (id > WH_MAXHOOK)) return 0;
-    if (!(hInst = GetExePtr( hInst ))) return 0;
 
     dprintf_hook( stddeb, "Setting hook %d: %08x %04x %04x\n",
                   id, (UINT32)proc, hInst, hTask );
 
+    if (!hInst && (type!=HOOK_WIN16))
+    	hInst = GetModuleHandle32A(NULL);/*FIXME: correct? probably not */
+
     if (id == WH_JOURNALPLAYBACK) EnableHardwareInput(FALSE);
 
     if (hTask)  /* Task-specific hook */
@@ -1176,7 +1185,7 @@
 	return 0;
     }
 
-    handle = HOOK_SetHook( id, proc, HOOK_WIN16, hInst, hTask );
+    handle = HOOK_SetHook( id, proc, HOOK_WIN16, GetExePtr(hInst), hTask );
     return (handle) ? (FARPROC16)MAKELONG( handle, HOOK_MAGIC ) : NULL;
 }
 
@@ -1221,7 +1230,7 @@
 HHOOK WINAPI SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
                                  HTASK16 hTask )
 {
-    HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN16, hInst, hTask );
+    HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN16, GetExePtr(hInst), hTask );
     return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
 }
 
diff --git a/windows/keyboard.c b/windows/keyboard.c
index be31d59..9421737 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -1184,9 +1184,21 @@
 /***********************************************************************
  *           GetKeyboardLayout			(USER32.249)
  */
-/*HKL*/ HANDLE32 WINAPI GetKeyboardLayout(DWORD dwLayout)
+HKL32 WINAPI GetKeyboardLayout(DWORD dwLayout)
 {
 	fprintf(stderr,"GetKeyboardLayout(%ld),STUB!\n",dwLayout);
-	return 0;
+	return (0xcafe<<16)|GetSystemDefaultLCID(); /* FIXME */
+}
+
+/***********************************************************************
+ *           GetKeyboardLayoutList		(USER32.250)
+ * FIXME
+ */
+INT32 WINAPI GetKeyboardLayoutList(INT32 nBuff,HKL32 *layouts)
+{
+	fprintf(stderr,"GetKeyboardLayoutList(%d,%p),STUB!\n",nBuff,layouts);
+	if (layouts)
+		layouts[0] = GetKeyboardLayout(0);
+	return 1;
 }
 
diff --git a/windows/mdi.c b/windows/mdi.c
index fe881b9..3fd4b95 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -32,7 +32,6 @@
 
 #define MDIF_NEEDUPDATE		0x0001
 
-
 static HBITMAP16 hBmpClose   = 0;
 static HBITMAP16 hBmpRestore = 0;
 
@@ -59,12 +58,12 @@
 
 static void MDI_PostUpdate(HWND16 hwnd, MDICLIENTINFO* ci, WORD recalc)
 {
- if( !(ci->mdiFlags & MDIF_NEEDUPDATE) )
-   {
-      ci->mdiFlags |= MDIF_NEEDUPDATE;
-      PostMessage16( hwnd, WM_MDICALCCHILDSCROLL, 0, 0);
-   }
- ci->sbRecalc = recalc;
+    if( !(ci->mdiFlags & MDIF_NEEDUPDATE) )
+    {
+	ci->mdiFlags |= MDIF_NEEDUPDATE;
+	PostMessage16( hwnd, WM_MDICALCCHILDSCROLL, 0, 0);
+    }
+    ci->sbRecalc = recalc;
 }
 
 /**********************************************************************
@@ -92,22 +91,22 @@
  */
 static BOOL32 MDI_MenuModifyItem(WND* clientWnd, HWND16 hWndChild )
 {
- char            buffer[128];
- MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
- WND            *wndPtr     = WIN_FindWndPtr(hWndChild);
- UINT32		 n          = sprintf(buffer, "%d ",
-                              wndPtr->wIDmenu - clientInfo->idFirstChild + 1);
- BOOL32		 bRet	    = 0;
+    char            buffer[128];
+    MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
+    WND            *wndPtr     = WIN_FindWndPtr(hWndChild);
+    UINT32	    n          = sprintf(buffer, "%d ",
+				 wndPtr->wIDmenu - clientInfo->idFirstChild + 1);
+    BOOL32	    bRet	    = 0;
 
- if( !clientInfo->hWindowMenu ) return 0;
+    if( !clientInfo->hWindowMenu ) return 0;
 
- if (wndPtr->text) lstrcpyn32A(buffer + n, wndPtr->text, sizeof(buffer) - n );
+    if (wndPtr->text) lstrcpyn32A(buffer + n, wndPtr->text, sizeof(buffer) - n );
 
- n    = GetMenuState32(clientInfo->hWindowMenu,wndPtr->wIDmenu ,MF_BYCOMMAND); 
- bRet = ModifyMenu32A(clientInfo->hWindowMenu , wndPtr->wIDmenu, 
+    n    = GetMenuState32(clientInfo->hWindowMenu,wndPtr->wIDmenu ,MF_BYCOMMAND); 
+    bRet = ModifyMenu32A(clientInfo->hWindowMenu , wndPtr->wIDmenu, 
                       MF_BYCOMMAND | MF_STRING, wndPtr->wIDmenu, buffer );
- CheckMenuItem32(clientInfo->hWindowMenu ,wndPtr->wIDmenu , n & MF_CHECKED);
- return bRet;
+    CheckMenuItem32(clientInfo->hWindowMenu ,wndPtr->wIDmenu , n & MF_CHECKED);
+    return bRet;
 }
 
 /**********************************************************************
@@ -115,29 +114,29 @@
  */
 static BOOL32 MDI_MenuDeleteItem(WND* clientWnd, HWND16 hWndChild )
 {
- char    	 buffer[128];
- MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
- WND    	*wndPtr     = WIN_FindWndPtr(hWndChild);
- UINT32		 index      = 0,id,n;
+    char    	 buffer[128];
+    MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
+    WND    	*wndPtr     = WIN_FindWndPtr(hWndChild);
+    UINT32	 index      = 0,id,n;
 
- if( !clientInfo->nActiveChildren ||
-     !clientInfo->hWindowMenu ) return 0;
+    if( !clientInfo->nActiveChildren ||
+	!clientInfo->hWindowMenu ) return 0;
 
- id = wndPtr->wIDmenu;
- DeleteMenu32(clientInfo->hWindowMenu,id,MF_BYCOMMAND);
+    id = wndPtr->wIDmenu;
+    DeleteMenu32(clientInfo->hWindowMenu,id,MF_BYCOMMAND);
 
  /* walk the rest of MDI children to prevent gaps in the id 
   * sequence and in the menu child list */
 
- for( index = id+1; index <= clientInfo->nActiveChildren + 
-                             clientInfo->idFirstChild; index++ )
+    for( index = id+1; index <= clientInfo->nActiveChildren + 
+				clientInfo->idFirstChild; index++ )
     {
 	wndPtr = WIN_FindWndPtr(MDI_GetChildByID(clientWnd,index));
 	if( !wndPtr )
-	     {
+	{
 	      dprintf_mdi(stddeb,"MDIMenuDeleteItem: no window for id=%i\n",index);
 	      continue;
-    }
+	}
     
 	/* set correct id */
 	wndPtr->wIDmenu--;
@@ -150,40 +149,34 @@
 	ModifyMenu32A(clientInfo->hWindowMenu ,index ,MF_BYCOMMAND | MF_STRING,
                       index - 1 , buffer ); 
     }
- return 1;
+    return 1;
 }
 
 /**********************************************************************
  * 			MDI_GetWindow
  *
- * returns "activateable" child  or zero
+ * returns "activateable" child different from the current or zero
  */
-static HWND16 MDI_GetWindow(WND  *clientWnd, HWND16 hWnd, WORD wTo )
+static HWND16 MDI_GetWindow(WND *clientWnd, HWND16 hWnd, BOOL16 bNext, DWORD dwStyleMask )
 {
     MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
-    WND *wndPtr, *pWnd, *pWndLast;
+    WND *wndPtr, *pWnd, *pWndLast = NULL;
     
+    dwStyleMask |= WS_DISABLED | WS_VISIBLE;
     if( !hWnd ) hWnd = clientInfo->hwndActiveChild;
 
     if( !(wndPtr = WIN_FindWndPtr(hWnd)) ) return 0;
 
-    pWnd = wndPtr;
-    pWndLast = NULL;
-    for (;;)
+    for ( pWnd = wndPtr->next; ; pWnd = pWnd->next )
     {
-        pWnd = pWnd->next;
-        if (!pWnd) pWnd = wndPtr->parent->child;
-        if (pWnd == wndPtr)  /* not found */
-        {
-            if (!wTo || !pWndLast) return 0;
-            break;
-        }
+        if (!pWnd ) pWnd = wndPtr->parent->child;
 
-        if ( !pWnd->owner && (pWnd->dwStyle & 
-			     (WS_VISIBLE | WS_DISABLED)) == WS_VISIBLE )
+        if ( pWnd == wndPtr ) break; /* went full circle */
+
+        if (!pWnd->owner && (pWnd->dwStyle & dwStyleMask) == WS_VISIBLE )
         {
-            pWndLast = pWnd;
-            if (!wTo) break;
+	    pWndLast = pWnd;
+	    if ( bNext ) break;
         }
     }
     return pWndLast ? pWndLast->hwndSelf : 0;
@@ -192,23 +185,23 @@
 /**********************************************************************
  *			MDI_CalcDefaultChildPos
  *
- *  It seems that default height is 2/3 of client rect
+ *  It seems that the default height is about 2/3 of the client rect
  */
 static void MDI_CalcDefaultChildPos( WND* w, WORD n, LPPOINT16 lpPos,
                                      INT32 delta)
 {
- RECT32 rect = w->rectClient;
- INT32  spacing = GetSystemMetrics32(SM_CYCAPTION) +
-                  GetSystemMetrics32(SM_CYFRAME) - 1; 
- INT32  nstagger;
+    INT32  nstagger;
+    RECT32 rect = w->rectClient;
+    INT32  spacing = GetSystemMetrics32(SM_CYCAPTION) +
+		     GetSystemMetrics32(SM_CYFRAME) - 1; 
 
- if( rect.bottom - rect.top - delta >= spacing ) 
-     rect.bottom -= delta;
+    if( rect.bottom - rect.top - delta >= spacing ) 
+	rect.bottom -= delta;
 
- nstagger = (rect.bottom - rect.top)/(3*spacing);
- lpPos[1].x = (rect.right - rect.left - nstagger*spacing);
- lpPos[1].y = (rect.bottom - rect.top - nstagger*spacing);
- lpPos[0].x = lpPos[0].y = spacing*(n%(nstagger+1));
+    nstagger = (rect.bottom - rect.top)/(3 * spacing);
+    lpPos[1].x = (rect.right - rect.left - nstagger * spacing);
+    lpPos[1].y = (rect.bottom - rect.top - nstagger * spacing);
+    lpPos[0].x = lpPos[0].y = spacing * (n%(nstagger+1));
 }
 
 /**********************************************************************
@@ -226,7 +219,7 @@
     ci = (MDICLIENTINFO *) w->wExtra;
 
     if (!fRefresh) 
-       {
+    {
 	HWND16 hwndFrame = GetParent16(hwnd);
 	HMENU32 oldFrameMenu = GetMenu32(hwndFrame);
         
@@ -234,7 +227,7 @@
 	    MDI_RestoreFrameMenu(w->parent, ci->hwndChildMaximized );
 
 	if( hmenuWindow && hmenuWindow!=ci->hWindowMenu )
-	  {
+	{
 	    /* delete menu items from ci->hWindowMenu 
 	     * and add them to hmenuWindow */
 
@@ -244,13 +237,13 @@
             AppendMenu32A( hmenuWindow, MF_SEPARATOR, 0, NULL);
 
 	    if( ci->nActiveChildren )
-	      {
+	    {
 	        INT32 j = i - ci->nActiveChildren + 1;
 		char buffer[100];
 		UINT32 id,state;
 
 		for( ; i >= j ; i-- )
-		   {
+		{
 		     id = GetMenuItemID32(ci->hWindowMenu,i );
 		     state = GetMenuState32(ci->hWindowMenu,i,MF_BYPOSITION); 
 
@@ -260,24 +253,24 @@
 		     InsertMenu32A(hmenuWindow, pos, MF_BYPOSITION | MF_STRING,
 					     id, buffer);
 		     CheckMenuItem32(hmenuWindow ,pos , MF_BYPOSITION | (state & MF_CHECKED));
-		   }
-	      }
+		}
+	    }
 
 	    /* remove separator */
 	    DeleteMenu32(ci->hWindowMenu, i, MF_BYPOSITION); 
 
 	    ci->hWindowMenu = hmenuWindow;
-	  } 
+	} 
 
 	if( hmenuFrame && hmenuFrame!=oldFrameMenu)
-	  {
+	{
 	    SetMenu32(hwndFrame, hmenuFrame);
 	    if( ci->hwndChildMaximized )
 	        MDI_AugmentFrameMenu(ci, w->parent, ci->hwndChildMaximized );
 	    return oldFrameMenu;
-	  }
+	}
 
-       }
+    }
     return 0;
 }
 
@@ -319,21 +312,21 @@
         cs->cy = pos[1].y;
 
     if( cs->x == CW_USEDEFAULT16 )
-      {
+    {
  	cs->x = pos[0].x;
 	cs->y = pos[0].y;
-      }
+    }
 
     /* restore current maximized child */
     if( style & WS_VISIBLE && ci->hwndChildMaximized )
-      {
+    {
 	if( style & WS_MAXIMIZE )
-	  SendMessage16(w->hwndSelf, WM_SETREDRAW, FALSE, 0L );
+	    SendMessage16(w->hwndSelf, WM_SETREDRAW, FALSE, 0L );
 	hwndMax = ci->hwndChildMaximized;
 	ShowWindow16( hwndMax, SW_SHOWNOACTIVATE );
 	if( style & WS_MAXIMIZE )
-	  SendMessage16(w->hwndSelf, WM_SETREDRAW, TRUE, 0L );
-      }
+	    SendMessage16(w->hwndSelf, WM_SETREDRAW, TRUE, 0L );
+    }
 
     /* this menu is needed to set a check mark in MDI_ChildActivate */
     AppendMenu32A(ci->hWindowMenu ,MF_STRING ,wIDmenu, lpstrDef );
@@ -342,11 +335,11 @@
 
     /* fix window style */
     if( !(w->dwStyle & MDIS_ALLCHILDSTYLES) )
-      {
+    {
         style &= (WS_CHILD | WS_CLIPSIBLINGS | WS_MINIMIZE | WS_MAXIMIZE |
                   WS_CLIPCHILDREN | WS_DISABLED | WS_VSCROLL | WS_HSCROLL );
         style |= (WS_VISIBLE | WS_OVERLAPPEDWINDOW);
-      }
+    }
 
     hwnd = CreateWindow16( (LPCSTR)PTR_SEG_TO_LIN(cs->szClass),
                            (LPCSTR)PTR_SEG_TO_LIN(cs->szTitle), style, 
@@ -364,20 +357,20 @@
 	if( wnd->dwStyle & WS_MINIMIZE && ci->hwndActiveChild )
 	    ShowWindow16( hwnd, SW_SHOWMINNOACTIVE );
 	else
-	  {
+	{
 	    SetWindowPos32( hwnd, 0, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE );
 
 	    /* Set maximized state here in case hwnd didn't receive WM_SIZE
 	     * during CreateWindow - bad!
 	     */
 
-            if( wnd->dwStyle & WS_MAXIMIZE && !ci->hwndChildMaximized )
-              {
+            if((wnd->dwStyle & WS_MAXIMIZE) && !ci->hwndChildMaximized )
+            {
                 ci->hwndChildMaximized = wnd->hwndSelf;
                 MDI_AugmentFrameMenu( ci, w->parent, hwnd );
                 MDI_UpdateFrameText( w->parent, ci->self, MDI_REPAINTFRAME, NULL ); 
-	      }
-	  }
+	    }
+	}
         dprintf_mdi(stddeb, "MDICreateChild: created child - %04x\n",hwnd);
     }
     else
@@ -393,77 +386,73 @@
 
 /**********************************************************************
  *			MDI_ChildGetMinMaxInfo
+ *
+ * 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( WND* clientWnd, HWND16 hwnd,
                                     MINMAXINFO16* lpMinMax )
 {
- WND*	childWnd = WIN_FindWndPtr(hwnd);
- RECT32	rect 	 = clientWnd->rectClient;
+    WND*	childWnd = WIN_FindWndPtr(hwnd);
+    RECT32	rect 	 = clientWnd->rectClient;
 
- MapWindowPoints32(clientWnd->parent->hwndSelf, 
-                   ((MDICLIENTINFO*)clientWnd->wExtra)->self,
-                   (LPPOINT32)&rect, 2);
- AdjustWindowRectEx32( &rect, childWnd->dwStyle, 0, childWnd->dwExStyle );
+    MapWindowPoints32( clientWnd->parent->hwndSelf, 
+		     ((MDICLIENTINFO*)clientWnd->wExtra)->self, (LPPOINT32)&rect, 2);
+    AdjustWindowRectEx32( &rect, childWnd->dwStyle, 0, childWnd->dwExStyle );
 
- lpMinMax->ptMaxSize.x = rect.right -= rect.left;
- lpMinMax->ptMaxSize.y = rect.bottom -= rect.top;
+    lpMinMax->ptMaxSize.x = rect.right -= rect.left;
+    lpMinMax->ptMaxSize.y = rect.bottom -= rect.top;
 
- lpMinMax->ptMaxPosition.x = rect.left;
- lpMinMax->ptMaxPosition.y = rect.top; 
+    lpMinMax->ptMaxPosition.x = rect.left;
+    lpMinMax->ptMaxPosition.y = rect.top; 
 
- dprintf_mdi(stddeb,"\tChildMinMaxInfo: max rect (%i,%i - %i, %i)\n", 
+    dprintf_mdi(stddeb,"\tChildMinMaxInfo: max rect (%i,%i - %i, %i)\n", 
                         rect.left,rect.top,rect.right,rect.bottom);
-
 }
 
 /**********************************************************************
  *			MDI_SwitchActiveChild
  * 
- * Notes: SetWindowPos sends WM_CHILDACTIVATE to the child window that is
- *        being activated 
- *
- *	  wTo is basically lParam of WM_MDINEXT message or explicit 
- *        window handle
+ * Note: SetWindowPos sends WM_CHILDACTIVATE to the child window that is
+ *       being activated 
  */
 static void MDI_SwitchActiveChild( HWND16 clientHwnd, HWND16 childHwnd,
-                                   BOOL32 wTo )
+                                   BOOL32 bNextWindow )
 {
     WND		  *w	     = WIN_FindWndPtr(clientHwnd);
     HWND16	   hwndTo    = 0;
     HWND16	   hwndPrev  = 0;
     MDICLIENTINFO *ci;
 
-    hwndTo = MDI_GetWindow(w,childHwnd,(WORD)wTo);
+    hwndTo = MDI_GetWindow(w, childHwnd, bNextWindow, 0);
  
     ci = (MDICLIENTINFO *) w->wExtra;
 
     dprintf_mdi(stddeb, "MDI_SwitchActiveChild: from %04x, to %04x\n",childHwnd,hwndTo);
 
-    if ( !hwndTo ) return; 
+    if ( !hwndTo ) return; /* no window to switch to */
 
     hwndPrev = ci->hwndActiveChild;
 
     if ( hwndTo != hwndPrev )
+    {
+	BOOL32 bOptimize = 0;
+
+	if( ci->hwndChildMaximized )
 	{
-	  BOOL32 bOptimize = 0;
-
-	  if( ci->hwndChildMaximized )
-	    {
-	      bOptimize = 1; 
-	      w->dwStyle &= ~WS_VISIBLE;
-	    }
-
-	  SetWindowPos32( hwndTo, HWND_TOP, 0, 0, 0, 0, 
-			SWP_NOMOVE | SWP_NOSIZE );
-	  if( !wTo && hwndPrev )
-	    {
-	       SetWindowPos32( hwndPrev, HWND_BOTTOM, 0, 0, 0, 0, 
-		  	     SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
-	    }
-
-	  if( bOptimize )
-	       ShowWindow16( clientHwnd, SW_SHOW );
+	    bOptimize = 1; 
+	    w->dwStyle &= ~WS_VISIBLE;
 	}
+
+	SetWindowPos32( hwndTo, HWND_TOP, 0, 0, 0, 0, 
+			SWP_NOMOVE | SWP_NOSIZE );
+
+	if( bNextWindow && hwndPrev )
+	    SetWindowPos32( hwndPrev, HWND_BOTTOM, 0, 0, 0, 0, 
+		  	    SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
+	if( bOptimize )
+	    ShowWindow16( clientHwnd, SW_SHOW );
+    }
 }
 
 	    
@@ -478,21 +467,21 @@
     if( childPtr )
     {
         if( child == ci->hwndActiveChild )
-          {
-	    MDI_SwitchActiveChild(parent,child,0);
+        {
+	    MDI_SwitchActiveChild(parent, child, TRUE);
 
 	    if( child == ci->hwndActiveChild )
-	      {
+	    {
 		ShowWindow16( child, SW_HIDE);
 		if( child == ci->hwndChildMaximized )
-		  {
+		{
 		    MDI_RestoreFrameMenu(w_parent->parent, child);
 		    ci->hwndChildMaximized = 0;
 		    MDI_UpdateFrameText(w_parent->parent,parent,TRUE,NULL);
-		  }
+		}
 
-                MDI_ChildActivate(w_parent,0);
-	      }
+                MDI_ChildActivate(w_parent, 0);
+	    }
 	    MDI_MenuDeleteItem(w_parent, child);
 	}
 	
@@ -501,10 +490,10 @@
         dprintf_mdi(stddeb,"MDIDestroyChild: child destroyed - %04x\n",child);
 
         if (flagDestroy)
-	   {
+	{
 	    MDI_PostUpdate(GetParent16(child), ci, SB_BOTH+1);
             DestroyWindow32(child);
-	   }
+	}
     }
 
     return 0;
@@ -552,16 +541,16 @@
        	if( clientInfo->hWindowMenu )
        	        CheckMenuItem32( clientInfo->hWindowMenu,
                                  wndPrev->wIDmenu, 0);
-      }
+    }
 
     /* set appearance */
     if( clientInfo->hwndChildMaximized )
       if( clientInfo->hwndChildMaximized != hWndChild )
         if( hWndChild )
-	        {
+	{
 		  clientInfo->hwndActiveChild = hWndChild;
 		  ShowWindow16( hWndChild, SW_SHOWMAXIMIZED);
-	        }
+	}
 	else
 		ShowWindow16( clientInfo->hwndActiveChild, 
 			    SW_SHOWNORMAL );
@@ -570,11 +559,11 @@
 
     /* check if we have any children left */
     if( !hWndChild )
-	{
-	    if( isActiveFrameWnd )
-		SetFocus32( clientInfo->self );
-	    return 0;
-	}
+    {
+	if( isActiveFrameWnd )
+	    SetFocus32( clientInfo->self );
+	return 0;
+    }
 	
     /* check menu item */
     if( clientInfo->hWindowMenu )
@@ -585,7 +574,7 @@
     SetWindowPos32( hWndChild, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
 
     if( isActiveFrameWnd )
-	  {
+    {
 	    SendMessage16( hWndChild, WM_NCACTIVATE, TRUE, 0L);
 	    if( GetFocus32() == clientInfo->self )
 		SendMessage16( clientInfo->self, WM_SETFOCUS, 
@@ -767,39 +756,42 @@
 static BOOL32 MDI_AugmentFrameMenu( MDICLIENTINFO* ci, WND *frame,
                                     HWND16 hChild )
 {
- WND*		child = WIN_FindWndPtr(hChild);
- HMENU16  	hSysPopup = 0;
+    WND*	child = WIN_FindWndPtr(hChild);
+    HMENU16  	hSysPopup = 0;
 
- dprintf_mdi(stddeb,"MDI_AugmentFrameMenu: frame %p,child %04x\n",frame,hChild);
+    dprintf_mdi(stddeb,"MDI_AugmentFrameMenu: frame %p,child %04x\n",frame,hChild);
 
- if( !frame->wIDmenu || !child->hSysMenu ) return 0; 
+    if( !frame->wIDmenu || !child->hSysMenu ) return 0; 
 
- /* create a copy of sysmenu popup and insert it into frame menu bar */
+    /* create a copy of sysmenu popup and insert it into frame menu bar */
 
- if (!(hSysPopup = LoadMenuIndirect32A(SYSRES_GetResPtr(SYSRES_MENU_SYSMENU))))
-     return 0;
+    if (!(hSysPopup = LoadMenuIndirect32A(SYSRES_GetResPtr(SYSRES_MENU_SYSMENU))))
+	return 0;
  
- dprintf_mdi(stddeb,"\t\tgot popup %04x\n in sysmenu %04x",hSysPopup,child->hSysMenu);
+    dprintf_mdi(stddeb,"\t\tgot popup %04x\n in sysmenu %04x",hSysPopup,child->hSysMenu);
  
- if( !InsertMenu32A(frame->wIDmenu,0,MF_BYPOSITION | MF_BITMAP | MF_POPUP,
+    if( !InsertMenu32A(frame->wIDmenu,0,MF_BYPOSITION | MF_BITMAP | MF_POPUP,
                     hSysPopup, (LPSTR)(DWORD)hBmpClose ))
-   {  DestroyMenu32(hSysPopup); return 0; }
+    {  
+	DestroyMenu32(hSysPopup); 
+	return 0; 
+    }
 
- if( !AppendMenu32A(frame->wIDmenu,MF_HELP | MF_BITMAP,
+    if( !AppendMenu32A(frame->wIDmenu,MF_HELP | MF_BITMAP,
                     SC_RESTORE, (LPSTR)(DWORD)hBmpRestore ))
-   {
-      RemoveMenu32(frame->wIDmenu,0,MF_BYPOSITION);
-      return 0;
-   }
+    {
+	RemoveMenu32(frame->wIDmenu,0,MF_BYPOSITION);
+	return 0;
+    }
 
- EnableMenuItem32(hSysPopup, SC_SIZE, MF_BYCOMMAND | MF_GRAYED);
- EnableMenuItem32(hSysPopup, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
- EnableMenuItem32(hSysPopup, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED);
+    EnableMenuItem32(hSysPopup, SC_SIZE, MF_BYCOMMAND | MF_GRAYED);
+    EnableMenuItem32(hSysPopup, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
+    EnableMenuItem32(hSysPopup, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED);
 
- /* redraw menu */
- DrawMenuBar32(frame->hwndSelf);
+    /* redraw menu */
+    DrawMenuBar32(frame->hwndSelf);
 
- return 1;
+    return 1;
 }
 
 /**********************************************************************
@@ -807,20 +799,19 @@
  */
 static BOOL32 MDI_RestoreFrameMenu( WND *frameWnd, HWND16 hChild )
 {
- INT32 nItems = GetMenuItemCount32(frameWnd->wIDmenu) - 1;
+    INT32 nItems = GetMenuItemCount32(frameWnd->wIDmenu) - 1;
 
- dprintf_mdi(stddeb,"MDI_RestoreFrameMenu: for child %04x\n",hChild);
+    dprintf_mdi(stddeb,"MDI_RestoreFrameMenu: for child %04x\n",hChild);
 
- if( GetMenuItemID32(frameWnd->wIDmenu,nItems) != SC_RESTORE )
-     return 0; 
+    if( GetMenuItemID32(frameWnd->wIDmenu,nItems) != SC_RESTORE )
+	return 0; 
 
+    RemoveMenu32(frameWnd->wIDmenu,0,MF_BYPOSITION);
+    DeleteMenu32(frameWnd->wIDmenu,nItems-1,MF_BYPOSITION);
 
- RemoveMenu32(frameWnd->wIDmenu,0,MF_BYPOSITION);
- DeleteMenu32(frameWnd->wIDmenu,nItems-1,MF_BYPOSITION);
+    DrawMenuBar32(frameWnd->hwndSelf);
 
- DrawMenuBar32(frameWnd->hwndSelf);
-
- return 1;
+    return 1;
 }
 
 /**********************************************************************
@@ -833,65 +824,63 @@
 static void MDI_UpdateFrameText( WND *frameWnd, HWND16 hClient,
                                  BOOL32 repaint, LPCSTR lpTitle )
 {
- char   lpBuffer[MDI_MAXTITLELENGTH+1];
- WND* 	clientWnd = WIN_FindWndPtr(hClient);
+    char   lpBuffer[MDI_MAXTITLELENGTH+1];
+    WND*   clientWnd = WIN_FindWndPtr(hClient);
+    MDICLIENTINFO *ci = (MDICLIENTINFO *) clientWnd->wExtra;
 
- MDICLIENTINFO *ci = (MDICLIENTINFO *) clientWnd->wExtra;
+    dprintf_mdi(stddeb, "MDI: repaint %i, frameText %s\n", repaint, (lpTitle)?lpTitle:"NULL");
 
- dprintf_mdi(stddeb, "MDI: repaint %i, frameText %s\n", repaint, (lpTitle)?lpTitle:"NULL");
+    /* store new "default" title if lpTitle is not NULL */
+    if (lpTitle) 
+    {
+	if (ci->frameTitle) HeapFree( SystemHeap, 0, ci->frameTitle );
+	ci->frameTitle = HEAP_strdupA( SystemHeap, 0, lpTitle );
+    }
 
- /* store new "default" title if lpTitle is not NULL */
- if (lpTitle) 
- {
-     if (ci->frameTitle) HeapFree( SystemHeap, 0, ci->frameTitle );
-     ci->frameTitle = HEAP_strdupA( SystemHeap, 0, lpTitle );
- }
+    if (ci->frameTitle)
+    {
+	WND* childWnd = WIN_FindWndPtr( ci->hwndChildMaximized );     
 
- if (ci->frameTitle)
-   {
-     WND* childWnd = WIN_FindWndPtr( ci->hwndChildMaximized );     
+	if( childWnd && childWnd->text )
+	{
+	    /* combine frame title and child title if possible */
 
-     if( childWnd && childWnd->text )
-       {
-	 /* combine frame title and child title if possible */
+	    LPCSTR lpBracket  = " - [";
+	    int	i_frame_text_length = strlen(ci->frameTitle);
+	    int	i_child_text_length = strlen(childWnd->text);
 
-	 LPCSTR lpBracket  = " - [";
-	 int	i_frame_text_length = strlen(ci->frameTitle);
-	 int    i_child_text_length = strlen(childWnd->text);
+	    lstrcpyn32A( lpBuffer, ci->frameTitle, MDI_MAXTITLELENGTH);
 
-	 lstrcpyn32A( lpBuffer, ci->frameTitle, MDI_MAXTITLELENGTH);
+	    if( i_frame_text_length + 6 < MDI_MAXTITLELENGTH )
+            {
+		strcat( lpBuffer, lpBracket );
 
-	 if( i_frame_text_length + 6 < MDI_MAXTITLELENGTH )
-         {
-	     strcat( lpBuffer, lpBracket );
-
-	     if( i_frame_text_length + i_child_text_length + 6 < MDI_MAXTITLELENGTH )
-             {
-                 strcat( lpBuffer, childWnd->text );
-                 strcat( lpBuffer, "]" );
-             }
-	     else
-             {
-                 lstrcpyn32A( lpBuffer + i_frame_text_length + 4, 
-                              childWnd->text,
-                              MDI_MAXTITLELENGTH - i_frame_text_length - 5 );
-                 strcat( lpBuffer, "]" );
+		if( i_frame_text_length + i_child_text_length + 6 < MDI_MAXTITLELENGTH )
+		{
+		    strcat( lpBuffer, childWnd->text );
+		    strcat( lpBuffer, "]" );
 		}
-	   }
-       }
-     else
-       {
-         strncpy(lpBuffer, ci->frameTitle, MDI_MAXTITLELENGTH );
-	 lpBuffer[MDI_MAXTITLELENGTH]='\0';
-       }
-   }
- else
-   lpBuffer[0] = '\0';
+		else
+		{
+		    lstrcpyn32A( lpBuffer + i_frame_text_length + 4, 
+				 childWnd->text, MDI_MAXTITLELENGTH - i_frame_text_length - 5 );
+		    strcat( lpBuffer, "]" );
+		}
+	    }
+	}
+	else
+	{
+            strncpy(lpBuffer, ci->frameTitle, MDI_MAXTITLELENGTH );
+	    lpBuffer[MDI_MAXTITLELENGTH]='\0';
+	}
+    }
+    else
+	lpBuffer[0] = '\0';
 
- DEFWND_SetText( frameWnd, lpBuffer );
- if( repaint == MDI_REPAINTFRAME)
-     SetWindowPos32(frameWnd->hwndSelf, 0,0,0,0,0, SWP_FRAMECHANGED |
-                    SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
+    DEFWND_SetText( frameWnd, lpBuffer );
+    if( repaint == MDI_REPAINTFRAME)
+	SetWindowPos32( frameWnd->hwndSelf, 0,0,0,0,0, SWP_FRAMECHANGED |
+			SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
 }
 
 
@@ -901,7 +890,7 @@
 /**********************************************************************
  *					MDIClientWndProc
  *
- * This function is the handler for all MDI requests.
+ * This function handles all MDI requests.
  */
 LRESULT WINAPI MDIClientWndProc(HWND16 hwnd, UINT16 message, WPARAM16 wParam,
                                 LPARAM lParam)
@@ -960,13 +949,15 @@
 	NC_HandleNCCalcSize( w, &rect );
 	w->rectClient = rect;
 
-	dprintf_mdi(stddeb,"MDI: Client created - hwnd = %04x, idFirst = %u\n",hwnd,ci->idFirstChild);
+	dprintf_mdi(stddeb,"MDI: Client created - hwnd = %04x, idFirst = %u\n",
+			   hwnd, ci->idFirstChild );
 
 	return 0;
       
       case WM_DESTROY:
 	if( ci->hwndChildMaximized ) MDI_RestoreFrameMenu(w, frameWnd->hwndSelf);
-	if((nItems = GetMenuItemCount32(ci->hWindowMenu)) > 0) {
+	if((nItems = GetMenuItemCount32(ci->hWindowMenu)) > 0) 
+	{
     	    ci->idFirstChild = nItems - 1;
 	    ci->nActiveChildren++; 		/* to delete a separator */
 	    while( ci->nActiveChildren-- )
@@ -1001,15 +992,15 @@
 	ci->mdiFlags |= MDIF_NEEDUPDATE;
 	MDIIconArrange(hwnd);
 	ci->sbRecalc = SB_BOTH+1;
-	SendMessage16(hwnd,WM_MDICALCCHILDSCROLL,0,0L);
+	SendMessage16(hwnd, WM_MDICALCCHILDSCROLL, 0, 0L);
 	return 0;
 	
       case WM_MDIMAXIMIZE:
 	ShowWindow16((HWND16)wParam, SW_MAXIMIZE);
 	return 0;
 
-      case WM_MDINEXT:
-	MDI_SwitchActiveChild(hwnd, (HWND16)wParam, (lParam)?1:0);
+      case WM_MDINEXT: /* lParam != 0 means previous window */
+	MDI_SwitchActiveChild(hwnd, (HWND16)wParam, (lParam)? FALSE : TRUE );
 	break;
 	
       case WM_MDIRESTORE:
@@ -1026,24 +1017,24 @@
       case WM_MDITILE:
 	ci->mdiFlags |= MDIF_NEEDUPDATE;
 	ShowScrollBar32(hwnd,SB_BOTH,FALSE);
-	MDITile(w, ci,wParam);
+	MDITile(w, ci, wParam);
         ci->mdiFlags &= ~MDIF_NEEDUPDATE;
         return 0;
 
       case WM_VSCROLL:
       case WM_HSCROLL:
 	ci->mdiFlags |= MDIF_NEEDUPDATE;
-        ScrollChildren32(hwnd,message,wParam,lParam);
+        ScrollChildren32(hwnd, message, wParam, lParam);
 	ci->mdiFlags &= ~MDIF_NEEDUPDATE;
         return 0;
 
       case WM_SETFOCUS:
 	if( ci->hwndActiveChild )
-	  {
+	{
 	   w = WIN_FindWndPtr( ci->hwndActiveChild );
 	   if( !(w->dwStyle & WS_MINIMIZE) )
 	       SetFocus32( ci->hwndActiveChild );
-	  } 
+	} 
 	return 0;
 	
       case WM_NCACTIVATE:
@@ -1076,7 +1067,7 @@
 			 rect.right - rect.left, rect.bottom - rect.top, 1);
 	}
 	else
-	  MDI_PostUpdate(hwnd, ci, SB_BOTH+1);
+	    MDI_PostUpdate(hwnd, ci, SB_BOTH+1);
 
 	break;
 
@@ -1251,7 +1242,8 @@
 	    SendMessage32W(hwndMDIClient, message, wParam, lParam);
 	    break;
 
-	  case WM_SETTEXT: {
+	  case WM_SETTEXT: 
+	  {
 	      LPSTR txt = HEAP_strdupWtoA(GetProcessHeap(),0,(LPWSTR)lParam);
 	      LRESULT ret = DefFrameProc32A( hwnd, hwndMDIClient, message,
                                      wParam, (DWORD)txt );
@@ -1311,7 +1303,7 @@
 
       case WM_SYSCOMMAND:
 	switch( wParam )
-	  {
+	{
 		case SC_MOVE:
 		     if( ci->hwndChildMaximized == hwnd) return 0;
 		     break;
@@ -1331,7 +1323,7 @@
 		case SC_PREVWINDOW:
 		     SendMessage16( ci->self, WM_MDINEXT, 0, 1);
 		     return 0;
-	  }
+	}
 	break;
 	
       case WM_GETMINMAXINFO:
@@ -1348,29 +1340,29 @@
 	/* do not change */
 
 	if( ci->hwndActiveChild == hwnd && wParam != SIZE_MAXIMIZED )
-	  {
+	{
   	    ci->hwndChildMaximized = 0;
 	    
 	    MDI_RestoreFrameMenu( clientWnd->parent, hwnd);
             MDI_UpdateFrameText( clientWnd->parent, ci->self,
                                  MDI_REPAINTFRAME, NULL );
-	  }
+	}
 
 	if( wParam == SIZE_MAXIMIZED )
-	  {
+	{
 	    HWND16 hMaxChild = ci->hwndChildMaximized;
 
 	    if( hMaxChild == hwnd ) break;
 
 	    if( hMaxChild)
-	      {	    
-	       SendMessage16( hMaxChild, WM_SETREDRAW, FALSE, 0L );
+	    {	    
+	        SendMessage16( hMaxChild, WM_SETREDRAW, FALSE, 0L );
 
-	       MDI_RestoreFrameMenu( clientWnd->parent, hMaxChild);
-	       ShowWindow16( hMaxChild, SW_SHOWNOACTIVATE);
+	        MDI_RestoreFrameMenu( clientWnd->parent, hMaxChild);
+	        ShowWindow16( hMaxChild, SW_SHOWNOACTIVATE);
 
-	       SendMessage16( hMaxChild, WM_SETREDRAW, TRUE, 0L );
-	      }
+	        SendMessage16( hMaxChild, WM_SETREDRAW, TRUE, 0L );
+	    }
 
 	    dprintf_mdi(stddeb,"\tMDI: maximizing child %04x\n", hwnd );
 
@@ -1379,16 +1371,16 @@
 	    MDI_AugmentFrameMenu( ci, clientWnd->parent, hwnd);
 	    MDI_UpdateFrameText( clientWnd->parent, ci->self,
 				 MDI_REPAINTFRAME, NULL ); 
-	  }
+	}
 
 	if( wParam == SIZE_MINIMIZED )
-	  {
-	    HWND16 switchTo = MDI_GetWindow(clientWnd, hwnd, 0);
+	{
+	    HWND16 switchTo = MDI_GetWindow(clientWnd, hwnd, TRUE, WS_MINIMIZE);
 
 	    if( switchTo )
 	        SendMessage16( switchTo, WM_CHILDACTIVATE, 0, 0L);
-	  }
-	  
+	}
+	 
 	MDI_PostUpdate(clientWnd->hwndSelf, ci, SB_BOTH+1);
 	break;
 
diff --git a/windows/message.c b/windows/message.c
index 6d4aa84..9470710 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -55,6 +55,32 @@
 }
 
 /***********************************************************************
+ *           MSG_SendParentNotify
+ *
+ * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
+ * the window has the WS_EX_NOPARENTNOTIFY style.
+ */
+static void MSG_SendParentNotify(WND* wndPtr, WORD event, WORD idChild, LPARAM lValue)
+{
+#define lppt ((LPPOINT16)&lValue)
+
+    /* pt has to be in the client coordinates of the parent window */
+
+    MapWindowPoints16( 0, wndPtr->hwndSelf, lppt, 1 );
+    while (wndPtr)
+    {
+	if (!(wndPtr->dwStyle & WS_CHILD) || (wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY)) break;
+	lppt->x += wndPtr->rectClient.left;
+	lppt->y += wndPtr->rectClient.top;
+	wndPtr = wndPtr->parent;
+	SendMessage32A( wndPtr->hwndSelf, WM_PARENTNOTIFY,
+			MAKEWPARAM( event, idChild ), lValue );
+    }
+#undef lppt
+}
+
+
+/***********************************************************************
  *           MSG_TranslateMouseMsg
  *
  * Translate an mouse hardware event into a real mouse message.
@@ -192,8 +218,7 @@
 	     * notification message is still WM_L/M/RBUTTONDOWN.
 	     */
 
-            WIN_SendParentNotify( hWnd, msg->message, 0,
-                              MAKELPARAM( screen_pt.x, screen_pt.y ) );
+            MSG_SendParentNotify( pWnd, msg->message, 0, MAKELPARAM(screen_pt.x, screen_pt.y) );
 
             /* Activate the window if needed */
 
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 03f6091..fa30a1e 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -709,23 +709,23 @@
 
 	lpt[4].x = lpt[0].x = rect->left;
 	lpt[5].x = lpt[1].x = rect->left + width;
-	lpt[6].x = lpt[2].x = rect->right - width - 1;
-	lpt[7].x = lpt[3].x = rect->right - 1;
+	lpt[6].x = lpt[2].x = rect->right - 1;
+	lpt[7].x = lpt[3].x = rect->right - width - 1;
 
 	lpt[0].y = lpt[1].y = lpt[2].y = lpt[3].y = 
 		  rect->top + SYSMETRICS_CYFRAME + SYSMETRICS_CYSIZE;
 	lpt[4].y = lpt[5].y = lpt[6].y = lpt[7].y =
-		  rect->bottom - 1 - SYSMETRICS_CYFRAME - SYSMETRICS_CYSIZE;
+		  rect->bottom - SYSMETRICS_CYFRAME - SYSMETRICS_CYSIZE;
 
         lpt[8].x = lpt[9].x = lpt[10].x = lpt[11].x =
 		  rect->left + SYSMETRICS_CXFRAME + SYSMETRICS_CXSIZE;
 	lpt[12].x = lpt[13].x = lpt[14].x = lpt[15].x = 
-		  rect->right - 1 - SYSMETRICS_CXFRAME - SYSMETRICS_CYSIZE;
+		  rect->right - SYSMETRICS_CXFRAME - SYSMETRICS_CYSIZE;
 
 	lpt[12].y = lpt[8].y = rect->top; 
 	lpt[13].y = lpt[9].y = rect->top + height;
-	lpt[14].y = lpt[10].y = rect->bottom - height - 1; 
-	lpt[15].y = lpt[11].y = rect->bottom - 1;
+	lpt[14].y = lpt[10].y = rect->bottom - 1;
+	lpt[15].y = lpt[11].y = rect->bottom - height - 1;
 
 	GRAPH_DrawLines( hdc, lpt, 8, (HPEN32)0 );	/* 8 is the maximum */
 	InflateRect32( rect, -width - 1, -height - 1 );
@@ -868,7 +868,7 @@
     }
 
     MoveTo( hdc, r.left, r.bottom );
-    LineTo32( hdc, r.right-1, r.bottom );
+    LineTo32( hdc, r.right, r.bottom );
 
     if (style & WS_SYSMENU)
     {
diff --git a/windows/queue.c b/windows/queue.c
index a0f50c4..f9534cd 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -85,7 +85,7 @@
         }
         fprintf( stderr, "%04x %5d %4d %04x %s\n",
                  hQueue, queue->msgSize, queue->msgCount, queue->hTask,
-                 MODULE_GetModuleName( GetExePtr(queue->hTask) ) );
+                 MODULE_GetModuleName( queue->hTask ) );
         hQueue = queue->next;
     }
     fprintf( stderr, "\n" );
@@ -761,7 +761,7 @@
        HOOK_ResetQueueHooks( hNewQueue );
        if( WIN_GetDesktop()->hmemTaskQ == hQueue )
 	   WIN_GetDesktop()->hmemTaskQ = hNewQueue;
-       WIN_ResetQueueWindows( WIN_GetDesktop()->child, hQueue, hNewQueue );
+       WIN_ResetQueueWindows( WIN_GetDesktop(), hQueue, hNewQueue );
        QUEUE_DeleteMsgQueue( hQueue );
     }
 
diff --git a/windows/syscolor.c b/windows/syscolor.c
index 9f86835..e722daa 100644
--- a/windows/syscolor.c
+++ b/windows/syscolor.c
@@ -39,7 +39,11 @@
     "GrayText", "192 192 192",       /* COLOR_GRAYTEXT            */
     "ButtonText", "0 0 0",           /* COLOR_BTNTEXT             */
     "InactiveTitleText", "0 0 0",    /* COLOR_INACTIVECAPTIONTEXT */
-    "ButtonHilight", "255 255 255"   /* COLOR_BTNHIGHLIGHT        */
+    "ButtonHilight", "255 255 255",  /* COLOR_BTNHIGHLIGHT        */
+    "3DDarkShadow", "32 32 32",      /* COLOR_3DDKSHADOW          */
+    "3DLight", "192 192 192",        /* COLOR_3DLIGHT             */
+    "InfoText", "0 0 0",             /* COLOR_INFOTEXT            */
+    "InfoBackground", "255 255 192"  /* COLOR_INFOBK              */
 };
 
 static const char * const DefSysColors95[] =
@@ -64,11 +68,15 @@
     "GrayText", "192 192 192",       /* COLOR_GRAYTEXT            */
     "ButtonText", "0 0 0",           /* COLOR_BTNTEXT             */
     "InactiveTitleText", "0 0 0",    /* COLOR_INACTIVECAPTIONTEXT */
-    "ButtonHilight", "255 255 255"   /* COLOR_BTNHIGHLIGHT        */
+    "ButtonHilight", "255 255 255",  /* COLOR_BTNHIGHLIGHT        */
+    "3DDarkShadow", "32 32 32",      /* COLOR_3DDKSHADOW          */
+    "3DLight", "192 192 192",        /* COLOR_3DLIGHT             */
+    "InfoText", "0 0 0",             /* COLOR_INFOTEXT            */
+    "InfoBackground", "255 255 192"  /* COLOR_INFOBK              */
 };
 
 
-#define NUM_SYS_COLORS     (COLOR_BTNHIGHLIGHT+1)
+#define NUM_SYS_COLORS     (COLOR_INFOBK+1)
 
 static COLORREF SysColors[NUM_SYS_COLORS];
 
@@ -80,6 +88,7 @@
  */
 static void SYSCOLOR_SetColor( int index, COLORREF color )
 {
+    if (index < 0 || index >= NUM_SYS_COLORS) return;
     SysColors[index] = color;
     switch(index)
     {
@@ -149,6 +158,11 @@
 	DeleteObject32( sysColorObjects.hbrushBtnHighlight );
 	sysColorObjects.hbrushBtnHighlight = CreateSolidBrush32( color );
 	break;
+    case COLOR_3DDKSHADOW:
+    case COLOR_3DLIGHT:
+    case COLOR_INFOTEXT:
+    case COLOR_INFOBK:
+	break;
     }
 }
 
@@ -166,7 +180,7 @@
 	 i < NUM_SYS_COLORS; i++, p += 2)
     {
 	GetProfileString32A( "colors", p[0], p[1], buffer, 100 );
-	if (!sscanf( buffer, " %d %d %d", &r, &g, &b )) r = g = b = 0;
+	if (sscanf( buffer, " %d %d %d", &r, &g, &b ) != 3) r = g = b = 0;
 	SYSCOLOR_SetColor( i, RGB(r,g,b) );
     }
 }
@@ -177,7 +191,7 @@
  */
 COLORREF WINAPI GetSysColor16( INT16 nIndex )
 {
-    return SysColors[nIndex];
+    return GetSysColor32 (nIndex);
 }
 
 
@@ -186,15 +200,19 @@
  */
 COLORREF WINAPI GetSysColor32( INT32 nIndex )
 {
-    return SysColors[nIndex];
+    if (nIndex >= 0 && nIndex < NUM_SYS_COLORS)
+	return SysColors[nIndex];
+    else
+	return 0;
 }
 
 
 /*************************************************************************
  *             SetSysColors16   (USER.181)
  */
+/* FIXME -- check return type and insert comment if correct.  */
 VOID WINAPI SetSysColors16( INT16 nChanges, const INT16 *lpSysColor,
-                            const COLORREF *lpColorValues )
+			    const COLORREF *lpColorValues )
 {
     int i;
 
diff --git a/windows/user.c b/windows/user.c
index 8c7c9a5..90e7567 100644
--- a/windows/user.c
+++ b/windows/user.c
@@ -8,6 +8,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "windows.h"
+#include "resource.h"
 #include "heap.h"
 #include "gdi.h"
 #include "user.h"
@@ -22,6 +23,8 @@
 
 WORD USER_HeapSel = 0;
 
+extern HGLOBAL16 LoadDIBCursorHandler( HGLOBAL16, HINSTANCE16, HRSRC16 );
+extern HGLOBAL16 LoadDIBIconHandler( HGLOBAL16, HINSTANCE16, HRSRC16 );
 extern BOOL32 MENU_PatchResidentPopup( HQUEUE16, WND* );
 extern void QUEUE_FlushMessages(HQUEUE16);
 
@@ -93,6 +96,35 @@
     return TRUE;
 }
 
+static RESOURCEHANDLER16 __r16loader = NULL;
+
+/**********************************************************************
+ *           USER_CallDefaultRsrcHandler
+ *
+ * Called by the LoadDIBIcon/CursorHandler().
+ */
+HGLOBAL16 USER_CallDefaultRsrcHandler( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc )
+{
+    return __r16loader( hMemObj, hModule, hRsrc );
+}
+
+/**********************************************************************
+ *           USER_InstallRsrcHandler
+ */
+static void USER_InstallRsrcHandler( HINSTANCE16 hInstance )
+{
+    FARPROC16 proc;
+
+    /* SetResourceHandler() returns previous function which is set
+     * when a module's resource table is loaded. */
+
+    proc = SetResourceHandler( hInstance, RT_ICON, (FARPROC32)LoadDIBIconHandler );
+    if(!__r16loader ) 
+	__r16loader = (RESOURCEHANDLER16)proc;
+    proc = SetResourceHandler( hInstance, RT_CURSOR, (FARPROC32)LoadDIBCursorHandler );
+    if(!__r16loader )
+	__r16loader = (RESOURCEHANDLER16)proc;
+}
 
 /**********************************************************************
  *           InitApp   (USER.5)
@@ -101,6 +133,15 @@
 {
     int queueSize;
 
+      /* InitTask() calls LibMain()'s of implicitly loaded DLLs 
+       * prior to InitApp() so there is no clean way to do
+       * SetTaskSignalHandler() in time. So, broken Windows bypasses 
+       * a pTask->userhandler on startup and simply calls a global 
+       * function pointer to the default USER signal handler.
+       */
+
+    USER_InstallRsrcHandler( hInstance );
+
       /* Create task message queue */
     queueSize = GetProfileInt32A( "windows", "DefaultQueueSize", 8 );
     if (!SetMessageQueue32( queueSize )) return 0;
@@ -109,9 +150,18 @@
 }
 
 /**********************************************************************
+ *           USER_ModuleUnload
+ */
+static void USER_ModuleUnload( HMODULE16 hModule )
+{
+    HOOK_FreeModuleHooks( hModule );
+    CLASS_FreeModuleClasses( hModule );
+}
+
+/**********************************************************************
  *           USER_AppExit
  */
-void USER_AppExit( HTASK16 hTask, HINSTANCE16 hInstance, HQUEUE16 hQueue )
+static void USER_AppExit( HTASK16 hTask, HINSTANCE16 hInstance, HQUEUE16 hQueue )
 {
     /* FIXME: empty clipboard if needed, maybe destroy menus (Windows
      *	      only complains about them but does nothing);
@@ -132,12 +182,18 @@
     HOOK_FreeQueueHooks( hQueue );
 
     QUEUE_SetExitingQueue( hQueue );
-    WIN_ResetQueueWindows( desktop->child, hQueue, (HQUEUE16)0);
+    WIN_ResetQueueWindows( desktop, hQueue, (HQUEUE16)0);
     QUEUE_SetExitingQueue( 0 );
 
     /* Free the message queue */
 
     QUEUE_DeleteMsgQueue( hQueue );
+
+    /* ModuleUnload() in "Internals" */
+
+    hInstance = GetExePtr( hInstance );
+    if( GetModuleUsage( hInstance ) <= 1 ) 
+	USER_ModuleUnload( hInstance );
 }
 
 
@@ -160,6 +216,34 @@
 
 
 /***********************************************************************
+ *           USER_SignalProc (USER.314)
+ */
+void WINAPI USER_SignalProc( HANDLE16 hTaskOrModule, UINT16 uCode,
+                             UINT16 uExitFn, HINSTANCE16 hInstance,
+                             HQUEUE16 hQueue )
+{
+    switch( uCode )
+    {
+	case USIG_GPF:
+	case USIG_TERMINATION:
+	     USER_AppExit( hTaskOrModule, hInstance, hQueue ); /* task */
+	     break;
+
+	case USIG_DLL_LOAD:
+	     USER_InstallRsrcHandler( hTaskOrModule ); /* module */
+	     break;
+
+	case USIG_DLL_UNLOAD:
+	     USER_ModuleUnload( hTaskOrModule ); /* module */
+	     break;
+
+	default:
+	     fprintf(stderr,"Unimplemented USER signal: %i\n", (int)uCode );
+    }
+}
+
+
+/***********************************************************************
  *           ExitWindows16   (USER.7)
  */
 BOOL16 WINAPI ExitWindows16( DWORD dwReturnCode, UINT16 wReserved )
diff --git a/windows/win.c b/windows/win.c
index 9f4375b..22d8eaf 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -270,41 +270,6 @@
 
 
 /***********************************************************************
- *           WIN_SendParentNotify
- *
- * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
- * the window has the WS_EX_NOPARENTNOTIFY style.
- */
-void WIN_SendParentNotify(HWND32 hwnd, WORD event, WORD idChild, LPARAM lValue)
-{
-    LPPOINT16 lppt = (LPPOINT16)&lValue;
-    WND     *wndPtr = WIN_FindWndPtr( hwnd );
-    BOOL32 bMouse = ((event <= WM_MOUSELAST) && (event >= WM_MOUSEFIRST));
-
-    /* if lValue contains cursor coordinates they have to be
-     * mapped to the client area of parent window */
-
-    if (bMouse) MapWindowPoints16( 0, hwnd, lppt, 1 );
-
-    while (wndPtr)
-    {
-        if ((wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) ||
-	   !(wndPtr->dwStyle & WS_CHILD)) break;
-
-        if (bMouse)
-        {
-	    lppt->x += wndPtr->rectClient.left;
-	    lppt->y += wndPtr->rectClient.top;
-        }
-
-        wndPtr = wndPtr->parent;
-	SendMessage32A( wndPtr->hwndSelf, WM_PARENTNOTIFY, 
-                        MAKEWPARAM( event, idChild ), lValue );
-    }
-}
-
-
-/***********************************************************************
  *           WIN_DestroyWindow
  *
  * Destroy storage associated to a window. "Internals" p.358
@@ -377,20 +342,50 @@
 
 /***********************************************************************
  *           WIN_ResetQueueWindows
+ *
+ * Reset the queue of all the children of a given window.
+ * Return TRUE if something was done.
  */
-void WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew )
+BOOL32 WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew )
 {
-    WND* next;
+    BOOL32 ret = FALSE;
 
-    while (wnd)
+    if (hNew)  /* Set a new queue */
     {
-        next = wnd->next;
-        if (wnd->hmemTaskQ == hQueue)
-	   if( hNew ) wnd->hmemTaskQ = hNew;
-	   else DestroyWindow32( wnd->hwndSelf );
-        else WIN_ResetQueueWindows( wnd->child, hQueue, hNew );
-        wnd = next;
+        for (wnd = wnd->child; (wnd); wnd = wnd->next)
+        {
+            if (wnd->hmemTaskQ == hQueue)
+            {
+                wnd->hmemTaskQ = hNew;
+                ret = TRUE;
+            }
+            if (wnd->child)
+                ret |= WIN_ResetQueueWindows( wnd->child, hQueue, hNew );
+        }
     }
+    else  /* Queue is being destroyed */
+    {
+        while (wnd->child)
+        {
+            WND *tmp = wnd->child;
+            ret = FALSE;
+            while (tmp)
+            {
+                if (tmp->hmemTaskQ == hQueue)
+                {
+                    DestroyWindow32( tmp->hwndSelf );
+                    ret = TRUE;
+                    break;
+                }
+                if (tmp->child && WIN_ResetQueueWindows(tmp->child,hQueue,0))
+                    ret = TRUE;
+                else
+                    tmp = tmp->next;
+            }
+            if (!ret) break;
+        }
+    }
+    return ret;
 }
 
 /***********************************************************************
@@ -465,7 +460,7 @@
     WND *wndPtr;
     HWND16 hwnd, hwndLinkAfter;
     POINT32 maxSize, maxPos, minTrack, maxTrack;
-    LRESULT (*localSend32)(HWND32, UINT32, WPARAM32, LPARAM);
+    LRESULT (WINAPI *localSend32)(HWND32, UINT32, WPARAM32, LPARAM);
 
     dprintf_win( stddeb, "CreateWindowEx: " );
     if (HIWORD(cs->lpszName)) dprintf_win( stddeb, "'%s' ", cs->lpszName );
@@ -495,9 +490,7 @@
     }
 
     /* Find the window class */
-
-    if (!(classPtr = CLASS_FindClassByAtom( classAtom,
-                                            GetExePtr(cs->hInstance) )))
+    if (!(classPtr = CLASS_FindClassByAtom( classAtom, win32?cs->hInstance:GetExePtr(cs->hInstance) )))
     {
         char buffer[256];
         GlobalGetAtomName32A( classAtom, buffer, sizeof(buffer) );
@@ -703,8 +696,11 @@
                        LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
                        LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
 #else
-            SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
-            if (menuName) cs->hMenu = LoadMenu16( cs->hInstance, menuName );
+	    SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
+	    if (HIWORD(cs->hInstance))
+	    	cs->hMenu = LoadMenu32A(cs->hInstance,PTR_SEG_TO_LIN(menuName));
+	    else
+	    	cs->hMenu = LoadMenu16(cs->hInstance,menuName);
 #endif
         }
         if (cs->hMenu) SetMenu32( hwnd, cs->hMenu );
@@ -732,6 +728,7 @@
             if (!(wndPtr->flags & WIN_NEED_SIZE))
             {
                 /* send it anyway */
+
                 SendMessage32A( hwnd, WM_SIZE, SIZE_RESTORED,
                                 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
                                          wndPtr->rectClient.bottom-wndPtr->rectClient.top));
@@ -740,27 +737,27 @@
                                           wndPtr->rectClient.top ) );
             }
 
-            WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LPARAM)hwnd );
-            if (!IsWindow32(hwnd)) return 0;
-
             /* Show the window, maximizing or minimizing if needed */
 
-            if (wndPtr->dwStyle & WS_MINIMIZE)
+            if (wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE))
             {
 		RECT16 newPos;
+		UINT16 swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
                 wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
-		WINPOS_MinMaximize( wndPtr, SW_MINIMIZE, &newPos );
-                SetWindowPos32( hwnd, 0, newPos.left, newPos.top, newPos.right, newPos.bottom,
-                                SWP_FRAMECHANGED | ((GetActiveWindow32())? SWP_NOACTIVATE : 0));
+		WINPOS_MinMaximize( wndPtr, swFlag, &newPos );
+		swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow32()) ? SWP_NOACTIVATE : 0;
+                SetWindowPos32( hwnd, 0, newPos.left, newPos.top, 
+					 newPos.right, newPos.bottom, SWP_FRAMECHANGED | swFlag );
             }
-            else if (wndPtr->dwStyle & WS_MAXIMIZE)
-            {
-		RECT16 newPos;
-		wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
-		WINPOS_MinMaximize( wndPtr, SW_MAXIMIZE, &newPos );
-                SetWindowPos32( hwnd, 0, newPos.left, newPos.top, newPos.right, newPos.bottom,
-                    ((GetActiveWindow32())? SWP_NOACTIVATE : 0) | SWP_FRAMECHANGED );
-            }
+
+	    if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
+	    {
+		/* Notify the parent window only */
+
+		SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
+				MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
+		if( !IsWindow32(hwnd) ) return 0;
+	    }
 
             if (cs->style & WS_VISIBLE) ShowWindow32( hwnd, SW_SHOW );
 
@@ -1000,8 +997,13 @@
     }
 
     if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) )
-	 WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LPARAM)hwnd );
-    if (!IsWindow32(hwnd)) return TRUE;
+	if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
+	{
+	    /* Notify the parent window only */
+	    SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
+			    MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd );
+	    if( !IsWindow32(hwnd) ) return TRUE;
+	}
 
     if( wndPtr->window ) CLIPBOARD_DisOwn( wndPtr ); /* before window is unmapped */
 
@@ -1020,7 +1022,7 @@
     if( !(wndPtr->dwStyle & WS_CHILD) )
     {
       /* make sure top menu popup doesn't get destroyed */
-      MENU_PatchResidentPopup( TRUE, wndPtr );
+      MENU_PatchResidentPopup( (HQUEUE16)0xFFFF, wndPtr );
 
       for (;;)
       {
@@ -1214,7 +1216,7 @@
         /* with this name exists either. */
         if (!(atom = GlobalFindAtom32A( className ))) return 0;
     }
-    return WIN_FindWindow( 0, 0, atom, title );
+    return WIN_FindWindow( parent, child, atom, title );
 }
 
 
@@ -1235,7 +1237,7 @@
         if (!(atom = GlobalFindAtom32W( className ))) return 0;
     }
     buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
-    hwnd = WIN_FindWindow( 0, 0, atom, buffer );
+    hwnd = WIN_FindWindow( parent, child, atom, buffer );
     HeapFree( GetProcessHeap(), 0, buffer );
     return hwnd;
 }
@@ -1388,9 +1390,15 @@
     }
     switch(offset)
     {
-    case GWW_ID:         return (WORD)wndPtr->wIDmenu;
+    case GWW_ID:         
+    	if (HIWORD(wndPtr->wIDmenu))
+    		fprintf(stderr,"GetWindowWord32(GWW_ID) discards high bits of 0x%08x!\n",wndPtr->wIDmenu);
+    	return (WORD)wndPtr->wIDmenu;
     case GWW_HWNDPARENT: return wndPtr->parent ? wndPtr->parent->hwndSelf : 0;
-    case GWW_HINSTANCE:  return (WORD)wndPtr->hInstance;
+    case GWW_HINSTANCE:  
+    	if (HIWORD(wndPtr->hInstance))
+    		fprintf(stderr,"GetWindowWord32(GWW_HINSTANCE) discards high bits of 0x%08x!\n",wndPtr->hInstance);
+   	return (WORD)wndPtr->hInstance;
     default:
         fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
         return 0;
@@ -1401,10 +1409,10 @@
 /**********************************************************************
  *	     WIN_GetWindowInstance
  */
-HINSTANCE16 WIN_GetWindowInstance( HWND32 hwnd )
+HINSTANCE32 WIN_GetWindowInstance( HWND32 hwnd )
 {
     WND * wndPtr = WIN_FindWndPtr( hwnd );
-    if (!wndPtr) return (HINSTANCE16)0;
+    if (!wndPtr) return (HINSTANCE32)0;
     return wndPtr->hInstance;
 }
 
@@ -1483,7 +1491,7 @@
                                                            type );
         case GWL_HWNDPARENT: return wndPtr->parent ?
                                         (HWND32)wndPtr->parent->hwndSelf : 0;
-        case GWL_HINSTANCE:  return (HINSTANCE32)wndPtr->hInstance;
+        case GWL_HINSTANCE:  return wndPtr->hInstance;
         default:
             fprintf( stderr, "GetWindowLong: unknown offset %d\n", offset );
     }
@@ -1501,6 +1509,7 @@
 {
     LONG *ptr, retval;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
+
     if (!wndPtr) return 0;
     if (offset >= 0)
     {
@@ -1522,8 +1531,10 @@
     else switch(offset)
     {
         case GWL_ID:
+	    ptr = (DWORD*)&wndPtr->wIDmenu;
+	    break;
         case GWL_HINSTANCE:
-            return SetWindowWord32( hwnd, offset, (WORD)newval );
+            return SetWindowWord32( hwnd, offset, newval );
 	case GWL_WNDPROC:
             retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
             WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval, 
diff --git a/windows/winhelp.c b/windows/winhelp.c
index 856d2d5..89be98b 100644
--- a/windows/winhelp.c
+++ b/windows/winhelp.c
@@ -52,11 +52,12 @@
 	switch(wCommand)
 	{
 		case HELP_CONTEXT:
-		case HELP_CONTENTS:
 		case HELP_SETCONTENTS:
+		case HELP_CONTENTS:
 		case HELP_CONTEXTPOPUP:
 		case HELP_FORCEFILE:
 		case HELP_HELPONHELP:
+		case HELP_FINDER:
 		case HELP_QUIT:
 			dsize=0;
 			break;
diff --git a/windows/winpos.c b/windows/winpos.c
index e418e7e..b7cadcb 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -274,10 +274,9 @@
 /*******************************************************************
  *         ClientToScreen16   (USER.28)
  */
-BOOL16 WINAPI ClientToScreen16( HWND16 hwnd, LPPOINT16 lppnt )
+void WINAPI ClientToScreen16( HWND16 hwnd, LPPOINT16 lppnt )
 {
     MapWindowPoints16( hwnd, 0, lppnt, 1 );
-    return TRUE;
 }
 
 
@@ -1566,14 +1565,19 @@
  */
 LONG WINPOS_HandleWindowPosChanging16( WND *wndPtr, WINDOWPOS16 *winpos )
 {
-    POINT32 maxSize;
+    POINT32 maxSize, minTrack;
     if (winpos->flags & SWP_NOSIZE) return 0;
     if ((wndPtr->dwStyle & WS_THICKFRAME) ||
 	((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) == 0))
     {
-	WINPOS_GetMinMaxInfo( wndPtr, &maxSize, NULL, NULL, NULL );
-	winpos->cx = MIN( winpos->cx, maxSize.x );
-	winpos->cy = MIN( winpos->cy, maxSize.y );
+	WINPOS_GetMinMaxInfo( wndPtr, &maxSize, NULL, &minTrack, NULL );
+	if (maxSize.x < winpos->cx) winpos->cx = maxSize.x;
+	if (maxSize.y < winpos->cy) winpos->cy = maxSize.y;
+	if (!(wndPtr->dwStyle & WS_MINIMIZE))
+	{
+	    if (winpos->cx < minTrack.x ) winpos->cx = minTrack.x;
+	    if (winpos->cy < minTrack.y ) winpos->cy = minTrack.y;
+	}
     }
     return 0;
 }
@@ -2380,14 +2384,19 @@
     int i;
     HDWP32 newhdwp = hdwp;
     HWND32 parent;
+    WND *pWnd;
 
     pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
     if (!pDWP) return 0;
     if (hwnd == GetDesktopWindow32()) return 0;
 
-      /* All the windows of a DeferWindowPos() must have the same parent */
-
-    parent = WIN_FindWndPtr( hwnd )->parent->hwndSelf;
+    /* All the windows of a DeferWindowPos() must have the same parent */
+    if (!(pWnd=WIN_FindWndPtr( hwnd ))) {
+        USER_HEAP_FREE( hdwp );
+        return 0;
+    }
+    	
+    parent = pWnd->parent->hwndSelf;
     if (pDWP->actualCount == 0) pDWP->hwndParent = parent;
     else if (parent != pDWP->hwndParent)
     {
diff --git a/windows/winproc.c b/windows/winproc.c
index b2a9207..267029e 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -42,11 +42,6 @@
     BYTE       pushl_func;           /* pushl $proc */
     WNDPROC16  proc WINE_PACKED;
     BYTE       pushl_eax;            /* pushl %eax */
-    BYTE       pushl_ebp;            /* pushl %ebp */
-    BYTE       pushl_name;           /* pushl $name */
-    LPCSTR     name WINE_PACKED;
-    BYTE       pushl_thunk;          /* pushl $thunkfrom32 */
-    void     (*thunk32)() WINE_PACKED;
     BYTE       jmp;                  /* jmp   relay (relative jump)*/
     void     (*relay)() WINE_PACKED; /* WINPROC_CallProc32ATo16() */
 } WINPROC_THUNK_FROM32;
@@ -87,15 +82,14 @@
 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
                                  WPARAM16 wParam, LPARAM lParam,
                                  WNDPROC32 func );
-static LRESULT WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
-                                        UINT32 msg, WPARAM32 wParam,
-                                        LPARAM lParam );
-static LRESULT WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
-                                        UINT32 msg, WPARAM32 wParam,
-                                        LPARAM lParam );
+static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
+                                               UINT32 msg, WPARAM32 wParam,
+                                               LPARAM lParam );
+static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
+                                               UINT32 msg, WPARAM32 wParam,
+                                               LPARAM lParam );
 
 extern void CallFrom16_long_wwwll(void);
-extern void CallFrom32_stdcall_5(void);
 
 static HANDLE32 WinProcHeap;
 
@@ -105,7 +99,6 @@
                                       WPARAM32 wParam, LPARAM lParam );
 
 static WINPROC_CALLWNDPROC16 WINPROC_CallWndProc16Ptr = WINPROC_CallWndProc16;
-static WINPROC_CALLWNDPROC32 WINPROC_CallWndProc32Ptr = WINPROC_CallWndProc32;
 
 
 /**********************************************************************
@@ -143,8 +136,8 @@
 static LRESULT WINPROC_CallWndProc32( WNDPROC32 proc, HWND32 hwnd, UINT32 msg,
                                       WPARAM32 wParam, LPARAM lParam )
 {
-/*  dprintf_relay( stddeb, "CallTo32(wndproc=%p,hwnd=%08x,msg=%08x,wp=%08x,lp=%08lx)\n",
-                   proc, hwnd, msg, wParam, lParam ); */
+    dprintf_relay( stddeb, "CallTo32(wndproc=%p,hwnd=%08x,msg=%08x,wp=%08x,lp=%08lx)\n",
+                   proc, hwnd, msg, wParam, lParam );
     return proc( hwnd, msg, wParam, lParam );
 }
 
@@ -159,15 +152,6 @@
 
 
 /**********************************************************************
- *	     WINPROC_SetCallWndProc32
- */
-void WINPROC_SetCallWndProc32( WINPROC_CALLWNDPROC32 proc )
-{
-    WINPROC_CallWndProc32Ptr = proc;
-}
-
-
-/**********************************************************************
  *	     WINPROC_GetPtr
  *
  * Return a pointer to the win proc.
@@ -238,14 +222,9 @@
             proc->thunk.t_from32.pushl_func  = 0x68;   /* pushl $proc */
             proc->thunk.t_from32.proc        = func;
             proc->thunk.t_from32.pushl_eax   = 0x50;   /* pushl %eax */
-            proc->thunk.t_from32.pushl_ebp   = 0x55;   /* pushl %ebp */
-            proc->thunk.t_from32.pushl_name  = 0x68;   /* pushl $name */
-            proc->thunk.t_from32.name        = "WINPROC_CallProc32ATo16";
-            proc->thunk.t_from32.pushl_thunk = 0x68;   /* pushl $thunkfrom32 */
-            proc->thunk.t_from32.thunk32     = (void(*)())WINPROC_CallProc32ATo16;
             proc->thunk.t_from32.jmp         = 0xe9;   /* jmp   relay*/
             proc->thunk.t_from32.relay =  /* relative jump */
-                (void (*)())((DWORD)CallFrom32_stdcall_5 -
+                (void(*)())((DWORD)WINPROC_CallProc32ATo16 -
                                      (DWORD)(&proc->thunk.t_from32.relay + 1));
             break;
         case WIN_PROC_32A:
@@ -1723,7 +1702,7 @@
     LRESULT result;
 
     if (WINPROC_MapMsg32ATo32W( msg, wParam, &lParam ) == -1) return 0;
-    result = WINPROC_CallWndProc32Ptr( func, hwnd, msg, wParam, lParam );
+    result = WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
     WINPROC_UnmapMsg32ATo32W( msg, wParam, lParam );
     return result;
 }
@@ -1741,7 +1720,7 @@
     LRESULT result;
 
     if (WINPROC_MapMsg32WTo32A( msg, wParam, &lParam ) == -1) return 0;
-    result = WINPROC_CallWndProc32Ptr( func, hwnd, msg, wParam, lParam );
+    result = WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
     WINPROC_UnmapMsg32WTo32A( msg, wParam, lParam );
     return result;
 }
@@ -1762,7 +1741,7 @@
 
     if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
         return 0;
-    result = WINPROC_CallWndProc32Ptr( func, hwnd, msg32, wParam32, lParam );
+    result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
     WINPROC_UnmapMsg16To32A( msg32, wParam32, lParam );
     return result;
 }
@@ -1783,7 +1762,7 @@
 
     if (WINPROC_MapMsg16To32W( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
         return 0;
-    result = WINPROC_CallWndProc32Ptr( func, hwnd, msg32, wParam32, lParam );
+    result = WINPROC_CallWndProc32( func, hwnd, msg32, wParam32, lParam );
     WINPROC_UnmapMsg16To32W( msg32, wParam32, lParam );
     return result;
 }
@@ -1794,9 +1773,9 @@
  *
  * Call a 16-bit window procedure, translating the 32-bit args.
  */
-static LRESULT WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
-                                        UINT32 msg, WPARAM32 wParam,
-                                        LPARAM lParam )
+static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
+                                               UINT32 msg, WPARAM32 wParam,
+                                               LPARAM lParam )
 {
     UINT16 msg16;
     MSGPARAM16 mp16;
@@ -1821,9 +1800,9 @@
  *
  * Call a 16-bit window procedure, translating the 32-bit args.
  */
-static LRESULT WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
-                                        UINT32 msg, WPARAM32 wParam,
-                                        LPARAM lParam )
+static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
+                                               UINT32 msg, WPARAM32 wParam,
+                                               LPARAM lParam )
 {
     UINT16 msg16;
     MSGPARAM16 mp16;
@@ -1906,12 +1885,11 @@
 {
     WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
 
-    if (!proc) return WINPROC_CallWndProc32Ptr( func, hwnd, msg,
-                                                wParam, lParam );
+    if (!proc) return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
 
 #if testing
     func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
-    return WINPROC_CallWndProc32Ptr( func, hwnd, msg, wParam, lParam );
+    return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
 #endif
 
     switch(proc->type)
@@ -1922,8 +1900,8 @@
                                         hwnd, msg, wParam, lParam );
     case WIN_PROC_32A:
         if (!proc->thunk.t_from16.proc) return 0;
-        return WINPROC_CallWndProc32Ptr( proc->thunk.t_from16.proc,
-                                         hwnd, msg, wParam, lParam );
+        return WINPROC_CallWndProc32( proc->thunk.t_from16.proc,
+                                      hwnd, msg, wParam, lParam );
     case WIN_PROC_32W:
         if (!proc->thunk.t_from16.proc) return 0;
         return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
@@ -1943,12 +1921,11 @@
 {
     WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
 
-    if (!proc) return WINPROC_CallWndProc32Ptr( func, hwnd, msg,
-                                                wParam, lParam );
+    if (!proc) return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
 
 #if testing
     func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
-    return WINPROC_CallWndProc32Ptr( func, hwnd, msg, wParam, lParam );
+    return WINPROC_CallWndProc32( func, hwnd, msg, wParam, lParam );
 #endif
 
     switch(proc->type)
@@ -1963,8 +1940,8 @@
                                          hwnd, msg, wParam, lParam );
     case WIN_PROC_32W:
         if (!proc->thunk.t_from16.proc) return 0;
-        return WINPROC_CallWndProc32Ptr( proc->thunk.t_from16.proc,
-                                         hwnd, msg, wParam, lParam );
+        return WINPROC_CallWndProc32( proc->thunk.t_from16.proc,
+                                      hwnd, msg, wParam, lParam );
     default:
         fprintf( stderr, "CallWindowProc32W: invalid proc %p\n", proc );
         return 0;