Release 970215

Sat Feb 15 11:59:17 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [*/*]
	Converted a lot of functions to Win32 types.
	Removed HWND type.

Fri Feb 14 15:09:19 1997  Onno Hovers <onno@stack.nl>

	* [memory/global.c]
	Implemented GMEM_MOVEABLE blocks for Win32.

Fri Feb 14 00:24:39 1997  Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [loader/task.c] [windows/queue.c]
	Do not read X events while in the intertask SendMessage().

	* [misc/lstr.c]
	Fixed CharPrev32A().

	* [windows/hook.c] [include/hook.h]
	Restored broken WH_CALLWNDPROC functionality for dialogs, etc...

	* [windows/win.c] [windows/defwnd.c] [windows/mdi.c]
	  [windows/event.c] [controls/edit.c] 
	Added WIN_ISWIN32 flag to windows created by Win32 calls. 
	Several new Win32 messages are sent when this flag is on.
	
	* [msdos/dosmem.c] [memory/global.c]
	Some changes in DOS memory allocation.

Fri Feb  7 21:46:03 1997  Andrew Taylor  <andrew@riscan.com>

	* [win32/security.c]
	Added SID manipulation functions.

	* [include/debug.h]
	Added debugging class "security".

Fri  Feb 7 20:46:33 1997  Robert Pouliot <krynos@clic.net>

	* [debugger/msc.c] [debugger/source.c] 
	  [documentation/wine_os2.txt] [loader/signal.c]
	Some more changes for OS/2. Doesn't work yet.

Fri  Feb 7 09:31:17 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [scheduler/process.c]
	Added ExpandEnvironmentStrings*.

	* [misc/ntdll.c] [include/ntdll.h]
	Added some new functions.

	* [objects/cursoricon.c]
	CURSORICON_LoadHandler: check against some bizarre out of memory
	conditions.
	
	* [windows/mdi.c]
	Fixed DefFrameProc32*, added TranslateMDISysAccel32.

Wed Feb  5 01:31:05 1997  John Zero <john@globe.graphisoft.hu>

	* [resources/sysres_Hu.rc] [misc/ole2nls.c] [misc/main.c]
	  [programs/progman/Hu.rc] [programs/winhelp/Hu.rc]
	Added Hungarian language support.
diff --git a/windows/caret.c b/windows/caret.c
index 2419d96..0fdc6ef 100644
--- a/windows/caret.c
+++ b/windows/caret.c
@@ -145,10 +145,11 @@
     }
     else
     {
-        Caret.width = width ? width : GetSystemMetrics(SM_CXBORDER);
-        Caret.height = height ? height : GetSystemMetrics(SM_CYBORDER);
-        Caret.hBrush = CreateSolidBrush32(bitmap ? GetSysColor(COLOR_GRAYTEXT):
-                                          GetSysColor(COLOR_WINDOW) );
+        Caret.width = width ? width : GetSystemMetrics32(SM_CXBORDER);
+        Caret.height = height ? height : GetSystemMetrics32(SM_CYBORDER);
+        Caret.hBrush = CreateSolidBrush32(bitmap ?
+                                          GetSysColor32(COLOR_GRAYTEXT) :
+                                          GetSysColor32(COLOR_WINDOW) );
     }
 
     Caret.hwnd = hwnd;
@@ -204,9 +205,18 @@
 
 
 /*****************************************************************
- *           HideCaret   (USER.166) (USER32.316)
+ *           HideCaret16   (USER.166)
  */
-BOOL16 HideCaret( HWND32 hwnd )
+BOOL16 HideCaret16( HWND16 hwnd )
+{
+    return HideCaret32( hwnd );
+}
+
+
+/*****************************************************************
+ *           HideCaret32   (USER32.316)
+ */
+BOOL32 HideCaret32( HWND32 hwnd )
 {
     if (!Caret.hwnd) return FALSE;
     if (hwnd && (Caret.hwnd != hwnd)) return FALSE;
@@ -222,9 +232,18 @@
 
 
 /*****************************************************************
- *           ShowCaret   (USER.167) (USER32.528)
+ *           ShowCaret16   (USER.167)
  */
-BOOL16 ShowCaret( HWND32 hwnd )
+BOOL16 ShowCaret16( HWND16 hwnd )
+{
+    return ShowCaret32( hwnd );
+}
+
+
+/*****************************************************************
+ *           ShowCaret32   (USER32.528)
+ */
+BOOL32 ShowCaret32( HWND32 hwnd )
 {
     if (!Caret.hwnd) return FALSE;
     if (hwnd && (Caret.hwnd != hwnd)) return FALSE;
diff --git a/windows/defdlg.c b/windows/defdlg.c
index 0ec5c44..d5d2f33 100644
--- a/windows/defdlg.c
+++ b/windows/defdlg.c
@@ -196,7 +196,7 @@
 	    return dlgInfo->hUserFont;
 
         case WM_CLOSE:
-            EndDialog( hwnd, TRUE );
+            EndDialog32( hwnd, TRUE );
             DestroyWindow32( hwnd );
             return 0;
     }
diff --git a/windows/defwnd.c b/windows/defwnd.c
index d408432..5581bf7 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -93,6 +93,25 @@
     case WM_NCLBUTTONDBLCLK:
 	return NC_HandleNCLButtonDblClk( wndPtr, wParam, lParam );
 
+    case WM_RBUTTONDOWN:
+    case WM_NCRBUTTONDOWN:
+        if( wndPtr->flags & WIN_ISWIN32 ) 
+        {
+	    ClientToScreen16(wndPtr->hwndSelf, (LPPOINT16)&lParam);
+            SendMessage32A( wndPtr->hwndSelf, WM_CONTEXTMENU,
+			    wndPtr->hwndSelf, lParam);
+        }
+        break;
+
+    case WM_CONTEXTMENU:
+	if( wndPtr->dwStyle & WS_CHILD )
+	    SendMessage32A( wndPtr->parent->hwndSelf, msg, wParam, lParam );
+
+     /* else 
+      *     FIXME: Track system popup if click was in the caption area. */
+
+	break;
+
     case WM_NCACTIVATE:
 	return NC_HandleNCActivate( wndPtr, wParam );
 
@@ -119,7 +138,7 @@
 			SYSMETRICS_CYICON)/2;
 		dprintf_win(stddeb,"Painting class icon: vis rect=(%i,%i - %i,%i)\n",
 		ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom );
-	        DrawIcon( hdc, x, y, wndPtr->class->hIcon );
+	        DrawIcon32( hdc, x, y, wndPtr->class->hIcon );
 	      }
 	      EndPaint16( wndPtr->hwndSelf, &ps );
 	    }
@@ -172,15 +191,12 @@
                                (HDC16)wParam, sysColorObjects.hbrushActiveCaption );
 		   return 1;
 		 }
-
-		 /* FIXME: should draw parent' background somehow
-			     (e.g for textured desktop) ? */
 	    }
 
 	    if (wndPtr->class->hbrBackground <= (HBRUSH16)(COLOR_MAX+1))
             {
                 HBRUSH32 hbrush = CreateSolidBrush32( 
-			 GetSysColor(((DWORD)wndPtr->class->hbrBackground)-1));
+                       GetSysColor32(((DWORD)wndPtr->class->hbrBackground)-1));
                  FillWindow( GetParent16(wndPtr->hwndSelf), wndPtr->hwndSelf,
                              (HDC16)wParam, hbrush);
                  DeleteObject32( hbrush );
@@ -199,8 +215,8 @@
     case WM_CTLCOLORBTN:
     case WM_CTLCOLORDLG:
     case WM_CTLCOLORSTATIC:
-        SetBkColor( (HDC32)wParam, GetSysColor(COLOR_WINDOW) );
-        SetTextColor( (HDC32)wParam, GetSysColor(COLOR_WINDOWTEXT) );
+        SetBkColor( (HDC32)wParam, GetSysColor32(COLOR_WINDOW) );
+        SetTextColor( (HDC32)wParam, GetSysColor32(COLOR_WINDOWTEXT) );
         return (LRESULT)sysColorObjects.hbrushWindow;
 
     case WM_CTLCOLORSCROLLBAR:
@@ -220,8 +236,8 @@
 	    }
 	    else
 	    {
-		SetBkColor( (HDC32)wParam, GetSysColor(COLOR_WINDOW) );
-		SetTextColor( (HDC32)wParam, GetSysColor(COLOR_WINDOWTEXT) );
+		SetBkColor( (HDC32)wParam, GetSysColor32(COLOR_WINDOW) );
+		SetTextColor( (HDC32)wParam, GetSysColor32(COLOR_WINDOWTEXT) );
 		return (LRESULT)sysColorObjects.hbrushWindow;
 	    }
 	}
@@ -293,7 +309,7 @@
                                (WPARAM16)SC_KEYMENU, (LPARAM)(DWORD)wParam );
         } 
 	else /* check for Ctrl-Esc */
-            if (wParam != VK_ESCAPE) MessageBeep(0);
+            if (wParam != VK_ESCAPE) MessageBeep32(0);
 	break;
 
     case WM_SHOWWINDOW:
diff --git a/windows/dialog.c b/windows/dialog.c
index 7be07fe..17d1680 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -745,10 +745,10 @@
     while (MSG_InternalGetMessage(&msg, hwnd, owner, MSGF_DIALOGBOX, PM_REMOVE,
                                   !(wndPtr->dwStyle & DS_NOIDLEMSG) ))
     {
-	if (!IsDialogMessage( hwnd, &msg))
+	if (!IsDialogMessage16( hwnd, &msg))
 	{
-	    TranslateMessage( &msg );
-	    DispatchMessage( &msg );
+	    TranslateMessage16( &msg );
+	    DispatchMessage16( &msg );
 	}
 	if (dlgInfo->fEnd) break;
     }
@@ -859,9 +859,18 @@
 
 
 /***********************************************************************
- *           EndDialog   (USER.88) (USER32.173)
+ *           EndDialog16   (USER32.173)
  */
-BOOL16 EndDialog( HWND32 hwnd, INT32 retval )
+BOOL16 EndDialog16( HWND16 hwnd, INT16 retval )
+{
+    return EndDialog32( hwnd, retval );
+}
+
+
+/***********************************************************************
+ *           EndDialog32   (USER32.173)
+ */
+BOOL32 EndDialog32( HWND32 hwnd, INT32 retval )
 {
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     DIALOGINFO * dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
@@ -873,40 +882,41 @@
 
 
 /***********************************************************************
- *           IsDialogMessage   (USER.90)
+ *           DIALOG_IsDialogMessage
  */
-BOOL16 IsDialogMessage( HWND16 hwndDlg, LPMSG16 msg )
+static BOOL32 DIALOG_IsDialogMessage( HWND32 hwnd, HWND32 hwndDlg,
+                                      UINT32 message, WPARAM32 wParam,
+                                      LPARAM lParam, BOOL32 *translate,
+                                      BOOL32 *dispatch )
 {
-    WND * wndPtr;
-    int dlgCode;
+    INT32 dlgCode;
 
-    if (!(wndPtr = WIN_FindWndPtr( hwndDlg ))) return FALSE;
-    if ((hwndDlg != msg->hwnd) && !IsChild16( hwndDlg, msg->hwnd )) return FALSE;
+    *translate = *dispatch = FALSE;
 
       /* Only the key messages get special processing */
-    if ((msg->message != WM_KEYDOWN) &&
-        (msg->message != WM_SYSCHAR) &&
-	(msg->message != WM_CHAR))
+    if ((message != WM_KEYDOWN) &&
+        (message != WM_SYSCHAR) &&
+	(message != WM_CHAR))
         return FALSE;
 
-    dlgCode = SendMessage16( msg->hwnd, WM_GETDLGCODE, 0, 0 );
+    dlgCode = SendMessage32A( hwnd, WM_GETDLGCODE, 0, 0 );
     if (dlgCode & DLGC_WANTMESSAGE)
     {
-        DispatchMessage( msg );
+        *dispatch = TRUE;
         return TRUE;
     }
 
-    switch(msg->message)
+    switch(message)
     {
     case WM_KEYDOWN:
         if (dlgCode & DLGC_WANTALLKEYS) break;
-        switch(msg->wParam)
+        switch(wParam)
         {
         case VK_TAB:
             if (!(dlgCode & DLGC_WANTTAB))
             {
-                SendMessage16( hwndDlg, WM_NEXTDLGCTL,
-                             (GetKeyState32(VK_SHIFT) & 0x8000), 0 );
+                SendMessage32A( hwndDlg, WM_NEXTDLGCTL,
+                                (GetKeyState32(VK_SHIFT) & 0x8000), 0 );
                 return TRUE;
             }
             break;
@@ -949,8 +959,9 @@
             }
             break;
 
-	default: 
-	    TranslateMessage( msg );
+	default:
+            *translate = TRUE;
+            break;
         }
         break;  /* case WM_KEYDOWN */
 
@@ -964,13 +975,70 @@
         break;
     }
 
-      /* If we get here, the message has not been treated specially */
-      /* and can be sent to its destination window. */
-    DispatchMessage( msg );
+    /* If we get here, the message has not been treated specially */
+    /* and can be sent to its destination window. */
+    *dispatch = TRUE;
     return TRUE;
 }
 
 
+/***********************************************************************
+ *           IsDialogMessage16   (USER.90)
+ */
+BOOL16 IsDialogMessage16( HWND16 hwndDlg, LPMSG16 msg )
+{
+    BOOL32 ret, translate, dispatch;
+
+    if ((hwndDlg != msg->hwnd) && !IsChild16( hwndDlg, msg->hwnd ))
+        return FALSE;
+
+    ret = DIALOG_IsDialogMessage( msg->hwnd, hwndDlg, msg->message,
+                                  msg->wParam, msg->lParam,
+                                  &translate, &dispatch );
+    if (translate) TranslateMessage16( msg );
+    if (dispatch) DispatchMessage16( msg );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           IsDialogMessage32A   (USER32.341)
+ */
+BOOL32 IsDialogMessage32A( HWND32 hwndDlg, LPMSG32 msg )
+{
+    BOOL32 ret, translate, dispatch;
+
+    if ((hwndDlg != msg->hwnd) && !IsChild32( hwndDlg, msg->hwnd ))
+        return FALSE;
+
+    ret = DIALOG_IsDialogMessage( msg->hwnd, hwndDlg, msg->message,
+                                  msg->wParam, msg->lParam,
+                                  &translate, &dispatch );
+    if (translate) TranslateMessage32( msg );
+    if (dispatch) DispatchMessage32A( msg );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           IsDialogMessage32W   (USER32.342)
+ */
+BOOL32 IsDialogMessage32W( HWND32 hwndDlg, LPMSG32 msg )
+{
+    BOOL32 ret, translate, dispatch;
+
+    if ((hwndDlg != msg->hwnd) && !IsChild32( hwndDlg, msg->hwnd ))
+        return FALSE;
+
+    ret = DIALOG_IsDialogMessage( msg->hwnd, hwndDlg, msg->message,
+                                  msg->wParam, msg->lParam,
+                                  &translate, &dispatch );
+    if (translate) TranslateMessage32( msg );
+    if (dispatch) DispatchMessage32W( msg );
+    return ret;
+}
+
+
 /****************************************************************
  *         GetDlgCtrlID16   (USER.277)
  */
diff --git a/windows/event.c b/windows/event.c
index d8e6dfb..4800aed 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -61,6 +61,7 @@
 static INT16  captureHT = HTCLIENT;
 static HWND32 captureWnd = 0;
 static BOOL32 InputEnabled = TRUE;
+static BOOL32 SwappedButtons = FALSE;
 
 static Atom wmProtocols = None;
 static Atom wmDeleteWindow = None;
@@ -84,23 +85,23 @@
 static void EVENT_ButtonPress( XButtonEvent *event );
 static void EVENT_ButtonRelease( XButtonEvent *event );
 static void EVENT_MotionNotify( XMotionEvent *event );
-static void EVENT_FocusIn( HWND hwnd, XFocusChangeEvent *event );
-static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event );
+static void EVENT_FocusIn( HWND32 hwnd, XFocusChangeEvent *event );
+static void EVENT_FocusOut( HWND32 hwnd, XFocusChangeEvent *event );
 static void EVENT_Expose( WND *pWnd, XExposeEvent *event );
 static void EVENT_GraphicsExpose( WND *pWnd, XGraphicsExposeEvent *event );
-static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event );
+static void EVENT_ConfigureNotify( HWND32 hwnd, XConfigureEvent *event );
 static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event);
 static void EVENT_SelectionNotify( XSelectionEvent *event);
 static void EVENT_SelectionClear( WND *pWnd, XSelectionClearEvent *event);
 static void EVENT_ClientMessage( WND *pWnd, XClientMessageEvent *event );
-static void EVENT_MapNotify( HWND hwnd, XMapEvent *event );
+static void EVENT_MapNotify( HWND32 hwnd, XMapEvent *event );
 
 /* Usable only with OLVWM - compile option perhaps?
 static void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event );
 */
 
 extern void FOCUS_SetXFocus( HWND32 );
