Removed a number of direct accesses to the window structure.

diff --git a/windows/defdlg.c b/windows/defdlg.c
index 5170bf4..fccd140 100644
--- a/windows/defdlg.c
+++ b/windows/defdlg.c
@@ -38,32 +38,45 @@
 /***********************************************************************
  *           DEFDLG_SaveFocus
  */
-static BOOL DEFDLG_SaveFocus( HWND hwnd, DIALOGINFO *infoPtr )
+static void DEFDLG_SaveFocus( HWND hwnd )
 {
+    DIALOGINFO *infoPtr;
+    WND *wndPtr;
     HWND hwndFocus = GetFocus();
 
-    if (!hwndFocus || !IsChild( hwnd, hwndFocus )) return FALSE;
+    if (!hwndFocus || !IsChild( hwnd, hwndFocus )) return;
+    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return;
+    infoPtr = (DIALOGINFO *)&wndPtr->wExtra;
     infoPtr->hwndFocus = hwndFocus;
-      /* Remove default button */
-    return TRUE;
+    WIN_ReleaseWndPtr( wndPtr );
+    /* Remove default button */
 }
 
 
 /***********************************************************************
  *           DEFDLG_RestoreFocus
  */
-static BOOL DEFDLG_RestoreFocus( HWND hwnd, DIALOGINFO *infoPtr )
+static void DEFDLG_RestoreFocus( HWND hwnd )
 {
-    if (!infoPtr->hwndFocus || IsIconic(hwnd)) return FALSE;
-    if (!IsWindow( infoPtr->hwndFocus )) return FALSE;
+    DIALOGINFO *infoPtr;
+    WND *wndPtr;
 
-    /* Don't set the focus back to controls if EndDialog is already called.*/
-    if (!(infoPtr->flags & DF_END))
-       DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus );
-
-    /* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
-       sometimes losing focus when receiving WM_SETFOCUS messages. */
-    return TRUE;
+    if (IsIconic( hwnd )) return;
+    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return;
+    infoPtr = (DIALOGINFO *)&wndPtr->wExtra;
+    if (IsWindow( infoPtr->hwndFocus ))
+    {
+        /* Don't set the focus back to controls if EndDialog is already called.*/
+        if (!(infoPtr->flags & DF_END))
+        {
+            WIN_ReleaseWndPtr( wndPtr );
+            DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus );
+            return;
+        }
+        /* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
+           sometimes losing focus when receiving WM_SETFOCUS messages. */
+    }
+    WIN_ReleaseWndPtr( wndPtr );
 }
 
 
@@ -161,16 +174,16 @@
 	    return DefWindowProcA( hwnd, msg, wParam, lParam );
 
 	case WM_SHOWWINDOW:
-	    if (!wParam) DEFDLG_SaveFocus( hwnd, dlgInfo );
+	    if (!wParam) DEFDLG_SaveFocus( hwnd );
 	    return DefWindowProcA( hwnd, msg, wParam, lParam );
 
 	case WM_ACTIVATE:
-	    if (wParam) DEFDLG_RestoreFocus( hwnd, dlgInfo );
-	    else DEFDLG_SaveFocus( hwnd, dlgInfo );
+	    if (wParam) DEFDLG_RestoreFocus( hwnd );
+	    else DEFDLG_SaveFocus( hwnd );
 	    return 0;
 
 	case WM_SETFOCUS:
-	    DEFDLG_RestoreFocus( hwnd, dlgInfo );
+	    DEFDLG_RestoreFocus( hwnd );
 	    return 0;
 
         case DM_SETDEFID:
@@ -231,7 +244,7 @@
 /***********************************************************************
  *           DEFDLG_Epilog
  */
-static LRESULT DEFDLG_Epilog(DIALOGINFO* dlgInfo, UINT msg, BOOL fResult)
+static LRESULT DEFDLG_Epilog(HWND hwnd, UINT msg, BOOL fResult)
 {
     /* see SDK 3.1 */
 
@@ -241,7 +254,7 @@
          msg == WM_QUERYDRAGICON || msg == WM_INITDIALOG)
         return fResult; 
 
-    return dlgInfo->msgResult;
+    return GetWindowLongA( hwnd, DWL_MSGRESULT );
 }
 
 /***********************************************************************
@@ -251,18 +264,22 @@
                              LPARAM lParam )
 {
     DIALOGINFO * dlgInfo;
+    WNDPROC16 dlgproc;
     BOOL result = FALSE;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
-    
+
     if (!wndPtr) return 0;
     dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
     dlgInfo->msgResult = 0;
+    dlgproc = (WNDPROC16)dlgInfo->dlgProc;
+    WIN_ReleaseWndPtr(wndPtr);
 
-    if (dlgInfo->dlgProc) {	/* Call dialog procedure */
-	result = CallWindowProc16( (WNDPROC16)dlgInfo->dlgProc,
-                                           hwnd, msg, wParam, lParam );
+    if (dlgproc)
+    {
+        /* Call dialog procedure */
+        result = CallWindowProc16( dlgproc, hwnd, msg, wParam, lParam );
         /* 16 bit dlg procs only return BOOL16 */
-        if( WINPROC_GetProcType( dlgInfo->dlgProc ) == WIN_PROC_16 )
+        if( WINPROC_GetProcType( dlgproc ) == WIN_PROC_16 )
             result = LOWORD(result);
     }
 
@@ -285,7 +302,6 @@
             case WM_ENTERMENULOOP:
             case WM_LBUTTONDOWN:
             case WM_NCLBUTTONDOWN:
-                WIN_ReleaseWndPtr(wndPtr);
                 return DEFDLG_Proc( (HWND)hwnd, msg, 
                                     (WPARAM)wParam, lParam, dlgInfo );
             case WM_INITDIALOG:
@@ -295,12 +311,10 @@
                 break;
 
             default:
-                WIN_ReleaseWndPtr(wndPtr);
                 return DefWindowProc16( hwnd, msg, wParam, lParam );
         }
-    }   
-    WIN_ReleaseWndPtr(wndPtr);
-    return DEFDLG_Epilog(dlgInfo, msg, result);
+    }
+    return DEFDLG_Epilog(hwnd, msg, result);
 }
 
 
@@ -311,18 +325,22 @@
                               WPARAM wParam, LPARAM lParam )
 {
     DIALOGINFO * dlgInfo;
+    WNDPROC dlgproc;
     BOOL result = FALSE;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
-    
+
     if (!wndPtr) return 0;
     dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
     dlgInfo->msgResult = 0;
+    dlgproc = dlgInfo->dlgProc;
+    WIN_ReleaseWndPtr(wndPtr);
 
-    if (dlgInfo->dlgProc) {      /* Call dialog procedure */
-        result = CallWindowProcA( (WNDPROC)dlgInfo->dlgProc,
-                                            hwnd, msg, wParam, lParam );
+    if (dlgproc)
+    {
+        /* Call dialog procedure */
+        result = CallWindowProcA( dlgproc, hwnd, msg, wParam, lParam );
         /* 16 bit dlg procs only return BOOL16 */
-        if( WINPROC_GetProcType( dlgInfo->dlgProc ) == WIN_PROC_16 )
+        if( WINPROC_GetProcType( dlgproc ) == WIN_PROC_16 )
             result = LOWORD(result);
     }
 
@@ -345,9 +363,7 @@
             case WM_ENTERMENULOOP:
             case WM_LBUTTONDOWN:
             case WM_NCLBUTTONDOWN:
-                 WIN_ReleaseWndPtr(wndPtr);
-                 return DEFDLG_Proc( (HWND)hwnd, msg,
-                                     (WPARAM)wParam, lParam, dlgInfo );
+                 return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
             case WM_INITDIALOG:
             case WM_VKEYTOITEM:
             case WM_COMPAREITEM:
@@ -355,12 +371,10 @@
                  break;
 
             default:
-                 WIN_ReleaseWndPtr(wndPtr);
                  return DefWindowProcA( hwnd, msg, wParam, lParam );
         }
     }
-    WIN_ReleaseWndPtr(wndPtr);
-    return DEFDLG_Epilog(dlgInfo, msg, result);
+    return DEFDLG_Epilog(hwnd, msg, result);
 }
 
 
@@ -372,17 +386,21 @@
 {
     DIALOGINFO * dlgInfo;
     BOOL result = FALSE;
+    WNDPROC dlgproc;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
-    
+
     if (!wndPtr) return 0;
     dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
     dlgInfo->msgResult = 0;
+    dlgproc = dlgInfo->dlgProc;
+    WIN_ReleaseWndPtr(wndPtr);
 
-    if (dlgInfo->dlgProc) {      /* Call dialog procedure */
-        result = CallWindowProcW( (WNDPROC)dlgInfo->dlgProc,
-                                            hwnd, msg, wParam, lParam );
+    if (dlgproc)
+    {
+        /* Call dialog procedure */
+        result = CallWindowProcW( dlgproc, hwnd, msg, wParam, lParam );
         /* 16 bit dlg procs only return BOOL16 */
-        if( WINPROC_GetProcType( dlgInfo->dlgProc ) == WIN_PROC_16 )
+        if( WINPROC_GetProcType( dlgproc ) == WIN_PROC_16 )
             result = LOWORD(result);
     }
 
@@ -405,9 +423,7 @@
             case WM_ENTERMENULOOP:
             case WM_LBUTTONDOWN:
             case WM_NCLBUTTONDOWN:
-                 WIN_ReleaseWndPtr(wndPtr);
-                 return DEFDLG_Proc( (HWND)hwnd, msg,
-                                     (WPARAM)wParam, lParam, dlgInfo );
+                 return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
             case WM_INITDIALOG:
             case WM_VKEYTOITEM:
             case WM_COMPAREITEM:
@@ -415,10 +431,8 @@
                  break;
 
             default:
-                 WIN_ReleaseWndPtr(wndPtr);
                  return DefWindowProcW( hwnd, msg, wParam, lParam );
         }
     }
-    WIN_ReleaseWndPtr(wndPtr);
-    return DEFDLG_Epilog(dlgInfo, msg, result);
+    return DEFDLG_Epilog(hwnd, msg, result);
 }
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 95a3df2..6b60957 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -35,21 +35,24 @@
  *
  * Handle the WM_WINDOWPOSCHANGED message.
  */
-static void DEFWND_HandleWindowPosChanged( WND *wndPtr, UINT flags )
+static void DEFWND_HandleWindowPosChanged( HWND hwnd, UINT flags )
 {
-    WPARAM wp = SIZE_RESTORED;
+    RECT rect;
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
+
+    rect = wndPtr->rectClient;
+    WIN_ReleaseWndPtr( wndPtr );
 
     if (!(flags & SWP_NOCLIENTMOVE))
-        SendMessageW( wndPtr->hwndSelf, WM_MOVE, 0,
-                    MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top));
+        SendMessageW( hwnd, WM_MOVE, 0, MAKELONG(rect.left, rect.top));
+
     if (!(flags & SWP_NOCLIENTSIZE))
     {
-        if (wndPtr->dwStyle & WS_MAXIMIZE) wp = SIZE_MAXIMIZED;
-        else if (wndPtr->dwStyle & WS_MINIMIZE) wp = SIZE_MINIMIZED;
+        WPARAM wp = SIZE_RESTORED;
+        if (IsZoomed(hwnd)) wp = SIZE_MAXIMIZED;
+        else if (IsIconic(hwnd)) wp = SIZE_MINIMIZED;
 
-        SendMessageW( wndPtr->hwndSelf, WM_SIZE, wp, 
-                     MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
-                            wndPtr->rectClient.bottom-wndPtr->rectClient.top));
+        SendMessageW( hwnd, WM_SIZE, wp, MAKELONG(rect.right-rect.left, rect.bottom-rect.top) );
     }
 }
 
@@ -59,21 +62,24 @@
  *
  * Set the window text.
  */
-void DEFWND_SetTextA( WND *wndPtr, LPCSTR text )
+static void DEFWND_SetTextA( HWND hwnd, LPCSTR text )
 {
     int count;
+    WCHAR *textW;
+    WND *wndPtr;
 
     if (!text) text = "";
     count = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 );
 
+    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return;
     if (wndPtr->text) HeapFree(GetProcessHeap(), 0, wndPtr->text);
-    if ((wndPtr->text = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR))))
+    if ((wndPtr->text = textW = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR))))
         MultiByteToWideChar( CP_ACP, 0, text, -1, wndPtr->text, count );
     else
         ERR("Not enough memory for window text\n");
+    WIN_ReleaseWndPtr( wndPtr );
 
-    if (USER_Driver.pSetWindowText)
-        USER_Driver.pSetWindowText(wndPtr->hwndSelf, wndPtr->text);
+    if (USER_Driver.pSetWindowText) USER_Driver.pSetWindowText( hwnd, textW );
 }
 
 /***********************************************************************
@@ -81,22 +87,25 @@
  *
  * Set the window text.
  */
-void DEFWND_SetTextW( WND *wndPtr, LPCWSTR text )
+static void DEFWND_SetTextW( HWND hwnd, LPCWSTR text )
 {
     static const WCHAR empty_string[] = {0};
+    WND *wndPtr;
     int count;
 
     if (!text) text = empty_string;
     count = strlenW(text) + 1;
 
+    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return;
     if (wndPtr->text) HeapFree(GetProcessHeap(), 0, wndPtr->text);
     if ((wndPtr->text = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR))))
 	strcpyW( wndPtr->text, text );
     else
         ERR("Not enough memory for window text\n");
+    text = wndPtr->text;
+    WIN_ReleaseWndPtr( wndPtr );
 
-    if (USER_Driver.pSetWindowText)
-        USER_Driver.pSetWindowText(wndPtr->hwndSelf, wndPtr->text);
+    if (USER_Driver.pSetWindowText) USER_Driver.pSetWindowText( hwnd, text );
 }
 
 /***********************************************************************
@@ -148,8 +157,9 @@
 /***********************************************************************
  *           DEFWND_SetRedraw
  */
-static void DEFWND_SetRedraw( WND* wndPtr, WPARAM wParam )
+static void DEFWND_SetRedraw( HWND hwnd, WPARAM wParam )
 {
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
     BOOL bVisible = wndPtr->dwStyle & WS_VISIBLE;
 
     TRACE("%04x %i\n", wndPtr->hwndSelf, (wParam!=0) );
@@ -171,6 +181,7 @@
 	DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
 	wndPtr->dwStyle &= ~WS_VISIBLE;
     }
+    WIN_ReleaseWndPtr( wndPtr );
 }
 
 /***********************************************************************
@@ -178,16 +189,13 @@
  *
  * This method handles the default behavior for the WM_PRINT message.
  */
-static void DEFWND_Print(
-  WND*  wndPtr,
-  HDC   hdc,
-  ULONG uFlags)
+static void DEFWND_Print( HWND hwnd, HDC hdc, ULONG uFlags)
 {
   /*
    * Visibility flag.
    */
   if ( (uFlags & PRF_CHECKVISIBLE) &&
-       !IsWindowVisible(wndPtr->hwndSelf) )
+       !IsWindowVisible(hwnd) )
       return;
 
   /*
@@ -204,13 +212,13 @@
    * Background
    */
   if ( uFlags & PRF_ERASEBKGND)
-    SendMessageW(wndPtr->hwndSelf, WM_ERASEBKGND, (WPARAM)hdc, 0);
+    SendMessageW(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0);
 
   /*
    * Client area
    */
   if ( uFlags & PRF_CLIENT)
-    SendMessageW(wndPtr->hwndSelf, WM_PRINTCLIENT, (WPARAM)hdc, PRF_CLIENT);
+    SendMessageW(hwnd, WM_PRINTCLIENT, (WPARAM)hdc, PRF_CLIENT);
 }
 
 
@@ -284,40 +292,33 @@
  *
  * Default window procedure for messages that are the same in Win16 and Win32.
  */
-static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT msg, WPARAM wParam,
-                                  LPARAM lParam, BOOL unicode )
+static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
 {
-    LRESULT (WINAPI *pSendMessage)(HWND, UINT, WPARAM, LPARAM);
-    BOOL (WINAPI *pPostMessage)(HWND, UINT, WPARAM, LPARAM);
-
-    pSendMessage = unicode ? SendMessageW : SendMessageA;
-    pPostMessage = unicode ? PostMessageW : PostMessageA;
-
     switch(msg)
     {
     case WM_NCPAINT:
-	return NC_HandleNCPaint( wndPtr->hwndSelf, (HRGN)wParam );
+        return NC_HandleNCPaint( hwnd, (HRGN)wParam );
 
     case WM_NCHITTEST:
         {
             POINT pt;
             pt.x = SLOWORD(lParam);
             pt.y = SHIWORD(lParam);
-            return NC_HandleNCHitTest( wndPtr->hwndSelf, pt );
+            return NC_HandleNCHitTest( hwnd, pt );
         }
 
     case WM_NCLBUTTONDOWN:
-        return NC_HandleNCLButtonDown( wndPtr->hwndSelf, wParam, lParam );
+        return NC_HandleNCLButtonDown( hwnd, wParam, lParam );
 
     case WM_LBUTTONDBLCLK:
     case WM_NCLBUTTONDBLCLK:
-        return NC_HandleNCLButtonDblClk( wndPtr->hwndSelf, wParam, lParam );
+        return NC_HandleNCLButtonDblClk( hwnd, wParam, lParam );
 
     case WM_NCRBUTTONDOWN:
         /* in Windows, capture is taken when right-clicking on the caption bar */
         if (wParam==HTCAPTION)
         {
-            SetCapture(wndPtr->hwndSelf);
+            SetCapture(hwnd);
         }
         break;
 
@@ -325,15 +326,14 @@
         {
             POINT pt;
 
-            if (wndPtr->hwndSelf == GetCapture())
+            if (hwnd == GetCapture())
                 /* release capture if we took it on WM_NCRBUTTONDOWN */
                 ReleaseCapture();
 
 	    pt.x = SLOWORD(lParam);
 	    pt.y = SHIWORD(lParam);
-	    ClientToScreen(wndPtr->hwndSelf, &pt);
-	    pSendMessage( wndPtr->hwndSelf, WM_CONTEXTMENU,
-                          wndPtr->hwndSelf, MAKELPARAM(pt.x, pt.y) );
+            ClientToScreen(hwnd, &pt);
+            SendMessageW( hwnd, WM_CONTEXTMENU, hwnd, MAKELPARAM(pt.x, pt.y) );
         }
         break;
 
@@ -347,89 +347,89 @@
         break;
 
     case WM_CONTEXTMENU:
-        if( wndPtr->dwStyle & WS_CHILD )
-	    pSendMessage( wndPtr->parent->hwndSelf, msg, wParam, lParam );
-        else if (wndPtr->hSysMenu)
+        if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)
+            SendMessageW( GetParent(hwnd), msg, wParam, lParam );
+        else
         {
             LONG hitcode;
             POINT pt;
+            WND *wndPtr = WIN_FindWndPtr( hwnd );
+            HMENU hMenu = wndPtr->hSysMenu;
+            WIN_ReleaseWndPtr( wndPtr );
+            if (!hMenu) return 0;
             pt.x = SLOWORD(lParam);
             pt.y = SHIWORD(lParam);
-
-            /*
-             * WM_CONTEXTMENU coordinates are relative to screen, but 
-             * NC_HandleNCHitTest expects coordinates relative to the parent's 
-             * client area (to compare with the rectangle returned by 
-             * GetWindowRect)
-             */
-            if (wndPtr->parent)
-                ScreenToClient(wndPtr->parent->hwndSelf, &pt);
-
-            hitcode = NC_HandleNCHitTest(wndPtr->hwndSelf, pt);
+            hitcode = NC_HandleNCHitTest(hwnd, pt);
 
             /* Track system popup if click was in the caption area. */
             if (hitcode==HTCAPTION || hitcode==HTSYSMENU)
-               TrackPopupMenu(GetSystemMenu(wndPtr->hwndSelf, FALSE),
+               TrackPopupMenu(GetSystemMenu(hwnd, FALSE),
                                TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
-                               pt.x, pt.y, 0, wndPtr->hwndSelf, NULL);
+                               pt.x, pt.y, 0, hwnd, NULL);
         }
         break;
 
     case WM_NCACTIVATE:
-        return NC_HandleNCActivate( wndPtr->hwndSelf, wParam );
+        return NC_HandleNCActivate( hwnd, wParam );
 
     case WM_NCDESTROY:
-	if (wndPtr->text) HeapFree( GetProcessHeap(), 0, wndPtr->text );
-	wndPtr->text = NULL;
-	if (wndPtr->pVScroll) HeapFree( GetProcessHeap(), 0, wndPtr->pVScroll );
-	if (wndPtr->pHScroll) HeapFree( GetProcessHeap(), 0, wndPtr->pHScroll );
-        wndPtr->pVScroll = wndPtr->pHScroll = NULL;
-	return 0;
+        {
+            WND *wndPtr = WIN_FindWndPtr( hwnd );
+            if (!wndPtr) return 0;
+            if (wndPtr->text) HeapFree( GetProcessHeap(), 0, wndPtr->text );
+            wndPtr->text = NULL;
+            if (wndPtr->pVScroll) HeapFree( GetProcessHeap(), 0, wndPtr->pVScroll );
+            if (wndPtr->pHScroll) HeapFree( GetProcessHeap(), 0, wndPtr->pHScroll );
+            wndPtr->pVScroll = wndPtr->pHScroll = NULL;
+            WIN_ReleaseWndPtr( wndPtr );
+            return 0;
+        }
 
     case WM_PRINT:
-        DEFWND_Print(wndPtr, (HDC)wParam, lParam);
+        DEFWND_Print(hwnd, (HDC)wParam, lParam);
         return 0;
 
     case WM_PAINTICON:
     case WM_PAINT:
 	{
 	    PAINTSTRUCT ps;
-	    HDC hdc = BeginPaint( wndPtr->hwndSelf, &ps );
+	    HDC hdc = BeginPaint( hwnd, &ps );
 	    if( hdc ) 
 	    {
               HICON hIcon;
-	      if( (wndPtr->dwStyle & WS_MINIMIZE) && ((hIcon = GetClassLongW( wndPtr->hwndSelf, GCL_HICON))) )
+	      if (IsIconic(hwnd) && ((hIcon = GetClassLongW( hwnd, GCL_HICON))) )
 	      {
-	        int x = (wndPtr->rectWindow.right - wndPtr->rectWindow.left -
-			GetSystemMetrics(SM_CXICON))/2;
-	        int y = (wndPtr->rectWindow.bottom - wndPtr->rectWindow.top -
-			GetSystemMetrics(SM_CYICON))/2;
-		TRACE("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, hIcon );
+                  RECT rc;
+                  int x, y;
+
+                  GetClientRect( hwnd, &rc );
+                  x = (rc.right - rc.left - GetSystemMetrics(SM_CXICON))/2;
+                  y = (rc.bottom - rc.top - GetSystemMetrics(SM_CYICON))/2;
+                  TRACE("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, hIcon );
 	      }
-	      EndPaint( wndPtr->hwndSelf, &ps );
+	      EndPaint( hwnd, &ps );
 	    }
 	    return 0;
 	}
 
     case WM_SYNCPAINT:
-        RedrawWindow ( wndPtr->hwndSelf, NULL, 0, RDW_ERASENOW | RDW_ERASE | RDW_ALLCHILDREN );
+        RedrawWindow ( hwnd, NULL, 0, RDW_ERASENOW | RDW_ERASE | RDW_ALLCHILDREN );
         return 0;
 
     case WM_SETREDRAW:
-	DEFWND_SetRedraw( wndPtr, wParam );
+        DEFWND_SetRedraw( hwnd, wParam );
         return 0;
 
     case WM_CLOSE:
-	DestroyWindow( wndPtr->hwndSelf );
+	DestroyWindow( hwnd );
 	return 0;
 
     case WM_MOUSEACTIVATE:
-	if (wndPtr->dwStyle & WS_CHILD)
+        if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)
 	{
-	    LONG ret = pSendMessage( wndPtr->parent->hwndSelf,
-                                      WM_MOUSEACTIVATE, wParam, lParam );
+	    LONG ret = SendMessageW( GetParent(hwnd), WM_MOUSEACTIVATE, wParam, lParam );
 	    if (ret) return ret;
 	}
 
@@ -440,17 +440,13 @@
 	/* The default action in Windows is to set the keyboard focus to
 	 * the window, if it's being activated and not minimized */
 	if (LOWORD(wParam) != WA_INACTIVE) {
-		if (!(wndPtr->dwStyle & WS_MINIMIZE))
-			SetFocus(wndPtr->hwndSelf);
+            if (!IsIconic(hwnd)) SetFocus(hwnd);
 	}
 	break;
 
-     case WM_MOUSEWHEEL:
-	if (wndPtr->dwStyle & WS_CHILD)
-	{
-	    return pSendMessage( wndPtr->parent->hwndSelf,
-				 WM_MOUSEWHEEL, wParam, lParam );
-	}
+    case WM_MOUSEWHEEL:
+        if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)
+            return SendMessageW( GetParent(hwnd), WM_MOUSEWHEEL, wParam, lParam );
 	break;
 
     case WM_ERASEBKGND:
@@ -458,13 +454,13 @@
 	{
 	    RECT rect;
             HDC hdc = (HDC)wParam;
-            HBRUSH hbr = GetClassLongW( wndPtr->hwndSelf, GCL_HBRBACKGROUND );
+            HBRUSH hbr = GetClassLongW( hwnd, GCL_HBRBACKGROUND );
             if (!hbr) return 0;
 
-            if (GetClassLongW( wndPtr->hwndSelf, GCL_STYLE ) & CS_PARENTDC)
+            if (GetClassLongW( hwnd, GCL_STYLE ) & CS_PARENTDC)
             {
                 /* can't use GetClipBox with a parent DC or we fill the whole parent */
-                GetClientRect( wndPtr->hwndSelf, &rect );
+                GetClientRect( hwnd, &rect );
                 DPtoLP( hdc, (LPPOINT)&rect, 2 );
             }
             else GetClipBox( hdc, &rect );
@@ -488,24 +484,23 @@
 	return (LRESULT)DEFWND_ControlColor( (HDC)wParam, HIWORD(lParam) );
 	
     case WM_SETCURSOR:
-	if (wndPtr->dwStyle & WS_CHILD)
+        if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)
 	{
             /* with the exception of the border around a resizable wnd,
              * give the parent first chance to set the cursor */
             if ((LOWORD(lParam) < HTSIZEFIRST) || (LOWORD(lParam) > HTSIZELAST))
             {
-                if (pSendMessage(wndPtr->parent->hwndSelf, WM_SETCURSOR, wParam, lParam))
-                    return TRUE;
+                if (SendMessageW(GetParent(hwnd), WM_SETCURSOR, wParam, lParam)) return TRUE;
             }
         }
-	return NC_HandleSetCursor( wndPtr->hwndSelf, wParam, lParam );
+	return NC_HandleSetCursor( hwnd, wParam, lParam );
 
     case WM_SYSCOMMAND:
         {
             POINT pt;
             pt.x = SLOWORD(lParam);
             pt.y = SHIWORD(lParam);
-            return NC_HandleSysCommand( wndPtr->hwndSelf, wParam, pt );
+            return NC_HandleSysCommand( hwnd, wParam, pt );
         }
 
     case WM_KEYDOWN:
@@ -525,18 +520,16 @@
 
 	    if( wParam == VK_F4 )	/* try to close the window */
 	    {
-		HWND hWnd = WIN_GetTopParent( wndPtr->hwndSelf );
-		wndPtr = WIN_FindWndPtr( hWnd );
-		if( wndPtr && !(wndPtr->clsStyle & CS_NOCLOSE) )
-		    pPostMessage( hWnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
-                WIN_ReleaseWndPtr(wndPtr);
+                HWND top = WIN_GetTopParent( hwnd );
+                if (!(GetClassLongW( top, GCL_STYLE ) & CS_NOCLOSE))
+                    PostMessageW( top, WM_SYSCOMMAND, SC_CLOSE, 0 );
 	    }
 	} 
 	else if( wParam == VK_F10 )
 	        iF10Key = 1;
 	     else
 	        if( wParam == VK_ESCAPE && (GetKeyState(VK_SHIFT) & 0x8000))
-		    pSendMessage( wndPtr->hwndSelf, WM_SYSCOMMAND, SC_KEYMENU, VK_SPACE );
+                    SendMessageW( hwnd, WM_SYSCOMMAND, SC_KEYMENU, VK_SPACE );
 	break;
 
     case WM_KEYUP:
@@ -544,42 +537,44 @@
 	/* Press and release F10 or ALT */
 	if (((wParam == VK_MENU) && iMenuSysKey) ||
             ((wParam == VK_F10) && iF10Key))
-	      pSendMessage( WIN_GetTopParent(wndPtr->hwndSelf),
-                             WM_SYSCOMMAND, SC_KEYMENU, 0L );
+              SendMessageW( WIN_GetTopParent(hwnd), WM_SYSCOMMAND, SC_KEYMENU, 0L );
 	iMenuSysKey = iF10Key = 0;
         break;
 
     case WM_SYSCHAR:
 	iMenuSysKey = 0;
-	if (wParam == VK_RETURN && (wndPtr->dwStyle & WS_MINIMIZE))
+	if (wParam == VK_RETURN && IsIconic(hwnd))
         {
-	    pPostMessage( wndPtr->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, 0L );
+            PostMessageW( hwnd, WM_SYSCOMMAND, SC_RESTORE, 0L );
 	    break;
         } 
 	if ((HIWORD(lParam) & KEYDATA_ALT) && wParam)
         {
 	    if (wParam == VK_TAB || wParam == VK_ESCAPE) break;
-	    if (wParam == VK_SPACE && (wndPtr->dwStyle & WS_CHILD))
-		pSendMessage( wndPtr->parent->hwndSelf, msg, wParam, lParam );
+            if (wParam == VK_SPACE && (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD))
+                SendMessageW( GetParent(hwnd), msg, wParam, lParam );
 	    else
-		pSendMessage( wndPtr->hwndSelf, WM_SYSCOMMAND, SC_KEYMENU, wParam );
+                SendMessageW( hwnd, WM_SYSCOMMAND, SC_KEYMENU, wParam );
         } 
 	else /* check for Ctrl-Esc */
             if (wParam != VK_ESCAPE) MessageBeep(0);
 	break;
 
     case WM_SHOWWINDOW:
-        if (!lParam) return 0; /* sent from ShowWindow */
-        if (!(wndPtr->dwStyle & WS_POPUP) || !wndPtr->owner) return 0;
-        if ((wndPtr->dwStyle & WS_VISIBLE) && wParam) return 0;
-	else if (!(wndPtr->dwStyle & WS_VISIBLE) && !wParam) return 0;
-        ShowWindow( wndPtr->hwndSelf, wParam ? SW_SHOWNOACTIVATE : SW_HIDE );
-	break; 
+        {
+            LONG style = GetWindowLongW( hwnd, GWL_STYLE );
+            if (!lParam) return 0; /* sent from ShowWindow */
+            if (!(style & WS_POPUP)) return 0;
+            if ((style & WS_VISIBLE) && wParam) return 0;
+            if (!(style & WS_VISIBLE) && !wParam) return 0;
+            if (!GetWindow( hwnd, GW_OWNER )) return 0;
+            ShowWindow( hwnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE );
+            break;
+        }
 
     case WM_CANCELMODE:
-	if (wndPtr->parent == WIN_GetDesktop()) EndMenu();
-	if (GetCapture() == wndPtr->hwndSelf) ReleaseCapture();
-        WIN_ReleaseDesktop();
+        if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD)) EndMenu();
+	if (GetCapture() == hwnd) ReleaseCapture();
 	break;
 
     case WM_VKEYTOITEM:
@@ -590,27 +585,32 @@
 	return DRAG_FILE;  
 
     case WM_QUERYDROPOBJECT:
-	if (wndPtr->dwExStyle & WS_EX_ACCEPTFILES) return 1;
-	break;
+        return (GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES) != 0;
 
     case WM_QUERYDRAGICON:
         {
             UINT len;
 
-            HICON hIcon = GetClassLongW( wndPtr->hwndSelf, GCL_HICON );
+            HICON hIcon = GetClassLongW( hwnd, GCL_HICON );
+            HINSTANCE instance = GetWindowLongW( hwnd, GWL_HINSTANCE );
             if (hIcon) return hIcon;
             for(len=1; len<64; len++)
-                if((hIcon = LoadIconW(wndPtr->hInstance, MAKEINTRESOURCEW(len))))
+                if((hIcon = LoadIconW(instance, MAKEINTRESOURCEW(len))))
                     return (LRESULT)hIcon;
             return (LRESULT)LoadIconW(0, IDI_APPLICATIONW);
         }
         break;
 
     case WM_ISACTIVEICON:
-	return ((wndPtr->flags & WIN_NCACTIVATED) != 0);
+        {
+            WND *wndPtr = WIN_FindWndPtr( hwnd );
+            BOOL ret = (wndPtr->flags & WIN_NCACTIVATED) != 0;
+            WIN_ReleaseWndPtr( wndPtr );
+            return ret;
+        }
 
     case WM_NOTIFYFORMAT:
-      if (IsWindowUnicode(wndPtr->hwndSelf)) return NFR_UNICODE;
+      if (IsWindowUnicode(hwnd)) return NFR_UNICODE;
       else return NFR_ANSI;
         
     case WM_QUERYOPEN:
@@ -619,14 +619,14 @@
 
     case WM_SETICON:
         if (USER_Driver.pSetWindowIcon)
-            return USER_Driver.pSetWindowIcon( wndPtr->hwndSelf, lParam, (wParam != ICON_SMALL) );
+            return USER_Driver.pSetWindowIcon( hwnd, lParam, (wParam != ICON_SMALL) );
         else
 	{
 		int index = (wParam != ICON_SMALL) ? GCL_HICON : GCL_HICONSM;
-		HICON hOldIcon = GetClassLongW(wndPtr->hwndSelf, index); 
-		SetClassLongW(wndPtr->hwndSelf, index, lParam);
+		HICON hOldIcon = GetClassLongW(hwnd, index); 
+		SetClassLongW(hwnd, index, lParam);
 
-		SetWindowPos(wndPtr->hwndSelf, 0, 0, 0, 0, 0, SWP_FRAMECHANGED
+		SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED
 			 | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE
 			 | SWP_NOZORDER);
 		return hOldIcon;
@@ -635,11 +635,11 @@
     case WM_GETICON:
 	{
 		int index = (wParam != ICON_SMALL) ? GCL_HICON : GCL_HICONSM;
-		return GetClassLongW(wndPtr->hwndSelf, index); 
+		return GetClassLongW(hwnd, index); 
 	}
 
     case WM_HELP:
-	pSendMessage( wndPtr->parent->hwndSelf, msg, wParam, lParam );
+        SendMessageW( GetParent(hwnd), msg, wParam, lParam );
 	break;
     }
 
@@ -654,10 +654,9 @@
 LRESULT WINAPI DefWindowProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
                                 LPARAM lParam )
 {
-    WND * wndPtr = WIN_FindWndPtr( hwnd );
     LRESULT result = 0;
 
-    if (!wndPtr) return 0;
+    if (!IsWindow( hwnd )) return 0;
     SPY_EnterMessage( SPY_DEFWNDPROC16, hwnd, msg, wParam, lParam );
 
     switch(msg)
@@ -668,7 +667,7 @@
 	    /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
 	     * may have child window IDs instead of window name */
 	    if (HIWORD(cs->lpszName))
-		DEFWND_SetTextA( wndPtr, MapSL(cs->lpszName) );
+                DEFWND_SetTextA( hwnd, MapSL(cs->lpszName) );
 	    result = 1;
 	}
         break;
@@ -689,39 +688,20 @@
     case WM_WINDOWPOSCHANGED:
 	{
 	    WINDOWPOS16 * winPos = MapSL(lParam);
-            DEFWND_HandleWindowPosChanged( wndPtr, winPos->flags );
+            DEFWND_HandleWindowPosChanged( hwnd, winPos->flags );
 	}
         break;
 
-    case WM_GETTEXTLENGTH:
-        if (wndPtr->text)
-            result = WideCharToMultiByte( CP_ACP, 0, wndPtr->text, strlenW(wndPtr->text),
-                                          NULL, 0, NULL, NULL );
-        break;
-
     case WM_GETTEXT:
-        if (wParam && wndPtr->text)
-        {
-            LPSTR dest = MapSL(lParam);
-            if (!WideCharToMultiByte( CP_ACP, 0, wndPtr->text, -1, dest, wParam, NULL, NULL ))
-                dest[wParam-1] = 0;
-            result = strlen(dest);
-        }
-        break;
-
     case WM_SETTEXT:
-	DEFWND_SetTextA( wndPtr, MapSL(lParam) );
-	if( (wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION )
-	    NC_HandleNCPaint( hwnd , (HRGN)1 );
-	result = 1; /* success. FIXME: check text length */
+        result = DefWindowProcA( hwnd, msg, wParam, (LPARAM)MapSL(lParam) );
         break;
 
     default:
-        result = DEFWND_DefWinProc( wndPtr, msg, wParam, lParam, FALSE );
+        result = DefWindowProcA( hwnd, msg, wParam, lParam );
         break;
     }
 
-    WIN_ReleaseWndPtr(wndPtr);
     SPY_ExitMessage( SPY_RESULT_DEFWND16, hwnd, msg, result, wParam, lParam );
     return result;
 }
@@ -731,13 +711,11 @@
  *		DefWindowProcA (USER32.@)
  *
  */
-LRESULT WINAPI DefWindowProcA( HWND hwnd, UINT msg, WPARAM wParam,
-                                 LPARAM lParam )
+LRESULT WINAPI DefWindowProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
 {
-    WND * wndPtr = WIN_FindWndPtr( hwnd );
     LRESULT result = 0;
 
-    if (!wndPtr) return 0;
+    if (!IsWindow( hwnd )) return 0;
     SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam );
 
     switch(msg)
@@ -748,7 +726,7 @@
 	    /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
 	     * may have child window IDs instead of window name */
 	    if (HIWORD(cs->lpszName))
-	        DEFWND_SetTextA( wndPtr, cs->lpszName );
+                DEFWND_SetTextA( hwnd, cs->lpszName );
 	    result = 1;
 	}
         break;
@@ -764,29 +742,37 @@
     case WM_WINDOWPOSCHANGED:
 	{
 	    WINDOWPOS * winPos = (WINDOWPOS *)lParam;
-            DEFWND_HandleWindowPosChanged( wndPtr, winPos->flags );
+            DEFWND_HandleWindowPosChanged( hwnd, winPos->flags );
 	}
         break;
 
     case WM_GETTEXTLENGTH:
-        if (wndPtr->text)
-            result = WideCharToMultiByte( CP_ACP, 0, wndPtr->text, strlenW(wndPtr->text),
-                                          NULL, 0, NULL, NULL );
+        {
+            WND *wndPtr = WIN_FindWndPtr( hwnd );
+            if (wndPtr && wndPtr->text)
+                result = WideCharToMultiByte( CP_ACP, 0, wndPtr->text, strlenW(wndPtr->text),
+                                              NULL, 0, NULL, NULL );
+            WIN_ReleaseWndPtr( wndPtr );
+        }
         break;
 
     case WM_GETTEXT:
-        if (wParam && wndPtr->text)
         {
-            if (!WideCharToMultiByte( CP_ACP, 0, wndPtr->text, -1,
-                                      (LPSTR)lParam, wParam, NULL, NULL ))
-                ((LPSTR)lParam)[wParam-1] = 0;
-            result = (LRESULT)strlen( (LPSTR)lParam );
+            WND *wndPtr = WIN_FindWndPtr( hwnd );
+            if (wParam && wndPtr && wndPtr->text)
+            {
+                LPSTR dest = (LPSTR)lParam;
+                if (!WideCharToMultiByte( CP_ACP, 0, wndPtr->text, -1,
+                                          dest, wParam, NULL, NULL )) dest[wParam-1] = 0;
+                result = strlen( dest );
+            }
+            WIN_ReleaseWndPtr( wndPtr );
         }
         break;
 
     case WM_SETTEXT:
-	DEFWND_SetTextA( wndPtr, (LPCSTR)lParam );
-	if( (wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION )
+        DEFWND_SetTextA( hwnd, (LPCSTR)lParam );
+        if( (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CAPTION) == WS_CAPTION )
 	    NC_HandleNCPaint( hwnd , (HRGN)1 );  /* Repaint caption */
 	result = 1; /* success. FIXME: check text length */
         break;
@@ -832,11 +818,10 @@
 	break;
 
     default:
-	result = DEFWND_DefWinProc( wndPtr, msg, wParam, lParam, FALSE );
+        result = DEFWND_DefWinProc( hwnd, msg, wParam, lParam );
         break;
     }
 
-    WIN_ReleaseWndPtr(wndPtr);
     SPY_ExitMessage( SPY_RESULT_DEFWND, hwnd, msg, result, wParam, lParam );
     return result;
 }
@@ -857,10 +842,9 @@
     WPARAM wParam,  /* [in] first message parameter */
     LPARAM lParam )   /* [in] second message parameter */
 {
-    WND * wndPtr = WIN_FindWndPtr( hwnd );
     LRESULT result = 0;
 
-    if (!wndPtr) return 0;
+    if (!IsWindow( hwnd )) return 0;
     SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam );
 
     switch(msg)
@@ -871,7 +855,7 @@
 	    /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
 	     * may have child window IDs instead of window name */
 	    if (HIWORD(cs->lpszName))
-	        DEFWND_SetTextW( wndPtr, cs->lpszName );
+	        DEFWND_SetTextW( hwnd, cs->lpszName );
 	    result = 1;
 	}
         break;
@@ -887,25 +871,34 @@
     case WM_WINDOWPOSCHANGED:
 	{
 	    WINDOWPOS * winPos = (WINDOWPOS *)lParam;
-            DEFWND_HandleWindowPosChanged( wndPtr, winPos->flags );
+            DEFWND_HandleWindowPosChanged( hwnd, winPos->flags );
 	}
         break;
 
     case WM_GETTEXTLENGTH:
-        if (wndPtr->text) result = (LRESULT)strlenW(wndPtr->text);
+        {
+            WND *wndPtr = WIN_FindWndPtr( hwnd );
+            if (wndPtr && wndPtr->text) result = (LRESULT)strlenW(wndPtr->text);
+            WIN_ReleaseWndPtr( wndPtr );
+        }
         break;
 
     case WM_GETTEXT:
-        if (wParam && wndPtr->text)
         {
-            lstrcpynW( (LPWSTR)lParam, wndPtr->text, wParam );
-            result = strlenW( (LPWSTR)lParam );
+            WND *wndPtr = WIN_FindWndPtr( hwnd );
+            if (wParam && wndPtr && wndPtr->text)
+            {
+                LPWSTR dest = (LPWSTR)lParam;
+                lstrcpynW( dest, wndPtr->text, wParam );
+                result = strlenW( dest );
+            }
+            WIN_ReleaseWndPtr( wndPtr );
         }
         break;
 
     case WM_SETTEXT:
-	DEFWND_SetTextW( wndPtr, (LPCWSTR)lParam );
-	if( (wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION )
+        DEFWND_SetTextW( hwnd, (LPCWSTR)lParam );
+        if( (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CAPTION) == WS_CAPTION )
 	    NC_HandleNCPaint( hwnd , (HRGN)1 );  /* Repaint caption */
 	result = 1; /* success. FIXME: check text length */
         break;
@@ -925,10 +918,9 @@
 	break;
 
     default:
-	result = DEFWND_DefWinProc( wndPtr, msg, wParam, lParam, TRUE );
+        result = DEFWND_DefWinProc( hwnd, msg, wParam, lParam );
         break;
     }
-    WIN_ReleaseWndPtr(wndPtr);
     SPY_ExitMessage( SPY_RESULT_DEFWND, hwnd, msg, result, wParam, lParam );
     return result;
 }
diff --git a/windows/mdi.c b/windows/mdi.c
index e0d1975..feb2430 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -115,21 +115,19 @@
     UINT      nTotalCreated;
     UINT      mdiFlags;
     UINT      sbRecalc;   /* SB_xxx flags for scrollbar fixup */
-    HWND      self;
 } MDICLIENTINFO;
 
 static HBITMAP hBmpClose   = 0;
 static HBITMAP hBmpRestore = 0;
 
 /* ----------------- declarations ----------------- */
-static void MDI_UpdateFrameText(WND *, HWND, BOOL, LPCWSTR);
-static BOOL MDI_AugmentFrameMenu(WND *, HWND);
-static BOOL MDI_RestoreFrameMenu(WND *, HWND);
+static void MDI_UpdateFrameText( HWND, HWND, BOOL, LPCWSTR);
+static BOOL MDI_AugmentFrameMenu( HWND, HWND );
+static BOOL MDI_RestoreFrameMenu( HWND, HWND );
+static LONG MDI_ChildActivate( HWND, HWND );
 