-extern BOOL16 DRAG_QueryUpdate( HWND, SEGPTR, BOOL32 );
+extern BOOL16 DRAG_QueryUpdate( HWND16, SEGPTR, BOOL32 );
 
 /***********************************************************************
  *           EVENT_ProcessEvent
@@ -333,7 +334,8 @@
                             (char **)&pWnd ) || (event.type == NoExpose))
               continue;
 
-	  /* check for the "safe" hardware events */
+	  /* Check only for those events which can be processed
+	   * internally. */
 
 	  if( event.type == MotionNotify ||
 	      event.type == ButtonPress || event.type == ButtonRelease ||
@@ -491,6 +493,7 @@
     int buttonNum = event->button - 1;
 
     if (buttonNum >= NB_BUTTONS) return;
+    if (SwappedButtons) buttonNum = NB_BUTTONS - 1 - buttonNum;
     MouseButtonsStates[buttonNum] = 0x8000;
     AsyncMouseButtonsStates[buttonNum] = 0x8000;
     hardware_event( messages[buttonNum],
@@ -510,6 +513,7 @@
     int buttonNum = event->button - 1;
 
     if (buttonNum >= NB_BUTTONS) return;    
+    if (SwappedButtons) buttonNum = NB_BUTTONS - 1 - buttonNum;
     MouseButtonsStates[buttonNum] = FALSE;
     hardware_event( messages[buttonNum],
 		    EVENT_XStateToKeyState( event->state ), 0L,
@@ -521,7 +525,7 @@
 /**********************************************************************
  *              EVENT_FocusIn
  */
-static void EVENT_FocusIn (HWND hwnd, XFocusChangeEvent *event )
+static void EVENT_FocusIn( HWND32 hwnd, XFocusChangeEvent *event )
 {
     if (event->detail == NotifyPointer) return;
     if (hwnd != GetActiveWindow32()) WINPOS_ChangeActiveWindow( hwnd, FALSE );
@@ -535,7 +539,7 @@
  *
  * Note: only top-level override-redirect windows get FocusOut events.
  */
-static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event )
+static void EVENT_FocusOut( HWND32 hwnd, XFocusChangeEvent *event )
 {
     if (event->detail == NotifyPointer) return;
     if (hwnd == GetActiveWindow32()) WINPOS_ChangeActiveWindow( 0, FALSE );
@@ -543,6 +547,21 @@
         SetFocus32( 0 );
 }
 
+/**********************************************************************
+ *              EVENT_CheckFocus
+ */
+BOOL32 EVENT_CheckFocus(void)
+{
+    WND*   pWnd;
+    Window xW;
+    int	   state;
+
+    XGetInputFocus(display, &xW, &state);
+    if( xW == None ||
+        XFindContext(display, xW, winContext, (char **)&pWnd) ) 
+        return FALSE;
+    return TRUE;
+}
 
 /**********************************************************************
  *              EVENT_ConfigureNotify
@@ -550,7 +569,7 @@
  * The ConfigureNotify event is only selected on the desktop window
  * and on top-level windows when the -managed flag is used.
  */
-static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event )
+static void EVENT_ConfigureNotify( HWND32 hwnd, XConfigureEvent *event )
 {
     /* FIXME: with -desktop xxx we get this event _before_ desktop 
      * window structure is created. WIN_GetDesktop() check is a hack.
@@ -574,10 +593,6 @@
 	
         if (!(winpos = SEGPTR_NEW(WINDOWPOS16))) return;
 
-/*	XTranslateCoordinates(display, event->window, rootWindow,
-	    event->x, event->y, &event->x, &event->y, &child);
-            */
-
 	/* Fill WINDOWPOS struct */
 	winpos->flags = SWP_NOACTIVATE | SWP_NOZORDER;
 	winpos->hwnd = hwnd;
@@ -652,8 +667,8 @@
 	{
             /* open to make sure that clipboard is available */
 
-	    BOOL 	couldOpen = OpenClipboard( pWnd->hwndSelf );
-	    char*	lpstr = 0;
+	    BOOL32 couldOpen = OpenClipboard32( pWnd->hwndSelf );
+	    char* lpstr = 0;
 
 	    hText = GetClipboardData(CF_TEXT);
 	    text = GlobalLock16(hText);
@@ -677,7 +692,7 @@
 
 	    /* close only if we opened before */
 
-	    if(couldOpen) CloseClipboard();
+	    if(couldOpen) CloseClipboard32();
 	}
     }
 
@@ -858,7 +873,7 @@
 /**********************************************************************
  *		EVENT_MapNotify
  */
-void EVENT_MapNotify( HWND hWnd, XMapEvent *event )
+void EVENT_MapNotify( HWND32 hWnd, XMapEvent *event )
 {
     HWND32 hwndFocus = GetFocus32();
 
@@ -877,27 +892,36 @@
 HWND32 EVENT_Capture(HWND32 hwnd, INT16 ht)
 {
     Window win;
-    HWND32 old_capture_wnd = captureWnd;
+    HWND32 capturePrev = captureWnd;
 
     if (!hwnd)
     {
-        ReleaseCapture();
-        return old_capture_wnd;
+        XUngrabPointer(display, CurrentTime );
+        captureWnd = NULL; captureHT = 0; 
     }
-    if ((win = WIN_GetXWindow( hwnd )))
+    else if ((win = WIN_GetXWindow( hwnd )))
     {
-        if (XGrabPointer(display, win, False,
-                     ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
-                     GrabModeAsync, GrabModeAsync,
-                     None, None, CurrentTime ) == GrabSuccess)
+	WND* wndPtr = WIN_FindWndPtr( hwnd );
+
+        if ( wndPtr && 
+	     (XGrabPointer(display, win, False, 
+			   ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
+                           GrabModeAsync, GrabModeAsync,
+                           None, None, CurrentTime ) == GrabSuccess) )
 	{
-            dprintf_win(stddeb, "SetCapture: %04x\n", hwnd);
+            dprintf_win(stddeb, "SetCapture(0x%04x)\n", hwnd );
             captureWnd   = hwnd;
 	    captureHT    = ht;
-            return old_capture_wnd;
         }
     }
-    return 0;
+
+    if( capturePrev && capturePrev != captureWnd )
+    {
+	WND* wndPtr = WIN_FindWndPtr( capturePrev );
+        if( wndPtr && (wndPtr->flags & WIN_ISWIN32) )
+            SendMessage32A( capturePrev, WM_CAPTURECHANGED, 0L, hwnd);
+    }
+    return capturePrev;
 }
 
 /**********************************************************************
@@ -931,10 +955,8 @@
  */
 void ReleaseCapture(void)
 {
-    if (captureWnd == 0) return;
-    XUngrabPointer( display, CurrentTime );
-    captureWnd = 0;
-    dprintf_win(stddeb, "ReleaseCapture\n");
+    dprintf_win(stddeb, "ReleaseCapture() [%04x]\n", captureWnd );
+    if( captureWnd ) EVENT_Capture( 0, 0 );
 }
 
 
@@ -943,7 +965,7 @@
  */
 HWND16 GetCapture16(void)
 {
-    return (HWND16)captureWnd;
+    return captureWnd;
 }
 
 
@@ -1018,3 +1040,24 @@
   return bOldState;
 }
 
+
+/***********************************************************************
+ *	     SwapMouseButton16   (USER.186)
+ */
+BOOL16 SwapMouseButton16( BOOL16 fSwap )
+{
+    BOOL16 ret = SwappedButtons;
+    SwappedButtons = fSwap;
+    return ret;
+}
+
+
+/***********************************************************************
+ *	     SwapMouseButton32   (USER32.536)
+ */
+BOOL32 SwapMouseButton32( BOOL32 fSwap )
+{
+    BOOL32 ret = SwappedButtons;
+    SwappedButtons = fSwap;
+    return ret;
+}
diff --git a/windows/focus.c b/windows/focus.c
index f40c5db..06467a6 100644
--- a/windows/focus.c
+++ b/windows/focus.c
@@ -60,11 +60,21 @@
 {
     hwndFocus = hFocusTo;
 
+#if 0
     if (hFocusFrom) SendMessage32A( hFocusFrom, WM_KILLFOCUS, hFocusTo, 0 );
+#else
+    /* FIXME: must be SendMessage16() because 32A doesn't do
+     * intertask at this time */
+    if (hFocusFrom) SendMessage16( hFocusFrom, WM_KILLFOCUS, hFocusTo, 0 );
+#endif
     if( !hFocusTo || hFocusTo != hwndFocus )
 	return;
 
+#if 0
     SendMessage32A( hFocusTo, WM_SETFOCUS, hFocusFrom, 0 );
+#else
+    SendMessage16( hFocusTo, WM_SETFOCUS, hFocusFrom, 0 );
+#endif
     FOCUS_SetXFocus( hFocusTo );
 }
 
diff --git a/windows/hook.c b/windows/hook.c
index 1a9b793..59ffd20 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -22,6 +22,7 @@
 #include "user.h"
 #include "heap.h"
 #include "struct32.h"
+#include "winproc.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -35,8 +36,7 @@
     INT16      id;                 /* 06 Hook id (WH_xxx) */
     HQUEUE16   ownerQueue;         /* 08 Owner queue (0 for system hook) */
     HMODULE16  ownerModule;        /* 0a Owner module */
-    WORD       inHookProc;         /* 0c TRUE if in this->proc */
-    INT32      flags;
+    WORD       flags;              /* 0c flags */
 } HOOKDATA;
 
 #pragma pack(4)
@@ -50,33 +50,29 @@
 typedef VOID (*HOOK_UnMapFunc)(INT32, INT32, WPARAM32, LPARAM, WPARAM32,
 			       LPARAM);
 
-
-/***********************************************************************
- *           Hook Mapping Functions
- */
-
-
 /***********************************************************************
  *           HOOK_Map16To32Common
  */
 static void HOOK_Map16To32Common(INT32 id, INT32 code, WPARAM32 *pwParam,
-				 LPARAM *plParam)
+				 LPARAM *plParam, BOOL32 bA )
 {
-    switch (id)
-    {
-    case WH_MSGFILTER:
-    case WH_SYSMSGFILTER:
-    case WH_GETMESSAGE:
-    case WH_JOURNALRECORD:
+
+   switch( id )
+   {
+	case WH_MSGFILTER:
+	case WH_SYSMSGFILTER: 
+	case WH_GETMESSAGE: 
+	case WH_JOURNALRECORD:
         {
             LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(*plParam);
             LPMSG32 lpmsg32 = HeapAlloc( SystemHeap, 0, sizeof(*lpmsg32) );
 	
             STRUCT32_MSG16to32( lpmsg16, lpmsg32 );
             *plParam = (LPARAM)lpmsg32;
-            break;
-        }
-    case WH_JOURNALPLAYBACK:
+	    break;
+        } 
+
+	case WH_JOURNALPLAYBACK:
         {
             LPEVENTMSG16 lpem16 = PTR_SEG_TO_LIN(*plParam);
             LPEVENTMSG32 lpem32 = HeapAlloc( SystemHeap, 0, sizeof(*lpem32) );
@@ -88,12 +84,61 @@
             lpem32->hwnd = 0;	/* FIXME */
 
             *plParam = (LPARAM)lpem32;
-            break;
-        }
-    case WH_CBT:
-	switch (code)
+	    break;
+        } 
+
+	case WH_CALLWNDPROC:
 	{
-        case HCBT_ACTIVATE:
+	    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 );
+	    break;
+	}
+
+	case WH_CBT:
+	  switch (code)
+	  {
+	    case HCBT_CREATEWND:
+	    {
+		LPCBT_CREATEWND16  lpcbtcw16 = PTR_SEG_TO_LIN(*plParam);
+		LPCREATESTRUCT16   lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
+		LPCBT_CREATEWND32A lpcbtcw32 = HeapAlloc( SystemHeap, 0,
+							  sizeof(*lpcbtcw32) );
+		lpcbtcw32->lpcs = HeapAlloc( SystemHeap, 0,
+					     sizeof(*lpcbtcw32->lpcs) );
+
+		STRUCT32_CREATESTRUCT16to32A( lpcs16,
+					     (LPCREATESTRUCT32A)lpcbtcw32->lpcs );
+
+		if (HIWORD(lpcs16->lpszName))
+		    lpcbtcw32->lpcs->lpszName = 
+			(bA) ? PTR_SEG_TO_LIN(lpcs16->lpszName)
+			     : HEAP_strdupAtoW( SystemHeap, 0,
+                                                PTR_SEG_TO_LIN(lpcs16->lpszName) );
+		else
+		    lpcbtcw32->lpcs->lpszName = (LPCSTR)lpcs16->lpszName;
+
+		if (HIWORD(lpcs16->lpszClass))
+		    lpcbtcw32->lpcs->lpszClass =
+			(bA) ? PTR_SEG_TO_LIN(lpcs16->lpszClass)
+			     : HEAP_strdupAtoW( SystemHeap, 0,
+                                                PTR_SEG_TO_LIN(lpcs16->lpszClass) );
+		else
+		    lpcbtcw32->lpcs->lpszClass = (LPCSTR)lpcs16->lpszClass;
+
+		lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
+
+		*plParam = (LPARAM)lpcbtcw32;
+		break;
+	    } 
+	    case HCBT_ACTIVATE:
             {
                 LPCBTACTIVATESTRUCT16 lpcas16 = PTR_SEG_TO_LIN(*plParam);
                 LPCBTACTIVATESTRUCT32 lpcas32 = HeapAlloc( SystemHeap, 0,
@@ -103,7 +148,7 @@
                 *plParam = (LPARAM)lpcas32;
                 break;
             }
-        case HCBT_CLICKSKIPPED:
+            case HCBT_CLICKSKIPPED:
             {
                 LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
                 LPMOUSEHOOKSTRUCT32 lpms32 = HeapAlloc( SystemHeap, 0,
@@ -120,7 +165,7 @@
                 *plParam = (LPARAM)lpms32;
                 break;
             }
-        case HCBT_MOVESIZE:
+            case HCBT_MOVESIZE:
             {
                 LPRECT16 lprect16 = PTR_SEG_TO_LIN(*plParam);
                 LPRECT32 lprect32 = HeapAlloc( SystemHeap, 0,
@@ -130,9 +175,10 @@
                 *plParam = (LPARAM)lprect32;
                 break;
             }
-	}
-	break;
-    case WH_MOUSE:
+	    break;
+	  } 
+
+	case WH_MOUSE:
         {
             LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
             LPMOUSEHOOKSTRUCT32 lpms32 = HeapAlloc( SystemHeap, 0,
@@ -146,9 +192,10 @@
             lpms32->dwExtraInfo = lpms16->dwExtraInfo;
             lpms32->hwnd = lpms16->hwnd;
             *plParam = (LPARAM)lpms32;
-            break;
-        }
-    case WH_DEBUG:
+	    break;
+        } 
+
+	case WH_DEBUG:
         {
             LPDEBUGHOOKINFO16 lpdh16 = PTR_SEG_TO_LIN(*plParam);
             LPDEBUGHOOKINFO32 lpdh32 = HeapAlloc( SystemHeap, 0,
@@ -164,19 +211,17 @@
             if (*pwParam == 0xffff) *pwParam = WH_MSGFILTER;
 
             *plParam = (LPARAM)lpdh32;
-            break;
+	    break;
         }
-    case WH_SHELL:
-    case WH_KEYBOARD:
-	break;
 
-    case WH_CALLWNDPROC:
-    case WH_HARDWARE:
-	break;	/* NYI */
+	case WH_SHELL:
+	case WH_KEYBOARD:
+	    break;
 
-    default:
-	fprintf(stderr, "Unknown hook id: %d\n", id);
-	return;
+	case WH_HARDWARE: 
+	case WH_FOREGROUNDIDLE: 
+	case WH_CALLWNDPROCRET:
+	    fprintf(stderr, "\t[%i] 16to32 translation unimplemented\n", id);
     }
 }
 
@@ -187,34 +232,7 @@
 static void HOOK_Map16To32A(INT32 id, INT32 code, WPARAM32 *pwParam,
 			    LPARAM *plParam)
 {
-    if (id == WH_CBT && code == HCBT_CREATEWND)
-    {
-	LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(*plParam);
-	LPCBT_CREATEWND32A lpcbtcw32 = HeapAlloc( SystemHeap, 0,
-						  sizeof(*lpcbtcw32) );
-	lpcbtcw32->lpcs = HeapAlloc( SystemHeap, 0,
-				     sizeof(*lpcbtcw32->lpcs) );
-
-	STRUCT32_CREATESTRUCT16to32A( lpcbtcw16->lpcs, lpcbtcw32->lpcs );
-
-	if (HIWORD(lpcbtcw16->lpcs->lpszName))
-            lpcbtcw32->lpcs->lpszName
-                = PTR_SEG_TO_LIN(lpcbtcw16->lpcs->lpszName);
-	else
-            lpcbtcw32->lpcs->lpszName = (LPSTR)lpcbtcw16->lpcs->lpszName;
-
-	if (HIWORD(lpcbtcw16->lpcs->lpszClass))
-            lpcbtcw32->lpcs->lpszClass
-                = PTR_SEG_TO_LIN(lpcbtcw16->lpcs->lpszClass);
-	else
-            lpcbtcw32->lpcs->lpszClass = (LPSTR)lpcbtcw16->lpcs->lpszClass;
-
-	lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
-
-	*plParam = (LPARAM)lpcbtcw32;
-    }
-    else
-        HOOK_Map16To32Common( id, code, pwParam, plParam );
+    HOOK_Map16To32Common( id, code, pwParam, plParam, TRUE );
 }
 
 
@@ -224,35 +242,7 @@
 static void HOOK_Map16To32W(INT32 id, INT32 code, WPARAM32 *pwParam,
 			    LPARAM *plParam)
 {
-    if (id == WH_CBT && code == HCBT_CREATEWND)
-    {
-	LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(*plParam);
-	LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
-	LPCBT_CREATEWND32W lpcbtcw32 = HeapAlloc( SystemHeap, 0,
-						  sizeof(*lpcbtcw32) );
-	lpcbtcw32->lpcs = HeapAlloc( SystemHeap, 0,
-				     sizeof(*lpcbtcw32->lpcs) );
-
-	STRUCT32_CREATESTRUCT16to32A( lpcs16,
-				      (LPCREATESTRUCT32A)lpcbtcw32->lpcs );
-
-	if (HIWORD(lpcs16->lpszName))
-            lpcbtcw32->lpcs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
-                                            PTR_SEG_TO_LIN(lpcs16->lpszName) );
-	else
-            lpcbtcw32->lpcs->lpszName = (LPWSTR)lpcs16->lpszName;
-
-	if (HIWORD(lpcs16->lpszClass))
-            lpcbtcw32->lpcs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
-                                           PTR_SEG_TO_LIN(lpcs16->lpszClass) );
-	else
-            lpcbtcw32->lpcs->lpszClass = (LPWSTR)lpcs16->lpszClass;
-
-	lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
-
-	*plParam = (LPARAM)lpcbtcw32;
-    }
-    else HOOK_Map16To32Common( id, code, pwParam, plParam );
+    HOOK_Map16To32Common( id, code, pwParam, plParam, FALSE );
 }
 
 