-static LONG MDI_ChildActivate( WND*, HWND );
-
-static HWND MDI_MoreWindowsDialog(WND*);
-static void MDI_SwapMenuItems(WND *, UINT, UINT);
+static HWND MDI_MoreWindowsDialog(HWND);
+static void MDI_SwapMenuItems(HWND, UINT, UINT);
 static LRESULT WINAPI MDIClientWndProcA( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
 static LRESULT WINAPI MDIClientWndProcW( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
 
@@ -137,11 +135,20 @@
  *
  *			MDI_GetChildByID
  */
-static HWND MDI_GetChildByID(WND* wndPtr, UINT id)
+static HWND MDI_GetChildByID(HWND hwnd, UINT id)
 {
-    for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
-        if (wndPtr->wIDmenu == id) return wndPtr->hwndSelf;
-    return 0;
+    HWND ret;
+    HWND *win_array;
+    int i;
+
+    if (!(win_array = WIN_BuildWinArray( hwnd ))) return 0;
+    for (i = 0; win_array[i]; i++)
+    {
+        if (GetWindowLongA( win_array[i], GWL_ID ) == id) break;
+    }
+    ret = win_array[i];
+    WIN_ReleaseWinArray( win_array );
+    return ret;
 }
 
 static void MDI_PostUpdate(HWND hwnd, MDICLIENTINFO* ci, WORD recalc)
@@ -170,56 +177,57 @@
 };
 
 
+static MDICLIENTINFO *get_client_info( HWND client )
+{
+    MDICLIENTINFO *ret = NULL;
+    WND *win = WIN_FindWndPtr( client );
+    if (win)
+    {
+        if (win->cbWndExtra < sizeof(MDICLIENTINFO)) WARN( "%x is not an MDI client\n", client );
+        else ret = (MDICLIENTINFO *)win->wExtra;
+        WIN_ReleaseWndPtr( win );
+    }
+    return ret;
+}
+
 /**********************************************************************
  *			MDI_MenuModifyItem
  */
-static BOOL MDI_MenuModifyItem(WND* clientWnd, HWND hWndChild )
+static BOOL MDI_MenuModifyItem( HWND client, HWND hWndChild )
 {
-    WCHAR           buffer[128];
     static const WCHAR format[] = {'%','d',' ',0};
-    MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
-    WND            *wndPtr     = WIN_FindWndPtr(hWndChild);
-    UINT	    n          = wsprintfW(buffer, format,
-                                           wndPtr->wIDmenu - clientInfo->idFirstChild + 1);
-    BOOL	    bRet	    = 0;
 
-    if( !clientInfo->hWindowMenu )
-    {
-        bRet =  FALSE;
-        goto END;
-    }
+    MDICLIENTINFO *clientInfo = get_client_info( client );
+    WCHAR buffer[128];
+    UINT n, id;
+    BOOL bRet;
 
-    if (wndPtr->text) lstrcpynW(buffer + n, wndPtr->text, sizeof(buffer)/sizeof(WCHAR) - n );
+    if (!clientInfo || !clientInfo->hWindowMenu) return FALSE;
 
-    n    = GetMenuState(clientInfo->hWindowMenu,wndPtr->wIDmenu ,MF_BYCOMMAND); 
-    bRet = ModifyMenuW(clientInfo->hWindowMenu , wndPtr->wIDmenu, 
-                      MF_BYCOMMAND | MF_STRING, wndPtr->wIDmenu, buffer );
-    CheckMenuItem(clientInfo->hWindowMenu ,wndPtr->wIDmenu , n & MF_CHECKED);
-END:
-    WIN_ReleaseWndPtr(wndPtr);
+    id = GetWindowLongA( hWndChild, GWL_ID );
+    n = wsprintfW(buffer, format, id - clientInfo->idFirstChild + 1);
+    GetWindowTextW( hWndChild, buffer + n, sizeof(buffer)/sizeof(WCHAR) - n );
+
+    n    = GetMenuState(clientInfo->hWindowMenu, id, MF_BYCOMMAND);
+    bRet = ModifyMenuW(clientInfo->hWindowMenu, id, MF_BYCOMMAND | MF_STRING, id, buffer );
+    CheckMenuItem(clientInfo->hWindowMenu, id, n & MF_CHECKED);
     return bRet;
 }
 
 /**********************************************************************
  *			MDI_MenuDeleteItem
  */
-static BOOL MDI_MenuDeleteItem(WND* clientWnd, HWND hWndChild )
+static BOOL MDI_MenuDeleteItem( HWND client, HWND hWndChild )
 {
     WCHAR    	 buffer[128];
     static const WCHAR format[] = {'&','%','d',' ',0};
-    MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
-    WND    	*wndPtr     = WIN_FindWndPtr(hWndChild);
+    MDICLIENTINFO *clientInfo = get_client_info( client );
     UINT	 index      = 0,id,n;
-    BOOL         retvalue;
 
-    if( !clientInfo->nActiveChildren ||
-        !clientInfo->hWindowMenu )
-    {
-        retvalue = FALSE;
-        goto END;
-    }
+    if( !clientInfo->nActiveChildren || !clientInfo->hWindowMenu )
+        return FALSE;
 
-    id = wndPtr->wIDmenu;
+    id = GetWindowLongA( hWndChild, GWL_ID );
     DeleteMenu(clientInfo->hWindowMenu,id,MF_BYCOMMAND);
 
  /* walk the rest of MDI children to prevent gaps in the id 
@@ -228,20 +236,18 @@
     for( index = id+1; index <= clientInfo->nActiveChildren + 
 				clientInfo->idFirstChild; index++ )
     {
-        WND *tmpWnd = WIN_FindWndPtr(MDI_GetChildByID(clientWnd,index));
-	if( !tmpWnd )
-	{
-	      TRACE("no window for id=%i\n",index);
-            WIN_ReleaseWndPtr(tmpWnd);
-	      continue;
-	}
-    
+        HWND hwnd = MDI_GetChildByID(client,index);
+        if (!hwnd)
+        {
+            TRACE("no window for id=%i\n",index);
+            continue;
+        }
+
 	/* set correct id */
-	tmpWnd->wIDmenu--;
+        SetWindowLongW( hwnd, GWL_ID, GetWindowLongW( hwnd, GWL_ID ) - 1 );
 
 	n = wsprintfW(buffer, format ,index - clientInfo->idFirstChild);
-	if (tmpWnd->text)
-            lstrcpynW(buffer + n, tmpWnd->text, sizeof(buffer)/sizeof(WCHAR) - n );	
+        GetWindowTextW( hwnd, buffer + n, sizeof(buffer)/sizeof(WCHAR) - n );
 
 	/*  change menu if the current child is to be shown in the 
          *  "Windows" menu
@@ -249,10 +255,9 @@
         if (index <= clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT) 
 	ModifyMenuW(clientInfo->hWindowMenu ,index ,MF_BYCOMMAND | MF_STRING,
                       index - 1 , buffer ); 
-        WIN_ReleaseWndPtr(tmpWnd);
     }
 
-    /*  We must restore the "More Windows..." option if there is enough child 
+    /*  We must restore the "More Windows..." option if there are enough children
      */
     if (clientInfo->nActiveChildren - 1 > MDI_MOREWINDOWSLIMIT)
     {
@@ -260,10 +265,7 @@
         LoadStringW(GetModuleHandleA("USER32"), MDI_IDS_MOREWINDOWS, szTmp, sizeof(szTmp)/sizeof(szTmp[0]));
         AppendMenuW(clientInfo->hWindowMenu, MF_STRING, clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT, szTmp);
     }
-    retvalue = TRUE;
-END:
-    WIN_ReleaseWndPtr(wndPtr);
-    return retvalue;
+    return TRUE;
 }
 
 /**********************************************************************
@@ -271,10 +273,9 @@
  *
  * returns "activateable" child different from the current or zero
  */
-static HWND MDI_GetWindow(WND *clientWnd, HWND hWnd, BOOL bNext,
+static HWND MDI_GetWindow(MDICLIENTINFO *clientInfo, HWND hWnd, BOOL bNext,
                             DWORD dwStyleMask )
 {
-    MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
     WND *wndPtr, *pWnd, *pWndLast = NULL;
     
     dwStyleMask |= WS_DISABLED | WS_VISIBLE;
@@ -304,14 +305,14 @@
  *
  *  It seems that the default height is about 2/3 of the client rect
  */
-static void MDI_CalcDefaultChildPos( WND* w, WORD n, LPPOINT lpPos,
-                                     INT delta)
+static void MDI_CalcDefaultChildPos( HWND hwnd, WORD n, LPPOINT lpPos, INT delta)
 {
     INT  nstagger;
-    RECT rect = w->rectClient;
+    RECT rect;
     INT  spacing = GetSystemMetrics(SM_CYCAPTION) +
 		     GetSystemMetrics(SM_CYFRAME) - 1; 
 
+    GetClientRect( hwnd, &rect );
     if( rect.bottom - rect.top - delta >= spacing ) 
 	rect.bottom -= delta;
 
@@ -327,7 +328,6 @@
 static LRESULT MDISetMenu( HWND hwnd, HMENU hmenuFrame,
                            HMENU hmenuWindow)
 {
-    WND *w;
     MDICLIENTINFO *ci;
     HWND hwndFrame = GetParent(hwnd);
     HMENU oldFrameMenu = GetMenu(hwndFrame);
@@ -346,12 +346,11 @@
 	WARN("hmenuWindow is not a menu handle\n");
 	return 0L;
     }
-	
-    w = WIN_FindWndPtr(hwnd);
-    ci = (MDICLIENTINFO *) w->wExtra;
+
+    if (!(ci = get_client_info( hwnd ))) return 0;
 
     if( ci->hwndChildMaximized && hmenuFrame && hmenuFrame!=oldFrameMenu )
-        MDI_RestoreFrameMenu(w->parent, ci->hwndChildMaximized );
+        MDI_RestoreFrameMenu( GetParent(hwnd), ci->hwndChildMaximized );
 
     if( hmenuWindow && ci->hWindowMenu && hmenuWindow!=ci->hWindowMenu )
     {
@@ -413,15 +412,15 @@
         if( hmenuFrame!=oldFrameMenu )
         {
             if( ci->hwndChildMaximized )
-                MDI_AugmentFrameMenu( w->parent, ci->hwndChildMaximized );
-            WIN_ReleaseWndPtr(w);
+                MDI_AugmentFrameMenu( GetParent(hwnd), ci->hwndChildMaximized );
             return oldFrameMenu;
         }
     }
     else
     {
-	INT nItems = GetMenuItemCount(w->parent->wIDmenu) - 1;
-	UINT iId = GetMenuItemID(w->parent->wIDmenu,nItems) ;
+        HMENU menu = GetMenu( GetParent(hwnd) );
+	INT nItems = GetMenuItemCount(menu) - 1;
+	UINT iId = GetMenuItemID(menu,nItems) ;
 
 	if( !(iId == SC_RESTORE || iId == SC_CLOSE) )
 	{
@@ -432,10 +431,9 @@
 	     * augment the frame menu.
 	     */
 	    if( ci->hwndChildMaximized )
-		MDI_AugmentFrameMenu( w->parent, ci->hwndChildMaximized );
+		MDI_AugmentFrameMenu( GetParent(hwnd), ci->hwndChildMaximized );
 	}
     }
-    WIN_ReleaseWndPtr(w);
     return 0;
 }
 
@@ -463,19 +461,20 @@
 /**********************************************************************
  *					MDICreateChild
  */
-static HWND MDICreateChild( WND *wndParent, MDICLIENTINFO *ci,
+static HWND MDICreateChild( HWND parent, MDICLIENTINFO *ci,
 			    LPMDICREATESTRUCTA cs, BOOL unicode )
 {
     POINT          pos[2]; 
     DWORD	     style = cs->style | (WS_CHILD | WS_CLIPSIBLINGS);
     HWND 	     hwnd, hwndMax = 0;
-    WORD	     wIDmenu = ci->idFirstChild + ci->nActiveChildren;
+    UINT wIDmenu = ci->idFirstChild + ci->nActiveChildren;
+    WND *wndParent;
     static const WCHAR lpstrDef[] = {'j','u','n','k','!',0};
 
     TRACE("origin %i,%i - dim %i,%i, style %08lx\n", 
                 cs->x, cs->y, cs->cx, cs->cy, cs->style);
     /* calculate placement */
-    MDI_CalcDefaultChildPos(wndParent, ci->nTotalCreated++, pos, 0);
+    MDI_CalcDefaultChildPos(parent, ci->nTotalCreated++, pos, 0);
 
     if (cs->cx == CW_USEDEFAULT || !cs->cx) cs->cx = pos[1].x;
     if (cs->cy == CW_USEDEFAULT || !cs->cy) cs->cy = pos[1].y;
@@ -491,11 +490,11 @@
     {
 	TRACE("Restoring current maximized child %04x\n", ci->hwndChildMaximized);
 	if( style & WS_MAXIMIZE )
-	    SendMessageW(wndParent->hwndSelf, WM_SETREDRAW, FALSE, 0L);
+	    SendMessageW(parent, WM_SETREDRAW, FALSE, 0L);
 	hwndMax = ci->hwndChildMaximized;
 	ShowWindow( hwndMax, SW_SHOWNOACTIVATE );
 	if( style & WS_MAXIMIZE )
-	    SendMessageW(wndParent->hwndSelf, WM_SETREDRAW, TRUE, 0L);
+	    SendMessageW(parent, WM_SETREDRAW, TRUE, 0L);
     }
 
     if (ci->nActiveChildren <= MDI_MOREWINDOWSLIMIT)
@@ -506,6 +505,7 @@
     ci->nActiveChildren++;
 
     /* fix window style */
+    wndParent = WIN_FindWndPtr( parent );
     if( !(wndParent->dwStyle & MDIS_ALLCHILDSTYLES) )
     {
 	TRACE("MDIS_ALLCHILDSTYLES is missing, fixing window style\n");
@@ -516,16 +516,17 @@
 
     if( wndParent->flags & WIN_ISWIN32 )
     {
+        WIN_ReleaseWndPtr( wndParent );
 	if(unicode)
 	{
 	    MDICREATESTRUCTW *csW = (MDICREATESTRUCTW *)cs;
 	    hwnd = CreateWindowW( csW->szClass, csW->szTitle, style, 
-                                csW->x, csW->y, csW->cx, csW->cy, wndParent->hwndSelf,
+                                csW->x, csW->y, csW->cx, csW->cy, parent,
                                 (HMENU)wIDmenu, csW->hOwner, csW );
 	}
 	else
 	    hwnd = CreateWindowA( cs->szClass, cs->szTitle, style, 
-                                cs->x, cs->y, cs->cx, cs->cy, wndParent->hwndSelf,
+                                cs->x, cs->y, cs->cx, cs->cy, parent,
                                 (HMENU)wIDmenu, cs->hOwner, cs );
     }
     else
@@ -533,6 +534,7 @@
     	MDICREATESTRUCT16 *cs16;
         LPSTR title, cls;
 
+        WIN_ReleaseWndPtr( wndParent );
         cs16 = SEGPTR_NEW(MDICREATESTRUCT16);
         STRUCT32_MDICREATESTRUCT32Ato16( cs, cs16 );
         title = SEGPTR_STRDUP( cs->szTitle );
@@ -541,7 +543,7 @@
         cs16->szClass = SEGPTR_GET(cls);
 
 	hwnd = CreateWindow16( cs->szClass, cs->szTitle, style, 
-			       cs16->x, cs16->y, cs16->cx, cs16->cy, wndParent->hwndSelf, 
+			       cs16->x, cs16->y, cs16->cx, cs16->cy, parent,
 			       (HMENU)wIDmenu, cs16->hOwner,
                                (LPVOID)SEGPTR_GET(cs16) );
         SEGPTR_FREE( title );
@@ -553,18 +555,17 @@
 
     if (hwnd)
     {
-	WND* wnd = WIN_FindWndPtr( hwnd );
-
 	/* All MDI child windows have the WS_EX_MDICHILD style */
-	wnd->dwExStyle |= WS_EX_MDICHILD;
+        SetWindowLongW( hwnd, GWL_EXSTYLE, GetWindowLongW( hwnd, GWL_EXSTYLE ) | WS_EX_MDICHILD );
 
         /*  If we have more than 9 windows, we must insert the new one at the
          *  9th position in order to see it in the "Windows" menu
          */
         if (ci->nActiveChildren > MDI_MOREWINDOWSLIMIT)
-            MDI_SwapMenuItems(wnd->parent, wnd->wIDmenu, ci->idFirstChild + MDI_MOREWINDOWSLIMIT - 1);
+            MDI_SwapMenuItems( parent, GetWindowLongW( hwnd, GWL_ID ),
+                               ci->idFirstChild + MDI_MOREWINDOWSLIMIT - 1);
 
-	MDI_MenuModifyItem(wndParent, hwnd);
+	MDI_MenuModifyItem(parent, hwnd);
 
         /* Have we hit the "More Windows..." limit? If so, we must 
          * add a "More Windows..." option 
@@ -580,8 +581,8 @@
                         ci->idFirstChild + MDI_MOREWINDOWSLIMIT, 
                         szTmp);
         }
-        
-	if( (wnd->dwStyle & WS_MINIMIZE) && ci->hwndActiveChild )
+
+        if( IsIconic(hwnd) && ci->hwndActiveChild )
 	{
 	    TRACE("Minimizing created MDI child %04x\n", hwnd);
 	    ShowWindow( hwnd, SW_SHOWMINNOACTIVE );
@@ -593,10 +594,8 @@
              * MDICreateStruct. If so the created window is not shown nor 
              * activated.
              */
-            if(wnd->dwStyle & WS_VISIBLE)
-		ShowWindow(hwnd, SW_SHOW);
+            if (IsWindowVisible(hwnd)) ShowWindow(hwnd, SW_SHOW);
 	}
-        WIN_ReleaseWndPtr(wnd);
         TRACE("created child - %04x\n",hwnd);
     }
     else
@@ -616,15 +615,13 @@
  * Note: The rule here is that client rect of the maximized MDI child 
  *	 is equal to the client rect of the MDI client window.
  */
-static void MDI_ChildGetMinMaxInfo( WND* clientWnd, HWND hwnd,
-                                    MINMAXINFO* lpMinMax )
+static void MDI_ChildGetMinMaxInfo( HWND client, HWND hwnd, MINMAXINFO* lpMinMax )
 {
-    WND*	childWnd = WIN_FindWndPtr(hwnd);
-    RECT	rect 	 = clientWnd->rectClient;
+    RECT rect;
 
-    MapWindowPoints( clientWnd->parent->hwndSelf, 
-		     ((MDICLIENTINFO*)clientWnd->wExtra)->self, (LPPOINT)&rect, 2);
-    AdjustWindowRectEx( &rect, childWnd->dwStyle, 0, childWnd->dwExStyle );
+    GetClientRect( client, &rect );
+    AdjustWindowRectEx( &rect, GetWindowLongW( hwnd, GWL_STYLE ),
+                        0, GetWindowLongW( hwnd, GWL_EXSTYLE ));
 
     lpMinMax->ptMaxSize.x = rect.right -= rect.left;
     lpMinMax->ptMaxSize.y = rect.bottom -= rect.top;
@@ -632,11 +629,8 @@
     lpMinMax->ptMaxPosition.x = rect.left;
     lpMinMax->ptMaxPosition.y = rect.top; 
 
-    WIN_ReleaseWndPtr(childWnd);
-    
     TRACE("max rect (%i,%i - %i, %i)\n", 
                         rect.left,rect.top,rect.right,rect.bottom);
-    
 }
 
 /**********************************************************************
@@ -648,88 +642,66 @@
 static void MDI_SwitchActiveChild( HWND clientHwnd, HWND childHwnd,
                                    BOOL bNextWindow )
 {
-    WND		  *w	     = WIN_FindWndPtr(clientHwnd);
     HWND	   hwndTo    = 0;
     HWND	   hwndPrev  = 0;
-    MDICLIENTINFO *ci;
+    MDICLIENTINFO *ci = get_client_info( clientHwnd );
 
-    hwndTo = MDI_GetWindow(w, childHwnd, bNextWindow, 0);
- 
-    ci = (MDICLIENTINFO *) w->wExtra;
+    hwndTo = MDI_GetWindow(ci, childHwnd, bNextWindow, 0);
 
     TRACE("from %04x, to %04x\n",childHwnd,hwndTo);
 
-    if ( !hwndTo ) goto END; /* no window to switch to */
+    if ( !hwndTo ) return; /* no window to switch to */
 
     hwndPrev = ci->hwndActiveChild;
 
     if ( hwndTo != hwndPrev )
     {
-	BOOL bOptimize = 0;
-
-	if( ci->hwndChildMaximized )
-	{
-	    bOptimize = 1; 
-	    w->dwStyle &= ~WS_VISIBLE;
-	}
-
 	SetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0, 
-			SWP_NOMOVE | SWP_NOSIZE );
+                      SWP_NOMOVE | SWP_NOSIZE );
 
 	if( bNextWindow && hwndPrev )
 	    SetWindowPos( hwndPrev, HWND_BOTTOM, 0, 0, 0, 0, 
-		  	    SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
-	if( bOptimize )
-	    ShowWindow( clientHwnd, SW_SHOW );
+                          SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
     }
-END:
-    WIN_ReleaseWndPtr(w);
 }
 
-	    
+
 /**********************************************************************
  *                                      MDIDestroyChild
  */
-static LRESULT MDIDestroyChild( WND *w_parent, MDICLIENTINFO *ci,
+static LRESULT MDIDestroyChild( HWND parent, MDICLIENTINFO *ci,
                                 HWND child, BOOL flagDestroy )
 {
-    WND         *childPtr = WIN_FindWndPtr(child);
-
-    if( childPtr )
+    if( child == ci->hwndActiveChild )
     {
+        MDI_SwitchActiveChild(parent, child, TRUE);
+
         if( child == ci->hwndActiveChild )
         {
-	    MDI_SwitchActiveChild(w_parent->hwndSelf, child, TRUE);
+            ShowWindow( child, SW_HIDE);
+            if( child == ci->hwndChildMaximized )
+            {
+                HWND frame = GetParent(parent);
+                MDI_RestoreFrameMenu( frame, child );
+                ci->hwndChildMaximized = 0;
+                MDI_UpdateFrameText( frame, parent, TRUE, NULL);
+            }
 
-	    if( child == ci->hwndActiveChild )
-	    {
-		ShowWindow( child, SW_HIDE);
-		if( child == ci->hwndChildMaximized )
-		{
-		    MDI_RestoreFrameMenu(w_parent->parent, child);
-		    ci->hwndChildMaximized = 0;
-		    MDI_UpdateFrameText(w_parent->parent, w_parent->hwndSelf, TRUE, NULL);
-		}
-
-                MDI_ChildActivate(w_parent, 0);
-	    }
+            MDI_ChildActivate(parent, 0);
         }
-
-        MDI_MenuDeleteItem(w_parent, child);
-
-        WIN_ReleaseWndPtr(childPtr);
-	
-        ci->nActiveChildren--;
-
-        TRACE("child destroyed - %04x\n",child);
-
-        if (flagDestroy)
-	{
-	    MDI_PostUpdate(GetParent(child), ci, SB_BOTH+1);
-            DestroyWindow(child);
-	}
     }
 
+    MDI_MenuDeleteItem(parent, child);
+
+    ci->nActiveChildren--;
+
+    TRACE("child destroyed - %04x\n",child);
+
+    if (flagDestroy)
+    {
+        MDI_PostUpdate(GetParent(child), ci, SB_BOTH+1);
+        DestroyWindow(child);
+    }
     return 0;
 }
 
@@ -739,112 +711,89 @@
  *
  * Note: hWndChild is NULL when last child is being destroyed
  */
-static LONG MDI_ChildActivate( WND *clientPtr, HWND hWndChild )
+static LONG MDI_ChildActivate( HWND client, HWND child )
 {
-    MDICLIENTINFO       *clientInfo = (MDICLIENTINFO*)clientPtr->wExtra; 
-    HWND               prevActiveWnd = clientInfo->hwndActiveChild;
-    WND                 *wndPtr = WIN_FindWndPtr( hWndChild );
-    WND			*wndPrev = WIN_FindWndPtr( prevActiveWnd );
-    BOOL		 isActiveFrameWnd = 0;	 
-    LONG               retvalue;
+    MDICLIENTINFO *clientInfo = get_client_info( client );
+    HWND prevActiveWnd = clientInfo->hwndActiveChild;
+    BOOL isActiveFrameWnd;
 
-    if( wndPtr )
-    {
-        if( wndPtr->dwStyle & WS_DISABLED )
-        {
-            retvalue = 0L;
-            goto END;
-        }
-    }
+    if (!IsWindowEnabled( child )) return 0;
 
     /* Don't activate if it is already active. Might happen 
        since ShowWindow DOES activate MDI children */
-    if (clientInfo->hwndActiveChild == hWndChild)
-    {
-      retvalue = 0L;
-      goto END;
-    }
+    if (clientInfo->hwndActiveChild == child) return 0;
 
-    TRACE("%04x\n", hWndChild);
+    TRACE("%04x\n", child);
 
-    if( GetActiveWindow() == clientPtr->parent->hwndSelf )
-        isActiveFrameWnd = TRUE;
-	
+    isActiveFrameWnd = (GetActiveWindow() == GetParent(client));
+
     /* deactivate prev. active child */
-    if( wndPrev )
+    if(prevActiveWnd)
     {
-	wndPrev->dwStyle |= WS_SYSMENU;
+        SetWindowLongA( prevActiveWnd, GWL_STYLE,
+                        GetWindowLongA( prevActiveWnd, GWL_STYLE ) | WS_SYSMENU );
 	SendMessageA( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L );
-        SendMessageA( prevActiveWnd, WM_MDIACTIVATE, (WPARAM)prevActiveWnd,
-                        (LPARAM)hWndChild);
+        SendMessageA( prevActiveWnd, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, (LPARAM)child);
         /* uncheck menu item */
        	if( clientInfo->hWindowMenu )
         {
-            WORD wPrevID = wndPrev->wIDmenu - clientInfo->idFirstChild;
+            UINT prevID = GetWindowLongA( prevActiveWnd, GWL_ID );
 
-            if (wPrevID < MDI_MOREWINDOWSLIMIT)
-       	        CheckMenuItem( clientInfo->hWindowMenu,
-                                 wndPrev->wIDmenu, 0);
+            if (prevID - clientInfo->idFirstChild < MDI_MOREWINDOWSLIMIT)
+                CheckMenuItem( clientInfo->hWindowMenu, prevID, 0);
             else
        	        CheckMenuItem( clientInfo->hWindowMenu,
                                clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT - 1, 0);
-    }
+        }
     }
 
     /* set appearance */
-    if( clientInfo->hwndChildMaximized )
+    if (clientInfo->hwndChildMaximized && clientInfo->hwndChildMaximized != child)
     {
-      if( clientInfo->hwndChildMaximized != hWndChild ) {
-        if( hWndChild ) {
-		  clientInfo->hwndActiveChild = hWndChild;
-		  ShowWindow( hWndChild, SW_SHOWMAXIMIZED);
-	} else
-		ShowWindow( clientInfo->hwndActiveChild, SW_SHOWNORMAL );
-      }
+        if( child )
+        {
+            clientInfo->hwndActiveChild = child;
+            ShowWindow( child, SW_SHOWMAXIMIZED);
+        }
+        else ShowWindow( clientInfo->hwndActiveChild, SW_SHOWNORMAL );
     }
 
-    clientInfo->hwndActiveChild = hWndChild;
+    clientInfo->hwndActiveChild = child;
 
     /* check if we have any children left */
-    if( !hWndChild )
+    if( !child )
     {
 	if( isActiveFrameWnd )
-	    SetFocus( clientInfo->self );
-        retvalue = 0;
-        goto END;
+	    SetFocus( client );
+        return 0;
     }
-	
+
     /* check menu item */
     if( clientInfo->hWindowMenu )
     {
-          /* The window to be activated must be displayed in the "Windows" menu */
-          if (wndPtr->wIDmenu >= clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT)
-          {
-              MDI_SwapMenuItems(wndPtr->parent, wndPtr->wIDmenu, clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT - 1);    
-              MDI_MenuModifyItem(wndPtr->parent ,wndPtr->hwndSelf); 
-          }
+        UINT id = GetWindowLongA( child, GWL_ID );
+        /* The window to be activated must be displayed in the "Windows" menu */
+        if (id >= clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT)
+        {
+            MDI_SwapMenuItems( GetParent(child), id, clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT - 1);
+            MDI_MenuModifyItem( GetParent(child), child );
+        }
 
-          CheckMenuItem(clientInfo->hWindowMenu, wndPtr->wIDmenu, MF_CHECKED);
+        CheckMenuItem(clientInfo->hWindowMenu, id, MF_CHECKED);
     }
     /* bring active child to the top */
-    SetWindowPos( hWndChild, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
+    SetWindowPos( child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
 
     if( isActiveFrameWnd )
     {
-	    SendMessageA( hWndChild, WM_NCACTIVATE, TRUE, 0L);
-	    if( GetFocus() == clientInfo->self )
-		SendMessageA( clientInfo->self, WM_SETFOCUS, 
-                                (WPARAM)clientInfo->self, 0L );
+	    SendMessageA( child, WM_NCACTIVATE, TRUE, 0L);
+	    if( GetFocus() == client )
+		SendMessageA( client, WM_SETFOCUS, (WPARAM)client, 0L );
 	    else
-		SetFocus( clientInfo->self );
+		SetFocus( client );
     }
-    SendMessageA( hWndChild, WM_MDIACTIVATE, (WPARAM)prevActiveWnd,
-                    (LPARAM)hWndChild );
-    retvalue = 1;
-END:
-    WIN_ReleaseWndPtr(wndPtr);
-    WIN_ReleaseWndPtr(wndPrev);
-    return retvalue;
+    SendMessageA( child, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, (LPARAM)child );
+    return TRUE;
 }
 
 /* -------------------- MDI client window functions ------------------- */
@@ -886,123 +835,138 @@
 /**********************************************************************
  *				MDICascade
  */
-static LONG MDICascade(WND* clientWnd, MDICLIENTINFO *ci)
+static LONG MDICascade( HWND client, MDICLIENTINFO *ci )
 {
-    WND**	ppWnd;
-    UINT	total;
-  
+    HWND *win_array;
+    BOOL has_icons = FALSE;
+    int i, total;
+
     if (ci->hwndChildMaximized)
-        SendMessageA( clientWnd->hwndSelf, WM_MDIRESTORE,
+        SendMessageA( client, WM_MDIRESTORE,
                         (WPARAM)ci->hwndChildMaximized, 0);
 
     if (ci->nActiveChildren == 0) return 0;
 
-    if ((ppWnd = WIN_BuildWinArray(clientWnd, BWA_SKIPHIDDEN | BWA_SKIPOWNED | 
-					      BWA_SKIPICONIC, &total)))
+    if (!(win_array = WIN_BuildWinArray( client ))) return 0;
+
+    /* remove all the windows we don't want */
+    for (i = total = 0; win_array[i]; i++)
     {
-	WND**	heapPtr = ppWnd;
-	if( total )
-	{
-	    INT	delta = 0, n = 0;
-	    POINT	pos[2];
-	    if( total < ci->nActiveChildren )
-		delta = GetSystemMetrics(SM_CYICONSPACING) +
-			GetSystemMetrics(SM_CYICON);
-
-	    /* walk the list (backwards) and move windows */
-            while (*ppWnd) ppWnd++;
-	    while (ppWnd != heapPtr)
-	    {
-                ppWnd--;
-		TRACE("move %04x to (%ld,%ld) size [%ld,%ld]\n", 
-                            (*ppWnd)->hwndSelf, pos[0].x, pos[0].y, pos[1].x, pos[1].y);
-
-		MDI_CalcDefaultChildPos(clientWnd, n++, pos, delta);
-		SetWindowPos( (*ppWnd)->hwndSelf, 0, pos[0].x, pos[0].y,
-                                pos[1].x, pos[1].y,
-                                SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
-	    }
-	}
-	WIN_ReleaseWinArray(heapPtr);
+        if (!IsWindowVisible( win_array[i] )) continue;
+        if (GetWindow( win_array[i], GW_OWNER )) continue; /* skip owned windows */
+        if (IsIconic( win_array[i] ))
+        {
+            has_icons = TRUE;
+            continue;
+        }
+        win_array[total++] = win_array[i];
     }
+    win_array[total] = 0;
 
-    if( total < ci->nActiveChildren )
-        ArrangeIconicWindows( clientWnd->hwndSelf );
+    if (total)
+    {
+        INT delta = 0, n = 0, i;
+        POINT pos[2];
+        if (has_icons) delta = GetSystemMetrics(SM_CYICONSPACING) + GetSystemMetrics(SM_CYICON);
+
+        /* walk the list (backwards) and move windows */
+        for (i = total - 1; i >= 0; i--)
+        {
+            TRACE("move %04x to (%ld,%ld) size [%ld,%ld]\n", 
+                  win_array[i], pos[0].x, pos[0].y, pos[1].x, pos[1].y);
+
+            MDI_CalcDefaultChildPos(client, n++, pos, delta);
+            SetWindowPos( win_array[i], 0, pos[0].x, pos[0].y, pos[1].x, pos[1].y,
+                          SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
+        }
+    }
+    WIN_ReleaseWinArray( win_array );
+
+    if (has_icons) ArrangeIconicWindows( client );
     return 0;
 }
 
 /**********************************************************************
  *					MDITile
  */
-static void MDITile( WND* wndClient, MDICLIENTINFO *ci, WPARAM wParam )
+static void MDITile( HWND client, MDICLIENTINFO *ci, WPARAM wParam )
 {
-    WND**	ppWnd;
-    UINT	total = 0;
+    HWND *win_array;
+    int i, total;
+    BOOL has_icons = FALSE;
 
     if (ci->hwndChildMaximized)
-        SendMessageA( wndClient->hwndSelf, WM_MDIRESTORE,
-                        (WPARAM)ci->hwndChildMaximized, 0);
+        SendMessageA( client, WM_MDIRESTORE, (WPARAM)ci->hwndChildMaximized, 0);
 
     if (ci->nActiveChildren == 0) return;
 
-    ppWnd = WIN_BuildWinArray(wndClient, BWA_SKIPHIDDEN | BWA_SKIPOWNED | BWA_SKIPICONIC |
-	    ((wParam & MDITILE_SKIPDISABLED)? BWA_SKIPDISABLED : 0), &total );
+    if (!(win_array = WIN_BuildWinArray( client ))) return;
+
+    /* remove all the windows we don't want */
+    for (i = total = 0; win_array[i]; i++)
+    {
+        if (!IsWindowVisible( win_array[i] )) continue;
+        if (GetWindow( win_array[i], GW_OWNER )) continue; /* skip owned windows (icon titles) */
+        if (IsIconic( win_array[i] ))
+        {
+            has_icons = TRUE;
+            continue;
+        }
+        if ((wParam & MDITILE_SKIPDISABLED) && !IsWindowEnabled( win_array[i] )) continue;
+        win_array[total++] = win_array[i];
+    }
+    win_array[total] = 0;
 
     TRACE("%u windows to tile\n", total);
 
-    if( ppWnd )
+    if (total)
     {
-	WND**	heapPtr = ppWnd;
+        HWND *pWnd = win_array;
+        RECT rect;
+        int x, y, xsize, ysize;
+        int rows, columns, r, c, i;
 
-	if( total )
-	{
-	    RECT	rect;
-	    int		x, y, xsize, ysize;
-	    int		rows, columns, r, c, i;
+        GetClientRect(client,&rect);
+        rows    = (int) sqrt((double)total);
+        columns = total / rows;
 
-	    GetClientRect(wndClient->hwndSelf,&rect);
-	    rows    = (int) sqrt((double)total);
-	    columns = total / rows;
+        if( wParam & MDITILE_HORIZONTAL )  /* version >= 3.1 */
+        {
+            i = rows;
+            rows = columns;  /* exchange r and c */
+            columns = i;
+        }
 
-	    if( wParam & MDITILE_HORIZONTAL )  /* version >= 3.1 */
-	    {
-	        i = rows;
-	        rows = columns;  /* exchange r and c */
-	        columns = i;
-	    }
+        if (has_icons)
+        {
+            y = rect.bottom - 2 * GetSystemMetrics(SM_CYICONSPACING) - GetSystemMetrics(SM_CYICON);
+            rect.bottom = ( y - GetSystemMetrics(SM_CYICON) < rect.top )? rect.bottom: y;
+        }
 
-	    if( total != ci->nActiveChildren)
-	    {
-	        y = rect.bottom - 2 * GetSystemMetrics(SM_CYICONSPACING) - GetSystemMetrics(SM_CYICON);
-	        rect.bottom = ( y - GetSystemMetrics(SM_CYICON) < rect.top )? rect.bottom: y;
-	    }
+        ysize   = rect.bottom / rows;
+        xsize   = rect.right  / columns;
 
-	    ysize   = rect.bottom / rows;
-	    xsize   = rect.right  / columns;
-    
-	    for (x = i = 0, c = 1; c <= columns && *ppWnd; c++)
-	    {
-	        if (c == columns)
-		{
-		    rows  = total - i;
-		    ysize = rect.bottom / rows;
-		}
+        for (x = i = 0, c = 1; c <= columns && *pWnd; c++)
+        {
+            if (c == columns)
+            {
+                rows  = total - i;
+                ysize = rect.bottom / rows;
+            }
 
-		y = 0;
-		for (r = 1; r <= rows && *ppWnd; r++, i++)
-		{
-		    SetWindowPos((*ppWnd)->hwndSelf, 0, x, y, xsize, ysize, 
-				   SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
-                    y += ysize;
-		    ppWnd++;
-		}
-		x += xsize;
-	    }
-	}
-	WIN_ReleaseWinArray(heapPtr);
+            y = 0;
+            for (r = 1; r <= rows && *pWnd; r++, i++)
+            {
+                SetWindowPos(*pWnd, 0, x, y, xsize, ysize,
+                             SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
+                y += ysize;
+                pWnd++;
+            }
+            x += xsize;
+        }
     }
-  
-    if( total < ci->nActiveChildren ) ArrangeIconicWindows( wndClient->hwndSelf );
+    WIN_ReleaseWinArray( win_array );
+    if (has_icons) ArrangeIconicWindows( client );
 }
 
 /* ----------------------- Frame window ---------------------------- */
@@ -1011,15 +975,16 @@
 /**********************************************************************
  *					MDI_AugmentFrameMenu
  */
-static BOOL MDI_AugmentFrameMenu( WND *frame, HWND hChild )
+static BOOL MDI_AugmentFrameMenu( HWND frame, HWND hChild )
 {
+    HMENU menu = GetMenu( frame );
     WND*	child = WIN_FindWndPtr(hChild);
     HMENU  	hSysPopup = 0;
   HBITMAP hSysMenuBitmap = 0;
 
-    TRACE("frame %p,child %04x\n",frame,hChild);
+    TRACE("frame %04x,child %04x\n",frame,hChild);
 
-    if( !frame->wIDmenu || !child->hSysMenu )
+    if( !menu || !child->hSysMenu )
     {
         WIN_ReleaseWndPtr(child);
         return 0;
@@ -1030,13 +995,10 @@
 
     if (!(hSysPopup = LoadMenuA(GetModuleHandleA("USER32"), "SYSMENU")))
 	return 0;
- 
-    TRACE("\tgot popup %04x in sysmenu %04x\n", 
-		hSysPopup, child->hSysMenu);
- 
-    AppendMenuA(frame->wIDmenu,MF_HELP | MF_BITMAP,
+
+    AppendMenuA(menu,MF_HELP | MF_BITMAP,
                    SC_MINIMIZE, (LPSTR)(DWORD)HBMMENU_MBAR_MINIMIZE ) ;
-    AppendMenuA(frame->wIDmenu,MF_HELP | MF_BITMAP,
+    AppendMenuA(menu,MF_HELP | MF_BITMAP,
                    SC_RESTORE, (LPSTR)(DWORD)HBMMENU_MBAR_RESTORE );
 
   /* In Win 95 look, the system menu is replaced by the child icon */
@@ -1075,7 +1037,7 @@
   else
     hSysMenuBitmap = hBmpClose;
 
-    if( !InsertMenuA(frame->wIDmenu,0,MF_BYPOSITION | MF_BITMAP | MF_POPUP,
+    if( !InsertMenuA(menu,0,MF_BYPOSITION | MF_BITMAP | MF_POPUP,
                     hSysPopup, (LPSTR)(DWORD)hSysMenuBitmap))
     {  
         TRACE("not inserted\n");
@@ -1086,7 +1048,7 @@
     /* The close button is only present in Win 95 look */
     if(TWEAK_WineLook > WIN31_LOOK)
     {
-        AppendMenuA(frame->wIDmenu,MF_HELP | MF_BITMAP,
+        AppendMenuA(menu,MF_HELP | MF_BITMAP,
                        SC_CLOSE, (LPSTR)(DWORD)HBMMENU_MBAR_CLOSE );
     }
 
@@ -1096,7 +1058,7 @@
     SetMenuDefaultItem(hSysPopup, SC_CLOSE, FALSE);
 
     /* redraw menu */
-    DrawMenuBar(frame->hwndSelf);
+    DrawMenuBar(frame);
 
     return 1;
 }
@@ -1104,14 +1066,14 @@
 /**********************************************************************
  *					MDI_RestoreFrameMenu
  */
-static BOOL MDI_RestoreFrameMenu( WND *frameWnd, HWND hChild )
+static BOOL MDI_RestoreFrameMenu( HWND frame, HWND hChild )
 {
     MENUITEMINFOW menuInfo;
-    INT nItems = GetMenuItemCount(frameWnd->wIDmenu) - 1;
-    UINT iId = GetMenuItemID(frameWnd->wIDmenu,nItems) ;
+    HMENU menu = GetMenu( frame );
+    INT nItems = GetMenuItemCount(menu) - 1;
+    UINT iId = GetMenuItemID(menu,nItems) ;
 
-    TRACE("frameWnd %p,(%04x),child %04x,nIt=%d,iId=%d\n",
-           frameWnd,frameWnd->hwndSelf,hChild,nItems,iId);
+    TRACE("frame %04x,child %04x,nIt=%d,iId=%d\n",frame,hChild,nItems,iId);
 
     if(!(iId == SC_RESTORE || iId == SC_CLOSE) )
 	return 0; 
@@ -1124,12 +1086,12 @@
     menuInfo.cbSize = sizeof(menuInfo);
     menuInfo.fMask  = MIIM_DATA | MIIM_TYPE;
 
-    GetMenuItemInfoW(frameWnd->wIDmenu, 
+    GetMenuItemInfoW(menu,
 		     0, 
 		     TRUE,
 		     &menuInfo);
 
-    RemoveMenu(frameWnd->wIDmenu,0,MF_BYPOSITION);
+    RemoveMenu(menu,0,MF_BYPOSITION);
 
     if ( (menuInfo.fType & MFT_BITMAP)           &&
 	 (LOWORD(menuInfo.dwTypeData)!=0)        &&
@@ -1141,14 +1103,14 @@
     if(TWEAK_WineLook > WIN31_LOOK)
     {
         /* close */
-        DeleteMenu(frameWnd->wIDmenu,GetMenuItemCount(frameWnd->wIDmenu) - 1,MF_BYPOSITION);
+        DeleteMenu(menu,GetMenuItemCount(menu) - 1,MF_BYPOSITION);
     }
     /* restore */
-    DeleteMenu(frameWnd->wIDmenu,GetMenuItemCount(frameWnd->wIDmenu) - 1,MF_BYPOSITION);
+    DeleteMenu(menu,GetMenuItemCount(menu) - 1,MF_BYPOSITION);
     /* minimize */
-    DeleteMenu(frameWnd->wIDmenu,GetMenuItemCount(frameWnd->wIDmenu) - 1,MF_BYPOSITION);
+    DeleteMenu(menu,GetMenuItemCount(menu) - 1,MF_BYPOSITION);
 
-    DrawMenuBar(frameWnd->hwndSelf);
+    DrawMenuBar(frame);
 
     return 1;
 }
@@ -1161,22 +1123,20 @@
  *
  * Note: lpTitle can be NULL
  */
-static void MDI_UpdateFrameText( WND *frameWnd, HWND hClient,
+static void MDI_UpdateFrameText( HWND frame, HWND hClient,
                                  BOOL repaint, LPCWSTR lpTitle )
 {
     WCHAR   lpBuffer[MDI_MAXTITLELENGTH+1];
-    WND*   clientWnd = WIN_FindWndPtr(hClient);
-    MDICLIENTINFO *ci = (MDICLIENTINFO *) clientWnd->wExtra;
+    MDICLIENTINFO *ci = get_client_info( hClient );
 
     TRACE("repaint %i, frameText %s\n", repaint, (lpTitle)?debugstr_w(lpTitle):"NULL");
 
-    if (!clientWnd)
-           return;
+    if (!ci) return;
 
-    if (!ci)
+    if (!lpTitle && !ci->frameTitle)  /* first time around, get title from the frame window */
     {
-       WIN_ReleaseWndPtr(clientWnd);
-           return;
+        GetWindowTextW( frame, lpBuffer, sizeof(lpBuffer)/sizeof(WCHAR) );
+        lpTitle = lpBuffer;
     }
 
     /* store new "default" title if lpTitle is not NULL */
@@ -1229,13 +1189,10 @@
     else
 	lpBuffer[0] = '\0';
 
-    DEFWND_SetTextW( frameWnd, lpBuffer );
+    DefWindowProcW( frame, WM_SETTEXT, 0, (LPARAM)lpBuffer );
     if( repaint == MDI_REPAINTFRAME)
-	SetWindowPos( frameWnd->hwndSelf, 0,0,0,0,0, SWP_FRAMECHANGED |
-			SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
-
-    WIN_ReleaseWndPtr(clientWnd);
-
+        SetWindowPos( frame, 0,0,0,0,0, SWP_FRAMECHANGED |
+                      SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
 }
 
 
@@ -1243,35 +1200,24 @@
 
 
 /**********************************************************************
- *		MDIClientWndProc_locked
+ *		MDIClientWndProc_common
  */
-static LRESULT WINAPI MDIClientWndProc_locked( WND *wndPtr, UINT message,
-				WPARAM wParam, LPARAM lParam, BOOL unicode )
+static LRESULT MDIClientWndProc_common( HWND hwnd, UINT message,
+                                        WPARAM wParam, LPARAM lParam, BOOL unicode )
 {
-    LPCREATESTRUCTA	 cs;
-    MDICLIENTINFO       *ci;
-    RECT		 rect;
-    WND                 *frameWnd;
-    INT 		 nItems;
-    LRESULT              retvalue;
-    LRESULT (WINAPI *pSendMessage)(HWND, UINT, WPARAM, LPARAM);
+    MDICLIENTINFO *ci;
 
-    pSendMessage = unicode ? SendMessageW : SendMessageA;
-
-    if ( !wndPtr )
-       return 0;
-
-    if ( ( frameWnd = WIN_LockWndPtr(wndPtr->parent) ) == NULL )
-       return 0;
-
-    ci = (MDICLIENTINFO *) wndPtr->wExtra;
+    if (!(ci = get_client_info( hwnd ))) return 0;
 
     switch (message)
     {
       case WM_CREATE:
-	/* Since we are using only cs->lpCreateParams, we can safely
-	 * cast to LPCREATESTRUCTA here */
-	cs = (LPCREATESTRUCTA)lParam;
+      {
+          RECT rect;
+          /* Since we are using only cs->lpCreateParams, we can safely
+           * cast to LPCREATESTRUCTA here */
+          LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam;
+          WND *wndPtr = WIN_FindWndPtr( hwnd );
 
 	/* Translation layer doesn't know what's in the cs->lpCreateParams
 	 * so we have to keep track of what environment we're in. */
@@ -1289,136 +1235,120 @@
 	    ci->hWindowMenu	= ccs->hWindowMenu;
 	    ci->idFirstChild	= ccs->idFirstChild;
 	}
+        WIN_ReleaseWndPtr( wndPtr );
 
 	ci->hwndChildMaximized  = 0;
 	ci->nActiveChildren	= 0;
 	ci->nTotalCreated	= 0;
 	ci->frameTitle		= NULL;
 	ci->mdiFlags		= 0;
-	ci->self		= wndPtr->hwndSelf;
-	wndPtr->dwStyle        |= WS_CLIPCHILDREN;
+        SetWindowLongW( hwnd, GWL_STYLE, GetWindowLongW(hwnd,GWL_STYLE) | WS_CLIPCHILDREN );
 
 	if (!hBmpClose)
         {
             hBmpClose = CreateMDIMenuBitmap();
             hBmpRestore = LoadBitmapW( 0, MAKEINTRESOURCEW(OBM_RESTORE) );
         }
-	MDI_UpdateFrameText(frameWnd, wndPtr->hwndSelf, MDI_NOFRAMEREPAINT, frameWnd->text);
 
 	if (ci->hWindowMenu != 0)
 	    AppendMenuW( ci->hWindowMenu, MF_SEPARATOR, 0, NULL );
 
-	GetClientRect(frameWnd->hwndSelf, &rect);
-	NC_HandleNCCalcSize( wndPtr->hwndSelf, &rect );
-	wndPtr->rectClient = rect;
+	GetClientRect( GetParent(hwnd), &rect);
+        MoveWindow( hwnd, 0, 0, rect.right, rect.bottom, FALSE );
+
+        MDI_UpdateFrameText( GetParent(hwnd), hwnd, MDI_NOFRAMEREPAINT, NULL);
 
 	TRACE("Client created - hwnd = %04x, idFirst = %u\n",
-				wndPtr->hwndSelf, ci->idFirstChild );
+              hwnd, ci->idFirstChild );
+        return 0;
+      }
 
-        retvalue = 0;
-        goto END;
-      
       case WM_DESTROY:
-	if( ci->hwndChildMaximized )
-            MDI_RestoreFrameMenu(wndPtr->parent, ci->hwndChildMaximized);
-	if((ci->hWindowMenu != 0) && 
-	   (nItems = GetMenuItemCount(ci->hWindowMenu)) > 0) 
-	{
-    	    ci->idFirstChild = nItems - 1;
-	    ci->nActiveChildren++; 		/* to delete a separator */
-	    while( ci->nActiveChildren-- )
-	        DeleteMenu(ci->hWindowMenu,MF_BYPOSITION,ci->idFirstChild--);
-	}
-        retvalue = 0;
-        goto END;
+      {
+          INT nItems;
+          if( ci->hwndChildMaximized )
+              MDI_RestoreFrameMenu( GetParent(hwnd), ci->hwndChildMaximized);
+          if((ci->hWindowMenu != 0) &&
+             (nItems = GetMenuItemCount(ci->hWindowMenu)) > 0)
+          {
+              ci->idFirstChild = nItems - 1;
+              ci->nActiveChildren++;  /* to delete a separator */
+              while( ci->nActiveChildren-- )
+                  DeleteMenu(ci->hWindowMenu,MF_BYPOSITION,ci->idFirstChild--);
+          }
+          if (ci->frameTitle) HeapFree( GetProcessHeap(), 0, ci->frameTitle );
+          return 0;
+      }
 
       case WM_MDIACTIVATE:
         if( ci->hwndActiveChild != (HWND)wParam )
 	    SetWindowPos((HWND)wParam, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE);
-        retvalue = 0;
-        goto END;
+        return 0;
 
       case WM_MDICASCADE:
-        retvalue = MDICascade(wndPtr, ci);
-        goto END;
+        return MDICascade(hwnd, ci);
 
       case WM_MDICREATE:
-        if (lParam) retvalue = MDICreateChild( wndPtr, ci,
-				    (MDICREATESTRUCTA *)lParam, unicode );
-        else retvalue = 0;
-        goto END;
+        if (lParam) return MDICreateChild( hwnd, ci,
+                                           (MDICREATESTRUCTA *)lParam, unicode );
+        else return 0;
 
       case WM_MDIDESTROY:
-	retvalue = MDIDestroyChild( wndPtr, ci, (HWND)wParam, TRUE );
-        goto END;
+          return MDIDestroyChild( hwnd, ci, (HWND)wParam, TRUE );
 
       case WM_MDIGETACTIVE:
           if (lParam) *(BOOL *)lParam = (ci->hwndChildMaximized > 0);
-          retvalue = ci->hwndActiveChild;
-          goto END;
+          return ci->hwndActiveChild;
 
       case WM_MDIICONARRANGE:
 	ci->mdiFlags |= MDIF_NEEDUPDATE;
-        ArrangeIconicWindows(wndPtr->hwndSelf);
+        ArrangeIconicWindows( hwnd );
 	ci->sbRecalc = SB_BOTH+1;
-	pSendMessage(wndPtr->hwndSelf, WM_MDICALCCHILDSCROLL, 0, 0L);
-        retvalue = 0;
-        goto END;
-	
+        SendMessageW( hwnd, WM_MDICALCCHILDSCROLL, 0, 0 );
+        return 0;
+
       case WM_MDIMAXIMIZE:
 	ShowWindow( (HWND)wParam, SW_MAXIMIZE );
-        retvalue = 0;
-        goto END;
+        return 0;
 
       case WM_MDINEXT: /* lParam != 0 means previous window */
-	MDI_SwitchActiveChild(wndPtr->hwndSelf, (HWND)wParam, (lParam)? FALSE : TRUE );
+	MDI_SwitchActiveChild( hwnd, (HWND)wParam, !lParam );
 	break;
 	
       case WM_MDIRESTORE:
-        pSendMessage( (HWND)wParam, WM_SYSCOMMAND, SC_RESTORE, 0);
-        retvalue = 0;
-        goto END;
+        SendMessageW( (HWND)wParam, WM_SYSCOMMAND, SC_RESTORE, 0);
+        return 0;
 
       case WM_MDISETMENU:
-          retvalue = MDISetMenu( wndPtr->hwndSelf, (HMENU)wParam, (HMENU)lParam );
-	  goto END;
+          return MDISetMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
 
       case WM_MDIREFRESHMENU:
-          retvalue = MDIRefreshMenu( wndPtr->hwndSelf, (HMENU)wParam, (HMENU)lParam );
-          goto END;
+          return MDIRefreshMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
 
       case WM_MDITILE:
 	ci->mdiFlags |= MDIF_NEEDUPDATE;
-	ShowScrollBar(wndPtr->hwndSelf, SB_BOTH, FALSE);
-	MDITile(wndPtr, ci, wParam);
+        ShowScrollBar( hwnd, SB_BOTH, FALSE );
+        MDITile( hwnd, ci, wParam );
         ci->mdiFlags &= ~MDIF_NEEDUPDATE;
-        retvalue = 0;
-        goto END;
+        return 0;
 
       case WM_VSCROLL:
       case WM_HSCROLL:
 	ci->mdiFlags |= MDIF_NEEDUPDATE;
-        ScrollChildren(wndPtr->hwndSelf, message, wParam, lParam);
+        ScrollChildren( hwnd, message, wParam, lParam );
 	ci->mdiFlags &= ~MDIF_NEEDUPDATE;
-        retvalue = 0;
-        goto END;
+        return 0;
 
       case WM_SETFOCUS:
-	if( ci->hwndActiveChild )
-	{
-	   WND*	pw = WIN_FindWndPtr( ci->hwndActiveChild );
-	   if( !(pw->dwStyle & WS_MINIMIZE) )
-	       SetFocus( pw->hwndSelf );
-	   WIN_ReleaseWndPtr(pw);
-	} 
-        retvalue = 0;
-        goto END;
-	
+          if (ci->hwndActiveChild && !IsIconic( ci->hwndActiveChild ))
+              SetFocus( ci->hwndActiveChild );
+          return 0;
+
       case WM_NCACTIVATE:
         if( ci->hwndActiveChild )
-	     pSendMessage(ci->hwndActiveChild, message, wParam, lParam);
+            SendMessageW(ci->hwndActiveChild, message, wParam, lParam);
 	break;
-	
+
       case WM_PARENTNOTIFY:
         if (LOWORD(wParam) == WM_LBUTTONDOWN)
         {
@@ -1426,20 +1356,18 @@
             POINT pt;
             pt.x = SLOWORD(lParam);
             pt.y = SHIWORD(lParam);
-            child = ChildWindowFromPoint(wndPtr->hwndSelf, pt);
+            child = ChildWindowFromPoint(hwnd, pt);
 
 	    TRACE("notification from %04x (%li,%li)\n",child,pt.x,pt.y);
 
-            if( child && child != wndPtr->hwndSelf && child != ci->hwndActiveChild )
+            if( child && child != hwnd && child != ci->hwndActiveChild )
                 SetWindowPos(child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
         }
-        retvalue = 0;
-        goto END;
+        return 0;
 
       case WM_SIZE:
         if( IsWindow(ci->hwndChildMaximized) )
 	{
-	    WND*	child = WIN_FindWndPtr(ci->hwndChildMaximized);
 	    RECT	rect;
 
 	    rect.left = 0;
@@ -1447,32 +1375,27 @@
 	    rect.right = LOWORD(lParam);
 	    rect.bottom = HIWORD(lParam);
 
-	    AdjustWindowRectEx(&rect, child->dwStyle, 0, child->dwExStyle);
+	    AdjustWindowRectEx(&rect, GetWindowLongA(ci->hwndChildMaximized,GWL_STYLE),
+                               0, GetWindowLongA(ci->hwndChildMaximized,GWL_EXSTYLE) );
 	    MoveWindow(ci->hwndChildMaximized, rect.left, rect.top,
 			 rect.right - rect.left, rect.bottom - rect.top, 1);
-            WIN_ReleaseWndPtr(child);
 	}
 	else
-	    MDI_PostUpdate(wndPtr->hwndSelf, ci, SB_BOTH+1);
+            MDI_PostUpdate(hwnd, ci, SB_BOTH+1);
 
 	break;
 
       case WM_MDICALCCHILDSCROLL:
 	if( (ci->mdiFlags & MDIF_NEEDUPDATE) && ci->sbRecalc )
 	{
-	    CalcChildScroll(wndPtr->hwndSelf, ci->sbRecalc-1);
+            CalcChildScroll(hwnd, ci->sbRecalc-1);
 	    ci->sbRecalc = 0;
 	    ci->mdiFlags &= ~MDIF_NEEDUPDATE;
 	}
-        retvalue = 0;
-        goto END;
+        return 0;
     }
-    
-    retvalue = unicode ? DefWindowProcW( wndPtr->hwndSelf, message, wParam, lParam ) :
-			 DefWindowProcA( wndPtr->hwndSelf, message, wParam, lParam );
-END:
-    WIN_ReleaseWndPtr(frameWnd);
-    return retvalue;
+    return unicode ? DefWindowProcW( hwnd, message, wParam, lParam ) :
+                     DefWindowProcA( hwnd, message, wParam, lParam );
 }
 
 /***********************************************************************
@@ -1480,13 +1403,8 @@
  */
 static LRESULT WINAPI MDIClientWndProcA( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
 {
-    LRESULT res;
-    WND *wndPtr = WIN_FindWndPtr(hwnd);
-
-    res = MDIClientWndProc_locked(wndPtr, message, wParam, lParam, FALSE);
-
-    WIN_ReleaseWndPtr(wndPtr);
-    return res;
+    if (!IsWindow(hwnd)) return 0;
+    return MDIClientWndProc_common( hwnd, message, wParam, lParam, FALSE );
 }
 
 /***********************************************************************
@@ -1494,13 +1412,8 @@
  */
 static LRESULT WINAPI MDIClientWndProcW( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
 {
-    LRESULT res;
-    WND *wndPtr = WIN_FindWndPtr(hwnd);
-
-    res = MDIClientWndProc_locked(wndPtr, message, wParam, lParam, TRUE);
-
-    WIN_ReleaseWndPtr(wndPtr);
-    return res;
+    if (!IsWindow(hwnd)) return 0;
+    return MDIClientWndProc_common( hwnd, message, wParam, lParam, TRUE );
 }
 
 /***********************************************************************
@@ -1509,121 +1422,26 @@
 LRESULT WINAPI DefFrameProc16( HWND16 hwnd, HWND16 hwndMDIClient,
                                UINT16 message, WPARAM16 wParam, LPARAM lParam )
 {
-    HWND16	         childHwnd;
-    MDICLIENTINFO*       ci;
-    WND*                 wndPtr;
-
-    if (hwndMDIClient)
+    switch (message)
     {
-	switch (message)
-	{
-	  case WM_COMMAND:
-	    wndPtr = WIN_FindWndPtr(hwndMDIClient);
+    case WM_SETTEXT:
+        return DefFrameProcA( hwnd, hwndMDIClient, message, wParam, (LPARAM)MapSL(lParam) );
 
-            if (!wndPtr) {
-               ERR("null wndPtr for mdi window hwndMDIClient=%04x\n",
-                             hwndMDIClient);
-               return 0;
-            } 
+    case WM_COMMAND:
+    case WM_NCACTIVATE:
+    case WM_SETFOCUS:
+    case WM_SIZE:
+        return DefFrameProcW( hwnd, hwndMDIClient, message, wParam, lParam );
 
-	    ci     = (MDICLIENTINFO*)wndPtr->wExtra;
-
-	    /* check for possible syscommands for maximized MDI child */
-            WIN_ReleaseWndPtr(wndPtr);
-
-	    if( ci && (
-	    	wParam <  ci->idFirstChild || 
-		wParam >= ci->idFirstChild + ci->nActiveChildren
-	    )){
-		if( (wParam - 0xF000) & 0xF00F ) break;
-		switch( wParam )
-		  {
-		    case SC_SIZE:
-		    case SC_MOVE:
-		    case SC_MINIMIZE:
-		    case SC_MAXIMIZE:
-		    case SC_NEXTWINDOW:
-		    case SC_PREVWINDOW:
-		    case SC_CLOSE:
-		    case SC_RESTORE:
-		       if( ci->hwndChildMaximized )
-                           return SendMessageW( ci->hwndChildMaximized, WM_SYSCOMMAND,
-                                                wParam, lParam);
-		  }
-	      }
-	    else
-	      {
-                wndPtr = WIN_FindWndPtr(hwndMDIClient);
-                ci     = (MDICLIENTINFO*)wndPtr->wExtra;
-
-                if (wParam - ci->idFirstChild == MDI_MOREWINDOWSLIMIT)
-                    /* User chose "More Windows..." */
-                    childHwnd = MDI_MoreWindowsDialog(wndPtr);
-                else
-                    /* User chose one of the windows listed in the "Windows" menu */
-                childHwnd = MDI_GetChildByID(wndPtr,wParam );
-
-                WIN_ReleaseWndPtr(wndPtr);
- 	    	if( childHwnd )
-                    SendMessageW( hwndMDIClient, WM_MDIACTIVATE, (WPARAM)childHwnd, 0 );
-	      }
-	    break;
-
-	  case WM_NCACTIVATE:
-	    SendMessageW(hwndMDIClient, message, wParam, lParam);
-	    break;
-
-	  case WM_SETTEXT:
-            {
-                LPWSTR text = HEAP_strdupAtoW( GetProcessHeap(), 0, MapSL(lParam) );
-                wndPtr = WIN_FindWndPtr(hwnd);
-                MDI_UpdateFrameText(wndPtr, hwndMDIClient,
-                                    MDI_REPAINTFRAME, text );
-                WIN_ReleaseWndPtr(wndPtr);
-                HeapFree( GetProcessHeap(), 0, text );
-            }
-	    return 1; /* success. FIXME: check text length */
-	
-	  case WM_SETFOCUS:
-	    SetFocus(hwndMDIClient);
-	    break;
-
-	  case WM_SIZE:
-	    MoveWindow16(hwndMDIClient, 0, 0, 
-		         LOWORD(lParam), HIWORD(lParam), TRUE);
-	    break;
-
-	  case WM_NEXTMENU:
-
-            wndPtr = WIN_FindWndPtr(hwndMDIClient);
-            ci     = (MDICLIENTINFO*)wndPtr->wExtra;
-
-	    if( !(wndPtr->parent->dwStyle & WS_MINIMIZE) 
-		&& ci->hwndActiveChild && !ci->hwndChildMaximized )
-	    {
-		/* control menu is between the frame system menu and 
-		 * the first entry of menu bar */
-
-		if( (wParam == VK_LEFT &&
-		     wndPtr->parent->wIDmenu == LOWORD(lParam)) ||
-		    (wParam == VK_RIGHT &&
-		     GetSubMenu16(wndPtr->parent->hSysMenu, 0) == LOWORD(lParam)) )
-		{
-                    LRESULT retvalue;
-                    WIN_ReleaseWndPtr(wndPtr);
-		    wndPtr = WIN_FindWndPtr(ci->hwndActiveChild);
-		    retvalue = MAKELONG( GetSubMenu16(wndPtr->hSysMenu, 0),
-						  ci->hwndActiveChild);
-                    WIN_ReleaseWndPtr(wndPtr);
-                    return retvalue;
-		}
-	    }
-            WIN_ReleaseWndPtr(wndPtr);
-	    break;
-	}
+    case WM_NEXTMENU:
+        {
+            MDINEXTMENU next_menu;
+            DefFrameProcW( hwnd, hwndMDIClient, message, wParam, (LPARAM)&next_menu );
+            return MAKELONG( next_menu.hmenuNext, next_menu.hwndNext );
+        }
+    default:
+        return DefWindowProc16(hwnd, message, wParam, lParam);
     }
-    
-    return DefWindowProc16(hwnd, message, wParam, lParam);
 }
 
 
@@ -1637,33 +1455,22 @@
     {
 	switch (message)
 	{
-	  case WM_COMMAND:
-              return DefFrameProc16( hwnd, hwndMDIClient, message,
-                                     (WPARAM16)wParam,
-                              MAKELPARAM( (HWND16)lParam, HIWORD(wParam) ) );
+        case WM_SETTEXT:
+            {
+                LPWSTR text = HEAP_strdupAtoW( GetProcessHeap(), 0, (LPSTR)lParam );
+                MDI_UpdateFrameText(hwnd, hwndMDIClient, MDI_REPAINTFRAME, text );
+                HeapFree( GetProcessHeap(), 0, text );
+            }
+            return 1; /* success. FIXME: check text length */
 
-	  case WM_NCACTIVATE:
-	    SendMessageA(hwndMDIClient, message, wParam, lParam);
-	    break;
-
-	  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_NEXTMENU:
-	  case WM_SETFOCUS:
-	  case WM_SIZE:
-              return DefFrameProc16( hwnd, hwndMDIClient, message,
-                                     wParam, lParam );
-	}
+        case WM_COMMAND:
+        case WM_NCACTIVATE:
+        case WM_NEXTMENU:
+        case WM_SETFOCUS:
+        case WM_SIZE:
+            return DefFrameProcW( hwnd, hwndMDIClient, message, wParam, lParam );
+        }
     }
-    
     return DefWindowProcA(hwnd, message, wParam, lParam);
 }
 
@@ -1674,35 +1481,91 @@
 LRESULT WINAPI DefFrameProcW( HWND hwnd, HWND hwndMDIClient,
                                 UINT message, WPARAM wParam, LPARAM lParam)
 {
-    if (hwndMDIClient)
+    MDICLIENTINFO *ci = get_client_info( hwndMDIClient );
+
+    if (ci)
     {
 	switch (message)
 	{
-	  case WM_COMMAND:
-              return DefFrameProc16( hwnd, hwndMDIClient, message,
-                                     (WPARAM16)wParam,
-                              MAKELPARAM( (HWND16)lParam, HIWORD(wParam) ) );
+        case WM_COMMAND:
+            {
+                WORD id = LOWORD(wParam);
+                /* check for possible syscommands for maximized MDI child */
+                if (id <  ci->idFirstChild || id >= ci->idFirstChild + ci->nActiveChildren)
+                {
+                    if( (id - 0xf000) & 0xf00f ) break;
+                    if( !ci->hwndChildMaximized ) break;
+                    switch( id )
+                    {
+                    case SC_SIZE:
+                    case SC_MOVE:
+                    case SC_MINIMIZE:
+                    case SC_MAXIMIZE:
+                    case SC_NEXTWINDOW:
+                    case SC_PREVWINDOW:
+                    case SC_CLOSE:
+                    case SC_RESTORE:
+                        return SendMessageW( ci->hwndChildMaximized, WM_SYSCOMMAND,
+                                             wParam, lParam);
+                    }
+                }
+                else
+                {
+                    HWND childHwnd;
+                    if (id - ci->idFirstChild == MDI_MOREWINDOWSLIMIT)
+                        /* User chose "More Windows..." */
+                        childHwnd = MDI_MoreWindowsDialog(hwnd);
+                    else
+                        /* User chose one of the windows listed in the "Windows" menu */
+                        childHwnd = MDI_GetChildByID(hwndMDIClient,id);
 
-	  case WM_NCACTIVATE:
+                    if( childHwnd )
+                        SendMessageW( hwndMDIClient, WM_MDIACTIVATE, (WPARAM)childHwnd, 0 );
+                }
+            }
+            break;
+
+        case WM_NCACTIVATE:
 	    SendMessageW(hwndMDIClient, message, wParam, lParam);
 	    break;
 
-	  case WM_SETTEXT: 
-	  {
-	      LPSTR txt = HEAP_strdupWtoA(GetProcessHeap(),0,(LPWSTR)lParam);
-	      LRESULT ret = DefFrameProcA( hwnd, hwndMDIClient, message,
-                                     wParam, (DWORD)txt );
-	      HeapFree(GetProcessHeap(),0,txt);
-	      return ret;
-	  }
-	  case WM_NEXTMENU:
-	  case WM_SETFOCUS:
-	  case WM_SIZE:
-              return DefFrameProcA( hwnd, hwndMDIClient, message,
-                                      wParam, lParam );
+        case WM_SETTEXT: 
+            MDI_UpdateFrameText(hwnd, hwndMDIClient, MDI_REPAINTFRAME, (LPWSTR)lParam );
+	    return 1; /* success. FIXME: check text length */
+
+        case WM_SETFOCUS:
+	    SetFocus(hwndMDIClient);
+	    break;
+
+        case WM_SIZE:
+            MoveWindow(hwndMDIClient, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
+            break;
+
+        case WM_NEXTMENU:
+            {
+                MDINEXTMENU *next_menu = (MDINEXTMENU *)lParam;
+
+                if (!IsIconic(hwnd) && ci->hwndActiveChild && !ci->hwndChildMaximized)
+                {
+                    /* control menu is between the frame system menu and 
+                     * the first entry of menu bar */
+                    WND *wndPtr = WIN_FindWndPtr(hwnd);
+
+                    if( (wParam == VK_LEFT && GetMenu(hwnd) == next_menu->hmenuIn) ||
+                        (wParam == VK_RIGHT && GetSubMenu(wndPtr->hSysMenu, 0) == next_menu->hmenuIn) )
+                    {
+                        WIN_ReleaseWndPtr(wndPtr);
+                        wndPtr = WIN_FindWndPtr(ci->hwndActiveChild);
+                        next_menu->hmenuNext = GetSubMenu(wndPtr->hSysMenu, 0);
+                        next_menu->hwndNext = ci->hwndActiveChild;
+                        WIN_ReleaseWndPtr(wndPtr);
+                    }
+                }
+                return 0;
+            }
 	}
     }
-    
+
     return DefWindowProcW( hwnd, message, wParam, lParam );
 }
 
@@ -1713,202 +1576,37 @@
 LRESULT WINAPI DefMDIChildProc16( HWND16 hwnd, UINT16 message,
                                   WPARAM16 wParam, LPARAM lParam )
 {
-    MDICLIENTINFO       *ci;
-    WND                 *clientWnd,*tmpWnd = 0;
-    LRESULT             retvalue;
-
-    tmpWnd     = WIN_FindWndPtr(hwnd);
-    if (!tmpWnd) return 0;
-    clientWnd  = WIN_FindWndPtr(tmpWnd->parent->hwndSelf);
-    ci         = (MDICLIENTINFO *) clientWnd->wExtra;
-    WIN_ReleaseWndPtr(tmpWnd);
-
-    /* Sanity check */
-    if (clientWnd->cbWndExtra < sizeof(MDICLIENTINFO))
-    {
-        WARN("called on non-MDI child window %x\n", hwnd);
-        WIN_ReleaseWndPtr(clientWnd);
-        return DefWindowProc16(hwnd, message, wParam, lParam);
-    }
-
     switch (message)
     {
-      case WM_SETTEXT:
-	DefWindowProc16(hwnd, message, wParam, lParam);
-	MDI_MenuModifyItem(clientWnd,hwnd);
-	if( ci->hwndChildMaximized == hwnd )
-	    MDI_UpdateFrameText( clientWnd->parent, ci->self,
-				 MDI_REPAINTFRAME, NULL );
-        retvalue = 1; /* success. FIXME: check text length */
-        goto END;
-
-      case WM_CLOSE:
-          SendMessageW( ci->self, WM_MDIDESTROY, (WPARAM)hwnd, 0 );
-        retvalue = 0;
-        goto END;
-
-      case WM_SETFOCUS:
-	if( ci->hwndActiveChild != hwnd )
-	    MDI_ChildActivate(clientWnd, hwnd);
-	break;
-
-      case WM_CHILDACTIVATE:
-	MDI_ChildActivate(clientWnd, hwnd);
-        retvalue = 0;
-        goto END;
-
-      case WM_NCPAINT:
-	TRACE("WM_NCPAINT for %04x, active %04x\n",
-					     hwnd, ci->hwndActiveChild );
-	break;
-
-      case WM_SYSCOMMAND:
-	switch( wParam )
-	{
-		case SC_MOVE:
-                     if( ci->hwndChildMaximized == hwnd)
-                     {
-                         retvalue = 0;
-                         goto END;
-                     }
-		     break;
-	        case SC_RESTORE:
-	        case SC_MINIMIZE:
-                     tmpWnd = WIN_FindWndPtr(hwnd);
-                     tmpWnd->dwStyle |= WS_SYSMENU;
-                     WIN_ReleaseWndPtr(tmpWnd);
-		     break;
-		case SC_MAXIMIZE:
-		     if( ci->hwndChildMaximized == hwnd) 
-                     {
-                         retvalue = SendMessageW( clientWnd->parent->hwndSelf,
-                                                  message, wParam, lParam);
-                          goto END;
-                     }
-                     tmpWnd = WIN_FindWndPtr(hwnd);
-                     tmpWnd->dwStyle &= ~WS_SYSMENU;
-                     WIN_ReleaseWndPtr(tmpWnd);
-		     break;
-		case SC_NEXTWINDOW:
-		     SendMessageW( ci->self, WM_MDINEXT, 0, 0);
-                     retvalue = 0;
-                     goto END;
-		case SC_PREVWINDOW:
-		     SendMessageW( ci->self, WM_MDINEXT, 0, 1);
-                     retvalue = 0;
-                     goto END;
-	}
-	break;
-	
-      case WM_GETMINMAXINFO:
-	{
-	    MINMAXINFO16 *mmi16 = (MINMAXINFO16 *)MapSL(lParam);
-	    MINMAXINFO mmi;
-	    STRUCT32_MINMAXINFO16to32( mmi16, &mmi );
-	    MDI_ChildGetMinMaxInfo( clientWnd, hwnd, &mmi );
-	    STRUCT32_MINMAXINFO32to16( &mmi, mmi16 );
-	}
-        retvalue = 0;
-        goto END;
-
-      case WM_SETVISIBLE:
-         if( ci->hwndChildMaximized) ci->mdiFlags &= ~MDIF_NEEDUPDATE;
-	 else
-            MDI_PostUpdate(clientWnd->hwndSelf, ci, SB_BOTH+1);
-	break;
-
-      case WM_SIZE:
-	/* do not change */
-
-	if( ci->hwndActiveChild == hwnd && wParam != SIZE_MAXIMIZED )
-	{
-  	    ci->hwndChildMaximized = 0;
-	    
-	    MDI_RestoreFrameMenu( clientWnd->parent, hwnd);
-            MDI_UpdateFrameText( clientWnd->parent, ci->self,
-                                 MDI_REPAINTFRAME, NULL );
-	}
-
-	if( wParam == SIZE_MAXIMIZED )
-	{
-	    HWND16 hMaxChild = ci->hwndChildMaximized;
-
-	    if( hMaxChild == hwnd ) break;
-
-	    if( hMaxChild)
-	    {	    
-	        SendMessageW( hMaxChild, WM_SETREDRAW, FALSE, 0 );
-
-	        MDI_RestoreFrameMenu( clientWnd->parent, hMaxChild);
-	        ShowWindow16( hMaxChild, SW_SHOWNOACTIVATE);
-
-	        SendMessageW( hMaxChild, WM_SETREDRAW, TRUE, 0 );
-	    }
-
-	    TRACE("maximizing child %04x\n", hwnd );
-
-	    /*
-	     * Keep track of the maximized window.
-	     */
-	    ci->hwndChildMaximized = hwnd; /* !!! */
-
-	    /*
-	     * The maximized window should also be the active window
-	     */
-	    MDI_ChildActivate(clientWnd, hwnd);
-
-	    MDI_AugmentFrameMenu( clientWnd->parent, hwnd );
-	    MDI_UpdateFrameText( clientWnd->parent, ci->self,
-				 MDI_REPAINTFRAME, NULL ); 
-	}
-
-	if( wParam == SIZE_MINIMIZED )
-	{
-	    HWND16 switchTo = MDI_GetWindow(clientWnd, hwnd, TRUE, WS_MINIMIZE);
-
-	    if( switchTo )
-	        SendMessageW( switchTo, WM_CHILDACTIVATE, 0, 0);
-	}
-	 
-	MDI_PostUpdate(clientWnd->hwndSelf, ci, SB_BOTH+1);
-	break;
-
-      case WM_MENUCHAR:
-
-	/* MDI children don't have menu bars */
-        retvalue = 0x00010000L;
-        goto END;
-
-      case WM_NEXTMENU:
-
-	if( wParam == VK_LEFT )		/* switch to frame system menu */
+    case WM_SETTEXT:
+        return DefMDIChildProcA( hwnd, message, wParam, (LPARAM)MapSL(lParam) );
+    case WM_MENUCHAR:
+    case WM_CLOSE:
+    case WM_SETFOCUS:
+    case WM_CHILDACTIVATE:
+    case WM_SYSCOMMAND:
+    case WM_SETVISIBLE:
+    case WM_SIZE:
+    case WM_SYSCHAR:
+        return DefMDIChildProcW( hwnd, message, wParam, lParam );
+    case WM_GETMINMAXINFO:
         {
-            retvalue = MAKELONG( GetSubMenu16(clientWnd->parent->hSysMenu, 0),
-			   clientWnd->parent->hwndSelf );
-            goto END;
+            MINMAXINFO16 *mmi16 = (MINMAXINFO16 *)MapSL(lParam);
+            MINMAXINFO mmi;
+            STRUCT32_MINMAXINFO16to32( mmi16, &mmi );
+            DefMDIChildProcW( hwnd, message, wParam, (LPARAM)&mmi );
+            STRUCT32_MINMAXINFO32to16( &mmi, mmi16 );
+            return 0;
         }
-	if( wParam == VK_RIGHT )	/* to frame menu bar */
+    case WM_NEXTMENU:
         {
-            retvalue = MAKELONG( clientWnd->parent->wIDmenu,
-			   clientWnd->parent->hwndSelf );
-            goto END;
+            MDINEXTMENU next_menu;
+            DefMDIChildProcW( hwnd, message, wParam, (LPARAM)&next_menu );
+            return MAKELONG( next_menu.hmenuNext, next_menu.hwndNext );
         }
-
-	break;	
-
-      case WM_SYSCHAR:
-      	   if (wParam == '-')
-	   {
-               SendMessageW(hwnd,WM_SYSCOMMAND, SC_KEYMENU, (LPARAM)(DWORD)VK_SPACE);
-                retvalue = 0;
-                goto END;
-	   }
+    default:
+        return DefWindowProc16(hwnd, message, wParam, lParam);
     }
-	
-    retvalue = DefWindowProc16(hwnd, message, wParam, lParam);
-END:
-    WIN_ReleaseWndPtr(clientWnd);
-    return retvalue;
 }
 
 
@@ -1918,70 +1616,33 @@
 LRESULT WINAPI DefMDIChildProcA( HWND hwnd, UINT message,
                                    WPARAM wParam, LPARAM lParam )
 {
-    MDICLIENTINFO       *ci;
-    WND                 *clientWnd,*tmpWnd;
-    LRESULT             retvalue;
+    HWND client = GetParent(hwnd);
+    MDICLIENTINFO *ci = get_client_info( client );
 
-    tmpWnd     = WIN_FindWndPtr(hwnd);
-    if (!tmpWnd) return 0;
-    clientWnd  = WIN_FindWndPtr(tmpWnd->parent->hwndSelf);
-    ci         = (MDICLIENTINFO *) clientWnd->wExtra;
-    WIN_ReleaseWndPtr(tmpWnd);
-
-    /* Sanity check */
-    if (clientWnd->cbWndExtra < sizeof(MDICLIENTINFO))
-    {
-        WARN("called on non-MDI child window %x\n", hwnd);
-        WIN_ReleaseWndPtr(clientWnd);
-        return DefWindowProcA(hwnd, message, wParam, lParam);
-    }
+    if (!ci) return DefWindowProcA( hwnd, message, wParam, lParam );
 
     switch (message)
     {
-      case WM_SETTEXT:
+    case WM_SETTEXT:
 	DefWindowProcA(hwnd, message, wParam, lParam);
-	MDI_MenuModifyItem(clientWnd,hwnd);
+        MDI_MenuModifyItem( client, hwnd );
 	if( ci->hwndChildMaximized == hwnd )
-	    MDI_UpdateFrameText( clientWnd->parent, ci->self,
-				 MDI_REPAINTFRAME, NULL );
-        retvalue = 1; /* success. FIXME: check text length */
-        goto END;
+	    MDI_UpdateFrameText( GetParent(client), client, MDI_REPAINTFRAME, NULL );
+        return 1; /* success. FIXME: check text length */
 
-      case WM_GETMINMAXINFO:
-	MDI_ChildGetMinMaxInfo( clientWnd, hwnd, (MINMAXINFO *)lParam );
-        retvalue = 0;
-        goto END;
-
-      case WM_MENUCHAR:
-
-	/* MDI children don't have menu bars */
-        retvalue = 0x00010000L;
-        goto END;
-
-      case WM_CLOSE:
-      case WM_SETFOCUS:
-      case WM_CHILDACTIVATE:
-      case WM_NCPAINT:
-      case WM_SYSCOMMAND:
-      case WM_SETVISIBLE:
-      case WM_SIZE:
-      case WM_NEXTMENU:
-          retvalue = DefMDIChildProc16( hwnd, message, (WPARAM16)wParam, lParam );
-          goto END;
-
-      case WM_SYSCHAR:
-      	   if (wParam == '-')
-	   {
-	   	SendMessageA(hwnd,WM_SYSCOMMAND,
-			(WPARAM)SC_KEYMENU, (LPARAM)(DWORD)VK_SPACE);
-                retvalue = 0;
-                goto END;
-	   }
+    case WM_GETMINMAXINFO:
+    case WM_MENUCHAR:
+    case WM_CLOSE:
+    case WM_SETFOCUS:
+    case WM_CHILDACTIVATE:
+    case WM_SYSCOMMAND:
+    case WM_SETVISIBLE:
+    case WM_SIZE:
+    case WM_NEXTMENU:
+    case WM_SYSCHAR:
+        return DefMDIChildProcW( hwnd, message, wParam, lParam );
     }
-    retvalue = DefWindowProcA(hwnd, message, wParam, lParam);
-END:
-    WIN_ReleaseWndPtr(clientWnd);
-    return retvalue;
+    return DefWindowProcA(hwnd, message, wParam, lParam);
 }
 
 
@@ -1991,62 +1652,138 @@
 LRESULT WINAPI DefMDIChildProcW( HWND hwnd, UINT message,
                                    WPARAM wParam, LPARAM lParam )
 {
-    MDICLIENTINFO       *ci;
-    WND                 *clientWnd,*tmpWnd;
-    LRESULT             retvalue;
+    HWND client = GetParent(hwnd);
+    MDICLIENTINFO *ci = get_client_info( client );
 
-    tmpWnd     = WIN_FindWndPtr(hwnd);
-    if (!tmpWnd) return 0;
-    clientWnd  = WIN_FindWndPtr(tmpWnd->parent->hwndSelf);
-    ci         = (MDICLIENTINFO *) clientWnd->wExtra;
-    WIN_ReleaseWndPtr(tmpWnd);
-
-    /* Sanity check */
-    if (clientWnd->cbWndExtra < sizeof(MDICLIENTINFO))
-    {
-        WARN("called on non-MDI child window %x\n", hwnd);
-        WIN_ReleaseWndPtr(clientWnd);
-        return DefWindowProcW(hwnd, message, wParam, lParam);
-    }
+    if (!ci) return DefWindowProcW( hwnd, message, wParam, lParam );
 
     switch (message)
     {
-      case WM_SETTEXT:
-	DefWindowProcW(hwnd, message, wParam, lParam);
-	MDI_MenuModifyItem(clientWnd,hwnd);
-	if( ci->hwndChildMaximized == hwnd )
-	    MDI_UpdateFrameText( clientWnd->parent, ci->self,
-				 MDI_REPAINTFRAME, NULL );
-        retvalue = 1; /* success. FIXME: check text length */
-        goto END;
+    case WM_SETTEXT:
+        DefWindowProcW(hwnd, message, wParam, lParam);
+        MDI_MenuModifyItem( client, hwnd );
+        if( ci->hwndChildMaximized == hwnd )
+            MDI_UpdateFrameText( GetParent(client), client, MDI_REPAINTFRAME, NULL );
+        return 1; /* success. FIXME: check text length */
 
-      case WM_GETMINMAXINFO:
-      case WM_MENUCHAR:
-      case WM_CLOSE:
-      case WM_SETFOCUS:
-      case WM_CHILDACTIVATE:
-      case WM_NCPAINT:
-      case WM_SYSCOMMAND:
-      case WM_SETVISIBLE:
-      case WM_SIZE:
-      case WM_NEXTMENU:
-          retvalue = DefMDIChildProcA( hwnd, message, (WPARAM16)wParam, lParam );
-          goto END;
+    case WM_GETMINMAXINFO:
+        MDI_ChildGetMinMaxInfo( client, hwnd, (MINMAXINFO *)lParam );
+        return 0;
 
-      case WM_SYSCHAR:
-      	   if (wParam == '-')
-	   {
-	   	SendMessageW(hwnd,WM_SYSCOMMAND,
-			(WPARAM)SC_KEYMENU, (LPARAM)(DWORD)VK_SPACE);
-                retvalue = 0;
-                goto END;
-	   }
+    case WM_MENUCHAR:
+        return 0x00010000; /* MDI children don't have menu bars */
+
+    case WM_CLOSE:
+        SendMessageW( client, WM_MDIDESTROY, (WPARAM)hwnd, 0 );
+        return 0;
+
+    case WM_SETFOCUS:
+        if (ci->hwndActiveChild != hwnd) MDI_ChildActivate( client, hwnd );
+        break;
+
+    case WM_CHILDACTIVATE:
+        MDI_ChildActivate( client, hwnd );
+        return 0;
+
+    case WM_SYSCOMMAND:
+        switch( wParam )
+        {
+        case SC_MOVE:
+            if( ci->hwndChildMaximized == hwnd) return 0;
+            break;
+        case SC_RESTORE:
+        case SC_MINIMIZE:
+            SetWindowLongA( hwnd, GWL_STYLE,
+                            GetWindowLongA( hwnd, GWL_STYLE ) | WS_SYSMENU );
+            break;
+        case SC_MAXIMIZE:
+            if (ci->hwndChildMaximized == hwnd)
+                return SendMessageW( GetParent(client), message, wParam, lParam);
+            SetWindowLongW( hwnd, GWL_STYLE,
+                            GetWindowLongW( hwnd, GWL_STYLE ) & ~WS_SYSMENU );
+            break;
+        case SC_NEXTWINDOW:
+            SendMessageW( client, WM_MDINEXT, 0, 0);
+            return 0;
+        case SC_PREVWINDOW:
+            SendMessageW( client, WM_MDINEXT, 0, 1);
+            return 0;
+        }
+        break;
+
+    case WM_SETVISIBLE:
+        if( ci->hwndChildMaximized) ci->mdiFlags &= ~MDIF_NEEDUPDATE;
+        else MDI_PostUpdate(client, ci, SB_BOTH+1);
+        break;
+
+    case WM_SIZE:
+        if( ci->hwndActiveChild == hwnd && wParam != SIZE_MAXIMIZED )
+        {
+            ci->hwndChildMaximized = 0;
+            MDI_RestoreFrameMenu( GetParent(client), hwnd );
+            MDI_UpdateFrameText( GetParent(client), client, MDI_REPAINTFRAME, NULL );
+        }
+
+        if( wParam == SIZE_MAXIMIZED )
+        {
+            HWND hMaxChild = ci->hwndChildMaximized;
+
+            if( hMaxChild == hwnd ) break;
+            if( hMaxChild)
+            {
+                SendMessageW( hMaxChild, WM_SETREDRAW, FALSE, 0 );
+                MDI_RestoreFrameMenu( GetParent(client), hMaxChild );
+                ShowWindow( hMaxChild, SW_SHOWNOACTIVATE );
+                SendMessageW( hMaxChild, WM_SETREDRAW, TRUE, 0 );
+            }
+            TRACE("maximizing child %04x\n", hwnd );
+
+            /* keep track of the maximized window. */
+            ci->hwndChildMaximized = hwnd; /* !!! */
+
+            /* The maximized window should also be the active window */
+            MDI_ChildActivate( client, hwnd );
+            MDI_AugmentFrameMenu( GetParent(client), hwnd );
+            MDI_UpdateFrameText( GetParent(client), client, MDI_REPAINTFRAME, NULL );
+        }
+
+        if( wParam == SIZE_MINIMIZED )
+        {
+            HWND switchTo = MDI_GetWindow(ci, hwnd, TRUE, WS_MINIMIZE);
+
+            if (switchTo) SendMessageW( switchTo, WM_CHILDACTIVATE, 0, 0);
+        }
+        MDI_PostUpdate(client, ci, SB_BOTH+1);
+        break;
+
+    case WM_NEXTMENU:
+        {
+            MDINEXTMENU *next_menu = (MDINEXTMENU *)lParam;
+            HWND parent = GetParent(client);
+
+            if( wParam == VK_LEFT )  /* switch to frame system menu */
+            {
+                WND *wndPtr = WIN_FindWndPtr( parent );
+                next_menu->hmenuNext = GetSubMenu( wndPtr->hSysMenu, 0 );
+                WIN_ReleaseWndPtr( wndPtr );
+            }
+            if( wParam == VK_RIGHT )  /* to frame menu bar */
+            {
+                next_menu->hmenuNext = GetMenu(parent);
+            }
+            next_menu->hwndNext = parent;
+            return 0;
+        }
+
+    case WM_SYSCHAR:
+        if (wParam == '-')
+        {
+            SendMessageW( hwnd, WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, (DWORD)VK_SPACE);
+            return 0;
+        }
+        break;
     }
-    retvalue = DefWindowProcW(hwnd, message, wParam, lParam);
-END:
-    WIN_ReleaseWndPtr(clientWnd);
-    return retvalue;
-    
+    return DefWindowProcW(hwnd, message, wParam, lParam);
 }
 
 /**********************************************************************
@@ -2068,16 +1805,14 @@
     HINSTANCE hInstance, /* [in] Handle to application instance */
     LPARAM lParam)         /* [in] Application-defined value */
 {
-    MDICLIENTINFO* pCi;
+    MDICLIENTINFO *pCi = get_client_info( hWndParent );
     MDICREATESTRUCTA cs;
-    WND *pWndParent = WIN_FindWndPtr(hWndParent);
-    HWND retvalue;
 
     TRACE("(%s,%s,%ld,%d,%d,%d,%d,%x,%d,%ld)\n",
           debugstr_a(lpClassName),debugstr_a(lpWindowName),dwStyle,X,Y,
           nWidth,nHeight,hWndParent,hInstance,lParam);
 
-    if(!pWndParent)
+    if (!pCi)
     {
         ERR("bad hwnd for MDI-client: %04x\n", hWndParent);
         return 0;
@@ -2092,11 +1827,7 @@
     cs.style=dwStyle;
     cs.lParam=lParam;
 
-    pCi = (MDICLIENTINFO *)pWndParent->wExtra;
-    
-    retvalue = MDICreateChild(pWndParent, pCi, &cs, FALSE);
-    WIN_ReleaseWndPtr(pWndParent);
-    return retvalue;
+    return MDICreateChild(hWndParent, pCi, &cs, FALSE);
 }
 
 /***********************************************************************
@@ -2118,16 +1849,14 @@
     HINSTANCE hInstance, /* [in] Handle to application instance */
     LPARAM lParam)         /* [in] Application-defined value */
 {
-    MDICLIENTINFO *pCi;
+    MDICLIENTINFO *pCi = get_client_info( hWndParent );
     MDICREATESTRUCTW cs;
-    WND *pWndParent = WIN_FindWndPtr(hWndParent);
-    HWND retvalue;
 
     TRACE("(%s,%s,%ld,%d,%d,%d,%d,%x,%d,%ld)\n",
           debugstr_w(lpClassName), debugstr_w(lpWindowName), dwStyle, X, Y,
           nWidth, nHeight, hWndParent, hInstance, lParam);
 
-    if(!pWndParent)
+    if (!pCi)
     {
         ERR("bad hwnd for MDI-client: %04x\n", hWndParent);
         return 0;
@@ -2142,11 +1871,7 @@
     cs.style = dwStyle;
     cs.lParam = lParam;
 
-    pCi = (MDICLIENTINFO *)pWndParent->wExtra;
-    
-    retvalue = MDICreateChild(pWndParent, pCi, (MDICREATESTRUCTA *)&cs, TRUE);
-    WIN_ReleaseWndPtr(pWndParent);
-    return retvalue;
+    return MDICreateChild(hWndParent, pCi, (MDICREATESTRUCTA *)&cs, TRUE);
 }
 
 /**********************************************************************
@@ -2172,46 +1897,34 @@
  */
 BOOL WINAPI TranslateMDISysAccel( HWND hwndClient, LPMSG msg )
 {
-
-    if( IsWindow(hwndClient) && (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN))
+    if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
     {
-	MDICLIENTINFO	*ci = NULL;
-	HWND		wnd;
-        WND             *clientWnd = WIN_FindWndPtr(hwndClient);
+        MDICLIENTINFO *ci = get_client_info( hwndClient );
+        WPARAM wParam = 0;
 
-	ci = (MDICLIENTINFO*) clientWnd->wExtra;
-        wnd = ci->hwndActiveChild;
+        if (!ci || !IsWindowEnabled(ci->hwndActiveChild)) return 0;
 
-        WIN_ReleaseWndPtr(clientWnd);
+        /* translate if the Ctrl key is down and Alt not. */
 
-        if( IsWindow(wnd) && !(GetWindowLongW(wnd, GWL_STYLE) & WS_DISABLED) )
-	{
-	    WPARAM wParam = 0;
-
-	    /* translate if the Ctrl key is down and Alt not. */
-  
-	    if( (GetKeyState(VK_CONTROL) & 0x8000) && 
-	       !(GetKeyState(VK_MENU) & 0x8000))
-	    {
-		switch( msg->wParam )
-		{
-		    case VK_F6:
-		    case VK_TAB:
-			 wParam = ( GetKeyState(VK_SHIFT) & 0x8000 )
-				  ? SC_NEXTWINDOW : SC_PREVWINDOW;
-			 break;
-		    case VK_F4:
-		    case VK_RBUTTON:
-			 wParam = SC_CLOSE; 
-			 break;
-		    default:
-			 return 0;
-		}
-	        TRACE("wParam = %04x\n", wParam);
-	        SendMessageW(wnd, WM_SYSCOMMAND, wParam, (LPARAM)msg->wParam);
-	        return 1;
-	    }
-	}
+        if( (GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_MENU) & 0x8000))
+        {
+            switch( msg->wParam )
+            {
+            case VK_F6:
+            case VK_TAB:
+                wParam = ( GetKeyState(VK_SHIFT) & 0x8000 ) ? SC_NEXTWINDOW : SC_PREVWINDOW;
+                break;
+            case VK_F4:
+            case VK_RBUTTON:
+                wParam = SC_CLOSE;
+                break;
+            default:
+                return 0;
+            }
+            TRACE("wParam = %04x\n", wParam);
+            SendMessageW(ci->hwndActiveChild, WM_SYSCOMMAND, wParam, (LPARAM)msg->wParam);
+            return 1;
+        }
     }
     return 0; /* failure */
 }
@@ -2232,10 +1945,9 @@
     SCROLLINFO info;
     RECT childRect, clientRect;
     INT  vmin, vmax, hmin, hmax, vpos, hpos;
-    WND *pWnd, *Wnd;
+    WND *pWnd;
 
     if (!(pWnd = WIN_FindWndPtr( hwnd ))) return;
-    Wnd = WIN_FindWndPtr(hwnd);
     GetClientRect( hwnd, &clientRect );
     SetRectEmpty( &childRect );
 
@@ -2243,9 +1955,8 @@
     {
 	  if( pWnd->dwStyle & WS_MAXIMIZE )
 	  {
-	      ShowScrollBar(hwnd, SB_BOTH, FALSE);
               WIN_ReleaseWndPtr(pWnd);
-              WIN_ReleaseWndPtr(Wnd);
+	      ShowScrollBar(hwnd, SB_BOTH, FALSE);
 	      return;
 	  }
           if( pWnd->dwStyle & WS_VISIBLE )
@@ -2254,9 +1965,11 @@
     WIN_ReleaseWndPtr(pWnd);
     UnionRect( &childRect, &clientRect, &childRect );
 
-    hmin = childRect.left; hmax = childRect.right - clientRect.right;
+    hmin = childRect.left;
+    hmax = childRect.right - clientRect.right;
     hpos = clientRect.left - childRect.left;
-    vmin = childRect.top; vmax = childRect.bottom - clientRect.bottom;
+    vmin = childRect.top;
+    vmax = childRect.bottom - clientRect.bottom;
     vpos = clientRect.top - childRect.top;
 
     switch( scroll )
@@ -2270,10 +1983,9 @@
 			SetScrollInfo(hwnd, scroll, &info, TRUE);
 			break;
 	case SB_BOTH:
-			SCROLL_SetNCSbState( Wnd->hwndSelf, vmin, vmax, vpos,
+			SCROLL_SetNCSbState( hwnd, vmin, vmax, vpos,
                                              hmin, hmax, hpos);
     }    
-    WIN_ReleaseWndPtr(Wnd);
 }
 
 
@@ -2292,33 +2004,30 @@
 void WINAPI ScrollChildren(HWND hWnd, UINT uMsg, WPARAM wParam,
                              LPARAM lParam)
 {
-    WND	*wndPtr = WIN_FindWndPtr(hWnd);
     INT newPos = -1;
     INT curPos, length, minPos, maxPos, shift;
+    RECT rect;
 
-    if( !wndPtr ) return;
+    GetClientRect( hWnd, &rect );
 
-    if( uMsg == WM_HSCROLL )
+    switch(uMsg)
     {
+    case WM_HSCROLL:
 	GetScrollRange(hWnd,SB_HORZ,&minPos,&maxPos);
 	curPos = GetScrollPos(hWnd,SB_HORZ);
-	length = (wndPtr->rectClient.right - wndPtr->rectClient.left)/2;
+	length = (rect.right - rect.left) / 2;
 	shift = GetSystemMetrics(SM_CYHSCROLL);
-    }
-    else if( uMsg == WM_VSCROLL )
-    {
+        break;
+    case WM_VSCROLL:
 	GetScrollRange(hWnd,SB_VERT,&minPos,&maxPos);
 	curPos = GetScrollPos(hWnd,SB_VERT);
-	length = (wndPtr->rectClient.bottom - wndPtr->rectClient.top)/2;
+	length = (rect.bottom - rect.top) / 2;
 	shift = GetSystemMetrics(SM_CXVSCROLL);
-    }
-    else
-    {
-        WIN_ReleaseWndPtr(wndPtr);
+        break;
+    default:
         return;
     }
 
-    WIN_ReleaseWndPtr(wndPtr);
     switch( wParam )
     {
 	case SB_LINEUP:	
@@ -2427,7 +2136,7 @@
            UINT widest       = 0;
            UINT length;
            UINT i;
-           WND  *pParentWnd  = (WND *)lParam;
+           WND  *pParentWnd  = (WND *)WIN_FindWndPtr(lParam);
            MDICLIENTINFO *ci = (MDICLIENTINFO*)pParentWnd->wExtra;
            HWND hListBox = GetDlgItem(hDlg, MDI_IDC_LISTBOX);
 
@@ -2509,7 +2218,7 @@
  *     selected window.
  */
 
-static HWND MDI_MoreWindowsDialog(WND* wndPtr)
+static HWND MDI_MoreWindowsDialog(HWND hwnd)
 {
     LPCVOID template;
     HRSRC hRes;
@@ -2532,9 +2241,7 @@
 
     return (HWND) DialogBoxIndirectParamA(GetModuleHandleA("USER32"),
                                           (LPDLGTEMPLATEA) template,
-                                          wndPtr->hwndSelf,
-                                          (DLGPROC) MDI_MoreWindowsDlgProc,
-                                          (LPARAM) wndPtr);
+                                          hwnd, MDI_MoreWindowsDlgProc, (LPARAM) hwnd);
 }
 
 /*
@@ -2547,19 +2254,19 @@
  *    
  */
 
-static void MDI_SwapMenuItems(WND *parentWnd, UINT pos1, UINT pos2)
+static void MDI_SwapMenuItems(HWND parent, UINT pos1, UINT pos2)
 {
     WND *pWnd;
 
-    for (pWnd = WIN_LockWndPtr(parentWnd->child); pWnd; WIN_UpdateWndPtr(&pWnd,pWnd->next))
+    pWnd = WIN_FindWndPtr( GetWindow( parent, GW_CHILD ) );
+    while (pWnd)
     {
         if (pWnd->wIDmenu == pos1)
             pWnd->wIDmenu = pos2;
         else
             if (pWnd->wIDmenu == pos2)
                 pWnd->wIDmenu = pos1;
+        WIN_UpdateWndPtr(&pWnd,pWnd->next);
     }
-
-    WIN_ReleaseWndPtr(pWnd);
 }
 
diff --git a/windows/message.c b/windows/message.c
index 7134d04..99a276c 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -122,21 +122,18 @@
  */
 static void MSG_SendParentNotify( HWND hwnd, WORD event, WORD idChild, POINT pt )
 {
-    WND *tmpWnd = WIN_FindWndPtr(hwnd);
-
     /* pt has to be in the client coordinates of the parent window */
-    MapWindowPoints( 0, tmpWnd->hwndSelf, &pt, 1 );
-    while (tmpWnd)
+    MapWindowPoints( 0, hwnd, &pt, 1 );
+    for (;;)
     {
-        if (!(tmpWnd->dwStyle & WS_CHILD) || (tmpWnd->dwExStyle & WS_EX_NOPARENTNOTIFY))
-        {
-            WIN_ReleaseWndPtr(tmpWnd);
-            break;
-        }
-	pt.x += tmpWnd->rectClient.left;
-	pt.y += tmpWnd->rectClient.top;
-	WIN_UpdateWndPtr(&tmpWnd,tmpWnd->parent);
-	SendMessageA( tmpWnd->hwndSelf, WM_PARENTNOTIFY,
+        HWND parent;
+
+        if (!(GetWindowLongA( hwnd, GWL_STYLE ) & WS_CHILD)) break;
+        if (GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_NOPARENTNOTIFY) break;
+        if (!(parent = GetParent(hwnd))) break;
+        MapWindowPoints( hwnd, parent, &pt, 1 );
+        hwnd = parent;
+        SendMessageA( hwnd, WM_PARENTNOTIFY,
                       MAKEWPARAM( event, idChild ), MAKELPARAM( pt.x, pt.y ) );
     }
 }
diff --git a/windows/painting.c b/windows/painting.c
index 6ee8b9c..cb25b4d 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -324,7 +324,7 @@
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr) return 0;
 
-    bIcon = (wndPtr->dwStyle & WS_MINIMIZE && GetClassWord(wndPtr->hwndSelf, GCW_HICON));
+    bIcon = (wndPtr->dwStyle & WS_MINIMIZE && GetClassLongA(hwnd, GCL_HICON));
 
     wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
 
@@ -756,7 +756,7 @@
  */
     HDC  hDC;
     HWND hWnd = wndPtr->hwndSelf;
-    BOOL bIcon = ((wndPtr->dwStyle & WS_MINIMIZE) && GetClassWord(wndPtr->hwndSelf, GCW_HICON)); 
+    BOOL bIcon = ((wndPtr->dwStyle & WS_MINIMIZE) && GetClassLongA(hWnd, GCL_HICON));
 
       /* Erase/update the window itself ... */
 
@@ -814,20 +814,18 @@
     if( wndPtr->child && !(flags & RDW_NOCHILDREN) && !(wndPtr->dwStyle & WS_MINIMIZE) 
 	&& ((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)) )
     {
-	WND** list, **ppWnd;
+        HWND *list, *phwnd;
 
-	if( (list = WIN_BuildWinArray( wndPtr, 0, NULL )) )
+	if( (list = WIN_BuildWinArray( wndPtr->hwndSelf )) )
 	{
-            wndPtr = NULL;
-	    for (ppWnd = list; *ppWnd; ppWnd++)
+	    for (phwnd = list; *phwnd; phwnd++)
 	    {
-		WIN_UpdateWndPtr(&wndPtr,*ppWnd);
-		if (!IsWindow(wndPtr->hwndSelf)) continue;
-		    if ( (wndPtr->dwStyle & WS_VISIBLE) &&
-			 (wndPtr->hrgnUpdate || (wndPtr->flags & WIN_INTERNAL_PAINT)) )
-		        hrgn = RDW_Paint( wndPtr, hrgn, flags, ex );
+                if (!(wndPtr = WIN_FindWndPtr( *phwnd ))) continue;
+                if ( (wndPtr->dwStyle & WS_VISIBLE) &&
+                     (wndPtr->hrgnUpdate || (wndPtr->flags & WIN_INTERNAL_PAINT)) )
+                    hrgn = RDW_Paint( wndPtr, hrgn, flags, ex );
+                WIN_ReleaseWndPtr(wndPtr);
 	    }
-            WIN_ReleaseWndPtr(wndPtr);
 	    WIN_ReleaseWinArray(list);
 	}
     }
diff --git a/windows/user.c b/windows/user.c
index d114a12..40b5c91 100644
--- a/windows/user.c
+++ b/windows/user.c
@@ -220,38 +220,32 @@
 {
     int i;
     BOOL result;
-    WND **list, **ppWnd;
-        
+    HWND *list, *phwnd;
+
     /* We have to build a list of all windows first, as in EnumWindows */
 
-    if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
-    {
-        WIN_ReleaseDesktop();
-        return FALSE;
-    }
+    if (!(list = WIN_BuildWinArray( GetDesktopWindow() ))) return FALSE;
 
     /* Send a WM_QUERYENDSESSION message to every window */
 
-    for (ppWnd = list, i = 0; *ppWnd; ppWnd++, i++)
+    for (i = 0; list[i]; i++)
     {
         /* Make sure that the window still exists */
-        if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
-        if (!SendMessageW( (*ppWnd)->hwndSelf, WM_QUERYENDSESSION, 0, 0 ))
-            break;
+        if (!IsWindow( list[i] )) continue;
+        if (!SendMessageW( list[i], WM_QUERYENDSESSION, 0, 0 )) break;
     }
-    result = !(*ppWnd);
+    result = !list[i];
 
     /* Now notify all windows that got a WM_QUERYENDSESSION of the result */
 
-    for (ppWnd = list; i > 0; i--, ppWnd++)
+    for (phwnd = list; i > 0; i--, phwnd++)
     {
-        if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
-        SendMessageW( (*ppWnd)->hwndSelf, WM_ENDSESSION, result, 0 );
+        if (!IsWindow( *phwnd )) continue;
+        SendMessageW( *phwnd, WM_ENDSESSION, result, 0 );
     }
     WIN_ReleaseWinArray(list);
 
     if (result) ExitKernel16();
-    WIN_ReleaseDesktop();
     return FALSE;
 }
 
diff --git a/windows/win.c b/windows/win.c
index 377b486..704f660 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -19,6 +19,7 @@
 #include "hook.h"
 #include "message.h"
 #include "queue.h"
+#include "task.h"
 #include "winpos.h"
 #include "winerror.h"
 #include "stackframe.h"
@@ -1096,7 +1097,8 @@
 static void WIN_SendDestroyMsg( WND* pWnd )
 {
     if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret();
-    USER_Driver.pResetSelectionOwner( pWnd, TRUE ); 
+    if (USER_Driver.pResetSelectionOwner)
+        USER_Driver.pResetSelectionOwner( pWnd->hwndSelf, TRUE );
 
     /*
      * Send the WM_DESTROY to the window.
@@ -1261,7 +1263,8 @@
             }
 	}
 
-    USER_Driver.pResetSelectionOwner( wndPtr, FALSE ); /* before the window is unmapped */
+    if (USER_Driver.pResetSelectionOwner)
+        USER_Driver.pResetSelectionOwner( hwnd, FALSE ); /* before the window is unmapped */
 
       /* Hide the window */
 
@@ -2544,50 +2547,53 @@
 
 BOOL WIN_InternalShowOwnedPopups( HWND owner, BOOL fShow, BOOL unmanagedOnly )
 {
-    INT totalChild=0, count=0;
+    int count = 0;
+    HWND *win_array = WIN_BuildWinArray( GetDesktopWindow() );
 
-    WND **pWnd = WIN_BuildWinArray(WIN_GetDesktop(), 0, &totalChild);
-
-    if (!pWnd) return TRUE;
+    if (!win_array) return TRUE;
 
     /*
      * Show windows Lowest first, Highest last to preserve Z-Order
      */
-    for (count = totalChild-1 ; count >=0; count--)
+    while (win_array[count]) count++;
+    while (--count >= 0)
     {
-        if (pWnd[count]->owner && (pWnd[count]->owner->hwndSelf == owner) && (pWnd[count]->dwStyle & WS_POPUP))
+        WND *pWnd = WIN_FindWndPtr( win_array[count] );
+        if (!pWnd) continue;
+
+        if (pWnd->owner && (pWnd->owner->hwndSelf == owner) && (pWnd->dwStyle & WS_POPUP))
         {
             if (fShow)
             {
                 /* check in window was flagged for showing in previous WIN_InternalShowOwnedPopups call */
-                if (pWnd[count]->flags & WIN_NEEDS_INTERNALSOP) 
+                if (pWnd->flags & WIN_NEEDS_INTERNALSOP)
                 {
                     /*
                      * Call ShowWindow directly because an application can intercept WM_SHOWWINDOW messages
                      */
-                    ShowWindow(pWnd[count]->hwndSelf,SW_SHOW);
-                    pWnd[count]->flags &= ~WIN_NEEDS_INTERNALSOP; /* remove the flag */
+                    ShowWindow(pWnd->hwndSelf,SW_SHOW);
+                    pWnd->flags &= ~WIN_NEEDS_INTERNALSOP; /* remove the flag */
                 }
             }
             else
             {
-                if ( IsWindowVisible(pWnd[count]->hwndSelf) &&                   /* hide only if window is visible */
-                     !( pWnd[count]->flags & WIN_NEEDS_INTERNALSOP ) &&          /* don't hide if previous call already did it */
-                     !( unmanagedOnly && (pWnd[count]->dwExStyle & WS_EX_MANAGED) ) ) /* don't hide managed windows if unmanagedOnly is TRUE */
+                if ( IsWindowVisible(pWnd->hwndSelf) &&                   /* hide only if window is visible */
+                     !( pWnd->flags & WIN_NEEDS_INTERNALSOP ) &&          /* don't hide if previous call already did it */
+                     !( unmanagedOnly && (pWnd->dwExStyle & WS_EX_MANAGED) ) ) /* don't hide managed windows if unmanagedOnly is TRUE */
                 {
                     /*
                      * Call ShowWindow directly because an application can intercept WM_SHOWWINDOW messages
                      */
-                    ShowWindow(pWnd[count]->hwndSelf,SW_HIDE);
+                    ShowWindow(pWnd->hwndSelf,SW_HIDE);
                     /* flag the window for showing on next WIN_InternalShowOwnedPopups call */
-                    pWnd[count]->flags |= WIN_NEEDS_INTERNALSOP;
+                    pWnd->flags |= WIN_NEEDS_INTERNALSOP;
                 }
             }
         }
+        WIN_ReleaseWndPtr( pWnd );
     }
-    WIN_ReleaseDesktop();    
-    WIN_ReleaseWinArray(pWnd);
-    
+    WIN_ReleaseWinArray( win_array );
+
     return TRUE;
 }
 
@@ -2605,45 +2611,48 @@
  */
 BOOL WINAPI ShowOwnedPopups( HWND owner, BOOL fShow )
 {
-    UINT totalChild=0, count=0;
+    int count = 0;
 
-    WND **pWnd = WIN_BuildWinArray(WIN_GetDesktop(), 0, &totalChild);
+    HWND *win_array = WIN_BuildWinArray(GetDesktopWindow());
 
-    if (!pWnd) return TRUE;
+    if (!win_array) return TRUE;
 
-    for (; count < totalChild; count++)
+    while (win_array[count]) count++;
+    while (--count >= 0)
     {
-        if (pWnd[count]->owner && (pWnd[count]->owner->hwndSelf == owner) && (pWnd[count]->dwStyle & WS_POPUP))
+        WND *pWnd = WIN_FindWndPtr( win_array[count] );
+        if (!pWnd) continue;
+
+        if (pWnd->owner && (pWnd->owner->hwndSelf == owner) && (pWnd->dwStyle & WS_POPUP))
         {
             if (fShow)
             {
-                if (pWnd[count]->flags & WIN_NEEDS_SHOW_OWNEDPOPUP)
+                if (pWnd->flags & WIN_NEEDS_SHOW_OWNEDPOPUP)
                 {
-                    /*
-                     * In Windows, ShowOwnedPopups(TRUE) generates WM_SHOWWINDOW messages with SW_PARENTOPENING, 
+                    /* In Windows, ShowOwnedPopups(TRUE) generates
+                     * WM_SHOWWINDOW messages with SW_PARENTOPENING,
                      * regardless of the state of the owner
                      */
-                    SendMessageA(pWnd[count]->hwndSelf, WM_SHOWWINDOW, SW_SHOW, SW_PARENTOPENING);
-                    pWnd[count]->flags &= ~WIN_NEEDS_SHOW_OWNEDPOPUP;
+                    SendMessageA(pWnd->hwndSelf, WM_SHOWWINDOW, SW_SHOW, SW_PARENTOPENING);
+                    pWnd->flags &= ~WIN_NEEDS_SHOW_OWNEDPOPUP;
                 }
             }
             else
             {
-                if (IsWindowVisible(pWnd[count]->hwndSelf))
+                if (IsWindowVisible(pWnd->hwndSelf))
                 {
-                    /*
-                     * In Windows, ShowOwnedPopups(FALSE) generates WM_SHOWWINDOW messages with SW_PARENTCLOSING, 
+                    /* In Windows, ShowOwnedPopups(FALSE) generates
+                     * WM_SHOWWINDOW messages with SW_PARENTCLOSING,
                      * regardless of the state of the owner
                      */
-                    SendMessageA(pWnd[count]->hwndSelf, WM_SHOWWINDOW, SW_HIDE, SW_PARENTCLOSING);
-                    pWnd[count]->flags |= WIN_NEEDS_SHOW_OWNEDPOPUP;
+                    SendMessageA(pWnd->hwndSelf, WM_SHOWWINDOW, SW_HIDE, SW_PARENTCLOSING);
+                    pWnd->flags |= WIN_NEEDS_SHOW_OWNEDPOPUP;
                 }
             }
         }
+        WIN_ReleaseWndPtr( pWnd );
     }
-
-    WIN_ReleaseDesktop();    
-    WIN_ReleaseWinArray(pWnd);
+    WIN_ReleaseWinArray( win_array );
     return TRUE;
 }
 
@@ -2679,31 +2688,21 @@
  * The array must be freed with WIN_ReleaseWinArray. Return NULL
  * when no windows are found.
  */
-WND **WIN_BuildWinArray( WND *wndPtr, UINT bwaFlags, UINT* pTotal )
+HWND *WIN_BuildWinArray( HWND hwnd )
 {
     /* Future: this function will lock all windows associated with this array */
-    
-    WND **list, **ppWnd;
-    WND *pWnd;
-    UINT count = 0, skipOwned, skipHidden;
-    DWORD skipFlags;
-
-    skipHidden = bwaFlags & BWA_SKIPHIDDEN;
-    skipOwned = bwaFlags & BWA_SKIPOWNED;
-    skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
-    if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
+    WND *pWnd, *wndPtr = WIN_FindWndPtr( hwnd );
+    HWND *list, *phwnd;
+    UINT count = 0;
 
     /* First count the windows */
 
-    if (!wndPtr)
-        wndPtr = WIN_GetDesktop();
+    if (!wndPtr) return NULL;
 
     pWnd = WIN_LockWndPtr(wndPtr->child);
     while (pWnd)
     {
-	if( !(pWnd->dwStyle & skipFlags) && !(skipOwned && pWnd->owner) &&
-           (!skipHidden || (pWnd->dwStyle & WS_VISIBLE)) )
-            count++;
+        count++;
         WIN_UpdateWndPtr(&pWnd,pWnd->next);
     }
 
@@ -2711,34 +2710,29 @@
     {
 	/* Now build the list of all windows */
 
-	if ((list = (WND **)HeapAlloc( GetProcessHeap(), 0, sizeof(WND *) * (count + 1))))
+	if ((list = HeapAlloc( GetProcessHeap(), 0, sizeof(HWND) * (count + 1))))
 	{
-	    for (pWnd = WIN_LockWndPtr(wndPtr->child), ppWnd = list, count = 0; pWnd; WIN_UpdateWndPtr(&pWnd,pWnd->next))
+	    for (pWnd = WIN_LockWndPtr(wndPtr->child), phwnd = list, count = 0; pWnd; WIN_UpdateWndPtr(&pWnd,pWnd->next))
 	    {
-		if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) );
-		else if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
-		{
-		   *ppWnd++ = pWnd;
-		    count++;
-		}
+                *phwnd++ = pWnd->hwndSelf;
+                count++;
 	    }
             WIN_ReleaseWndPtr(pWnd);
-	   *ppWnd = NULL;
+            *phwnd = 0;
 	}
 	else count = 0;
     } else list = NULL;
 
-    if( pTotal ) *pTotal = count;
+    WIN_ReleaseWndPtr( wndPtr );
     return list;
 }
+
 /*******************************************************************
  *           WIN_ReleaseWinArray
  */
-void WIN_ReleaseWinArray(WND **wndArray)
+void WIN_ReleaseWinArray(HWND *wndArray)
 {
-    /* Future: this function will also unlock all windows associated with wndArray */
-     HeapFree( GetProcessHeap(), 0, wndArray );
-
+    if (wndArray) HeapFree( GetProcessHeap(), 0, wndArray );
 }
 
 /*******************************************************************
@@ -2746,82 +2740,28 @@
  */
 BOOL WINAPI EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam )
 {
-    WND **list, **ppWnd;
+    HWND *list;
+    BOOL ret = TRUE;
+    int i, iWndsLocks;
 
     /* We have to build a list of all windows first, to avoid */
     /* unpleasant side-effects, for instance if the callback */
     /* function changes the Z-order of the windows.          */
 
-    if (!(list = WIN_BuildWinArray(WIN_GetDesktop(), 0, NULL )))
-    {
-        WIN_ReleaseDesktop();
-        return FALSE;
-    }
+    if (!(list = WIN_BuildWinArray( GetDesktopWindow() ))) return FALSE;
 
     /* Now call the callback function for every window */
 
-    for (ppWnd = list; *ppWnd; ppWnd++)
+    iWndsLocks = WIN_SuspendWndsLock();
+    for (i = 0; list[i]; i++)
     {
-        LRESULT lpEnumFuncRetval;
-        int iWndsLocks = 0;
         /* Make sure that the window still exists */
-        if (!IsWindow((*ppWnd)->hwndSelf)) continue;
-
-        /* To avoid any deadlocks, all the locks on the windows
-           structures must be suspended before the control
-           is passed to the application */
-        iWndsLocks = WIN_SuspendWndsLock();
-        lpEnumFuncRetval = lpEnumFunc( (*ppWnd)->hwndSelf, lParam);
-        WIN_RestoreWndsLock(iWndsLocks);
-
-        if (!lpEnumFuncRetval) break;
+        if (!IsWindow( list[i] )) continue;
+        if (!(ret = lpEnumFunc( list[i], lParam ))) break;
     }
+    WIN_RestoreWndsLock(iWndsLocks);
     WIN_ReleaseWinArray(list);
-    WIN_ReleaseDesktop();
-    return TRUE;
-}
-
-
-/**********************************************************************
- *		WIN_EnumQueueWindows
- *
- * Helper for EnumTaskWindows16 and EnumThreadWindows.
- */
-static BOOL WIN_EnumQueueWindows( HQUEUE16 queue, WNDENUMPROC func, LPARAM lParam )
-{
-    WND **list, **ppWnd;
-
-    /* This function is the same as EnumWindows(),    */
-    /* except for an added check on the window's task. */
-
-    if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
-    {
-        WIN_ReleaseDesktop();
-        return FALSE;
-    }
-
-    /* Now call the callback function for every window */
-
-    for (ppWnd = list; *ppWnd; ppWnd++)
-    {
-        LRESULT funcRetval;
-        int iWndsLocks = 0;
-        /* Make sure that the window still exists */
-        if (!IsWindow((*ppWnd)->hwndSelf)) continue;
-        if ((*ppWnd)->hmemTaskQ != queue) continue;
-
-        /* To avoid any deadlocks, all the locks on the windows
-           structures must be suspended before the control
-           is passed to the application */
-        iWndsLocks = WIN_SuspendWndsLock();
-        funcRetval = func( (*ppWnd)->hwndSelf, lParam );
-        WIN_RestoreWndsLock(iWndsLocks);
-
-        if (!funcRetval) break;
-    }
-    WIN_ReleaseWinArray(list);
-    WIN_ReleaseDesktop();
-    return TRUE;
+    return ret;
 }
 
 
@@ -2831,9 +2771,9 @@
 BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
                                  LPARAM lParam )
 {
-    HQUEUE16 queue = GetTaskQueue16( hTask );
-    if (!queue) return FALSE;
-    return WIN_EnumQueueWindows( queue, (WNDENUMPROC)func, lParam );
+    TDB *tdb = TASK_GetPtr( hTask );
+    if (!tdb) return FALSE;
+    return EnumThreadWindows( (DWORD)tdb->teb->tid, (WNDENUMPROC)func, lParam );
 }
 
 
@@ -2842,9 +2782,22 @@
  */
 BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam )
 {
-    HQUEUE16 queue = GetThreadQueue16( id );
-    if (!queue) return FALSE;
-    return WIN_EnumQueueWindows( queue, func, lParam );
+    HWND *list;
+    int i, iWndsLocks;
+
+    if (!(list = WIN_BuildWinArray( GetDesktopWindow() ))) return FALSE;
+
+    /* Now call the callback function for every window */
+
+    iWndsLocks = WIN_SuspendWndsLock();
+    for (i = 0; list[i]; i++)
+    {
+        if (GetWindowThreadProcessId( list[i], NULL ) != id) continue;
+        if (!func( list[i], lParam )) break;
+    }
+    WIN_RestoreWndsLock(iWndsLocks);
+    WIN_ReleaseWinArray(list);
+    return TRUE;
 }
 
 
@@ -2853,26 +2806,21 @@
  *
  * Helper function for EnumChildWindows().
  */
-static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC func, LPARAM lParam )
+static BOOL WIN_EnumChildWindows( HWND *list, WNDENUMPROC func, LPARAM lParam )
 {
-    WND **childList;
-    BOOL16 ret = FALSE;
+    HWND *childList;
+    BOOL ret = FALSE;
 
-    for ( ; *ppWnd; ppWnd++)
+    for ( ; *list; list++)
     {
-        int iWndsLocks = 0;
-
         /* Make sure that the window still exists */
-        if (!IsWindow((*ppWnd)->hwndSelf)) continue;
+        if (!IsWindow( *list )) continue;
+        /* skip owned windows */
+        if (GetWindow( *list, GW_OWNER )) continue;
         /* Build children list first */
-        childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL );
-        
-        /* To avoid any deadlocks, all the locks on the windows
-           structures must be suspended before the control
-           is passed to the application */
-        iWndsLocks = WIN_SuspendWndsLock();
-        ret = func( (*ppWnd)->hwndSelf, lParam );
-        WIN_RestoreWndsLock(iWndsLocks);
+        childList = WIN_BuildWinArray( *list );
+
+        ret = func( *list, lParam );
 
         if (childList)
         {
@@ -2888,20 +2836,16 @@
 /**********************************************************************
  *		EnumChildWindows (USER32.@)
  */
-BOOL WINAPI EnumChildWindows( HWND parent, WNDENUMPROC func,
-                                  LPARAM lParam )
+BOOL WINAPI EnumChildWindows( HWND parent, WNDENUMPROC func, LPARAM lParam )
 {
-    WND **list, *pParent;
+    HWND *list;
+    int iWndsLocks;
 
-    if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
-    if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL )))
-    {
-        WIN_ReleaseWndPtr(pParent);
-        return FALSE;
-    }
+    if (!(list = WIN_BuildWinArray( parent ))) return FALSE;
+    iWndsLocks = WIN_SuspendWndsLock();
     WIN_EnumChildWindows( list, func, lParam );
+    WIN_RestoreWndsLock(iWndsLocks);
     WIN_ReleaseWinArray(list);
-    WIN_ReleaseWndPtr(pParent);
     return TRUE;
 }
 
@@ -3048,75 +2992,73 @@
  */
 BOOL16 DRAG_QueryUpdate( HWND hQueryWnd, SEGPTR spDragInfo, BOOL bNoSend )
 {
- BOOL16		wParam, bResult = 0;
- POINT        pt;
- LPDRAGINFO16	ptrDragInfo = MapSL(spDragInfo);
- WND 	       *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
- RECT		tempRect;
+    BOOL16 wParam, bResult = 0;
+    POINT pt;
+    LPDRAGINFO16 ptrDragInfo = MapSL(spDragInfo);
+    RECT tempRect;
 
- if( !ptrQueryWnd || !ptrDragInfo )
-    goto end;
+    if (!ptrDragInfo) return FALSE;
 
- CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
+    CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
 
- GetWindowRect(hQueryWnd,&tempRect); 
+    GetWindowRect(hQueryWnd,&tempRect);
 
- if( !PtInRect(&tempRect,pt) ||
-     (ptrQueryWnd->dwStyle & WS_DISABLED) )
-    goto end;
+    if( !PtInRect(&tempRect,pt) || !IsWindowEnabled(hQueryWnd)) return FALSE;
 
- if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) ) 
-   {
-     tempRect = ptrQueryWnd->rectClient;
-     if(ptrQueryWnd->parent)
-        MapWindowPoints( ptrQueryWnd->parent->hwndSelf, 0,
-                           (LPPOINT)&tempRect, 2 );
+    if (!IsIconic( hQueryWnd ))
+    {
+        WND *ptrWnd, *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd);
 
-     if (PtInRect( &tempRect, pt))
-	{
-	 wParam = 0;
-         
-         for (ptrWnd = WIN_LockWndPtr(ptrQueryWnd->child); ptrWnd ;WIN_UpdateWndPtr(&ptrWnd,ptrWnd->next))
-         {
-             if( ptrWnd->dwStyle & WS_VISIBLE )
-	     {
-                 GetWindowRect( ptrWnd->hwndSelf, &tempRect );
-                 if (PtInRect( &tempRect, pt )) break;
-	     }
-         }
+        tempRect = ptrQueryWnd->rectClient;
+        if(ptrQueryWnd->parent)
+            MapWindowPoints( ptrQueryWnd->parent->hwndSelf, 0,
+                             (LPPOINT)&tempRect, 2 );
 
-	 if(ptrWnd)
-         {
-	    TRACE_(msg)("hwnd = %04x, %d %d - %d %d\n",
-                        ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
-			ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
-            if( !(ptrWnd->dwStyle & WS_DISABLED) )
-	        bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
+        if (PtInRect( &tempRect, pt))
+        {
+            wParam = 0;
 
-            WIN_ReleaseWndPtr(ptrWnd);
-         }
+            for (ptrWnd = WIN_LockWndPtr(ptrQueryWnd->child); ptrWnd ;WIN_UpdateWndPtr(&ptrWnd,ptrWnd->next))
+            {
+                if( ptrWnd->dwStyle & WS_VISIBLE )
+                {
+                    GetWindowRect( ptrWnd->hwndSelf, &tempRect );
+                    if (PtInRect( &tempRect, pt )) break;
+                }
+            }
 
-         if(bResult)
-	    goto end;
-	}
-     else wParam = 1;
-   }
- else wParam = 1;
+            if(ptrWnd)
+            {
+                TRACE_(msg)("hwnd = %04x, %d %d - %d %d\n",
+                            ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
+                            ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
+                if( !(ptrWnd->dwStyle & WS_DISABLED) )
+                    bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
 
- ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
+                WIN_ReleaseWndPtr(ptrWnd);
+            }
 
- ptrDragInfo->hScope = hQueryWnd;
+            if(bResult)
+            {
+                WIN_ReleaseWndPtr(ptrQueryWnd);
+                return bResult;
+            }
+        }
+        else wParam = 1;
+        WIN_ReleaseWndPtr(ptrQueryWnd);
+    }
+    else wParam = 1;
 
- bResult = ( bNoSend ) 
-	   ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
-	   : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
-                          (WPARAM16)wParam ,(LPARAM) spDragInfo );
- if( !bResult ) 
-     CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
+    ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
 
-end:
- WIN_ReleaseWndPtr(ptrQueryWnd);
- return bResult;
+    ptrDragInfo->hScope = hQueryWnd;
+
+    if (bNoSend) bResult = (GetWindowLongA( hQueryWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES) != 0;
+    else bResult = SendMessage16( hQueryWnd, WM_QUERYDROPOBJECT, (WPARAM16)wParam, spDragInfo );
+
+    if( !bResult ) CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
+
+    return bResult;
 }
 
 
@@ -3183,25 +3125,17 @@
     SEGPTR	spDragInfo;
     HCURSOR16 	hDragCursor=0, hOldCursor=0, hBummer=0;
     HGLOBAL16	hDragInfo  = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO16));
-    WND        *wndPtr = WIN_FindWndPtr(hWnd);
     HCURSOR16	hCurrentCursor = 0;
     HWND16	hCurrentWnd = 0;
 
     lpDragInfo = (LPDRAGINFO16) GlobalLock16(hDragInfo);
     spDragInfo = K32WOWGlobalLock16(hDragInfo);
 
-    if( !lpDragInfo || !spDragInfo )
-    {
-        WIN_ReleaseWndPtr(wndPtr);
-        return 0L;
-    }
+    if( !lpDragInfo || !spDragInfo ) return 0L;
 
-    hBummer = LoadCursorA(0, MAKEINTRESOURCEA(OCR_NO));
-
-    if( !hBummer || !wndPtr )
+    if (!(hBummer = LoadCursorA(0, MAKEINTRESOURCEA(OCR_NO))))
     {
         GlobalFree16(hDragInfo);
-        WIN_ReleaseWndPtr(wndPtr);
         return 0L;
     }
 
@@ -3210,7 +3144,6 @@
 	if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
 	{
 	    GlobalFree16(hDragInfo);
-            WIN_ReleaseWndPtr(wndPtr);
 	    return 0L;
 	}
 
@@ -3232,8 +3165,7 @@
 
     do
     {
-	do{  WaitMessage(); }
-	while( !PeekMessageA(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
+        GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST );
 
        *(lpDragInfo+1) = *lpDragInfo;
 
@@ -3288,7 +3220,6 @@
     else
         msg.lParam = 0;
     GlobalFree16(hDragInfo);
-    WIN_ReleaseWndPtr(wndPtr);
 
     return (DWORD)(msg.lParam);
 }
diff --git a/windows/winpos.c b/windows/winpos.c
index d1ece6f..3a5eaf6 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -1570,37 +1570,33 @@
     /* send WM_ACTIVATEAPP if necessary */
     if (hOldActiveQueue != hNewActiveQueue)
     {
-        WND **list, **ppWnd;
-        WND *pDesktop = WIN_GetDesktop();
+        HWND *list, *phwnd;
+        DWORD old_thread = GetWindowThreadProcessId( hwndPrevActive, NULL );
+        DWORD new_thread = GetWindowThreadProcessId( hwndActive, NULL );
 
-        if ((list = WIN_BuildWinArray( pDesktop, 0, NULL )))
+        if ((list = WIN_BuildWinArray( GetDesktopWindow() )))
         {
-            DWORD new_thread = GetWindowThreadProcessId( hwndActive, NULL );
-            for (ppWnd = list; *ppWnd; ppWnd++)
+            for (phwnd = list; *phwnd; phwnd++)
             {
-                if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
-
-                if ((*ppWnd)->hmemTaskQ == hOldActiveQueue)
-                    SendMessageW( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP, 0, new_thread );
+                if (!IsWindow( *phwnd )) continue;
+                if (GetWindowThreadProcessId( *phwnd, NULL ) == old_thread)
+                    SendMessageW( *phwnd, WM_ACTIVATEAPP, 0, new_thread );
             }
             WIN_ReleaseWinArray(list);
         }
 
 	hActiveQueue = hNewActiveQueue;
 
-        if ((list = WIN_BuildWinArray(pDesktop, 0, NULL )))
+        if ((list = WIN_BuildWinArray( GetDesktopWindow() )))
         {
-            DWORD old_thread = GetWindowThreadProcessId( hwndPrevActive, NULL );
-            for (ppWnd = list; *ppWnd; ppWnd++)
+            for (phwnd = list; *phwnd; phwnd++)
             {
-                if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
-
-                if ((*ppWnd)->hmemTaskQ == hNewActiveQueue)
-                    SendMessageW( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP, 1, old_thread );
+                if (!IsWindow( *phwnd )) continue;
+                if (GetWindowThreadProcessId( *phwnd, NULL ) == new_thread)
+                    SendMessageW( *phwnd, WM_ACTIVATEAPP, 1, old_thread );
             }
             WIN_ReleaseWinArray(list);
         }
-        WIN_ReleaseDesktop();
         
 	if (hWnd && !IsWindow(hWnd)) goto CLEANUP;
     }
diff --git a/windows/x11drv/clipboard.c b/windows/x11drv/clipboard.c
index 3fda4fd..8c8a052 100644
--- a/windows/x11drv/clipboard.c
+++ b/windows/x11drv/clipboard.c
@@ -1109,11 +1109,12 @@
  * Any top level window can own the selection. See X11DRV_CLIPBOARD_Acquire
  * for a more detailed description of this.
  */
-void X11DRV_ResetSelectionOwner(WND *pWnd, BOOL bFooBar)
+void X11DRV_ResetSelectionOwner(HWND hwnd, BOOL bFooBar)
 {
     Display *display = thread_display();
     HWND hWndClipOwner = 0;
-    Window XWnd = get_whole_window(pWnd);
+    HWND tmp;
+    Window XWnd = X11DRV_get_whole_window(hwnd);
     Atom xaClipboard;
     BOOL bLostSelection = FALSE;
 
@@ -1141,11 +1142,8 @@
     selectionPrevWindow = selectionWindow;
     selectionWindow = None;
 
-    if( pWnd->next ) 
-        selectionWindow = get_whole_window(pWnd->next);
-    else if( pWnd->parent )
-         if( pWnd->parent->child != pWnd ) 
-             selectionWindow = get_whole_window(pWnd->parent->child);
+    if (!(tmp = GetWindow( hwnd, GW_HWNDNEXT ))) tmp = GetWindow( hwnd, GW_HWNDFIRST );
+    if (tmp && tmp != hwnd) selectionWindow = X11DRV_get_whole_window(tmp);
 
     if( selectionWindow != None )
     {