@@ -261,56 +251,82 @@
  */
 static void HOOK_UnMap16To32Common(INT32 id, INT32 code, WPARAM32 wParamOrig,
 				   LPARAM lParamOrig, WPARAM32 wParam,
-				   LPARAM lParam)
+				   LPARAM lParam, BOOL32 bA)
 {
     switch (id)
     {
-      case WH_MSGFILTER:
-      case WH_SYSMSGFILTER:
-      case WH_JOURNALRECORD:
-      case WH_JOURNALPLAYBACK:
-      {
-	  HeapFree( SystemHeap, 0, (LPVOID)lParam );
-	  break;
-      }
-
-      case WH_GETMESSAGE:
-      {
-	  LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(lParamOrig);
-	  STRUCT32_MSG32to16( (LPMSG32)lParam, lpmsg16 );
-	  HeapFree( SystemHeap, 0, (LPVOID)lParam );
-	  break;
-      }
-
-      case WH_MOUSE:
-      case WH_DEBUG:
-	HeapFree( SystemHeap, 0, (LPVOID)lParam );
-	break;
-
-	/* I don't think any of these need to be copied */
-      case WH_CBT:
-	switch (code)
-	{
-	  case HCBT_ACTIVATE:
-	  case HCBT_CLICKSKIPPED:
-	  case HCBT_MOVESIZE:
-	    HeapFree( SystemHeap, 0, (LPVOID)lParam);
+	case WH_MSGFILTER:
+	case WH_SYSMSGFILTER:
+	case WH_JOURNALRECORD:
+	case WH_JOURNALPLAYBACK:
+      
+	    HeapFree( SystemHeap, 0, (LPVOID)lParam );
 	    break;
+
+	case WH_CALLWNDPROC:
+	{
+            void          (*localUnMap)(UINT32, WPARAM32, LPARAM)
+                            = (bA) ? WINPROC_UnmapMsg16To32A : WINPROC_UnmapMsg16To32W;
+            LPCWPSTRUCT32   lpcwp32 = (LPCWPSTRUCT32)lParam;
+
+            (*localUnMap)(lpcwp32->message, lpcwp32->wParam, lpcwp32->lParam );
+	    HeapFree( SystemHeap, 0, lpcwp32 );
+            break;
 	}
-	break;
 
-      case WH_SHELL:
-      case WH_KEYBOARD:
-	break;
+	case WH_GETMESSAGE:
+        {
+	    LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(lParamOrig);
+	    STRUCT32_MSG32to16( (LPMSG32)lParam, lpmsg16 );
+	    HeapFree( SystemHeap, 0, (LPVOID)lParam );
+	    break;
+        }
 
-      case WH_CALLWNDPROC:
-      case WH_HARDWARE:
-	fprintf(stderr, "Can't map hook id: %d\n", id);
-	break;
+        case WH_MOUSE:
+        case WH_DEBUG:
 
-      default:
-	fprintf(stderr, "Unknown hook id: %d\n", id);
-	return;
+	    HeapFree( SystemHeap, 0, (LPVOID)lParam );
+	    break;
+
+        case WH_CBT:
+	    switch (code)
+  	    {
+	      case HCBT_CREATEWND:
+	      {
+		LPCBT_CREATEWND32A lpcbtcw32 = (LPCBT_CREATEWND32A)lParam;
+		LPCBT_CREATEWND16  lpcbtcw16 = PTR_SEG_TO_LIN(lParamOrig);
+
+		if( !bA )
+		{
+		   if (HIWORD(lpcbtcw32->lpcs->lpszName))
+                       HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszName );
+		   if (HIWORD(lpcbtcw32->lpcs->lpszClass))
+                       HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszClass );
+		}
+
+		lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
+
+		HeapFree( SystemHeap, 0, lpcbtcw32->lpcs );
+	      } /* fall through */
+
+	      case HCBT_ACTIVATE:
+	      case HCBT_CLICKSKIPPED:
+	      case HCBT_MOVESIZE:
+
+	        HeapFree( SystemHeap, 0, (LPVOID)lParam);
+	        break;
+	    }
+  	    break;
+
+        case WH_SHELL:
+        case WH_KEYBOARD:
+	    break;
+
+        case WH_HARDWARE:
+	case WH_FOREGROUNDIDLE:
+	case WH_CALLWNDPROCRET:
+	    fprintf(stderr, "\t[%i] skipping unmap\n", id);
+  	    break;
     }
 }
 
@@ -322,16 +338,8 @@
 			      LPARAM lParamOrig, WPARAM32 wParam,
 			      LPARAM lParam)
 {
-    if (id == WH_CBT && code == HCBT_CREATEWND)
-    {
-	LPCBT_CREATEWND32A lpcbtcw32 = (LPCBT_CREATEWND32A)lParam;
-	HeapFree( SystemHeap, 0, lpcbtcw32->lpcs );
-	HeapFree( SystemHeap, 0, lpcbtcw32 );
-    }
-    else
-      HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
-			      lParam);
-    return;
+    HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
+			    lParam, TRUE );
 }
 
 
@@ -342,18 +350,8 @@
 			      LPARAM lParamOrig, WPARAM32 wParam,
 			      LPARAM lParam)
 {
-    if (id == WH_CBT && code == HCBT_CREATEWND)
-    {
-	LPCBT_CREATEWND32W lpcbtcw32 = (LPCBT_CREATEWND32W)lParam;
-	if (HIWORD(lpcbtcw32->lpcs->lpszName))
-            HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszName );
-	if (HIWORD(lpcbtcw32->lpcs->lpszClass))
-            HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszClass );
-	HeapFree( SystemHeap, 0, lpcbtcw32->lpcs );
-	HeapFree( SystemHeap, 0, lpcbtcw32 );
-    }
-    else
-      HOOK_UnMap16To32Common(id, code, wParamOrig, lParamOrig, wParam, lParam);
+    HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam, 
+			    lParam, FALSE );
 }
 
 
@@ -361,7 +359,7 @@
  *           HOOK_Map32To16Common
  */
 static void HOOK_Map32To16Common(INT32 id, INT32 code, WPARAM32 *pwParam,
-				 LPARAM *plParam)
+				 LPARAM *plParam, BOOL32 bA)
 {
     switch (id)
     {
@@ -393,6 +391,22 @@
 	  break;
       }
 
+      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 );
+	  *plParam = (LPARAM)SEGPTR_GET( lpcwp16 );
+          break;
+      }
+
       case WH_CBT:
 	switch (code)
 	{
@@ -402,8 +416,8 @@
 	      LPCBTACTIVATESTRUCT16 lpcas16 =SEGPTR_NEW( CBTACTIVATESTRUCT16 );
 
 	      lpcas16->fMouse     = lpcas32->fMouse;
-	      lpcas16->hWndActive = lpcas32->hWndActive
-;
+	      lpcas16->hWndActive = lpcas32->hWndActive;
+
 	      *plParam = (LPARAM)SEGPTR_GET( lpcas16 );
 	      break;
 	  }
@@ -470,14 +484,10 @@
       case WH_KEYBOARD:
 	break;
 
-      case WH_CALLWNDPROC:
       case WH_HARDWARE:
-	fprintf(stderr, "Can't map hook id: %d\n", id);
-	break;
-
-      default:
-	fprintf(stderr, "Unknown hook id: %d\n", id);
-	return;
+      case WH_FOREGROUNDIDLE:
+      case WH_CALLWNDPROCRET:
+	fprintf(stderr,"\t[%i] 32to16 translation unimplemented\n", id);
     }
 }
 
@@ -513,7 +523,7 @@
 
 	*plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
     }
-    else HOOK_Map32To16Common(id, code, pwParam, plParam);
+    else HOOK_Map32To16Common(id, code, pwParam, plParam, TRUE);
 }
 
 
@@ -542,7 +552,7 @@
 
 	*plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
     }
-    else HOOK_Map32To16Common(id, code, pwParam, plParam);
+    else HOOK_Map32To16Common(id, code, pwParam, plParam, FALSE);
 }
 
 
@@ -551,7 +561,7 @@
  */
 static void HOOK_UnMap32To16Common(INT32 id, INT32 code, WPARAM32 wParamOrig,
 				   LPARAM lParamOrig, WPARAM32 wParam,
-				   LPARAM lParam)
+				   LPARAM lParam, BOOL32 bA)
 {
     switch (id)
     {
@@ -564,6 +574,18 @@
 	SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
 	break;
 
+      case WH_CALLWNDPROC:
+      {
+          void          (*localUnMap)(UINT32, WPARAM16, LPARAM)
+                          = (bA) ? WINPROC_UnmapMsg32ATo16 : WINPROC_UnmapMsg32WTo16;
+          LPCWPSTRUCT16   lpcwp16 = (LPCWPSTRUCT16)PTR_SEG_TO_LIN(lParam);
+	  LPCWPSTRUCT32   lpcwp32 = (LPCWPSTRUCT32)lParamOrig;
+
+          (*localUnMap)(lpcwp32->message, lpcwp16->wParam, lpcwp16->lParam );
+	  SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
+          break;
+      }
+
       case WH_GETMESSAGE:
       {
 	  LPMSG32 lpmsg32 = (LPMSG32)lParamOrig;
@@ -576,11 +598,29 @@
       case WH_CBT:
 	switch (code)
 	{
+	  case HCBT_CREATEWND:
+	  {
+	       LPCBT_CREATEWND32A lpcbtcw32 = (LPCBT_CREATEWND32A)(lParamOrig);
+               LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(lParam);
+               LPCREATESTRUCT16  lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
+
+               if (HIWORD(lpcs16->lpszName))
+                   SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszName) );
+
+               if (HIWORD(lpcs16->lpszClass))
+                   SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszClass) );
+
+	       lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
+
+               SEGPTR_FREE( lpcs16 );
+	  } /* fall through */
+
 	  case HCBT_ACTIVATE:
 	  case HCBT_CLICKSKIPPED:
 	  case HCBT_MOVESIZE:
-	    SEGPTR_FREE( (LPVOID)lParam );
-	    break;
+
+	       SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
+	       break;
 	}
 	break;
 
@@ -588,14 +628,10 @@
       case WH_KEYBOARD:
 	break;
 
-      case WH_CALLWNDPROC:
       case WH_HARDWARE:
-	fprintf(stderr, "Can't map hook id: %d\n", id);
-	break;
-
-      default:
-	fprintf(stderr, "Unknown hook id: %d\n", id);
-	return;
+      case WH_FOREGROUNDIDLE:
+      case WH_CALLWNDPROCRET:
+	fprintf(stderr, "\t[%i] skipping unmap\n", id);
     }
 }
 
@@ -607,24 +643,8 @@
 			      LPARAM lParamOrig, WPARAM32 wParam,
 			      LPARAM lParam)
 {
-    if (id == WH_CBT && code == HCBT_CREATEWND)
-    {
-	LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(lParam);
-	LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
-
-	if (HIWORD(lpcs16->lpszName))
-	  SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszName) );
-
-	if (HIWORD(lpcs16->lpszClass))
-	  SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszClass) );
-
-	SEGPTR_FREE( lpcs16 );
-	SEGPTR_FREE( lpcbtcw16 );
-    }
-    else
-      return HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
-				     lParam );
-    return;
+    HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
+			    lParam, TRUE );
 }
 
 
@@ -635,7 +655,8 @@
 			      LPARAM lParamOrig, WPARAM32 wParam,
 			      LPARAM lParam)
 {
-    HOOK_UnMap32ATo16( id, code, wParamOrig, lParamOrig, wParam, lParam );
+    HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
+                            lParam, FALSE );
 }
 
 
@@ -841,7 +862,6 @@
     data->id          = id;
     data->ownerQueue  = hQueue;
     data->ownerModule = hInst;
-    data->inHookProc  = 0;
     data->flags       = type;
 
     /* Insert it in the correct linked list */
@@ -876,7 +896,7 @@
     dprintf_hook( stddeb, "Removing hook %04x\n", hook );
 
     if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return FALSE;
-    if (data->inHookProc)
+    if (data->flags & HOOK_INUSE)
     {
         /* Mark it for deletion later on */
         dprintf_hook( stddeb, "Hook still running, deletion delayed\n" );
@@ -952,7 +972,7 @@
     if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
     prevHook = queue->hCurHook;
     queue->hCurHook = hook;
-    data->inHookProc = TRUE;
+    data->flags |= HOOK_INUSE;
 
     dprintf_hook( stddeb, "Calling hook %04x: %d %08x %08lx\n",
                   hook, code, wParam, lParam );
@@ -965,7 +985,7 @@
 
     dprintf_hook( stddeb, "Ret hook %04x = %08lx\n", hook, ret );
 
-    data->inHookProc = FALSE;
+    data->flags &= ~HOOK_INUSE;
     queue->hCurHook = prevHook;
 
     if (UnMapFunc)
@@ -1100,7 +1120,7 @@
 	      next = hptr->next;
 	      if( hptr->ownerModule == hModule )
                 {
-                  hptr->inHookProc = 0;
+                  hptr->flags &= HOOK_MAPTYPE;
                   HOOK_RemoveHook(hook);
                 }
 	      hook = next;
@@ -1130,7 +1150,7 @@
 	  hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
 	  if( hptr && hptr->ownerQueue == hQueue )
 	    {
-	      hptr->inHookProc = 0;
+	      hptr->flags &= HOOK_MAPTYPE;
 	      HOOK_RemoveHook(hook);
 	    }
 	  hook = next;
diff --git a/windows/keyboard.c b/windows/keyboard.c
index f83cc16..8ed9eeb 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -864,15 +864,27 @@
 	return 0;
 }
 
+
 /****************************************************************************
- *	GetKbCodePage   (KEYBOARD.132)
+ *	GetKBCodePage16   (KEYBOARD.132)
  */
-INT16 GetKbCodePage(VOID)
+INT16 GetKBCodePage16(void)
 {
-    	dprintf_keyboard(stddeb,"GetKbCodePage()\n");
-	return 850;
+    dprintf_keyboard(stddeb,"GetKBCodePage()\n");
+    return 850;
 }
 
+
+/****************************************************************************
+ *	GetKBCodePage32   (USER32.245)
+ */
+UINT32 GetKBCodePage32(void)
+{
+    dprintf_keyboard(stddeb,"GetKbCodePage()\n");
+    return 850;
+}
+
+
 /****************************************************************************
  *	GetKeyNameText32W   (USER32.247)
  */
diff --git a/windows/mdi.c b/windows/mdi.c
index 317c8ae..395a4ea 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -37,25 +37,25 @@
 DWORD SCROLL_SetNCSbState(WND*,int,int,int,int,int,int);
 
 /* ----------------- declarations ----------------- */
-void MDI_UpdateFrameText(WND *, HWND, BOOL, LPCSTR);
-BOOL MDI_AugmentFrameMenu(MDICLIENTINFO*, WND *, HWND);
-BOOL MDI_RestoreFrameMenu(WND *, HWND);
+static void MDI_UpdateFrameText(WND *, HWND16, BOOL32, LPCSTR);
+static BOOL32 MDI_AugmentFrameMenu(MDICLIENTINFO*, WND *, HWND16);
+static BOOL32 MDI_RestoreFrameMenu(WND *, HWND16);
 
-static LONG MDI_ChildActivate(WND* ,HWND );
+static LONG MDI_ChildActivate(WND* ,HWND16 );
 
 /* -------- Miscellaneous service functions ----------
  *
  *			MDI_GetChildByID
  */
 
-static HWND MDI_GetChildByID(WND* wndPtr,int id)
+static HWND16 MDI_GetChildByID(WND* wndPtr,int id)
 {
     for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
         if (wndPtr->wIDmenu == id) return wndPtr->hwndSelf;
     return 0;
 }
 
-static void MDI_PostUpdate(HWND hwnd, MDICLIENTINFO* ci, WORD recalc)
+static void MDI_PostUpdate(HWND16 hwnd, MDICLIENTINFO* ci, WORD recalc)
 {
  if( !ci->sbNeedUpdate )
    {
@@ -69,7 +69,7 @@
  *			MDI_MenuAppendItem
  */
 #ifdef SUPERFLUOUS_FUNCTIONS
-static BOOL MDI_MenuAppendItem(WND *clientWnd, HWND hWndChild)
+static BOOL MDI_MenuAppendItem(WND *clientWnd, HWND16 hWndChild)
 {
  char buffer[128];
  MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
@@ -88,7 +88,7 @@
 /**********************************************************************
  *			MDI_MenuModifyItem
  */
-static BOOL MDI_MenuModifyItem(WND* clientWnd, HWND hWndChild )
+static BOOL MDI_MenuModifyItem(WND* clientWnd, HWND16 hWndChild )
 {
  char            buffer[128];
  MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
@@ -111,7 +111,7 @@
 /**********************************************************************
  *			MDI_MenuDeleteItem
  */
-static BOOL MDI_MenuDeleteItem(WND* clientWnd, HWND hWndChild )
+static BOOL MDI_MenuDeleteItem(WND* clientWnd, HWND16 hWndChild )
 {
  char    	 buffer[128];
  MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
@@ -156,7 +156,7 @@
  *
  * returns "activateable" child  or zero
  */
-HWND MDI_GetWindow(WND  *clientWnd, HWND hWnd, WORD wTo )
+static HWND16 MDI_GetWindow(WND  *clientWnd, HWND16 hWnd, WORD wTo )
 {
     MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
     WND *wndPtr, *pWnd, *pWndLast;
@@ -194,10 +194,11 @@
  *
  *  It seems that default height is 2/3 of client rect
  */
-void MDI_CalcDefaultChildPos(WND* w, WORD n, LPPOINT16 lpPos, INT delta)
+static void MDI_CalcDefaultChildPos(WND* w, WORD n, LPPOINT16 lpPos, INT delta)
 {
  RECT16 rect = w->rectClient;
- INT  spacing = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME) - 1; 
+ INT  spacing = GetSystemMetrics32(SM_CYCAPTION) +
+                GetSystemMetrics32(SM_CYFRAME) - 1; 
  INT  nstagger;
 
  if( rect.bottom - rect.top - delta >= spacing ) 
@@ -210,10 +211,10 @@
 }
 
 /**********************************************************************
- *					MDISetMenu
+ *            MDISetMenu
  */
-HMENU16 MDISetMenu(HWND hwnd, BOOL fRefresh, HMENU16 hmenuFrame,
-                   HMENU16 hmenuWindow)
+static HMENU16 MDISetMenu(HWND16 hwnd, BOOL32 fRefresh, HMENU16 hmenuFrame,
+                          HMENU16 hmenuWindow)
 {
     WND           *w         = WIN_FindWndPtr(hwnd);
     MDICLIENTINFO *ci;
@@ -225,7 +226,7 @@
 
     if (!fRefresh) 
        {
-	HWND hwndFrame = GetParent16(hwnd);
+	HWND16 hwndFrame = GetParent16(hwnd);
 	HMENU32 oldFrameMenu = GetMenu32(hwndFrame);
         
 	if( ci->hwndChildMaximized && hmenuFrame && hmenuFrame!=oldFrameMenu )
@@ -280,9 +281,9 @@
 }
 
 /**********************************************************************
- *					MDIIconArrange
+ *            MDIIconArrange
  */
-WORD MDIIconArrange(HWND parent)
+static WORD MDIIconArrange(HWND16 parent)
 {
   return ArrangeIconicWindows16(parent);	/* Any reason why the    */
 						/* existing icon arrange */
@@ -297,20 +298,15 @@
 /**********************************************************************
  *					MDICreateChild
  */
-HWND MDICreateChild(WND *w, MDICLIENTINFO *ci, HWND parent, LPARAM lParam )
+static HWND16 MDICreateChild( WND *w, MDICLIENTINFO *ci, HWND16 parent, 
+                              LPMDICREATESTRUCT16 cs, LPARAM lParam )
 {
     POINT16          pos[2]; 
-    MDICREATESTRUCT16 *cs = (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
     DWORD	     style = cs->style | (WS_CHILD | WS_CLIPSIBLINGS);
-    HWND 	     hwnd, hwndMax = 0;
+    HWND16 	     hwnd, hwndMax = 0;
     WORD	     wIDmenu = ci->idFirstChild + ci->nActiveChildren;
     char	     lpstrDef[]="junk!";
 
-    /*
-     * Create child window
-     *
-     */
-
     dprintf_mdi(stdnimp,"MDICreateChild: origin %i,%i - dim %i,%i, style %08x\n", 
 					 cs->x, cs->y, cs->cx, cs->cy, (unsigned)cs->style);    
     /* calculate placement */
@@ -353,9 +349,9 @@
 
     hwnd = CreateWindow16( (LPCSTR)PTR_SEG_TO_LIN(cs->szClass),
                            (LPCSTR)PTR_SEG_TO_LIN(cs->szTitle), style, 
-			  cs->x, cs->y, cs->cx, cs->cy, parent, 
-                         (HMENU16)wIDmenu, w->hInstance, 
-			 (LPVOID)lParam);
+                           cs->x, cs->y, cs->cx, cs->cy, parent, 
+                           (HMENU16)wIDmenu, w->hInstance, 
+                           (LPVOID)lParam);
 
     /* MDI windows are WS_CHILD so they won't be activated by CreateWindow */
 
@@ -397,7 +393,8 @@
 /**********************************************************************
  *			MDI_ChildGetMinMaxInfo
  */
-void MDI_ChildGetMinMaxInfo(WND* clientWnd, HWND hwnd, MINMAXINFO16* lpMinMax )
+static void MDI_ChildGetMinMaxInfo( WND* clientWnd, HWND16 hwnd,
+                                    MINMAXINFO16* lpMinMax )
 {
  WND*	childWnd = WIN_FindWndPtr(hwnd);
  RECT16	rect 	 = clientWnd->rectClient;
@@ -426,11 +423,12 @@
  *	  wTo is basically lParam of WM_MDINEXT message or explicit 
  *        window handle
  */
-void MDI_SwitchActiveChild(HWND clientHwnd, HWND childHwnd, BOOL wTo )
+static void MDI_SwitchActiveChild( HWND16 clientHwnd, HWND16 childHwnd,
+                                   BOOL32 wTo )
 {
     WND		  *w	     = WIN_FindWndPtr(clientHwnd);
-    HWND	   hwndTo    = 0;
-    HWND	   hwndPrev  = 0;
+    HWND16	   hwndTo    = 0;
+    HWND16	   hwndPrev  = 0;
     MDICLIENTINFO *ci;
 
     hwndTo = MDI_GetWindow(w,childHwnd,(WORD)wTo);
@@ -470,8 +468,8 @@
 /**********************************************************************
  *                                      MDIDestroyChild
  */
-HWND MDIDestroyChild(WND *w_parent, MDICLIENTINFO *ci, HWND parent,
-                     HWND child, BOOL flagDestroy)
+static HWND16 MDIDestroyChild( WND *w_parent, MDICLIENTINFO *ci, HWND16 parent,
+                               HWND16 child, BOOL32 flagDestroy )
 {
     WND         *childPtr = WIN_FindWndPtr(child);
 
@@ -516,10 +514,10 @@
  *
  * Note: hWndChild is NULL when last child is being destroyed
  */
-LONG MDI_ChildActivate(WND *clientPtr, HWND hWndChild)
+static LONG MDI_ChildActivate( WND *clientPtr, HWND16 hWndChild )
 {
     MDICLIENTINFO       *clientInfo = (MDICLIENTINFO*)clientPtr->wExtra; 
-    HWND                 prevActiveWnd = clientInfo->hwndActiveChild;
+    HWND16                 prevActiveWnd = clientInfo->hwndActiveChild;
     WND                 *wndPtr = WIN_FindWndPtr( hWndChild );
     WND			*wndPrev = WIN_FindWndPtr( prevActiveWnd );
     BOOL		 isActiveFrameWnd = 0;	 
@@ -610,7 +608,7 @@
  *
  *  iTotal returns number of children available for tiling or cascading
  */
-MDIWCL* MDI_BuildWCL(WND* clientWnd, INT16* iTotal)
+static MDIWCL* MDI_BuildWCL(WND* clientWnd, INT16* iTotal)
 {
     MDIWCL *listTop,*listNext;
     WND    *childWnd;
@@ -628,6 +626,9 @@
     {
 	listNext = (MDIWCL*)xmalloc(sizeof(MDIWCL));
 	
+	/* FIXME: pay attention to MDITILE_SKIPDISABLED 
+	 *        when WIN_ISWIN32 is set.
+	 */
 	if( (childWnd->dwStyle & WS_DISABLED) ||
 	    (childWnd->dwStyle & WS_MINIMIZE) ||
 	    !(childWnd->dwStyle & WS_VISIBLE)   )
@@ -661,7 +662,7 @@
 /**********************************************************************
  *				CreateMDIMenuBitmap
  */
-HBITMAP16 CreateMDIMenuBitmap(void)
+static HBITMAP16 CreateMDIMenuBitmap(void)
 {
  HDC32 		hDCSrc  = CreateCompatibleDC32(0);
  HDC32		hDCDest	= CreateCompatibleDC32(hDCSrc);
@@ -689,7 +690,7 @@
 /**********************************************************************
  *				MDICascade
  */
-LONG MDICascade(WND* clientWnd, MDICLIENTINFO *ci)
+static LONG MDICascade(WND* clientWnd, MDICLIENTINFO *ci)
 {
     MDIWCL	 *listTop,*listPrev;
     INT16	  delta = 0,iToPosition = 0, n = 0;
@@ -733,7 +734,7 @@
  *					MDITile
  *
  */
-LONG MDITile(WND* wndClient, MDICLIENTINFO *ci,WORD wParam)
+static LONG MDITile(WND* wndClient, MDICLIENTINFO *ci,WORD wParam)
 {
     MDIWCL       *listTop,*listPrev;
     RECT16        rect;
@@ -835,7 +836,8 @@
 /**********************************************************************
  *					MDI_AugmentFrameMenu
  */
-BOOL MDI_AugmentFrameMenu(MDICLIENTINFO* ci, WND *frame, HWND hChild)
+static BOOL32 MDI_AugmentFrameMenu( MDICLIENTINFO* ci, WND *frame,
+                                    HWND16 hChild )
 {
  WND*		child = WIN_FindWndPtr(hChild);
  HMENU16  	hSysPopup = 0;
@@ -875,7 +877,7 @@
 /**********************************************************************
  *					MDI_RestoreFrameMenu
  */
-BOOL MDI_RestoreFrameMenu( WND *frameWnd, HWND hChild)
+static BOOL32 MDI_RestoreFrameMenu( WND *frameWnd, HWND16 hChild )
 {
  INT32 nItems = GetMenuItemCount32(frameWnd->wIDmenu) - 1;
 
@@ -900,7 +902,8 @@
  *
  * Note: lpTitle can be NULL
  */
-void MDI_UpdateFrameText(WND *frameWnd, HWND hClient, BOOL repaint, LPCSTR lpTitle)
+static void MDI_UpdateFrameText( WND *frameWnd, HWND16 hClient,
+                                 BOOL32 repaint, LPCSTR lpTitle )
 {
  char   lpBuffer[MDI_MAXTITLELENGTH+1];
  WND* 	clientWnd = WIN_FindWndPtr(hClient);
@@ -972,7 +975,7 @@
  *
  * This function is the handler for all MDI requests.
  */
-LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM16 wParam, LPARAM lParam)
+LRESULT MDIClientWndProc(HWND16 hwnd, UINT message, WPARAM16 wParam, LPARAM lParam)
 {
     LPCREATESTRUCT16     cs;
     LPCLIENTCREATESTRUCT16 ccs;
@@ -987,8 +990,16 @@
     switch (message)
     {
       case WM_CREATE:
-	cs                      = (LPCREATESTRUCT16) PTR_SEG_TO_LIN(lParam);
-	ccs                     = (LPCLIENTCREATESTRUCT16) PTR_SEG_TO_LIN(cs->lpCreateParams);
+
+	cs = (LPCREATESTRUCT16) PTR_SEG_TO_LIN(lParam);
+
+	/* Translation layer doesn't know what's in the cs->lpCreateParams
+	 * so we have to keep track of what environment we're in. */
+
+	if( w->flags & WIN_ISWIN32 )
+	    ccs = (LPCLIENTCREATESTRUCT16) cs->lpCreateParams;
+        else    
+	    ccs = (LPCLIENTCREATESTRUCT16) PTR_SEG_TO_LIN(cs->lpCreateParams);
 
 	ci->hWindowMenu         = ccs->hWindowMenu;
 	ci->idFirstChild        = ccs->idFirstChild;
@@ -1028,18 +1039,23 @@
 	return 0;
 
       case WM_MDIACTIVATE:
-        if( ci->hwndActiveChild != (HWND)wParam )
-	    SetWindowPos32((HWND)wParam, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE ); 
+        if( ci->hwndActiveChild != (HWND16)wParam )
+	    SetWindowPos32((HWND32)wParam, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE ); 
 	return 0;
 
       case WM_MDICASCADE:
 	return MDICascade(w, ci);
 
       case WM_MDICREATE:
-	return (LONG)MDICreateChild(w, ci, hwnd, lParam );
+        if( lParam )
+	{
+	    MDICREATESTRUCT16* cs = (MDICREATESTRUCT16*) PTR_SEG_TO_LIN(lParam);
+	    return (LONG)MDICreateChild(w, ci, hwnd, cs, lParam );
+	}
+	return 0;
 
       case WM_MDIDESTROY:
-	return (LONG)MDIDestroyChild(w, ci, hwnd, (HWND)wParam, TRUE);
+	return (LONG)MDIDestroyChild(w, ci, hwnd, (HWND32)wParam, TRUE);
 
       case WM_MDIGETACTIVE:
 	return ((LONG) ci->hwndActiveChild | 
@@ -1057,7 +1073,7 @@
 	return 0;
 
       case WM_MDINEXT:
-	MDI_SwitchActiveChild(hwnd, (HWND)wParam, (lParam)?1:0);
+	MDI_SwitchActiveChild(hwnd, (HWND16)wParam, (lParam)?1:0);
 	break;
 	
       case WM_MDIRESTORE:
@@ -1081,7 +1097,7 @@
       case WM_VSCROLL:
       case WM_HSCROLL:
 	ci->sbNeedUpdate = TRUE;
-        ScrollChildren(hwnd,message,wParam,lParam);
+        ScrollChildren32(hwnd,message,wParam,lParam);
 	ci->sbNeedUpdate = FALSE;
         return 0;
 
@@ -1103,21 +1119,14 @@
         if( wParam == WM_LBUTTONDOWN )
         {
             POINT16  pt = MAKEPOINT16(lParam);
-            HWND     child = ChildWindowFromPoint16(hwnd, pt);
+            HWND16 child = ChildWindowFromPoint16(hwnd, pt);
 
 	    dprintf_mdi(stddeb,"MDIClient: notification from %04x (%i,%i)\n",child,pt.x,pt.y);
 
-            if( child && child != hwnd )
-              {
-                WND*    wnd = WIN_FindWndPtr( child );
-
-                /* if we got owned popup */
-                if( wnd->owner ) child = wnd->owner->hwndSelf;
-
-                if( child != ci->hwndActiveChild )
-                    SetWindowPos32(child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
-              }
-          }
+            if( child && child != hwnd &&
+			 child != ci->hwndActiveChild )
+                SetWindowPos32(child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
+        }
         return 0;
 
       case WM_SIZE:
@@ -1155,7 +1164,7 @@
 LRESULT DefFrameProc16( HWND16 hwnd, HWND16 hwndMDIClient, UINT16 message, 
                         WPARAM16 wParam, LPARAM lParam )
 {
-    HWND	         childHwnd;
+    HWND16	         childHwnd;
     MDICLIENTINFO*       ci;
     WND*                 wndPtr;
 
@@ -1169,9 +1178,10 @@
 
 	    /* check for possible syscommands for maximized MDI child */
 
-	    if( wParam <  ci->idFirstChild || 
-		wParam >= ci->idFirstChild + ci->nActiveChildren )
-	      {
+	    if( ci && (
+	    	wParam <  ci->idFirstChild || 
+		wParam >= ci->idFirstChild + ci->nActiveChildren
+	    )){
 		if( (wParam - 0xF000) & 0xF00F ) break;
 		switch( wParam )
 		  {
@@ -1265,9 +1275,15 @@
 	    SendMessage32A(hwndMDIClient, message, wParam, lParam);
 	    break;
 
-	  case WM_SETTEXT:
-              return DefFrameProc16( hwnd, hwndMDIClient, message,
-                                     wParam, (LPARAM)PTR_SEG_TO_LIN(lParam) );
+	  case WM_SETTEXT: {
+	  	LRESULT	ret;
+		LPSTR	segstr = SEGPTR_STRDUP((LPSTR)lParam);
+
+                ret = DefFrameProc16(hwnd, hwndMDIClient, message,
+                                     wParam, (LPARAM)SEGPTR_GET(segstr) );
+	        SEGPTR_FREE(segstr);
+		return ret;
+	  }
 	
 	  case WM_SETFOCUS:
 	  case WM_SIZE:
@@ -1299,11 +1315,13 @@
 	    SendMessage32W(hwndMDIClient, message, wParam, lParam);
 	    break;
 
-	  case WM_SETTEXT:
-              /* FIXME: Unicode */
-              return DefFrameProc32A( hwnd, hwndMDIClient, message,
-                                     wParam, lParam );
-	
+	  case WM_SETTEXT: {
+	      LPSTR txt = HEAP_strdupWtoA(GetProcessHeap(),0,(LPWSTR)lParam);
+	      LRESULT ret = DefFrameProc32A( hwnd, hwndMDIClient, message,
+                                     wParam, (DWORD)txt );
+	      HeapFree(GetProcessHeap(),0,txt);
+	      return ret;
+	  }
 	  case WM_SETFOCUS:
 	  case WM_SIZE:
               return DefFrameProc32A( hwnd, hwndMDIClient, message,
@@ -1405,7 +1423,7 @@
 
 	if( wParam == SIZE_MAXIMIZED )
 	  {
-	    HWND hMaxChild = ci->hwndChildMaximized;
+	    HWND16 hMaxChild = ci->hwndChildMaximized;
 
 	    if( hMaxChild == hwnd ) break;
 
@@ -1430,7 +1448,7 @@
 
 	if( wParam == SIZE_MINIMIZED )
 	  {
-	    HWND switchTo = MDI_GetWindow(clientWnd, hwnd, 0);
+	    HWND16 switchTo = MDI_GetWindow(clientWnd, hwnd, 0);
 
 	    if( switchTo )
 	        SendMessage16( switchTo, WM_CHILDACTIVATE, 0, 0L);
@@ -1553,10 +1571,30 @@
 
 
 /**********************************************************************
- *					TranslateMDISysAccel (USER.451)
- *
+ *              CreateMDIWindowA (USER32.78)
  */
-BOOL TranslateMDISysAccel(HWND hwndClient, LPMSG16 msg)
+
+/**********************************************************************
+ *              CreateMDIWindowW (USER32.79)
+ */
+
+/**********************************************************************
+ *             TranslateMDISysAccel32   (USER32.554)
+ */
+BOOL32 TranslateMDISysAccel32( HWND32 hwndClient, LPMSG32 msg )
+{
+    MSG16 msg16;
+ 
+    STRUCT32_MSG32to16(msg,&msg16);
+    /* MDICLIENTINFO is still the same for win32 and win16 ... */
+    return TranslateMDISysAccel16(hwndClient,&msg16);
+}
+
+
+/**********************************************************************
+ *             TranslateMDISysAccel16   (USER.451)
+ */
+BOOL16 TranslateMDISysAccel16( HWND16 hwndClient, LPMSG16 msg )
 {
   WND* clientWnd = WIN_FindWndPtr( hwndClient);
   WND* wnd;
@@ -1580,6 +1618,7 @@
 	case VK_SEPARATOR:
 	     wParam = ( GetKeyState32(VK_SHIFT) & 0x8000 )? SC_NEXTWINDOW: SC_PREVWINDOW;
 	     break;
+        case VK_F4:
 	case VK_RBUTTON:
 	     wParam = SC_CLOSE; 
 	     break;
@@ -1599,7 +1638,7 @@
 /***********************************************************************
  *           CalcChildScroll   (USER.462)
  */
-void CalcChildScroll( HWND hwnd, WORD scroll )
+void CalcChildScroll( HWND16 hwnd, WORD scroll )
 {
     RECT16 childRect, clientRect;
     INT  vmin, vmax, hmin, hmax, vpos, hpos;
@@ -1645,18 +1684,24 @@
       }    
 }
 
+
 /***********************************************************************
- *           ScrollChildren   (USER.463)
+ *           ScrollChildren16   (USER.463)
  */
-void ScrollChildren(HWND hWnd, UINT uMsg, WPARAM16 wParam, LPARAM lParam)
+void ScrollChildren16(HWND16 hWnd, UINT16 uMsg, WPARAM16 wParam, LPARAM lParam)
 {
- WND	*wndPtr = WIN_FindWndPtr(hWnd);
- short 	 newPos=-1;
- short 	 curPos;
- short 	 length;
- INT32 	 minPos;
- INT32 	 maxPos;
- short   shift;
+    return ScrollChildren32( hWnd, uMsg, wParam, lParam );
+}
+
+
+/***********************************************************************
+ *           ScrollChildren32   (USER32.447)
+ */
+void ScrollChildren32(HWND32 hWnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
+{
+    WND	*wndPtr = WIN_FindWndPtr(hWnd);
+    INT32 newPos = -1;
+    INT32 curPos, length, minPos, maxPos, shift;
 
  if( !wndPtr ) return;
 
diff --git a/windows/message.c b/windows/message.c
index 4ceb269..dfce8b0 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -30,9 +30,6 @@
 #define WM_NCMOUSEFIRST         WM_NCMOUSEMOVE
 #define WM_NCMOUSELAST          WM_NCMBUTTONDBLCLK
 
-#define HWND_BROADCAST16  ((HWND16)0xffff)
-#define HWND_BROADCAST32  ((HWND32)0xffffffff)
-
 typedef enum { SYSQ_MSG_ABANDON, SYSQ_MSG_SKIP, 
                SYSQ_MSG_ACCEPT, SYSQ_MSG_CONTINUE } SYSQ_STATUS;
 
@@ -41,7 +38,7 @@
 
 DWORD MSG_WineStartTicks; /* Ticks at Wine startup */
 
-static WORD doubleClickSpeed = 452;
+static UINT32 doubleClickSpeed = 452;
 static INT32 debugSMRL = 0;       /* intertask SendMessage() recursion level */
 
 /***********************************************************************
@@ -172,7 +169,7 @@
 	eatMsg = sendSC = 1;
     else if( remove && mouseClick )
     {
-        HWND hwndTop = WIN_GetTopParent( hWnd );
+        HWND32 hwndTop = WIN_GetTopParent( hWnd );
 
 	if( mouseClick == 1 )
 	{
@@ -376,7 +373,7 @@
      AsyncKeyStateTable[VK_LBUTTON]= InputKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] << 8;
      AsyncKeyStateTable[VK_MBUTTON]= InputKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] << 8;
      AsyncKeyStateTable[VK_RBUTTON]= InputKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] << 8;
-     SetCursorPos(tmpMsg->paramL,tmpMsg->paramH);
+     SetCursorPos32(tmpMsg->paramL,tmpMsg->paramH);
      lParam=MAKELONG(tmpMsg->paramL,tmpMsg->paramH);
      wParam=0;             
      if (MouseButtonsStates[0]) wParam |= MK_LBUTTON;
@@ -505,18 +502,37 @@
 
 
 /**********************************************************************
- *           SetDoubleClickTime   (USER.20)
+ *           SetDoubleClickTime16   (USER.20)
  */
-void SetDoubleClickTime( WORD interval )
+void SetDoubleClickTime16( UINT16 interval )
 {
-    doubleClickSpeed = interval ? interval : 500;
+    SetDoubleClickTime32( interval );
 }		
 
 
 /**********************************************************************
- *           GetDoubleClickTime   (USER.21)
+ *           SetDoubleClickTime32   (USER32.479)
  */
-WORD GetDoubleClickTime()
+BOOL32 SetDoubleClickTime32( UINT32 interval )
+{
+    doubleClickSpeed = interval ? interval : 500;
+    return TRUE;
+}		
+
+
+/**********************************************************************
+ *           GetDoubleClickTime16   (USER.21)
+ */
+UINT16 GetDoubleClickTime16(void)
+{
+    return doubleClickSpeed;
+}		
+
+
+/**********************************************************************
+ *           GetDoubleClickTime32   (USER32.238)
+ */
+UINT32 GetDoubleClickTime32(void)
 {
     return doubleClickSpeed;
 }		
@@ -527,7 +543,7 @@
  *
  * Implementation of an inter-task SendMessage.
  */
-static LRESULT MSG_SendMessage( HQUEUE16 hDestQueue, HWND hwnd, UINT msg,
+static LRESULT MSG_SendMessage( HQUEUE16 hDestQueue, HWND16 hwnd, UINT msg,
                                 WPARAM16 wParam, LPARAM lParam )
 {
     INT32	  prevSMRL = debugSMRL;
@@ -643,7 +659,7 @@
 /***********************************************************************
  *           MSG_PeekMessage
  */
-static BOOL MSG_PeekMessage( LPMSG16 msg, HWND hwnd, WORD first, WORD last,
+static BOOL MSG_PeekMessage( LPMSG16 msg, HWND16 hwnd, WORD first, WORD last,
                              WORD flags, BOOL peek )
 {
     int pos, mask;
@@ -879,7 +895,7 @@
 /***********************************************************************
  *           GetMessage   (USER.108)
  */
-BOOL GetMessage( SEGPTR msg, HWND hwnd, UINT first, UINT last ) 
+BOOL GetMessage( SEGPTR msg, HWND16 hwnd, UINT first, UINT last ) 
 {
     MSG16 *lpmsg = (MSG16 *)PTR_SEG_TO_LIN(msg);
     MSG_PeekMessage( lpmsg,
@@ -895,7 +911,7 @@
 /***********************************************************************
  *           PostMessage   (USER.110)
  */
-BOOL PostMessage( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+BOOL PostMessage( HWND16 hwnd, WORD message, WORD wParam, LONG lParam )
 {
     MSG16 	msg;
     WND 	*wndPtr;
@@ -913,7 +929,7 @@
        return TRUE;
 #endif  /* CONFIG_IPC */
     
-    if (hwnd == HWND_BROADCAST16)
+    if (hwnd == HWND_BROADCAST)
     {
         dprintf_msg(stddeb,"PostMessage // HWND_BROADCAST !\n");
         for (wndPtr = WIN_GetDesktop()->child; wndPtr; wndPtr = wndPtr->next)
@@ -970,7 +986,7 @@
     if (DDE_SendMessage(&DDE_msg)) return TRUE;
 #endif  /* CONFIG_IPC */
 
-    if (hwnd == HWND_BROADCAST16)
+    if (hwnd == HWND_BROADCAST)
     {
         dprintf_msg(stddeb,"SendMessage // HWND_BROADCAST !\n");
         list = WIN_BuildWinArray( WIN_GetDesktop() );
@@ -992,24 +1008,18 @@
 
     if (HOOK_IsHooked( WH_CALLWNDPROC ))
     {
-	struct msgstruct
-	{
-	    LPARAM   lParam;
-	    WPARAM16 wParam;
-	    UINT16   wMsg;
-	    HWND16   hWnd;
-	} *pmsg;
+	LPCWPSTRUCT16 pmsg;
 
-	if ((pmsg = SEGPTR_NEW(struct msgstruct)))
+	if ((pmsg = SEGPTR_NEW(CWPSTRUCT16)))
 	{
-	    pmsg->hWnd   = hwnd;
-	    pmsg->wMsg   = msg;
+	    pmsg->hwnd   = hwnd;
+	    pmsg->message= msg;
 	    pmsg->wParam = wParam;
 	    pmsg->lParam = lParam;
 	    HOOK_CallHooks16( WH_CALLWNDPROC, HC_ACTION, 1,
 			      (LPARAM)SEGPTR_GET(pmsg) );
-	    hwnd   = pmsg->hWnd;
-	    msg    = pmsg->wMsg;
+	    hwnd   = pmsg->hwnd;
+	    msg    = pmsg->message;
 	    wParam = pmsg->wParam;
 	    lParam = pmsg->lParam;
 	    SEGPTR_FREE( pmsg );
@@ -1033,6 +1043,26 @@
     return ret;
 }
 
+/************************************************************************
+ *	     MSG_CallWndProcHook32
+ */
+static void  MSG_CallWndProcHook32( LPMSG32 pmsg, BOOL32 bUnicode )
+{
+   CWPSTRUCT32 cwp;
+
+   cwp.lParam = pmsg->lParam;
+   cwp.wParam = pmsg->wParam;
+   cwp.message = pmsg->message;
+   cwp.hwnd = pmsg->hwnd;
+
+   if (bUnicode) HOOK_CallHooks32W(WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp);
+   else HOOK_CallHooks32A( WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp );
+
+   pmsg->lParam = cwp.lParam;
+   pmsg->wParam = cwp.wParam;
+   pmsg->message = cwp.message;
+   pmsg->hwnd = cwp.hwnd;
+}
 
 /***********************************************************************
  *           SendMessage32A   (USER32.453)
@@ -1043,7 +1073,7 @@
     WND **list, **ppWnd;
     LRESULT ret;
 
-    if (hwnd == HWND_BROADCAST32)
+    if (hwnd == HWND_BROADCAST)
     {
         list = WIN_BuildWinArray( WIN_GetDesktop() );
         for (ppWnd = list; *ppWnd; ppWnd++)
@@ -1057,7 +1087,8 @@
         return TRUE;
     }
 
-    /* FIXME: call hooks */
+    if (HOOK_IsHooked( WH_CALLWNDPROC ))
+	MSG_CallWndProcHook32( (LPMSG32)&hwnd, FALSE);
 
     if (!(wndPtr = WIN_FindWndPtr( hwnd )))
     {
@@ -1065,24 +1096,12 @@
         return 0;
     }
 
-    if (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_16)
-    {
-        /* Use SendMessage16 for now to get hooks right */
-        UINT16 msg16;
-        WPARAM16 wParam16;
-        if (WINPROC_MapMsg32ATo16( msg, wParam, &msg16, &wParam16, &lParam ) == -1)
-            return 0;
-        ret = SendMessage16( hwnd, msg16, wParam16, lParam );
-        WINPROC_UnmapMsg32ATo16( msg, wParam16, lParam );
-        return ret;
-    }
-
     if (QUEUE_IsDoomedQueue(wndPtr->hmemTaskQ))
         return 0;  /* Don't send anything if the task is dying */
 
     if (wndPtr->hmemTaskQ != GetTaskQueue(0))
     {
-        fprintf( stderr, "SendMessage32A: intertask message not supported\n" );
+        fprintf( stderr, "SendMessage32A: intertask message [%04x] not supported\n", msg );
         return 0;
     }
 
@@ -1103,7 +1122,7 @@
     WND **list, **ppWnd;
     LRESULT ret;
 
-    if (hwnd == HWND_BROADCAST32)
+    if (hwnd == HWND_BROADCAST)
     {
         list = WIN_BuildWinArray( WIN_GetDesktop() );
         for (ppWnd = list; *ppWnd; ppWnd++)
@@ -1117,7 +1136,8 @@
         return TRUE;
     }
 
-    /* FIXME: call hooks */
+    if (HOOK_IsHooked( WH_CALLWNDPROC ))
+        MSG_CallWndProcHook32( (LPMSG32)&hwnd, TRUE);
 
     if (!(wndPtr = WIN_FindWndPtr( hwnd )))
     {
@@ -1141,7 +1161,7 @@
 
 
 /***********************************************************************
- *           WaitMessage    (USER.112)
+ *           WaitMessage    (USER.112) (USER32.577)
  */
 void WaitMessage( void )
 {
@@ -1149,126 +1169,144 @@
 }
 
 
+struct accent_char
+{
+    BYTE ac_accent;
+    BYTE ac_char;
+    BYTE ac_result;
+};
+
+static const struct accent_char accent_chars[] =
+{
+    {'`', 'A', '\300'},  {'`', 'a', '\340'},
+    {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
+    {'^', 'A', '\302'},  {'^', 'a', '\342'},
+    {'~', 'A', '\303'},  {'~', 'a', '\343'},
+    {'"', 'A', '\304'},  {'"', 'a', '\344'},
+    {'O', 'A', '\305'},  {'o', 'a', '\345'},
+    {'0', 'A', '\305'},  {'0', 'a', '\345'},
+    {'A', 'A', '\305'},  {'a', 'a', '\345'},
+    {'A', 'E', '\306'},  {'a', 'e', '\346'},
+    {',', 'C', '\307'},  {',', 'c', '\347'},
+    {'`', 'E', '\310'},  {'`', 'e', '\350'},
+    {'\'', 'E', '\311'}, {'\'', 'e', '\351'},
+    {'^', 'E', '\312'},  {'^', 'e', '\352'},
+    {'"', 'E', '\313'},  {'"', 'e', '\353'},
+    {'`', 'I', '\314'},  {'`', 'i', '\354'},
+    {'\'', 'I', '\315'}, {'\'', 'i', '\355'},
+    {'^', 'I', '\316'},  {'^', 'i', '\356'},
+    {'"', 'I', '\317'},  {'"', 'i', '\357'},
+    {'-', 'D', '\320'},  {'-', 'd', '\360'},
+    {'~', 'N', '\321'},  {'~', 'n', '\361'},
+    {'`', 'O', '\322'},  {'`', 'o', '\362'},
+    {'\'', 'O', '\323'}, {'\'', 'o', '\363'},
+    {'^', 'O', '\324'},  {'^', 'o', '\364'},
+    {'~', 'O', '\325'},  {'~', 'o', '\365'},
+    {'"', 'O', '\326'},  {'"', 'o', '\366'},
+    {'/', 'O', '\330'},  {'/', 'o', '\370'},
+    {'`', 'U', '\331'},  {'`', 'u', '\371'},
+    {'\'', 'U', '\332'}, {'\'', 'u', '\372'},
+    {'^', 'U', '\333'},  {'^', 'u', '\373'},
+    {'"', 'U', '\334'},  {'"', 'u', '\374'},
+    {'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
+    {'T', 'H', '\336'},  {'t', 'h', '\376'},
+    {'s', 's', '\337'},  {'"', 'y', '\377'},
+    {'s', 'z', '\337'},  {'i', 'j', '\377'},
+};
+
+
 /***********************************************************************
- *           TranslateMessage   (USER.113)
+ *           MSG_DoTranslateMessage
  *
- * TranlateMessage translate virtual-key messages into character-messages,
+ * Implementation of TranslateMessage.
+ *
+ * TranslateMessage translates virtual-key messages into character-messages,
  * as follows :
  * WM_KEYDOWN/WM_KEYUP combinations produce a WM_CHAR or WM_DEADCHAR message.
  * ditto replacing WM_* with WM_SYS*
  * This produces WM_CHAR messages only for keys mapped to ASCII characters
  * by the keyboard driver.
  */
-
-const struct accent_char
-	{
-	BYTE ac_accent;
-	BYTE ac_char;
-	BYTE ac_result;
-	} accent_chars[] =
-	{
-	{'`', 'A', '\300'},	{'`', 'a', '\340'},
-	{'\'', 'A', '\301'},	{'\'', 'a', '\341'},
-	{'^', 'A', '\302'},	{'^', 'a', '\342'},
-	{'~', 'A', '\303'},	{'~', 'a', '\343'},
-	{'"', 'A', '\304'},	{'"', 'a', '\344'},
-	{'O', 'A', '\305'},	{'o', 'a', '\345'},
-	{'0', 'A', '\305'},	{'0', 'a', '\345'},
-	{'A', 'A', '\305'},	{'a', 'a', '\345'},
-	{'A', 'E', '\306'},	{'a', 'e', '\346'},
-	{',', 'C', '\307'},	{',', 'c', '\347'},
-	{'`', 'E', '\310'},	{'`', 'e', '\350'},
-	{'\'', 'E', '\311'},	{'\'', 'e', '\351'},
-	{'^', 'E', '\312'},	{'^', 'e', '\352'},
-	{'"', 'E', '\313'},	{'"', 'e', '\353'},
-	{'`', 'I', '\314'},	{'`', 'i', '\354'},
-	{'\'', 'I', '\315'},	{'\'', 'i', '\355'},
-	{'^', 'I', '\316'},	{'^', 'i', '\356'},
-	{'"', 'I', '\317'},	{'"', 'i', '\357'},
-	{'-', 'D', '\320'},	{'-', 'd', '\360'},
-	{'~', 'N', '\321'},	{'~', 'n', '\361'},
-	{'`', 'O', '\322'},	{'`', 'o', '\362'},
-	{'\'', 'O', '\323'},	{'\'', 'o', '\363'},
-	{'^', 'O', '\324'},	{'^', 'o', '\364'},
-	{'~', 'O', '\325'},	{'~', 'o', '\365'},
-	{'"', 'O', '\326'},	{'"', 'o', '\366'},
-	{'/', 'O', '\330'},	{'/', 'o', '\370'},
-	{'`', 'U', '\331'},	{'`', 'u', '\371'},
-	{'\'', 'U', '\332'},	{'\'', 'u', '\372'},
-	{'^', 'U', '\333'},	{'^', 'u', '\373'},
-	{'"', 'U', '\334'},	{'"', 'u', '\374'},
-	{'\'', 'Y', '\335'},	{'\'', 'y', '\375'},
-	{'T', 'H', '\336'},	{'t', 'h', '\376'},
-	{'s', 's', '\337'},	{'"', 'y', '\377'},
-	{'s', 'z', '\337'},	{'i', 'j', '\377'},
-	};
-
-BOOL TranslateMessage( LPMSG16 msg )
+static BOOL32 MSG_DoTranslateMessage( UINT32 message, HWND32 hwnd,
+                                      WPARAM32 wParam, LPARAM lParam )
 {
-    UINT message = msg->message;
-    BYTE wparam[2];
+    static int dead_char;
+    BYTE wp[2];
     
-    if ((debugging_msg
-	&& message != WM_MOUSEMOVE && message != WM_TIMER)
-    || (debugging_key
-	&& message >= WM_KEYFIRST && message <= WM_KEYLAST))
-	    fprintf(stddeb, "TranslateMessage(%s, %04X, %08lX)\n",
-		SPY_GetMsgName(msg->message), msg->wParam, msg->lParam);
-    if ((message == WM_KEYDOWN) || (message == WM_SYSKEYDOWN))
+    if ((debugging_msg && message != WM_MOUSEMOVE && message != WM_TIMER)
+        || (debugging_key
+            && message >= WM_KEYFIRST && message <= WM_KEYLAST))
+        fprintf(stddeb, "TranslateMessage(%s, %04X, %08lX)\n",
+		SPY_GetMsgName(message), wParam, lParam );
+
+    if ((message != WM_KEYDOWN) && (message != WM_SYSKEYDOWN)) return FALSE;
+
+    dprintf_key( stddeb, "Translating key %04X, scancode %04X\n",
+                 wParam, HIWORD(lParam) );
+
+    /* FIXME : should handle ToAscii yielding 2 */
+    switch (ToAscii32(wParam, HIWORD(lParam),
+                      QueueKeyStateTable,(LPWORD)wp, 0)) 
     {
-	static dead_char;
+    case 1 :
+        message = (message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
+        /* Should dead chars handling go in ToAscii ? */
+        if (dead_char)
+        {
+            int i;
 
-	if (debugging_msg || debugging_key)
-	    fprintf(stddeb, "Translating key %04X, scancode %04X\n",
-		msg->wParam, HIWORD(msg->lParam) );
+            if (wp[0] == ' ') wp[0] =  dead_char;
+            if (dead_char == 0xa8) dead_char = '"';
+            else if (dead_char == 0xb4) dead_char = '\'';
+            for (i = 0; i < sizeof(accent_chars)/sizeof(accent_chars[0]); i++)
+                if ((accent_chars[i].ac_accent == dead_char) &&
+                    (accent_chars[i].ac_char == wp[0]))
+                {
+                    wp[0] = accent_chars[i].ac_result;
+                    break;
+                }
+            dead_char = 0;
+        }
+        dprintf_key(stddeb, "1 -> PostMessage(%s)\n", SPY_GetMsgName(message));
+        PostMessage( hwnd, message, wp[0], lParam );
+        return TRUE;
 
-	/* FIXME : should handle ToAscii yielding 2 */
-	switch (ToAscii32(msg->wParam, HIWORD(msg->lParam),
-		QueueKeyStateTable,(LPWORD)wparam, 0)) 
-	    {
-	    case 1 :
-		message = message == WM_KEYDOWN ? WM_CHAR : WM_SYSCHAR;
-		/* Should dead chars handling go in ToAscii ? */
-		if (dead_char)
-		    {
-		    int i;
-
-		    if (wparam[0] == ' ')
-			wparam[0] =  dead_char;
-		    if (dead_char == 0xa8)
-			dead_char = '"';
-		    else if (dead_char == 0xb4)
-			dead_char = '\'';
-		    for (i = 0;
-			i < sizeof(accent_chars) / sizeof(accent_chars[0]);
-			i += 1)
-			if (accent_chars[i].ac_accent == dead_char
-			&& accent_chars[i].ac_char == wparam[0])
-			    {
-			    wparam[0] = accent_chars[i].ac_result;
-			    break;
-			    }
-		    dead_char = 0;
-		    }
-dprintf_key(stddeb, "1 -> PostMessage(%s)\n", SPY_GetMsgName(message));
-		PostMessage( msg->hwnd, message, wparam[0], msg->lParam );
-		return TRUE;
-	    case -1 :
-		message = message == WM_KEYDOWN ? WM_DEADCHAR : WM_SYSDEADCHAR;
-		dead_char = wparam[0];
-dprintf_key(stddeb, "-1 -> PostMessage(%s)\n", SPY_GetMsgName(message));
-		PostMessage( msg->hwnd, message, wparam[0], msg->lParam );
-		return TRUE;
-	    }
+    case -1 :
+        message = (message == WM_KEYDOWN) ? WM_DEADCHAR : WM_SYSDEADCHAR;
+        dead_char = wp[0];
+        dprintf_key( stddeb, "-1 -> PostMessage(%s)\n",
+                     SPY_GetMsgName(message));
+        PostMessage( hwnd, message, wp[0], lParam );
+        return TRUE;
     }
     return FALSE;
 }
 
 
 /***********************************************************************
- *           DispatchMessage   (USER.114)
+ *           TranslateMessage16   (USER.113)
  */
-LONG DispatchMessage( const MSG16* msg )
+BOOL16 TranslateMessage16( const MSG16 *msg )
+{
+    return MSG_DoTranslateMessage( msg->message, msg->hwnd,
+                                   msg->wParam, msg->lParam );
+}
+
+
+/***********************************************************************
+ *           TranslateMessage32   (USER32.555)
+ */
+BOOL32 TranslateMessage32( const MSG32 *msg )
+{
+    return MSG_DoTranslateMessage( msg->message, msg->hwnd,
+                                   msg->wParam, msg->lParam );
+}
+
+
+/***********************************************************************
+ *           DispatchMessage16   (USER.114)
+ */
+LONG DispatchMessage16( const MSG16* msg )
 {
     WND * wndPtr;
     LONG retval;
@@ -1313,6 +1351,100 @@
 
 
 /***********************************************************************
+ *           DispatchMessage32A   (USER32.140)
+ */
+LONG DispatchMessage32A( const MSG32* msg )
+{
+    WND * wndPtr;
+    LONG retval;
+    int painting;
+    
+      /* Process timer messages */
+    if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
+    {
+	if (msg->lParam)
+        {
+/*            HOOK_CallHooks32A( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
+	    return CallWindowProc32A( (WNDPROC32)msg->lParam, msg->hwnd,
+                                   msg->message, msg->wParam, GetTickCount() );
+        }
+    }
+
+    if (!msg->hwnd) return 0;
+    if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
+    if (!wndPtr->winproc) return 0;
+    painting = (msg->message == WM_PAINT);
+    if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
+/*    HOOK_CallHooks32A( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
+
+    SPY_EnterMessage( SPY_DISPATCHMESSAGE32, msg->hwnd, msg->message,
+                      msg->wParam, msg->lParam );
+    retval = CallWindowProc32A( (WNDPROC32)wndPtr->winproc,
+                                msg->hwnd, msg->message,
+                                msg->wParam, msg->lParam );
+    SPY_ExitMessage( SPY_RESULT_OK32, msg->hwnd, msg->message, retval );
+
+    if (painting && (wndPtr = WIN_FindWndPtr( msg->hwnd )) &&
+        (wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
+    {
+	fprintf(stderr, "BeginPaint not called on WM_PAINT for hwnd %04x!\n", 
+		msg->hwnd);
+	wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
+        /* Validate the update region to avoid infinite WM_PAINT loop */
+        ValidateRect32( msg->hwnd, NULL );
+    }
+    return retval;
+}
+
+
+/***********************************************************************
+ *           DispatchMessage32W   (USER32.141)
+ */
+LONG DispatchMessage32W( const MSG32* msg )
+{
+    WND * wndPtr;
+    LONG retval;
+    int painting;
+    
+      /* Process timer messages */
+    if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
+    {
+	if (msg->lParam)
+        {
+/*            HOOK_CallHooks32W( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
+	    return CallWindowProc32W( (WNDPROC32)msg->lParam, msg->hwnd,
+                                   msg->message, msg->wParam, GetTickCount() );
+        }
+    }
+
+    if (!msg->hwnd) return 0;
+    if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
+    if (!wndPtr->winproc) return 0;
+    painting = (msg->message == WM_PAINT);
+    if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
+/*    HOOK_CallHooks32W( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
+
+    SPY_EnterMessage( SPY_DISPATCHMESSAGE32, msg->hwnd, msg->message,
+                      msg->wParam, msg->lParam );
+    retval = CallWindowProc32W( (WNDPROC32)wndPtr->winproc,
+                                msg->hwnd, msg->message,
+                                msg->wParam, msg->lParam );
+    SPY_ExitMessage( SPY_RESULT_OK32, msg->hwnd, msg->message, retval );
+
+    if (painting && (wndPtr = WIN_FindWndPtr( msg->hwnd )) &&
+        (wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
+    {
+	fprintf(stderr, "BeginPaint not called on WM_PAINT for hwnd %04x!\n", 
+		msg->hwnd);
+	wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
+        /* Validate the update region to avoid infinite WM_PAINT loop */
+        ValidateRect32( msg->hwnd, NULL );
+    }
+    return retval;
+}
+
+
+/***********************************************************************
  *           RegisterWindowMessage16   (USER.118)
  */
 WORD RegisterWindowMessage16( SEGPTR str )
@@ -1354,24 +1486,33 @@
 
 
 /***********************************************************************
- *           GetCurrentTime    (USER.15)
+ *           GetCurrentTime16    (USER.15)
  *
  * (effectively identical to GetTickCount)
  */
-DWORD GetCurrentTime(void)
+DWORD GetCurrentTime16(void)
 {
     return GetTickCount();
 }
 
 
 /***********************************************************************
- *           InSendMessage    (USER.192)
+ *           InSendMessage16    (USER.192)
  */
-BOOL InSendMessage()
+BOOL16 InSendMessage16(void)
+{
+    return InSendMessage32();
+}
+
+
+/***********************************************************************
+ *           InSendMessage32    (USER32.319)
+ */
+BOOL32 InSendMessage32(void)
 {
     MESSAGEQUEUE *queue;
 
     if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) )))
         return 0;
-    return (BOOL)queue->InSendMessageHandle;
+    return (BOOL32)queue->InSendMessageHandle;
 }
diff --git a/windows/msgbox.c b/windows/msgbox.c
index 1ad540d..d8a0978 100644
--- a/windows/msgbox.c
+++ b/windows/msgbox.c
@@ -173,7 +173,7 @@
      case IDIGNORE:
      case IDYES:
      case IDNO:
-      EndDialog(hwnd, wParam);
+      EndDialog32(hwnd, wParam);
       break;
     }
     break;
diff --git a/windows/nonclient.c b/windows/nonclient.c
index ba5f6cc..d4001a1 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -268,7 +268,7 @@
  * but without the borders (if any).
  * The rectangle is in window coordinates (for drawing with GetWindowDC()).
  */
-static void NC_GetInsideRect( HWND hwnd, RECT32 *rect )
+static void NC_GetInsideRect( HWND32 hwnd, RECT32 *rect )
 {
     WND * wndPtr = WIN_FindWndPtr( hwnd );
 
@@ -457,7 +457,7 @@
 /***********************************************************************
  *           NC_DrawMaxButton
  */
-static void NC_DrawMaxButton( HWND hwnd, HDC16 hdc, BOOL down )
+static void NC_DrawMaxButton( HWND32 hwnd, HDC16 hdc, BOOL down )
 {
     RECT32 rect;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
@@ -477,7 +477,7 @@
 /***********************************************************************
  *           NC_DrawMinButton
  */
-static void NC_DrawMinButton( HWND hwnd, HDC16 hdc, BOOL down )
+static void NC_DrawMinButton( HWND32 hwnd, HDC16 hdc, BOOL down )
 {
     RECT32 rect;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
@@ -589,7 +589,7 @@
  * Draw the window caption.
  * The correct pen for the window frame must be selected in the DC.
  */
-static void NC_DrawCaption( HDC16 hdc, RECT16 *rect, HWND hwnd,
+static void NC_DrawCaption( HDC16 hdc, RECT16 *rect, HWND32 hwnd,
 			    DWORD style, BOOL active )
 {
     RECT16 r = *rect;
@@ -647,8 +647,8 @@
 
     if (GetWindowText32A( hwnd, buffer, sizeof(buffer) ))
     {
-	if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
-	else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
+	if (active) SetTextColor( hdc, GetSysColor32( COLOR_CAPTIONTEXT ) );
+	else SetTextColor( hdc, GetSysColor32( COLOR_INACTIVECAPTIONTEXT ) );
 	SetBkMode32( hdc, TRANSPARENT );
 	DrawText16( hdc, buffer, -1, &r,
                     DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
@@ -805,7 +805,7 @@
 	    WORD msg = HIWORD( lParam );
 	    if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
 		(msg == WM_RBUTTONDOWN))
-		MessageBeep(0);
+		MessageBeep32(0);
 	}
 	break;
 
@@ -815,7 +815,7 @@
 	    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) break;
 	    if (wndPtr->class->hCursor)
 	    {
-		SetCursor( wndPtr->class->hCursor );
+		SetCursor16( wndPtr->class->hCursor );
 		return TRUE;
 	    }
 	    else return FALSE;
@@ -823,23 +823,23 @@
 
     case HTLEFT:
     case HTRIGHT:
-	return (LONG)SetCursor( LoadCursor16( 0, IDC_SIZEWE ) );
+	return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZEWE ) );
 
     case HTTOP:
     case HTBOTTOM:
-	return (LONG)SetCursor( LoadCursor16( 0, IDC_SIZENS ) );
+	return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENS ) );
 
     case HTTOPLEFT:
     case HTBOTTOMRIGHT:	
-	return (LONG)SetCursor( LoadCursor16( 0, IDC_SIZENWSE ) );
+	return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE ) );
 
     case HTTOPRIGHT:
     case HTBOTTOMLEFT:
-	return (LONG)SetCursor( LoadCursor16( 0, IDC_SIZENESW ) );
+	return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENESW ) );
     }
 
     /* Default cursor: arrow */
-    return (LONG)SetCursor( LoadCursor16( 0, IDC_ARROW ) );
+    return (LONG)SetCursor16( LoadCursor16( 0, IDC_ARROW ) );
 }
 
 /***********************************************************************
@@ -870,7 +870,7 @@
  *
  * Track a mouse button press on the system menu.
  */
-static void NC_TrackSysMenu( HWND hwnd, POINT16 pt )
+static void NC_TrackSysMenu( HWND32 hwnd, POINT16 pt )
 {
     WND*	wndPtr = WIN_FindWndPtr( hwnd );
     
@@ -928,7 +928,8 @@
  * Initialisation of a move or resize, when initiatied from a menu choice.
  * Return hit test code for caption or sizing border.
  */
-static LONG NC_StartSizeMove( HWND hwnd, WPARAM16 wParam, POINT16 *capturePoint )
+static LONG NC_StartSizeMove( HWND32 hwnd, WPARAM16 wParam,
+                              POINT16 *capturePoint )
 {
     LONG hittest = 0;
     POINT16 pt;
@@ -1000,7 +1001,7 @@
 	}
     }
     *capturePoint = pt;
-    SetCursorPos( capturePoint->x, capturePoint->y );
+    SetCursorPos32( capturePoint->x, capturePoint->y );
     NC_HandleSetCursor( hwnd, (WPARAM16)hwnd, MAKELONG( hittest, WM_MOUSEMOVE ));
     return hittest;
 }
@@ -1011,7 +1012,7 @@
  *
  * Perform SC_MOVE and SC_SIZE commands.
  */
-static void NC_DoSizeMove( HWND hwnd, WORD wParam, POINT16 pt )
+static void NC_DoSizeMove( HWND32 hwnd, WORD wParam, POINT16 pt )
 {
     MSG16 msg;
     RECT16 sizingRect, mouseRect;
@@ -1099,8 +1100,8 @@
       if( hIcon )
       {
         hDragCursor =  CURSORICON_IconToCursor( hIcon, TRUE );
-        hOldCursor = SetCursor(hDragCursor);
-        ShowCursor(1);
+        hOldCursor = SetCursor32(hDragCursor);
+        ShowCursor32( TRUE );
       } else iconic = FALSE;
     }
 
@@ -1143,7 +1144,7 @@
 	if (dx || dy)
 	{
             moved = 1;
-	    if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
+	    if (msg.message == WM_KEYDOWN) SetCursorPos32( pt.x, pt.y );
 	    else
 	    {
 		RECT16 newRect = sizingRect;
@@ -1167,9 +1168,9 @@
     ReleaseCapture();
     if( iconic )
     {
-      ShowCursor(0);
-      SetCursor(hOldCursor);
-      if( hDragCursor ) DestroyCursor(hDragCursor);
+      ShowCursor32( FALSE );
+      SetCursor32(hOldCursor);
+      if( hDragCursor ) DestroyCursor32( hDragCursor );
     }
     else
       NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
@@ -1225,7 +1226,7 @@
  *
  * Track a mouse button press on the minimize or maximize box.
  */
-static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
+static void NC_TrackMinMaxBox( HWND32 hwnd, WORD wParam )
 {
     MSG16 msg;
     HDC32 hdc = GetWindowDC32( hwnd );
@@ -1306,8 +1307,8 @@
             SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
 	    break;
         default:
-            TranslateMessage( msg );
-            DispatchMessage( msg );
+            TranslateMessage16( msg );
+            DispatchMessage16( msg );
             break;
 	}
         if (!IsWindow( hwnd ))
diff --git a/windows/painting.c b/windows/painting.c
index bdc5593..2c5e4f9 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -108,7 +108,7 @@
     wndPtr->hrgnUpdate = 0;
     wndPtr->flags &= ~WIN_INTERNAL_PAINT;
 
-    HideCaret( hwnd );
+    HideCaret32( hwnd );
 
     dprintf_win(stddeb,"hrgnUpdate = %04x, ", hrgnUpdate);
 
@@ -175,7 +175,7 @@
 BOOL16 EndPaint16( HWND16 hwnd, const PAINTSTRUCT16* lps )
 {
     ReleaseDC16( hwnd, lps->hdc );
-    ShowCaret( hwnd );
+    ShowCaret32( hwnd );
     return TRUE;
 }
 
@@ -186,7 +186,7 @@
 BOOL32 EndPaint32( HWND32 hwnd, const PAINTSTRUCT32 *lps )
 {
     ReleaseDC32( hwnd, lps->hdc );
-    ShowCaret( hwnd );
+    ShowCaret32( hwnd );
     return TRUE;
 }
 
@@ -225,7 +225,7 @@
 /***********************************************************************
  *           GetControlBrush    (USER.326)
  */
-HBRUSH16 GetControlBrush( HWND hwnd, HDC16 hdc, WORD control )
+HBRUSH16 GetControlBrush( HWND16 hwnd, HDC16 hdc, UINT16 control )
 {
     return (HBRUSH16)SendMessage32A( GetParent32(hwnd), WM_CTLCOLOR+control,
                                      (WPARAM32)hdc, (LPARAM)hwnd );
diff --git a/windows/queue.c b/windows/queue.c
index 709fa02..dc99aed 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -306,17 +306,20 @@
         !(senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask))) 
 	{ dprintf_msg(stddeb,"\trcm: nothing to do\n"); return; }
 
-    queue->InSendMessageHandle = queue->hSendingTask;
-    if( !(queue->hSendingTask = senderQ->hPrevSendingTask) )
+    if( !senderQ->hPrevSendingTask )
     {
       queue->wakeBits &= ~QS_SENDMESSAGE;	/* no more sent messages */
       queue->changeBits &= ~QS_SENDMESSAGE;
     }
 
-    /* Remove sending queue from the list */
+    /* Save current state on stack */
     prevSender                 = queue->InSendMessageHandle;
     prevCtrlPtr		       = queue->smResultCurrent;
+
+    /* Remove sending queue from the list */
+    queue->InSendMessageHandle = queue->hSendingTask;
     queue->smResultCurrent     = senderQ->smResultInit;
+    queue->hSendingTask	       = senderQ->hPrevSendingTask;
 
     dprintf_msg(stddeb, "\trcm: smResultCurrent = %08x, prevCtrl = %08x\n", 
 				(unsigned)queue->smResultCurrent, (unsigned)prevCtrlPtr );
@@ -488,8 +491,8 @@
 static void QUEUE_WakeSomeone( UINT message )
 {
     WND*	  wndPtr = NULL;
-    HWND          hwnd;
     WORD          wakeBit;
+    HWND32 hwnd;
     MESSAGEQUEUE *queue = pCursorQueue;
 
     if( (message >= WM_KEYFIRST) && (message <= WM_KEYLAST) )
@@ -561,7 +564,7 @@
     if ((pos == sysMsgQueue->nextMessage) && sysMsgQueue->msgCount)
     {
         /* Queue is full, beep (but not on every mouse motion...) */
-        if (message != WM_MOUSEMOVE) MessageBeep(0);
+        if (message != WM_MOUSEMOVE) MessageBeep32(0);
         return;
     }
 
@@ -647,9 +650,18 @@
 
 
 /***********************************************************************
- *           PostQuitMessage   (USER.6)
+ *           PostQuitMessage16   (USER.6)
  */
-void PostQuitMessage( INT exitCode )
+void PostQuitMessage16( INT16 exitCode )
+{
+    PostQuitMessage32( exitCode );
+}
+
+
+/***********************************************************************
+ *           PostQuitMessage32   (USER32.420)
+ */
+void PostQuitMessage32( INT32 exitCode )
 {
     MESSAGEQUEUE *queue;
 
@@ -673,8 +685,8 @@
 /***********************************************************************
  *           GetWindowThreadProcessId   (USER32.312)
  */
-DWORD
-GetWindowThreadProcessId(HWND32 hwnd,LPDWORD process) {
+DWORD GetWindowThreadProcessId( HWND32 hwnd, LPDWORD process )
+{
     HTASK16 htask;
     TDB	*tdb;
 
@@ -695,9 +707,18 @@
 
 
 /***********************************************************************
- *           SetMessageQueue   (USER.266)
+ *           SetMessageQueue16   (USER.266)
  */
-BOOL SetMessageQueue( int size )
+BOOL16 SetMessageQueue16( INT16 size )
+{
+    return SetMessageQueue32( size );
+}
+
+
+/***********************************************************************
+ *           SetMessageQueue32   (USER32.493)
+ */
+BOOL32 SetMessageQueue32( INT32 size )
 {
     HQUEUE16 hQueue, hNewQueue;
     MESSAGEQUEUE *queuePtr;
@@ -757,19 +778,29 @@
 
 
 /***********************************************************************
- *           GetInputState   (USER.335)
+ *           GetInputState16   (USER.335)
  */
-BOOL GetInputState()
+BOOL16 GetInputState16(void)
+{
+    return GetInputState32();
+}
+
+
+/***********************************************************************
+ *           GetInputState32   (USER32.243)
+ */
+BOOL32 GetInputState32(void)
 {
     MESSAGEQUEUE *queue;
 
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return FALSE;
+    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) )))
+        return FALSE;
     return queue->wakeBits & (QS_KEY | QS_MOUSEBUTTON);
 }
 
 
 /***********************************************************************
- *           GetMessagePos   (USER.119)
+ *           GetMessagePos   (USER.119) (USER32.271)
  */
 DWORD GetMessagePos(void)
 {
@@ -781,7 +812,7 @@
 
 
 /***********************************************************************
- *           GetMessageTime   (USER.120)
+ *           GetMessageTime   (USER.120) (USER32.272)
  */
 LONG GetMessageTime(void)
 {
@@ -793,7 +824,7 @@
 
 
 /***********************************************************************
- *           GetMessageExtraInfo   (USER.288)
+ *           GetMessageExtraInfo   (USER.288) (USER32.270)
  */
 LONG GetMessageExtraInfo(void)
 {
diff --git a/windows/scroll.c b/windows/scroll.c
index 9fec3e0..682b438 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -65,7 +65,7 @@
 	  hrgnClip = CreateRectRgnIndirect32( &rc );
 
           if ((hCaretWnd == hwnd) || IsChild32(hwnd,hCaretWnd))
-              HideCaret(hCaretWnd);
+              HideCaret32(hCaretWnd);
           else hCaretWnd = 0;
  
 	  hdc = GetDCEx32(hwnd, hrgnClip, DCX_CACHE | DCX_CLIPSIBLINGS);
@@ -75,7 +75,7 @@
        {
 	  CopyRect32(&rc, rect);
 
-          if (hCaretWnd == hwnd) HideCaret(hCaretWnd);
+          if (hCaretWnd == hwnd) HideCaret32(hCaretWnd);
           else hCaretWnd = 0;
 
 	  hdc = GetDCEx32( hwnd, 0, DCX_CACHE | DCX_USESTYLE );
@@ -114,7 +114,7 @@
 	GetCaretPos32(&pt);
 	pt.x += dx; pt.y += dy;
 	SetCaretPos(pt.x, pt.y);
-	ShowCaret(hCaretWnd);
+	ShowCaret32(hCaretWnd);
     }
     return TRUE;
 }
@@ -331,7 +331,7 @@
            MapWindowPoints32( hCaret, hWnd, (LPPOINT32)&rc, 2 );
            if( IntersectRect32(lprc, lprc, &rc) )
            {
-               HideCaret(0);
+               HideCaret32(0);
   	       lprc->left = pt.x; lprc->top = pt.y;
 	       return TRUE;
            }
@@ -450,7 +450,7 @@
 	if( bCaret )
 	{
 	    SetCaretPos( rc.left + dx, rc.top + dy );
-	    ShowCaret(0);
+	    ShowCaret32(0);
 	}
 
 	if( bOwnRgn && hrgnUpdate ) DeleteObject32( hrgnUpdate );
diff --git a/windows/syscolor.c b/windows/syscolor.c
index 596eceb..7bc455b 100644
--- a/windows/syscolor.c
+++ b/windows/syscolor.c
@@ -46,7 +46,7 @@
 static COLORREF SysColors[NUM_SYS_COLORS];
 
 #define MAKE_SOLID(color) \
-         (PALETTEINDEX(GetNearestPaletteIndex(STOCK_DEFAULT_PALETTE,(color))))
+       (PALETTEINDEX(GetNearestPaletteIndex32(STOCK_DEFAULT_PALETTE,(color))))
 
 /*************************************************************************
  *             SYSCOLOR_SetColor
@@ -145,22 +145,28 @@
 
 
 /*************************************************************************
- *             GetSysColor   (USER.180) (USER32.288)
+ *             GetSysColor16   (USER.180)
  */
-
-COLORREF GetSysColor( INT32 nIndex )
+COLORREF GetSysColor16( INT16 nIndex )
 {
-    dprintf_syscolor(stddeb,"System Color %d = %8lx\n", 
-		    nIndex, SysColors[nIndex]);
     return SysColors[nIndex];
 }
 
 
 /*************************************************************************
- *             SetSysColors          (USER.181)
+ *             GetSysColor32   (USER32.288)
  */
+COLORREF GetSysColor32( INT32 nIndex )
+{
+    return SysColors[nIndex];
+}
 
-void SetSysColors(int nChanges, LPINT16 lpSysColor, COLORREF *lpColorValues)
+
+/*************************************************************************
+ *             SetSysColors16   (USER.181)
+ */
+VOID SetSysColors16( INT16 nChanges, const INT16 *lpSysColor,
+                     const COLORREF *lpColorValues )
 {
     int i;
 
@@ -171,9 +177,35 @@
 
     /* Send WM_SYSCOLORCHANGE message to all windows */
 
-    /* ................ */
+    SendMessage32A( HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0 );
 
     /* Repaint affected portions of all visible windows */
 
-    /* ................ */
+    RedrawWindow32( GetDesktopWindow32(), NULL, 0,
+                RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN );
+}
+
+
+/*************************************************************************
+ *             SetSysColors32   (USER32.504)
+ */
+BOOL32 SetSysColors32( INT32 nChanges, const INT32 *lpSysColor,
+                       const COLORREF *lpColorValues )
+{
+    int i;
+
+    for (i = 0; i < nChanges; i++)
+    {
+	SYSCOLOR_SetColor( lpSysColor[i], lpColorValues[i] );
+    }
+
+    /* Send WM_SYSCOLORCHANGE message to all windows */
+
+    SendMessage32A( HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0 );
+
+    /* Repaint affected portions of all visible windows */
+
+    RedrawWindow32( GetDesktopWindow32(), NULL, 0,
+                RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN );
+    return TRUE;
 }
diff --git a/windows/sysmetrics.c b/windows/sysmetrics.c
index 5325a86..8bbfb5e 100644
--- a/windows/sysmetrics.c
+++ b/windows/sysmetrics.c
@@ -67,10 +67,20 @@
 
 
 /***********************************************************************
- *           GetSystemMetrics    (USER.179)
+ *           GetSystemMetrics16    (USER.179)
  */
-int GetSystemMetrics( WORD index )
+INT16 GetSystemMetrics16( INT16 index )
 {
-    if (index > SM_CMETRICS) return 0;
+    if ((index < 0) || (index > SM_CMETRICS)) return 0;
+    else return sysMetrics[index];    
+}
+
+
+/***********************************************************************
+ *           GetSystemMetrics32    (USER32.291)
+ */
+INT32 GetSystemMetrics32( INT32 index )
+{
+    if ((index < 0) || (index > SM_CMETRICS)) return 0;
     else return sysMetrics[index];    
 }
diff --git a/windows/win.c b/windows/win.c
index 5d96ee1..da44073 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -38,7 +38,7 @@
 /* Desktop window */
 static WND *pWndDesktop = NULL;
 
-static HWND hwndSysModal = 0;
+static HWND32 hwndSysModal = 0;
 
 static WORD wDragWidth = 4;
 static WORD wDragHeight= 3;
@@ -47,6 +47,7 @@
 extern HWND32 CARET_GetHwnd(void);
 extern BOOL32 WINPOS_ActivateOtherWindow(WND* pWnd);
 extern void   WINPOS_CheckActive(HWND32);
+extern BOOL32 EVENT_CheckFocus(void);
 
 /***********************************************************************
  *           WIN_FindWndPtr
@@ -224,7 +225,7 @@
  */
 HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue )
 {
-    HWND hwndRet;
+    HWND32 hwndRet;
     WND *pWnd = pWndDesktop;
 
     /* Note: the desktop window never gets WM_PAINT messages 
@@ -306,9 +307,9 @@
  *
  * Destroy storage associated to a window. "Internals" p.358
  */
-static void WIN_DestroyWindow( WND* wndPtr )
+static WND* WIN_DestroyWindow( WND* wndPtr )
 {
-    HWND hwnd = wndPtr->hwndSelf;
+    HWND32 hwnd = wndPtr->hwndSelf;
     WND *pWnd;
 
     dprintf_win( stddeb, "WIN_DestroyWindow: %04x\n", wndPtr->hwndSelf );
@@ -321,11 +322,7 @@
     /* free child windows */
 
     while ((pWnd = wndPtr->child))
-    {
-        /* Make sure the linked list remains coherent */
-        wndPtr->child = pWnd->next;
-        WIN_DestroyWindow( pWnd );
-    }
+        wndPtr->child = WIN_DestroyWindow( pWnd );
 
     SendMessage32A( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
 
@@ -370,8 +367,10 @@
 
     wndPtr->class->cWindows--;
     wndPtr->class = NULL;
+    pWnd = wndPtr->next;
 
     USER_HEAP_FREE( hwnd );
+    return pWnd;
 }
 
 /***********************************************************************
@@ -400,7 +399,7 @@
 BOOL32 WIN_CreateDesktopWindow(void)
 {
     CLASS *class;
-    HWND hwndDesktop;
+    HWND32 hwndDesktop;
 
     dprintf_win(stddeb,"Creating desktop window\n");
 
@@ -460,14 +459,14 @@
  *
  * Implementation of CreateWindowEx().
  */
-static HWND WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
-                                BOOL unicode )
+static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
+                                  BOOL32 win32, BOOL32 unicode )
 {
     CLASS *classPtr;
     WND *wndPtr;
     HWND16 hwnd, hwndLinkAfter;
     POINT16 maxSize, maxPos, minTrack, maxTrack;
-    LRESULT wmcreate;
+    LRESULT (*localSend32)(HWND32, UINT32, WPARAM32, LPARAM);
 
     dprintf_win( stddeb, "CreateWindowEx: " );
     if (HIWORD(cs->lpszName)) dprintf_win( stddeb, "'%s' ", cs->lpszName );
@@ -566,7 +565,7 @@
     wndPtr->dwStyle        = cs->style & ~WS_VISIBLE;
     wndPtr->dwExStyle      = cs->dwExStyle;
     wndPtr->wIDmenu        = 0;
-    wndPtr->flags          = 0;
+    wndPtr->flags          = win32 ? WIN_ISWIN32 : 0;
     wndPtr->pVScroll       = NULL;
     wndPtr->pHScroll       = NULL;
     wndPtr->pProp          = NULL;
@@ -585,9 +584,7 @@
 
 	cbtc.lpcs = cs;
 	cbtc.hwndInsertAfter = hwndLinkAfter;
-	wmcreate = !HOOK_CallHooks32A( WH_CBT, HCBT_CREATEWND, hwnd,
-				       (LPARAM)&cbtc );
-	if (!wmcreate)
+	if ( HOOK_CallHooks32A(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc) )
 	{
 	    dprintf_win(stddeb, "CreateWindowEx: CBT-hook returned 0\n");
 	    USER_HEAP_FREE( hwnd );
@@ -726,85 +723,70 @@
      */
 
     maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
-    if (unicode)
+
+    localSend32 = unicode ? SendMessage32W : SendMessage32A;
+    if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
     {
-        if (!SendMessage32W( hwnd, WM_NCCREATE, 0, (LPARAM)cs)) wmcreate = -1;
-        else
-        {
-            WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
-                                   NULL, NULL, 0, &wndPtr->rectClient );
-	    OffsetRect16(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
-					    maxPos.y - wndPtr->rectWindow.top);
-            wmcreate = SendMessage32W( hwnd, WM_CREATE, 0, (LPARAM)cs );
-        }
-    }
-    else
-    {
-        if (!SendMessage32A( hwnd, WM_NCCREATE, 0, (LPARAM)cs)) wmcreate = -1;
-        else
-        {
-            WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
-                                   NULL, NULL, 0, &wndPtr->rectClient );
-            OffsetRect16(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
+        WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
+                               NULL, NULL, 0, &wndPtr->rectClient );
+        OffsetRect16(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
                                             maxPos.y - wndPtr->rectWindow.top);
-            wmcreate = SendMessage32A( hwnd, WM_CREATE, 0, (LPARAM)cs );
+        if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
+        {
+            /* Send the size messages */
+
+            if (!(wndPtr->flags & WIN_NEED_SIZE))
+            {
+                /* send it anyway */
+                SendMessage16( hwnd, WM_SIZE, SIZE_RESTORED,
+                        MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
+                        wndPtr->rectClient.bottom-wndPtr->rectClient.top));
+                SendMessage16( hwnd, WM_MOVE, 0, MAKELONG( wndPtr->rectClient.left,
+                                                   wndPtr->rectClient.top ));
+            }
+
+            WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LPARAM)hwnd );
+            if (!IsWindow(hwnd)) return 0;
+
+            /* Show the window, maximizing or minimizing if needed */
+
+            if (wndPtr->dwStyle & WS_MINIMIZE)
+            {
+                /* MinMaximize(hwnd, SW_SHOWMINNOACTIVE, 1) in "Internals" */
+
+                wndPtr->dwStyle &= ~WS_MAXIMIZE;
+                WINPOS_FindIconPos( hwnd );
+                SetWindowPos32( hwnd, 0, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y,
+                        SYSMETRICS_CXICON, SYSMETRICS_CYICON,
+                        SWP_FRAMECHANGED | ((GetActiveWindow32())? SWP_NOACTIVATE : 0)  );
+            }
+            else if (wndPtr->dwStyle & WS_MAXIMIZE)
+            {
+                /* MinMaximize(hwnd, SW_SHOWMAXIMIZED, 1) */
+
+                NC_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack );
+                SetWindowPos32( hwnd, 0, maxPos.x, maxPos.y, maxSize.x, maxSize.y,
+                    ((GetActiveWindow32())? SWP_NOACTIVATE : 0) | SWP_FRAMECHANGED );
+            }
+
+            if (cs->style & WS_VISIBLE) ShowWindow32( hwnd, SW_SHOW );
+
+            /* Call WH_SHELL hook */
+
+            if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
+                HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
+
+            dprintf_win(stddeb, "CreateWindowEx: created window %04x\n", hwnd);
+            return hwnd;
         }
     }
-    
-    if (wmcreate == -1)
-    {
-	  /* Abort window creation */
-	dprintf_win(stddeb,"CreateWindowEx: wmcreate==-1, aborting\n");
-        WIN_UnlinkWindow( hwnd );
-        WIN_DestroyWindow( wndPtr );
-	return 0;
-    }
 
-    /* Send the size messages */
+    /* Abort window creation */
 
-    if (!(wndPtr->flags & WIN_NEED_SIZE))
-    {
-	/* send it anyway */
-	SendMessage16( hwnd, WM_SIZE, SIZE_RESTORED,
-                   MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
-                            wndPtr->rectClient.bottom-wndPtr->rectClient.top));
-        SendMessage16( hwnd, WM_MOVE, 0, MAKELONG( wndPtr->rectClient.left,
-                                                   wndPtr->rectClient.top ));
-    } 
-
-    WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LPARAM)hwnd );
-    if (!IsWindow(hwnd)) return 0;
-
-    /* Show the window, maximizing or minimizing if needed */
-
-    if (wndPtr->dwStyle & WS_MINIMIZE)
-    {
-	/* MinMaximize(hwnd, SW_SHOWMINNOACTIVE, 1) in "Internals" */
-
-        wndPtr->dwStyle &= ~WS_MAXIMIZE;
-        WINPOS_FindIconPos( hwnd );
-        SetWindowPos32( hwnd, 0, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y,
-                        SYSMETRICS_CXICON, SYSMETRICS_CYICON, 
-                        SWP_FRAMECHANGED | ((GetActiveWindow32())? SWP_NOACTIVATE : 0)  );
-    }
-    else if (wndPtr->dwStyle & WS_MAXIMIZE)
-    {
-	/* MinMaximize(hwnd, SW_SHOWMAXIMIZED, 1) */
-
-        NC_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack );
-        SetWindowPos32( hwnd, 0, maxPos.x, maxPos.y, maxSize.x, maxSize.y,
-            ((GetActiveWindow32())? SWP_NOACTIVATE : 0) | SWP_FRAMECHANGED );
-    }
-    
-    if (cs->style & WS_VISIBLE) ShowWindow32( hwnd, SW_SHOW );
-
-    /* Call WH_SHELL hook */
-
-    if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
-        HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
-
-    dprintf_win(stddeb, "CreateWindowEx: returning %04x\n", hwnd);
-    return hwnd;
+    dprintf_win(stddeb,"CreateWindowEx: aborted by WM_xxCREATE!\n");
+    WIN_UnlinkWindow( hwnd );
+    WIN_DestroyWindow( wndPtr );
+    return 0;
 }
 
 
@@ -859,7 +841,7 @@
     cs.lpszName       = windowName;
     cs.lpszClass      = className;
     cs.dwExStyle      = exStyle;
-    return WIN_CreateWindowEx( &cs, classAtom, FALSE );
+    return WIN_CreateWindowEx( &cs, classAtom, FALSE, FALSE );
 }
 
 
@@ -898,7 +880,7 @@
     cs.lpszName       = windowName;
     cs.lpszClass      = className;
     cs.dwExStyle      = exStyle;
-    return WIN_CreateWindowEx( &cs, classAtom, FALSE );
+    return WIN_CreateWindowEx( &cs, classAtom, TRUE, FALSE );
 }
 
 
@@ -944,7 +926,7 @@
     cs.dwExStyle      = exStyle;
     /* Note: we rely on the fact that CREATESTRUCT32A and */
     /* CREATESTRUCT32W have the same layout. */
-    return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE );
+    return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE, TRUE );
 }
 
 
@@ -1055,7 +1037,8 @@
         else break;
       }
 
-      WINPOS_ActivateOtherWindow(wndPtr);
+      if( !Options.managed || EVENT_CheckFocus() )
+          WINPOS_ActivateOtherWindow(wndPtr);
 
       if( wndPtr->owner &&
 	  wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
@@ -1079,25 +1062,43 @@
 
 
 /***********************************************************************
- *           CloseWindow   (USER.43)
+ *           CloseWindow16   (USER.43)
  */
-BOOL CloseWindow(HWND hWnd)
+BOOL16 CloseWindow16( HWND16 hwnd )
 {
-    WND * wndPtr = WIN_FindWndPtr(hWnd);
-    if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return TRUE;
-    ShowWindow32(hWnd, SW_MINIMIZE);
+    return CloseWindow32( hwnd );
+}
+
+ 
+/***********************************************************************
+ *           CloseWindow32   (USER32.55)
+ */
+BOOL32 CloseWindow32( HWND32 hwnd )
+{
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return FALSE;
+    ShowWindow32( hwnd, SW_MINIMIZE );
     return TRUE;
 }
 
  
 /***********************************************************************
- *           OpenIcon   (USER.44)
+ *           OpenIcon16   (USER.44)
  */
-BOOL OpenIcon(HWND hWnd)
+BOOL16 OpenIcon16( HWND16 hwnd )
 {
-    if (!IsIconic16(hWnd)) return FALSE;
-    ShowWindow32(hWnd, SW_SHOWNORMAL);
-    return(TRUE);
+    return OpenIcon32( hwnd );
+}
+
+
+/***********************************************************************
+ *           OpenIcon32   (USER32.409)
+ */
+BOOL32 OpenIcon32( HWND32 hwnd )
+{
+    if (!IsIconic32( hwnd )) return FALSE;
+    ShowWindow32( hwnd, SW_SHOWNORMAL );
+    return TRUE;
 }
 
 
@@ -1106,8 +1107,8 @@
  *
  * Implementation of FindWindow() and FindWindowEx().
  */
-static HWND WIN_FindWindow( HWND parent, HWND child, ATOM className,
-                            LPCSTR title )
+static HWND32 WIN_FindWindow( HWND32 parent, HWND32 child, ATOM className,
+                              LPCSTR title )
 {
     WND *pWnd;
     CLASS *pClass = NULL;
@@ -1220,7 +1221,7 @@
 {
     ATOM atom = 0;
     char *buffer;
-    HWND hwnd;
+    HWND32 hwnd;
 
     if (className)
     {
@@ -1415,7 +1416,7 @@
     {
 	case GWW_ID:        ptr = (WORD *)&wndPtr->wIDmenu; break;
 	case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
-	case GWW_HWNDPARENT: return SetParent( hwnd, newval );
+	case GWW_HWNDPARENT: return SetParent32( hwnd, newval );
 	default:
             fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
             return 0;
@@ -1504,6 +1505,9 @@
             WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval, type );
             return retval;
 	case GWL_STYLE:
+
+	    /* FIXME: WM_STYLE... messages for WIN_ISWIN32 windows */
+
             ptr = &wndPtr->dwStyle;
             /* Some bits can't be changed this way */
             newval &= ~(WS_VISIBLE | WS_CHILD);
@@ -1701,13 +1705,22 @@
 
 
 /*****************************************************************
- *         SetParent              (USER.233)
+ *         SetParent16   (USER.233)
  */
-HWND SetParent(HWND hwndChild, HWND hwndNewParent)
+HWND16 SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
 {
-    HWND oldParent;
+    return SetParent32( hwndChild, hwndNewParent );
+}
 
-    WND *wndPtr = WIN_FindWndPtr(hwndChild);
+
+/*****************************************************************
+ *         SetParent32   (USER32.494)
+ */
+HWND32 SetParent32( HWND32 hwndChild, HWND32 hwndNewParent )
+{
+    HWND32 oldParent;
+
+    WND *wndPtr = WIN_FindWndPtr( hwndChild );
     WND *pWndParent = WIN_FindWndPtr( hwndNewParent );
     if (!wndPtr || !pWndParent || !(wndPtr->dwStyle & WS_CHILD)) return 0;
 
@@ -1723,16 +1736,17 @@
 }
 
 
-
 /*******************************************************************
- *         IsChild    (USER.48)
+ *         IsChild16    (USER.48)
  */
 BOOL16 IsChild16( HWND16 parent, HWND16 child )
 {
     return IsChild32(parent,child);
 }
+
+
 /*******************************************************************
- *         IsChild    (USER32.338)
+ *         IsChild32    (USER32.338)
  */
 BOOL32 IsChild32( HWND32 parent, HWND32 child )
 {
@@ -1747,14 +1761,16 @@
 
 
 /***********************************************************************
- *           IsWindowVisible   (USER.49)
+ *           IsWindowVisible16   (USER.49)
  */
 BOOL16 IsWindowVisible16( HWND16 hwnd )
 {
     return IsWindowVisible32(hwnd);
 }
+
+
 /***********************************************************************
- *           IsWindowVisible   (USER32.350)
+ *           IsWindowVisible32   (USER32.350)
  */
 BOOL32 IsWindowVisible32( HWND32 hwnd )
 {
@@ -1767,6 +1783,7 @@
     return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
 }
 
+
 /***********************************************************************
  *           WIN_IsWindowDrawable
  * 
@@ -1776,7 +1793,7 @@
  */
 BOOL32 WIN_IsWindowDrawable( WND* wnd , BOOL32 icon )
 {
-  HWND   hwnd= wnd->hwndSelf;
+  HWND32 hwnd = wnd->hwndSelf;
   BOOL32 yes = TRUE;
 
   while(wnd && yes)
@@ -1791,14 +1808,16 @@
 }
 
 /*******************************************************************
- *         GetTopWindow    (USER.229)
+ *         GetTopWindow16    (USER.229)
  */
 HWND16 GetTopWindow16( HWND16 hwnd )
 {
     return GetTopWindow32(hwnd);
 }
+
+
 /*******************************************************************
- *         GetTopWindow    (USER.229)
+ *         GetTopWindow32    (USER.229)
  */
 HWND32 GetTopWindow32( HWND32 hwnd )
 {
@@ -1809,14 +1828,16 @@
 
 
 /*******************************************************************
- *         GetWindow    (USER.262)
+ *         GetWindow16    (USER.262)
  */
 HWND16 GetWindow16( HWND16 hwnd, WORD rel )
 {
     return GetWindow32( hwnd,rel );
 }
+
+
 /*******************************************************************
- *         GetWindow    (USER32.301)
+ *         GetWindow32    (USER32.301)
  */
 HWND32 GetWindow32( HWND32 hwnd, WORD rel )
 {
@@ -1859,7 +1880,7 @@
 
 
 /*******************************************************************
- *         GetNextWindow    (USER.230)
+ *         GetNextWindow16    (USER.230)
  */
 HWND16 GetNextWindow16( HWND16 hwnd, WORD flag )
 {
@@ -1868,9 +1889,18 @@
 }
 
 /*******************************************************************
- *         ShowOwnedPopups  (USER.265)
+ *         ShowOwnedPopups16  (USER.265)
  */
-void ShowOwnedPopups( HWND owner, BOOL fShow )
+void ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
+{
+    ShowOwnedPopups32( owner, fShow );
+}
+
+
+/*******************************************************************
+ *         ShowOwnedPopups32  (USER32.530)
+ */
+BOOL32 ShowOwnedPopups32( HWND32 owner, BOOL32 fShow )
 {
     WND *pWnd = pWndDesktop->child;
     while (pWnd)
@@ -1880,13 +1910,22 @@
             ShowWindow32( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
         pWnd = pWnd->next;
     }
+    return TRUE;
 }
 
 
 /*******************************************************************
- *         GetLastActivePopup    (USER.287)
+ *         GetLastActivePopup16   (USER.287)
  */
-HWND GetLastActivePopup(HWND hwnd)
+HWND16 GetLastActivePopup16( HWND16 hwnd )
+{
+    return GetLastActivePopup32( hwnd );
+}
+
+/*******************************************************************
+ *         GetLastActivePopup32   (USER32.255)
+ */
+HWND32 GetLastActivePopup32( HWND32 hwnd )
 {
     WND *wndPtr;
     wndPtr = WIN_FindWndPtr(hwnd);
@@ -2050,9 +2089,18 @@
 
 
 /*******************************************************************
- *           AnyPopup   (USER.52)
+ *           AnyPopup16   (USER.52)
  */
-BOOL AnyPopup(void)
+BOOL16 AnyPopup16(void)
+{
+    return AnyPopup32();
+}
+
+
+/*******************************************************************
+ *           AnyPopup32   (USER32.3)
+ */
+BOOL32 AnyPopup32(void)
 {
     WND *wndPtr;
     for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
@@ -2060,10 +2108,20 @@
     return FALSE;
 }
 
+
 /*******************************************************************
- *			FlashWindow		[USER.105]
+ *            FlashWindow16   (USER.105)
  */
-BOOL FlashWindow(HWND hWnd, BOOL bInvert)
+BOOL16 FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
+{
+    return FlashWindow32( hWnd, bInvert );
+}
+
+
+/*******************************************************************
+ *            FlashWindow32   (USER32.201)
+ */
+BOOL32 FlashWindow32( HWND32 hWnd, BOOL32 bInvert )
 {
     WND *wndPtr = WIN_FindWndPtr(hWnd);
 
@@ -2108,7 +2166,7 @@
  */
 HWND16 SetSysModalWindow16( HWND16 hWnd )
 {
-    HWND hWndOldModal = hwndSysModal;
+    HWND32 hWndOldModal = hwndSysModal;
     hwndSysModal = hWnd;
     dprintf_win(stdnimp,"EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
     return hWndOldModal;
@@ -2130,7 +2188,7 @@
  * recursively find a child that contains spDragInfo->pt point 
  * and send WM_QUERYDROPOBJECT
  */
-BOOL16 DRAG_QueryUpdate( HWND hQueryWnd, SEGPTR spDragInfo, BOOL32 bNoSend )
+BOOL16 DRAG_QueryUpdate( HWND32 hQueryWnd, SEGPTR spDragInfo, BOOL32 bNoSend )
 {
  BOOL16		wParam,bResult = 0;
  POINT16        pt;
@@ -2196,11 +2254,21 @@
  return bResult;
 }
 
+
 /*******************************************************************
- *                      DragDetect ( USER.465 )
- *
+ *             DragDetect   (USER.465)
  */
-BOOL16 DragDetect(HWND16 hWnd, POINT16 pt)
+BOOL16 DragDetect16( HWND16 hWnd, POINT16 pt )
+{
+    POINT32 pt32;
+    CONV_POINT16TO32( &pt, &pt32 );
+    return DragDetect32( hWnd, pt32 );
+}
+
+/*******************************************************************
+ *             DragDetect32   (USER32.150)
+ */
+BOOL32 DragDetect32( HWND32 hWnd, POINT32 pt )
 {
   MSG16 msg;
   RECT16  rect;
@@ -2241,7 +2309,7 @@
  *                              DragObject ( USER.464 )
  *
  */
-DWORD DragObject(HWND hwndScope, HWND hWnd, WORD wObj, HANDLE16 hOfStruct,
+DWORD DragObject(HWND16 hwndScope, HWND16 hWnd, WORD wObj, HANDLE16 hOfStruct,
                 WORD szList , HCURSOR16 hCursor)
 {
  MSG16	 	msg;
@@ -2253,7 +2321,7 @@
  DWORD		dwRet = 0;
  short	 	dragDone = 0;
  HCURSOR16	hCurrentCursor = 0;
- HWND		hCurrentWnd = 0;
+ HWND16		hCurrentWnd = 0;
  BOOL16		b;
 
  lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
@@ -2280,7 +2348,7 @@
 	if( hDragCursor == hCursor ) hDragCursor = 0;
 	else hCursor = hDragCursor;
 
-	hOldCursor = SetCursor(hDragCursor);
+	hOldCursor = SetCursor32(hDragCursor);
    }
 
  lpDragInfo->hWnd   = hWnd;
@@ -2291,7 +2359,7 @@
  lpDragInfo->l = 0L; 
 
  SetCapture32(hWnd);
- ShowCursor(1);
+ ShowCursor32( TRUE );
 
  while( !dragDone )
   {
@@ -2315,7 +2383,7 @@
          lpDragInfo->hScope = 0;
 	}
     if( hCurrentCursor )
-        SetCursor(hCurrentCursor);
+        SetCursor32(hCurrentCursor);
 
     dprintf_msg(stddeb,"drag: got %04x\n", b);
 
@@ -2344,14 +2412,13 @@
   }
 
  ReleaseCapture();
- ShowCursor(0);
+ ShowCursor32( FALSE );
 
  if( hCursor )
-   {
-     SetCursor(hOldCursor);
-     if( hDragCursor )
-	 DestroyCursor(hDragCursor);
-   }
+ {
+     SetCursor32( hOldCursor );
+     if (hDragCursor) DestroyCursor32( hDragCursor );
+ }
 
  if( hCurrentCursor != hBummer ) 
 	dwRet = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT, 
diff --git a/windows/winpos.c b/windows/winpos.c
index adac82f..d802981 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -1034,9 +1034,16 @@
 	    /* disregard refusal if hWnd is sysmodal */
         }
 
+#if 0
 	SendMessage32A( hwndPrevActive, WM_ACTIVATE,
                         MAKEWPARAM( WA_INACTIVE, wIconized ),
                         (LPARAM)hWnd );
+#else
+	/* FIXME: must be SendMessage16() because 32A doesn't do
+	 * intertask at this time */
+	SendMessage16( hwndPrevActive, WM_ACTIVATE, WA_INACTIVE,
+				MAKELPARAM( (HWND16)hWnd, wIconized ) );
+#endif
 
 	/* check if something happened during message processing */
 	if( hwndPrevActive != hwndActive ) return 0;
@@ -1120,9 +1127,14 @@
 
         wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
         SendMessage16( hWnd, WM_NCACTIVATE, TRUE, 0 );
+#if 0
         SendMessage32A( hWnd, WM_ACTIVATE,
 		 MAKEWPARAM( (fMouse) ? WA_CLICKACTIVE : WA_ACTIVE, wIconized),
 		 (LPARAM)hwndPrevActive );
+#else
+        SendMessage16(hWnd, WM_ACTIVATE, (fMouse) ? WA_CLICKACTIVE : WA_ACTIVE,
+                      MAKELPARAM( (HWND16)hwndPrevActive, wIconized) );
+#endif
 
         if( !IsWindow(hWnd) ) return 0;
     }