/* MDI.C
 *
 * Copyright 1994, Bob Amstadt
 *           1995,1996 Alex Korobka
 *
 * This file contains routines to support MDI (Multiple Document
 * Interface) features .
 *
 * Notes: Fairly complete implementation.
 *        Also, Excel and WinWord do _not_ use MDI so if you're trying
 *	  to fix them look elsewhere. 
 *
 * Notes on how the "More Windows..." is implemented:
 *
 *      When we have more than 9 opened windows, a "More Windows..."
 *      option appears in the "Windows" menu. Each child window has
 *      a WND* associated with it, accesible via the children list of
 *      the parent window. This WND* has a wIDmenu member, which reflects
 *      the position of the child in the window list. For example, with
 *      9 child windows, we could have the following pattern:
 *
 *
 *
 *                Name of the child window    pWndChild->wIDmenu
 *                     Doc1                       5000
 *                     Doc2                       5001
 *                     Doc3                       5002
 *                     Doc4                       5003
 *                     Doc5                       5004
 *                     Doc6                       5005
 *                     Doc7                       5006
 *                     Doc8                       5007
 *                     Doc9                       5008
 *
 *
 *       The "Windows" menu, as the "More windows..." dialog, are constructed
 *       in this order. If we add a child, we would have the following list:
 *
 *
 *               Name of the child window    pWndChild->wIDmenu
 *                     Doc1                       5000
 *                     Doc2                       5001
 *                     Doc3                       5002
 *                     Doc4                       5003
 *                     Doc5                       5004
 *                     Doc6                       5005
 *                     Doc7                       5006
 *                     Doc8                       5007
 *                     Doc9                       5008
 *                     Doc10                      5009
 *
 *       But only 5000 to 5008 would be displayed in the "Windows" menu. We want
 *       the last created child to be in the menu, so we swap the last child with
 *       the 9th... Doc9 will be accessible via the "More Windows..." option.
 *
 *                     Doc1                       5000
 *                     Doc2                       5001
 *                     Doc3                       5002
 *                     Doc4                       5003
 *                     Doc5                       5004
 *                     Doc6                       5005
 *                     Doc7                       5006
 *                     Doc8                       5007
 *                     Doc9                       5009
 *                     Doc10                      5008
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "windef.h"
#include "wingdi.h"
#include "winuser.h"
#include "win.h"
#include "heap.h"
#include "nonclient.h"
#include "mdi.h"
#include "user.h"
#include "menu.h"
#include "scroll.h"
#include "struct32.h"
#include "tweak.h"
#include "debugtools.h"
#include "dlgs.h"

DEFAULT_DEBUG_CHANNEL(mdi);

#define MDIF_NEEDUPDATE		0x0001

static HBITMAP16 hBmpClose   = 0;
static HBITMAP16 hBmpRestore = 0;

/* ----------------- declarations ----------------- */
static void MDI_UpdateFrameText(WND *, HWND, BOOL, LPCWSTR);
static BOOL MDI_AugmentFrameMenu(MDICLIENTINFO*, WND *, HWND);
static BOOL MDI_RestoreFrameMenu(WND *, HWND);

static LONG MDI_ChildActivate( WND*, HWND );

static HWND MDI_MoreWindowsDialog(WND*);
static void MDI_SwapMenuItems(WND *, UINT, UINT);
/* -------- Miscellaneous service functions ----------
 *
 *			MDI_GetChildByID
 */

static HWND MDI_GetChildByID(WND* wndPtr, INT id)
{
    for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
        if (wndPtr->wIDmenu == id) return wndPtr->hwndSelf;
    return 0;
}

static void MDI_PostUpdate(HWND hwnd, MDICLIENTINFO* ci, WORD recalc)
{
    if( !(ci->mdiFlags & MDIF_NEEDUPDATE) )
    {
	ci->mdiFlags |= MDIF_NEEDUPDATE;
	PostMessageA( hwnd, WM_MDICALCCHILDSCROLL, 0, 0);
    }
    ci->sbRecalc = recalc;
}

/**********************************************************************
 *			MDI_MenuModifyItem
 */
static BOOL MDI_MenuModifyItem(WND* clientWnd, 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;
    }

    if (wndPtr->text) lstrcpynW(buffer + n, wndPtr->text, sizeof(buffer)/sizeof(WCHAR) - n );

    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);
    return bRet;
}

/**********************************************************************
 *			MDI_MenuDeleteItem
 */
static BOOL MDI_MenuDeleteItem(WND* clientWnd, HWND hWndChild )
{
    WCHAR    	 buffer[128];
    static const WCHAR format[] = {'&','%','d',' ',0};
    MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
    WND    	*wndPtr     = WIN_FindWndPtr(hWndChild);
    UINT	 index      = 0,id,n;
    BOOL         retvalue;

    if( !clientInfo->nActiveChildren ||
        !clientInfo->hWindowMenu )
    {
        retvalue = FALSE;
        goto END;
    }

    id = wndPtr->wIDmenu;
    DeleteMenu(clientInfo->hWindowMenu,id,MF_BYCOMMAND);

 /* walk the rest of MDI children to prevent gaps in the id 
  * sequence and in the menu child list */

    for( index = id+1; index <= clientInfo->nActiveChildren + 
				clientInfo->idFirstChild; index++ )
    {
        WND *tmpWnd = WIN_FindWndPtr(MDI_GetChildByID(clientWnd,index));
	if( !tmpWnd )
	{
	      TRACE("no window for id=%i\n",index);
            WIN_ReleaseWndPtr(tmpWnd);
	      continue;
	}
    
	/* set correct id */
	tmpWnd->wIDmenu--;

	n = wsprintfW(buffer, format ,index - clientInfo->idFirstChild);
	if (tmpWnd->text)
            lstrcpynW(buffer + n, tmpWnd->text, sizeof(buffer)/sizeof(WCHAR) - n );	

	/*  change menu if the current child is to be shown in the 
         *  "Windows" menu
         */
        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 
     */
    if (clientInfo->nActiveChildren - 1 > MDI_MOREWINDOWSLIMIT)
    {
        char szTmp[50];
        LoadStringA(GetModuleHandleA("USER32"), MDI_IDS_MOREWINDOWS, szTmp, 50);

        AppendMenuA(clientInfo->hWindowMenu ,MF_STRING ,clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT, szTmp );
    }
    retvalue = TRUE;
END:
    WIN_ReleaseWndPtr(wndPtr);
    return retvalue;
}

/**********************************************************************
 * 			MDI_GetWindow
 *
 * returns "activateable" child different from the current or zero
 */
static HWND MDI_GetWindow(WND *clientWnd, HWND hWnd, BOOL bNext,
                            DWORD dwStyleMask )
{
    MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
    WND *wndPtr, *pWnd, *pWndLast = NULL;
    
    dwStyleMask |= WS_DISABLED | WS_VISIBLE;
    if( !hWnd ) hWnd = clientInfo->hwndActiveChild;

    if( !(wndPtr = WIN_FindWndPtr(hWnd)) ) return 0;

    for ( pWnd = WIN_LockWndPtr(wndPtr->next); ; WIN_UpdateWndPtr(&pWnd,pWnd->next))
    {
        if (!pWnd ) WIN_UpdateWndPtr(&pWnd,wndPtr->parent->child);

        if ( pWnd == wndPtr ) break; /* went full circle */

        if (!pWnd->owner && (pWnd->dwStyle & dwStyleMask) == WS_VISIBLE )
        {
	    pWndLast = pWnd;
	    if ( bNext ) break;
        }
    }
    WIN_ReleaseWndPtr(wndPtr);
    WIN_ReleaseWndPtr(pWnd);
    return pWndLast ? pWndLast->hwndSelf : 0;
}

/**********************************************************************
 *			MDI_CalcDefaultChildPos
 *
 *  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)
{
    INT  nstagger;
    RECT rect = w->rectClient;
    INT  spacing = GetSystemMetrics(SM_CYCAPTION) +
		     GetSystemMetrics(SM_CYFRAME) - 1; 

    if( rect.bottom - rect.top - delta >= spacing ) 
	rect.bottom -= delta;

    nstagger = (rect.bottom - rect.top)/(3 * spacing);
    lpPos[1].x = (rect.right - rect.left - nstagger * spacing);
    lpPos[1].y = (rect.bottom - rect.top - nstagger * spacing);
    lpPos[0].x = lpPos[0].y = spacing * (n%(nstagger+1));
}

/**********************************************************************
 *            MDISetMenu
 */
static LRESULT MDISetMenu( HWND hwnd, HMENU hmenuFrame,
                           HMENU hmenuWindow)
{
    WND *w;
    MDICLIENTINFO *ci;
    HWND hwndFrame = GetParent(hwnd);
    HMENU oldFrameMenu = GetMenu(hwndFrame);

    TRACE("%04x %04x %04x\n",
                hwnd, hmenuFrame, hmenuWindow);

    if (hmenuFrame && !IsMenu(hmenuFrame))
    {
	WARN("hmenuFrame is not a menu handle\n");
	return 0L;
    }
	
    if (hmenuWindow && !IsMenu(hmenuWindow))
    {
	WARN("hmenuWindow is not a menu handle\n");
	return 0L;
    }
	
    w = WIN_FindWndPtr(hwnd);
    ci = (MDICLIENTINFO *) w->wExtra;

    if( ci->hwndChildMaximized && hmenuFrame && hmenuFrame!=oldFrameMenu )
        MDI_RestoreFrameMenu(w->parent, ci->hwndChildMaximized );

    if( hmenuWindow && ci->hWindowMenu && hmenuWindow!=ci->hWindowMenu )
    {
        /* delete menu items from ci->hWindowMenu 
         * and add them to hmenuWindow */

        INT i = GetMenuItemCount(ci->hWindowMenu) - 1;
        INT pos = GetMenuItemCount(hmenuWindow) + 1;

        AppendMenuA( hmenuWindow, MF_SEPARATOR, 0, NULL);

        if( ci->nActiveChildren )
        {
            INT j;
            LPWSTR buffer = NULL;
	    MENUITEMINFOW mii;
            INT nbWindowsMenuItems; /* num of documents shown + "More Windows..." if present */

            if (ci->nActiveChildren <= MDI_MOREWINDOWSLIMIT)
                nbWindowsMenuItems = ci->nActiveChildren;
            else
                nbWindowsMenuItems = MDI_MOREWINDOWSLIMIT + 1;

            j = i - nbWindowsMenuItems + 1;

            for( ; i >= j ; i-- )
            {
		memset(&mii, 0, sizeof(mii));
		mii.cbSize = sizeof(mii);
		mii.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID | MIIM_STATE
		  | MIIM_SUBMENU | MIIM_TYPE | MIIM_BITMAP;

		GetMenuItemInfoW(ci->hWindowMenu, i, TRUE, &mii);
		if(mii.cch) { /* Menu is MFT_STRING */
		    mii.cch++; /* add room for '\0' */
		    buffer = HeapAlloc(GetProcessHeap(), 0,
				       mii.cch * sizeof(WCHAR));
		    mii.dwTypeData = buffer;
		    GetMenuItemInfoW(ci->hWindowMenu, i, TRUE, &mii);
		}
                DeleteMenu(ci->hWindowMenu, i, MF_BYPOSITION);
                InsertMenuItemW(hmenuWindow, pos, TRUE, &mii);
		if(buffer) {
		    HeapFree(GetProcessHeap(), 0, buffer);
		    buffer = NULL;
		}
            }
        }

        /* remove separator */
        DeleteMenu(ci->hWindowMenu, i, MF_BYPOSITION); 

        ci->hWindowMenu = hmenuWindow;
    } 

    if (hmenuFrame)
    {
        SetMenu(hwndFrame, hmenuFrame);
        if( hmenuFrame!=oldFrameMenu )
        {
            if( ci->hwndChildMaximized )
                MDI_AugmentFrameMenu(ci, w->parent, ci->hwndChildMaximized );
            WIN_ReleaseWndPtr(w);
            return oldFrameMenu;
        }
    }
    WIN_ReleaseWndPtr(w);
    return 0;
}

/**********************************************************************
 *            MDIRefreshMenu
 */
static LRESULT MDIRefreshMenu( HWND hwnd, HMENU hmenuFrame,
                           HMENU hmenuWindow)
{
    HWND hwndFrame = GetParent(hwnd);
    HMENU oldFrameMenu = GetMenu(hwndFrame);

    TRACE("%04x %04x %04x\n",
                hwnd, hmenuFrame, hmenuWindow);

    FIXME("partially function stub\n");

    return oldFrameMenu;
}


/* ------------------ MDI child window functions ---------------------- */


/**********************************************************************
 *					MDICreateChild
 */
static HWND MDICreateChild( WND *w, MDICLIENTINFO *ci, HWND parent, 
                              LPMDICREATESTRUCTA cs )
{
    POINT          pos[2]; 
    DWORD	     style = cs->style | (WS_CHILD | WS_CLIPSIBLINGS);
    HWND 	     hwnd, hwndMax = 0;
    WORD	     wIDmenu = ci->idFirstChild + ci->nActiveChildren;
    char	     lpstrDef[]="junk!";

    TRACE("origin %i,%i - dim %i,%i, style %08x\n", 
                cs->x, cs->y, cs->cx, cs->cy, (unsigned)cs->style);    
    /* calculate placement */
    MDI_CalcDefaultChildPos(w, 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;

    if( cs->x == CW_USEDEFAULT )
    {
 	cs->x = pos[0].x;
	cs->y = pos[0].y;
    }

    /* restore current maximized child */
    if( style & WS_VISIBLE && ci->hwndChildMaximized )
    {
	if( style & WS_MAXIMIZE )
	    SendMessageA(w->hwndSelf, WM_SETREDRAW, FALSE, 0L );
	hwndMax = ci->hwndChildMaximized;
	ShowWindow( hwndMax, SW_SHOWNOACTIVATE );
	if( style & WS_MAXIMIZE )
	    SendMessageA(w->hwndSelf, WM_SETREDRAW, TRUE, 0L );
    }

    if (ci->nActiveChildren <= MDI_MOREWINDOWSLIMIT)
    /* this menu is needed to set a check mark in MDI_ChildActivate */
    if (ci->hWindowMenu != 0)
        AppendMenuA(ci->hWindowMenu ,MF_STRING ,wIDmenu, lpstrDef );

    ci->nActiveChildren++;

    /* fix window style */
    if( !(w->dwStyle & MDIS_ALLCHILDSTYLES) )
    {
        style &= (WS_CHILD | WS_CLIPSIBLINGS | WS_MINIMIZE | WS_MAXIMIZE |
                  WS_CLIPCHILDREN | WS_DISABLED | WS_VSCROLL | WS_HSCROLL );
        style |= (WS_VISIBLE | WS_OVERLAPPEDWINDOW);
    }

    if( w->flags & WIN_ISWIN32 )
    {
	hwnd = CreateWindowA( cs->szClass, cs->szTitle, style, 
                                cs->x, cs->y, cs->cx, cs->cy, parent, 
                                (HMENU16)wIDmenu, cs->hOwner, cs );
    }
    else
    {
    	MDICREATESTRUCT16 *cs16;
        LPSTR title, cls;

        cs16 = SEGPTR_NEW(MDICREATESTRUCT16);
        STRUCT32_MDICREATESTRUCT32Ato16( cs, cs16 );
        title = SEGPTR_STRDUP( cs->szTitle );
        cls   = SEGPTR_STRDUP( cs->szClass );
        cs16->szTitle = SEGPTR_GET(title);
        cs16->szClass = SEGPTR_GET(cls);

	hwnd = CreateWindow16( cs->szClass, cs->szTitle, style, 
			       cs16->x, cs16->y, cs16->cx, cs16->cy, parent, 
			       (HMENU)wIDmenu, cs16->hOwner,
                               (LPVOID)SEGPTR_GET(cs16) );
        SEGPTR_FREE( title );
        SEGPTR_FREE( cls );
        SEGPTR_FREE( cs16 );
    }

    /* MDI windows are WS_CHILD so they won't be activated by CreateWindow */

    if (hwnd)
    {
	WND* wnd = WIN_FindWndPtr( hwnd );

	/* All MDI child windows have the WS_EX_MDICHILD style */
	wnd->dwExStyle |= 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_MenuModifyItem(w ,hwnd); 

        /* Have we hit the "More Windows..." limit? If so, we must 
         * add a "More Windows..." option 
         */
        if (ci->nActiveChildren == MDI_MOREWINDOWSLIMIT + 1)
        {
            char szTmp[50];
            LoadStringA(GetModuleHandleA("USER32"), MDI_IDS_MOREWINDOWS, szTmp, 50);

            ModifyMenuA(ci->hWindowMenu,
                        ci->idFirstChild + MDI_MOREWINDOWSLIMIT, 
                        MF_BYCOMMAND | MF_STRING, 
                        ci->idFirstChild + MDI_MOREWINDOWSLIMIT, 
                        szTmp);
        }
        
	if( wnd->dwStyle & WS_MINIMIZE && ci->hwndActiveChild )
	    ShowWindow( hwnd, SW_SHOWMINNOACTIVE );
	else
	{
            /* WS_VISIBLE is clear if a) the MDI client has
             * MDIS_ALLCHILDSTYLES style and 2) the flag is cleared in the
             * MDICreateStruct. If so the created window is not shown nor 
             * activated.
             */
            int showflag=wnd->dwStyle & WS_VISIBLE;
            /* clear visible flag, otherwise SetWindoPos32 ignores
             * the SWP_SHOWWINDOW command.
             */
            wnd->dwStyle &= ~WS_VISIBLE;
            if(showflag){
                SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE );

                /* Set maximized state here in case hwnd didn't receive WM_SIZE
                 * during CreateWindow - bad!
                 */

                if((wnd->dwStyle & WS_MAXIMIZE) && !ci->hwndChildMaximized )
                {
                    ci->hwndChildMaximized = wnd->hwndSelf;
                    MDI_AugmentFrameMenu( ci, w->parent, hwnd );
                    MDI_UpdateFrameText( w->parent, ci->self, MDI_REPAINTFRAME, NULL ); 
                }
            }else
                /* needed, harmless ? */
                SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE );

	}
        WIN_ReleaseWndPtr(wnd);
        TRACE("created child - %04x\n",hwnd);
    }
    else
    {
	ci->nActiveChildren--;
	DeleteMenu(ci->hWindowMenu,wIDmenu,MF_BYCOMMAND);
	if( IsWindow(hwndMax) )
	    ShowWindow(hwndMax, SW_SHOWMAXIMIZED);
    }
	
    return hwnd;
}

/**********************************************************************
 *			MDI_ChildGetMinMaxInfo
 *
 * Note: The rule here is that client rect of the maximized MDI child 
 *	 is equal to the client rect of the MDI client window.
 */
static void MDI_ChildGetMinMaxInfo( WND* clientWnd, HWND hwnd,
                                    MINMAXINFO16* lpMinMax )
{
    WND*	childWnd = WIN_FindWndPtr(hwnd);
    RECT	rect 	 = clientWnd->rectClient;

    MapWindowPoints( clientWnd->parent->hwndSelf, 
		     ((MDICLIENTINFO*)clientWnd->wExtra)->self, (LPPOINT)&rect, 2);
    AdjustWindowRectEx( &rect, childWnd->dwStyle, 0, childWnd->dwExStyle );

    lpMinMax->ptMaxSize.x = rect.right -= rect.left;
    lpMinMax->ptMaxSize.y = rect.bottom -= rect.top;

    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);
    
}

/**********************************************************************
 *			MDI_SwitchActiveChild
 * 
 * Note: SetWindowPos sends WM_CHILDACTIVATE to the child window that is
 *       being activated 
 */
static void MDI_SwitchActiveChild( HWND clientHwnd, HWND childHwnd,
                                   BOOL bNextWindow )
{
    WND		  *w	     = WIN_FindWndPtr(clientHwnd);
    HWND	   hwndTo    = 0;
    HWND	   hwndPrev  = 0;
    MDICLIENTINFO *ci;

    hwndTo = MDI_GetWindow(w, childHwnd, bNextWindow, 0);
 
    ci = (MDICLIENTINFO *) w->wExtra;

    TRACE("from %04x, to %04x\n",childHwnd,hwndTo);

    if ( !hwndTo ) goto END; /* 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 );

	if( bNextWindow && hwndPrev )
	    SetWindowPos( hwndPrev, HWND_BOTTOM, 0, 0, 0, 0, 
		  	    SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
	if( bOptimize )
	    ShowWindow( clientHwnd, SW_SHOW );
    }
END:
    WIN_ReleaseWndPtr(w);
}

	    
/**********************************************************************
 *                                      MDIDestroyChild
 */
static LRESULT MDIDestroyChild( WND *w_parent, MDICLIENTINFO *ci,
                                HWND parent, HWND child,
                                BOOL flagDestroy )
{
    WND         *childPtr = WIN_FindWndPtr(child);

    if( childPtr )
    {
        MDI_MenuDeleteItem(w_parent, child);

        if( child == ci->hwndActiveChild )
        {
	    MDI_SwitchActiveChild(parent, child, TRUE);

	    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,parent,TRUE,NULL);
		}

                MDI_ChildActivate(w_parent, 0);
	    }
	}

        WIN_ReleaseWndPtr(childPtr);
	
        ci->nActiveChildren--;

        TRACE("child destroyed - %04x\n",child);

        if (flagDestroy)
	{
	    MDI_PostUpdate(GetParent(child), ci, SB_BOTH+1);
            DestroyWindow(child);
	}
    }

    return 0;
}


/**********************************************************************
 *					MDI_ChildActivate
 *
 * Note: hWndChild is NULL when last child is being destroyed
 */
static LONG MDI_ChildActivate( WND *clientPtr, HWND hWndChild )
{
    MDICLIENTINFO       *clientInfo = (MDICLIENTINFO*)clientPtr->wExtra; 
    HWND               prevActiveWnd = clientInfo->hwndActiveChild;
    WND                 *wndPtr = WIN_FindWndPtr( hWndChild );
    WND			*wndPrev = WIN_FindWndPtr( prevActiveWnd );
    BOOL		 isActiveFrameWnd = 0;	 
    LONG               retvalue;

    if( wndPtr )
    {
        if( wndPtr->dwStyle & WS_DISABLED )
        {
            retvalue = 0L;
            goto END;
        }
    }

    /* Don't activate if it is already active. Might happen 
       since ShowWindow DOES activate MDI children */
    if (clientInfo->hwndActiveChild == hWndChild)
    {
      retvalue = 0L;
      goto END;
    }

    TRACE("%04x\n", hWndChild);

    if( GetActiveWindow() == clientPtr->parent->hwndSelf )
        isActiveFrameWnd = TRUE;
	
    /* deactivate prev. active child */
    if( wndPrev )
    {
	wndPrev->dwStyle |= WS_SYSMENU;
	SendMessageA( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L );
        SendMessageA( prevActiveWnd, WM_MDIACTIVATE, (WPARAM)prevActiveWnd,
                        (LPARAM)hWndChild);
        /* uncheck menu item */
       	if( clientInfo->hWindowMenu )
        {
            WORD wPrevID = wndPrev->wIDmenu - clientInfo->idFirstChild;

            if (wPrevID < MDI_MOREWINDOWSLIMIT)
       	        CheckMenuItem( clientInfo->hWindowMenu,
                                 wndPrev->wIDmenu, 0);
            else
       	        CheckMenuItem( clientInfo->hWindowMenu,
                               clientInfo->idFirstChild + MDI_MOREWINDOWSLIMIT - 1, 0);
    }
    }

    /* set appearance */
    if( clientInfo->hwndChildMaximized )
    {
      if( clientInfo->hwndChildMaximized != hWndChild ) {
        if( hWndChild ) {
		  clientInfo->hwndActiveChild = hWndChild;
		  ShowWindow( hWndChild, SW_SHOWMAXIMIZED);
	} else
		ShowWindow( clientInfo->hwndActiveChild, SW_SHOWNORMAL );
      }
    }

    clientInfo->hwndActiveChild = hWndChild;

    /* check if we have any children left */
    if( !hWndChild )
    {
	if( isActiveFrameWnd )
	    SetFocus( clientInfo->self );
        retvalue = 0;
        goto END;
    }
	
    /* 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); 
          }

          CheckMenuItem(clientInfo->hWindowMenu, wndPtr->wIDmenu, MF_CHECKED);
    }
    /* bring active child to the top */
    SetWindowPos( hWndChild, 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 );
	    else
		SetFocus( clientInfo->self );
    }
    SendMessageA( hWndChild, WM_MDIACTIVATE, (WPARAM)prevActiveWnd,
                    (LPARAM)hWndChild );
    retvalue = 1;
END:
    WIN_ReleaseWndPtr(wndPtr);
    WIN_ReleaseWndPtr(wndPrev);
    return retvalue;
}

/* -------------------- MDI client window functions ------------------- */

/**********************************************************************
 *				CreateMDIMenuBitmap
 */
static HBITMAP16 CreateMDIMenuBitmap(void)
{
 HDC 		hDCSrc  = CreateCompatibleDC(0);
 HDC		hDCDest	= CreateCompatibleDC(hDCSrc);
 HBITMAP16	hbClose = LoadBitmap16(0, MAKEINTRESOURCE16(OBM_CLOSE) );
 HBITMAP16	hbCopy;
 HANDLE16	hobjSrc, hobjDest;

 hobjSrc = SelectObject(hDCSrc, hbClose);
 hbCopy = CreateCompatibleBitmap(hDCSrc,GetSystemMetrics(SM_CXSIZE),GetSystemMetrics(SM_CYSIZE));
 hobjDest = SelectObject(hDCDest, hbCopy);

 BitBlt(hDCDest, 0, 0, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
          hDCSrc, GetSystemMetrics(SM_CXSIZE), 0, SRCCOPY);
  
 SelectObject(hDCSrc, hobjSrc);
 DeleteObject(hbClose);
 DeleteDC(hDCSrc);

 hobjSrc = SelectObject( hDCDest, GetStockObject(BLACK_PEN) );

 MoveToEx( hDCDest, GetSystemMetrics(SM_CXSIZE) - 1, 0, NULL );
 LineTo( hDCDest, GetSystemMetrics(SM_CXSIZE) - 1, GetSystemMetrics(SM_CYSIZE) - 1);

 SelectObject(hDCDest, hobjSrc );
 SelectObject(hDCDest, hobjDest);
 DeleteDC(hDCDest);

 return hbCopy;
}

/**********************************************************************
 *				MDICascade
 */
static LONG MDICascade(WND* clientWnd, MDICLIENTINFO *ci)
{
    WND**	ppWnd;
    UINT	total;
  
    if (ci->hwndChildMaximized)
        SendMessageA( clientWnd->hwndSelf, WM_MDIRESTORE,
                        (WPARAM)ci->hwndChildMaximized, 0);

    if (ci->nActiveChildren == 0) return 0;

    if ((ppWnd = WIN_BuildWinArray(clientWnd, BWA_SKIPHIDDEN | BWA_SKIPOWNED | 
					      BWA_SKIPICONIC, &total)))
    {
	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( total < ci->nActiveChildren )
        ArrangeIconicWindows( clientWnd->hwndSelf );
    return 0;
}

/**********************************************************************
 *					MDITile
 */
static void MDITile( WND* wndClient, MDICLIENTINFO *ci, WPARAM wParam )
{
    WND**	ppWnd;
    UINT	total = 0;

    if (ci->hwndChildMaximized)
        SendMessageA( wndClient->hwndSelf, 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 );

    TRACE("%u windows to tile\n", total);

    if( ppWnd )
    {
	WND**	heapPtr = ppWnd;

	if( total )
	{
	    RECT	rect;
	    int		x, y, xsize, ysize;
	    int		rows, columns, r, c, i;

	    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( 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;
    
	    for (x = i = 0, c = 1; c <= columns && *ppWnd; 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);
    }
  
    if( total < ci->nActiveChildren ) ArrangeIconicWindows( wndClient->hwndSelf );
}

/* ----------------------- Frame window ---------------------------- */


/**********************************************************************
 *					MDI_AugmentFrameMenu
 */
static BOOL MDI_AugmentFrameMenu( MDICLIENTINFO* ci, WND *frame,
                                    HWND hChild )
{
    WND*	child = WIN_FindWndPtr(hChild);
    HMENU  	hSysPopup = 0;
  HBITMAP hSysMenuBitmap = 0;

    TRACE("frame %p,child %04x\n",frame,hChild);

    if( !frame->wIDmenu || !child->hSysMenu )
    {
        WIN_ReleaseWndPtr(child);
        return 0;
    }
    WIN_ReleaseWndPtr(child);

    /* create a copy of sysmenu popup and insert it into frame menu bar */

    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,
                   SC_MINIMIZE, (LPSTR)(DWORD)HBMMENU_MBAR_MINIMIZE ) ;
    AppendMenuA(frame->wIDmenu,MF_HELP | MF_BITMAP,
                   SC_RESTORE, (LPSTR)(DWORD)HBMMENU_MBAR_RESTORE );

  /* In Win 95 look, the system menu is replaced by the child icon */

  if(TWEAK_WineLook > WIN31_LOOK)
  {
    HICON hIcon = GetClassLongA(hChild, GCL_HICONSM);
    if (!hIcon)
      hIcon = GetClassLongA(hChild, GCL_HICON);
    if (hIcon)
    {
      HDC hMemDC;
      HBITMAP hBitmap, hOldBitmap;
      HBRUSH hBrush;
      HDC hdc = GetDC(hChild);

      if (hdc)
      {
        int cx, cy;
        cx = GetSystemMetrics(SM_CXSMICON);
        cy = GetSystemMetrics(SM_CYSMICON);
        hMemDC = CreateCompatibleDC(hdc);
        hBitmap = CreateCompatibleBitmap(hdc, cx, cy);
        hOldBitmap = SelectObject(hMemDC, hBitmap);
        SetMapMode(hMemDC, MM_TEXT);
        hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU));
        DrawIconEx(hMemDC, 0, 0, hIcon, cx, cy, 0, hBrush, DI_NORMAL);
        SelectObject (hMemDC, hOldBitmap);
        DeleteObject(hBrush);
        DeleteDC(hMemDC);
        ReleaseDC(hChild, hdc);
        hSysMenuBitmap = hBitmap;
      }
    }
  }
  else
    hSysMenuBitmap = hBmpClose;

    if( !InsertMenuA(frame->wIDmenu,0,MF_BYPOSITION | MF_BITMAP | MF_POPUP,
                    hSysPopup, (LPSTR)(DWORD)hSysMenuBitmap))
    {  
        TRACE("not inserted\n");
	DestroyMenu(hSysPopup); 
	return 0; 
    }

    /* The close button is only present in Win 95 look */
    if(TWEAK_WineLook > WIN31_LOOK)
    {
        AppendMenuA(frame->wIDmenu,MF_HELP | MF_BITMAP,
                       SC_CLOSE, (LPSTR)(DWORD)HBMMENU_MBAR_CLOSE );
    }

    EnableMenuItem(hSysPopup, SC_SIZE, MF_BYCOMMAND | MF_GRAYED);
    EnableMenuItem(hSysPopup, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
    EnableMenuItem(hSysPopup, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED);
    SetMenuDefaultItem(hSysPopup, SC_CLOSE, FALSE);

    /* redraw menu */
    DrawMenuBar(frame->hwndSelf);

    return 1;
}

/**********************************************************************
 *					MDI_RestoreFrameMenu
 */
static BOOL MDI_RestoreFrameMenu( WND *frameWnd, HWND hChild )
{
    MENUITEMINFOA menuInfo;
    INT nItems = GetMenuItemCount(frameWnd->wIDmenu) - 1;
    UINT iId = GetMenuItemID(frameWnd->wIDmenu,nItems) ;

    TRACE("frameWnd %p,(%04x),child %04x,nIt=%d,iId=%d\n",
           frameWnd,frameWnd->hwndSelf,hChild,nItems,iId);

    if(!(iId == SC_RESTORE || iId == SC_CLOSE) )
	return 0; 

    /*
     * Remove the system menu, If that menu is the icon of the window
     * as it is in win95, we have to delete the bitmap.
     */
    menuInfo.cbSize = sizeof(MENUITEMINFOA);
    menuInfo.fMask  = MIIM_DATA | MIIM_TYPE;

    GetMenuItemInfoA(frameWnd->wIDmenu, 
		     0, 
		     TRUE,
		     &menuInfo);

    RemoveMenu(frameWnd->wIDmenu,0,MF_BYPOSITION);

    if ( (menuInfo.fType & MFT_BITMAP)           &&
	 (LOWORD(menuInfo.dwTypeData)!=0)        &&
	 (LOWORD(menuInfo.dwTypeData)!=hBmpClose) )
    {
      DeleteObject((HBITMAP)LOWORD(menuInfo.dwTypeData));
    }

    if(TWEAK_WineLook > WIN31_LOOK)
    {
        /* close */
        DeleteMenu(frameWnd->wIDmenu,GetMenuItemCount(frameWnd->wIDmenu) - 1,MF_BYPOSITION);
    }
    /* restore */
    DeleteMenu(frameWnd->wIDmenu,GetMenuItemCount(frameWnd->wIDmenu) - 1,MF_BYPOSITION);
    /* minimize */
    DeleteMenu(frameWnd->wIDmenu,GetMenuItemCount(frameWnd->wIDmenu) - 1,MF_BYPOSITION);

    DrawMenuBar(frameWnd->hwndSelf);

    return 1;
}


/**********************************************************************
 *				        MDI_UpdateFrameText
 *
 * used when child window is maximized/restored 
 *
 * Note: lpTitle can be NULL
 */
static void MDI_UpdateFrameText( WND *frameWnd, HWND hClient,
                                 BOOL repaint, LPCWSTR lpTitle )
{
    WCHAR   lpBuffer[MDI_MAXTITLELENGTH+1];
    WND*   clientWnd = WIN_FindWndPtr(hClient);
    MDICLIENTINFO *ci = (MDICLIENTINFO *) clientWnd->wExtra;

    TRACE("repaint %i, frameText %s\n", repaint, (lpTitle)?debugstr_w(lpTitle):"NULL");

    if (!clientWnd)
           return;

    if (!ci)
    {
       WIN_ReleaseWndPtr(clientWnd);
           return;
    }

    /* store new "default" title if lpTitle is not NULL */
    if (lpTitle) 
    {
	if (ci->frameTitle) HeapFree( SystemHeap, 0, ci->frameTitle );
	ci->frameTitle = HEAP_strdupW( SystemHeap, 0, lpTitle );
    }

    if (ci->frameTitle)
    {
	WND* childWnd = WIN_FindWndPtr( ci->hwndChildMaximized );     

	if( childWnd && childWnd->text )
	{
	    /* combine frame title and child title if possible */

	    static const WCHAR lpBracket[]  = {' ','-',' ','[',0};
	    static const WCHAR lpBracket2[]  = {']',0};
	    int	i_frame_text_length = lstrlenW(ci->frameTitle);
	    int	i_child_text_length = lstrlenW(childWnd->text);

	    lstrcpynW( lpBuffer, ci->frameTitle, MDI_MAXTITLELENGTH);

	    if( i_frame_text_length + 6 < MDI_MAXTITLELENGTH )
            {
		lstrcatW( lpBuffer, lpBracket );

		if( i_frame_text_length + i_child_text_length + 6 < MDI_MAXTITLELENGTH )
		{
		    lstrcatW( lpBuffer, childWnd->text );
		    lstrcatW( lpBuffer, lpBracket2 );
		}
		else
		{
		    lstrcpynW( lpBuffer + i_frame_text_length + 4, 
				 childWnd->text, MDI_MAXTITLELENGTH - i_frame_text_length - 5 );
		    lstrcatW( lpBuffer, lpBracket2 );
		}
	    }
	}
	else
	{
            lstrcpynW(lpBuffer, ci->frameTitle, MDI_MAXTITLELENGTH+1 );
	}
        WIN_ReleaseWndPtr(childWnd);

    }
    else
	lpBuffer[0] = '\0';

    DEFWND_SetTextW( frameWnd, 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);

}


/* ----------------------------- Interface ---------------------------- */


/**********************************************************************
 *					MDIClientWndProc
 *
 * This function handles all MDI requests.
 */
LRESULT WINAPI MDIClientWndProc( HWND hwnd, UINT message, WPARAM wParam,
                                 LPARAM lParam )
{
    LPCREATESTRUCTA	 cs;
    MDICLIENTINFO       *ci;
    RECT		 rect;
    WND                 *w, *frameWnd;
    INT 		 nItems;
    LRESULT              retvalue;
    
    if ( ( w = WIN_FindWndPtr(hwnd) ) == NULL )
       return 0;

    if ( ( frameWnd = WIN_LockWndPtr(w->parent) ) == NULL ) {
       WIN_ReleaseWndPtr(w);
       return 0;
    }

    ci = (MDICLIENTINFO *) w->wExtra;    

    switch (message)
    {
      case WM_CREATE:

	cs = (LPCREATESTRUCTA)lParam;

	/* Translation layer doesn't know what's in the cs->lpCreateParams
	 * so we have to keep track of what environment we're in. */

	if( w->flags & WIN_ISWIN32 )
	{
#define ccs ((LPCLIENTCREATESTRUCT)cs->lpCreateParams)
	    ci->hWindowMenu	= ccs->hWindowMenu;
	    ci->idFirstChild	= ccs->idFirstChild;
#undef ccs
	}
        else    
	{
	    LPCLIENTCREATESTRUCT16 ccs = (LPCLIENTCREATESTRUCT16) 
				   PTR_SEG_TO_LIN(cs->lpCreateParams);
	    ci->hWindowMenu	= ccs->hWindowMenu;
	    ci->idFirstChild	= ccs->idFirstChild;
	}

	ci->hwndChildMaximized  = 0;
	ci->nActiveChildren	= 0;
	ci->nTotalCreated	= 0;
	ci->frameTitle		= NULL;
	ci->mdiFlags		= 0;
	ci->self		= hwnd;
	w->dwStyle             |= WS_CLIPCHILDREN;

	if (!hBmpClose)
        {
            hBmpClose = CreateMDIMenuBitmap();
            hBmpRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
        }
	MDI_UpdateFrameText(frameWnd, hwnd, MDI_NOFRAMEREPAINT,frameWnd->text);

	if (ci->hWindowMenu != 0)
	    AppendMenuA( ci->hWindowMenu, MF_SEPARATOR, 0, NULL );

	GetClientRect(frameWnd->hwndSelf, &rect);
	NC_HandleNCCalcSize( w, &rect );
	w->rectClient = rect;

	TRACE("Client created - hwnd = %04x, idFirst = %u\n",
			   hwnd, ci->idFirstChild );

        retvalue = 0;
        goto END;
      
      case WM_DESTROY:
	if( ci->hwndChildMaximized )
            MDI_RestoreFrameMenu(w->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;

      case WM_MDIACTIVATE:
        if( ci->hwndActiveChild != (HWND)wParam )
	    SetWindowPos((HWND)wParam, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE);
        retvalue = 0;
        goto END;

      case WM_MDICASCADE:
        retvalue = MDICascade(w, ci);
        goto END;

      case WM_MDICREATE:
        if (lParam) retvalue = MDICreateChild( w, ci, hwnd,
                                           (MDICREATESTRUCTA*)lParam );
        else retvalue = 0;
        goto END;

      case WM_MDIDESTROY:
	retvalue = MDIDestroyChild( w, ci, hwnd, (HWND)wParam, TRUE );
        goto END;

      case WM_MDIGETACTIVE:
          if (lParam) *(BOOL *)lParam = (ci->hwndChildMaximized > 0);
          retvalue = ci->hwndActiveChild;
          goto END;

      case WM_MDIICONARRANGE:
	ci->mdiFlags |= MDIF_NEEDUPDATE;
        ArrangeIconicWindows(hwnd);
	ci->sbRecalc = SB_BOTH+1;
	SendMessageA(hwnd, WM_MDICALCCHILDSCROLL, 0, 0L);
        retvalue = 0;
        goto END;
	
      case WM_MDIMAXIMIZE:
	ShowWindow( (HWND)wParam, SW_MAXIMIZE );
        retvalue = 0;
        goto END;

      case WM_MDINEXT: /* lParam != 0 means previous window */
	MDI_SwitchActiveChild(hwnd, (HWND)wParam, (lParam)? FALSE : TRUE );
	break;
	
      case WM_MDIRESTORE:
        SendMessageA( (HWND)wParam, WM_SYSCOMMAND, SC_RESTORE, 0);
        retvalue = 0;
        goto END;

      case WM_MDISETMENU:
          retvalue = MDISetMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
	  goto END;
      case WM_MDIREFRESHMENU:
          retvalue = MDIRefreshMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
          goto END;

      case WM_MDITILE:
	ci->mdiFlags |= MDIF_NEEDUPDATE;
	ShowScrollBar(hwnd,SB_BOTH,FALSE);
	MDITile(w, ci, wParam);
        ci->mdiFlags &= ~MDIF_NEEDUPDATE;
        retvalue = 0;
        goto END;

      case WM_VSCROLL:
      case WM_HSCROLL:
	ci->mdiFlags |= MDIF_NEEDUPDATE;
        ScrollChildren(hwnd, message, wParam, lParam);
	ci->mdiFlags &= ~MDIF_NEEDUPDATE;
        retvalue = 0;
        goto END;

      case WM_SETFOCUS:
	if( ci->hwndActiveChild )
	{
	   WND*	pw = WIN_FindWndPtr( ci->hwndActiveChild );
	   if( !(pw->dwStyle & WS_MINIMIZE) )
	       SetFocus( ci->hwndActiveChild );
	   WIN_ReleaseWndPtr(pw);
	} 
        retvalue = 0;
        goto END;
	
      case WM_NCACTIVATE:
        if( ci->hwndActiveChild )
	     SendMessageA(ci->hwndActiveChild, message, wParam, lParam);
	break;
	
      case WM_PARENTNOTIFY:
        if (LOWORD(wParam) == WM_LBUTTONDOWN)
        {
            POINT16  pt = MAKEPOINT16(lParam);
            HWND16 child = ChildWindowFromPoint16(hwnd, pt);

	    TRACE("notification from %04x (%i,%i)\n",child,pt.x,pt.y);

            if( child && child != hwnd && child != ci->hwndActiveChild )
                SetWindowPos(child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
        }
        retvalue = 0;
        goto END;

      case WM_SIZE:
        if( IsWindow(ci->hwndChildMaximized) )
	{
	    WND*	child = WIN_FindWndPtr(ci->hwndChildMaximized);
	    RECT	rect;

	    rect.left = 0;
	    rect.top = 0;
	    rect.right = LOWORD(lParam);
	    rect.bottom = HIWORD(lParam);

	    AdjustWindowRectEx(&rect, child->dwStyle, 0, child->dwExStyle);
	    MoveWindow(ci->hwndChildMaximized, rect.left, rect.top,
			 rect.right - rect.left, rect.bottom - rect.top, 1);
            WIN_ReleaseWndPtr(child);
	}
	else
	    MDI_PostUpdate(hwnd, ci, SB_BOTH+1);

	break;

      case WM_MDICALCCHILDSCROLL:
	if( (ci->mdiFlags & MDIF_NEEDUPDATE) && ci->sbRecalc )
	{
	    CalcChildScroll16(hwnd, ci->sbRecalc-1);
	    ci->sbRecalc = 0;
	    ci->mdiFlags &= ~MDIF_NEEDUPDATE;
	}
        retvalue = 0;
        goto END;
    }
    
    retvalue = DefWindowProcA( hwnd, message, wParam, lParam );
END:
    WIN_ReleaseWndPtr(w);
    WIN_ReleaseWndPtr(frameWnd);
    return retvalue;
}


/***********************************************************************
 *           DefFrameProc16   (USER.445)
 */
LRESULT WINAPI DefFrameProc16( HWND16 hwnd, HWND16 hwndMDIClient,
                               UINT16 message, WPARAM16 wParam, LPARAM lParam )
{
    HWND16	         childHwnd;
    MDICLIENTINFO*       ci;
    WND*                 wndPtr;

    if (hwndMDIClient)
    {
	switch (message)
	{
	  case WM_COMMAND:
	    wndPtr = WIN_FindWndPtr(hwndMDIClient);

            if (!wndPtr) {
               ERR("null wndPtr for mdi window hwndMDIClient=%04x\n",
                             hwndMDIClient);
               return 0;
            } 

	    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 SendMessage16( 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 )
	            SendMessage16(hwndMDIClient, WM_MDIACTIVATE,
                                  (WPARAM16)childHwnd , 0L);
	      }
	    break;

	  case WM_NCACTIVATE:
	    SendMessage16(hwndMDIClient, message, wParam, lParam);
	    break;

	  case WM_SETTEXT:
            {
                LPWSTR text = HEAP_strdupAtoW( GetProcessHeap(), 0, 
                                               (LPCSTR)PTR_SEG_TO_LIN(lParam) );
                wndPtr = WIN_FindWndPtr(hwnd);
                MDI_UpdateFrameText(wndPtr, hwndMDIClient,
                                    MDI_REPAINTFRAME, text );
                WIN_ReleaseWndPtr(wndPtr);
                HeapFree( GetProcessHeap(), 0, text );
            }
	    return 0;
	
	  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;
	}
    }
    
    return DefWindowProc16(hwnd, message, wParam, lParam);
}


/***********************************************************************
 *           DefFrameProcA   (USER32.122)
 */
LRESULT WINAPI DefFrameProcA( HWND hwnd, HWND hwndMDIClient,
                                UINT message, WPARAM wParam, LPARAM lParam)
{
    if (hwndMDIClient)
    {
	switch (message)
	{
	  case WM_COMMAND:
              return DefFrameProc16( hwnd, hwndMDIClient, message,
                                     (WPARAM16)wParam,
                              MAKELPARAM( (HWND16)lParam, HIWORD(wParam) ) );

	  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 );
	}
    }
    
    return DefWindowProcA(hwnd, message, wParam, lParam);
}


/***********************************************************************
 *           DefFrameProcW   (USER32.123)
 */
LRESULT WINAPI DefFrameProcW( HWND hwnd, HWND hwndMDIClient,
                                UINT message, WPARAM wParam, LPARAM lParam)
{
    if (hwndMDIClient)
    {
	switch (message)
	{
	  case WM_COMMAND:
              return DefFrameProc16( hwnd, hwndMDIClient, message,
                                     (WPARAM16)wParam,
                              MAKELPARAM( (HWND16)lParam, HIWORD(wParam) ) );

	  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 );
	}
    }
    
    return DefWindowProcW( hwnd, message, wParam, lParam );
}


/***********************************************************************
 *           DefMDIChildProc16   (USER.447)
 */
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);

    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 = 0;
        goto END;

      case WM_CLOSE:
	SendMessage16(ci->self,WM_MDIDESTROY,(WPARAM16)hwnd,0L);
        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 = SendMessage16( clientWnd->parent->hwndSelf,
                                             message, wParam, lParam);
                          goto END;
                     }
                     tmpWnd = WIN_FindWndPtr(hwnd);
                     tmpWnd->dwStyle &= ~WS_SYSMENU;
                     WIN_ReleaseWndPtr(tmpWnd);
		     break;
		case SC_NEXTWINDOW:
		     SendMessage16( ci->self, WM_MDINEXT, 0, 0);
                     retvalue = 0;
                     goto END;
		case SC_PREVWINDOW:
		     SendMessage16( ci->self, WM_MDINEXT, 0, 1);
                     retvalue = 0;
                     goto END;
	}
	break;
	
      case WM_GETMINMAXINFO:
	MDI_ChildGetMinMaxInfo(clientWnd, hwnd, (MINMAXINFO16*) PTR_SEG_TO_LIN(lParam));
        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)
	    {	    
	        SendMessage16( hMaxChild, WM_SETREDRAW, FALSE, 0L );

	        MDI_RestoreFrameMenu( clientWnd->parent, hMaxChild);
	        ShowWindow16( hMaxChild, SW_SHOWNOACTIVATE);

	        SendMessage16( hMaxChild, WM_SETREDRAW, TRUE, 0L );
	    }

	    TRACE("maximizing child %04x\n", hwnd );

	    ci->hwndChildMaximized = hwnd; /* !!! */
	    ci->hwndActiveChild = hwnd;

	    MDI_AugmentFrameMenu( ci, clientWnd->parent, hwnd);
	    MDI_UpdateFrameText( clientWnd->parent, ci->self,
				 MDI_REPAINTFRAME, NULL ); 
	}

	if( wParam == SIZE_MINIMIZED )
	{
	    HWND16 switchTo = MDI_GetWindow(clientWnd, hwnd, TRUE, WS_MINIMIZE);

	    if( switchTo )
	        SendMessage16( switchTo, WM_CHILDACTIVATE, 0, 0L);
	}
	 
	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 */
        {
            retvalue = MAKELONG( GetSubMenu16(clientWnd->parent->hSysMenu, 0),
			   clientWnd->parent->hwndSelf );
            goto END;
        }
	if( wParam == VK_RIGHT )	/* to frame menu bar */
        {
            retvalue = MAKELONG( clientWnd->parent->wIDmenu,
			   clientWnd->parent->hwndSelf );
            goto END;
        }

	break;	

      case WM_SYSCHAR:
      	   if (wParam == '-')
	   {
	   	SendMessage16(hwnd,WM_SYSCOMMAND,
			(WPARAM16)SC_KEYMENU, (LPARAM)(DWORD)VK_SPACE);
                retvalue = 0;
                goto END;
	   }
    }
	
    retvalue = DefWindowProc16(hwnd, message, wParam, lParam);
END:
    WIN_ReleaseWndPtr(clientWnd);
    return retvalue;
}


/***********************************************************************
 *           DefMDIChildProcA   (USER32.124)
 */
LRESULT WINAPI DefMDIChildProcA( HWND hwnd, UINT message,
                                   WPARAM wParam, LPARAM lParam )
{
    MDICLIENTINFO       *ci;
    WND                 *clientWnd,*tmpWnd;
    LRESULT             retvalue;

    tmpWnd     = WIN_FindWndPtr(hwnd);
    if (!tmpWnd) return 0;
    clientWnd  = WIN_FindWndPtr(tmpWnd->parent->hwndSelf);
    ci         = (MDICLIENTINFO *) clientWnd->wExtra;
    WIN_ReleaseWndPtr(tmpWnd);

    switch (message)
    {
      case WM_SETTEXT:
	DefWindowProcA(hwnd, message, wParam, lParam);
	MDI_MenuModifyItem(clientWnd,hwnd);
	if( ci->hwndChildMaximized == hwnd )
	    MDI_UpdateFrameText( clientWnd->parent, ci->self,
				 MDI_REPAINTFRAME, NULL );
        retvalue = 0;
        goto END;

      case WM_GETMINMAXINFO:
        {
            MINMAXINFO16 mmi;
            STRUCT32_MINMAXINFO32to16( (MINMAXINFO *)lParam, &mmi );
            MDI_ChildGetMinMaxInfo( clientWnd, hwnd, &mmi );
            STRUCT32_MINMAXINFO16to32( &mmi, (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;
	   }
    }
    retvalue = DefWindowProcA(hwnd, message, wParam, lParam);
END:
    WIN_ReleaseWndPtr(clientWnd);
    return retvalue;
}


/***********************************************************************
 *           DefMDIChildProcW   (USER32.125)
 */
LRESULT WINAPI DefMDIChildProcW( HWND hwnd, UINT message,
                                   WPARAM wParam, LPARAM lParam )
{
    MDICLIENTINFO       *ci;
    WND                 *clientWnd,*tmpWnd;
    LRESULT             retvalue;

    tmpWnd     = WIN_FindWndPtr(hwnd);
    if (!tmpWnd) return 0;
    clientWnd  = WIN_FindWndPtr(tmpWnd->parent->hwndSelf);
    ci         = (MDICLIENTINFO *) clientWnd->wExtra;
    WIN_ReleaseWndPtr(tmpWnd);

    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 = 0;
        goto END;

      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_SYSCHAR:
      	   if (wParam == '-')
	   {
	   	SendMessageW(hwnd,WM_SYSCOMMAND,
			(WPARAM)SC_KEYMENU, (LPARAM)(DWORD)VK_SPACE);
                retvalue = 0;
                goto END;
	   }
    }
    retvalue = DefWindowProcW(hwnd, message, wParam, lParam);
END:
    WIN_ReleaseWndPtr(clientWnd);
    return retvalue;
    
}


/**********************************************************************
 * CreateMDIWindowA [USER32.79] Creates a MDI child in new thread
 * FIXME: its in the same thread now
 *
 * RETURNS
 *    Success: Handle to created window
 *    Failure: NULL
 */
HWND WINAPI CreateMDIWindowA(
    LPCSTR lpClassName,    /* [in] Pointer to registered child class name */
    LPCSTR lpWindowName,   /* [in] Pointer to window name */
    DWORD dwStyle,         /* [in] Window style */
    INT X,               /* [in] Horizontal position of window */
    INT Y,               /* [in] Vertical position of window */
    INT nWidth,          /* [in] Width of window */
    INT nHeight,         /* [in] Height of window */
    HWND hWndParent,     /* [in] Handle to parent window */
    HINSTANCE hInstance, /* [in] Handle to application instance */
    LPARAM lParam)         /* [in] Application-defined value */
{
    WARN("is only single threaded!\n");
    return MDI_CreateMDIWindowA(lpClassName, lpWindowName, dwStyle, X, Y, 
            nWidth, nHeight, hWndParent, hInstance, lParam);
}
 
/**********************************************************************
 * MDI_CreateMDIWindowA 
 * single threaded version of CreateMDIWindowA
 * called by CreateWindowExA
 */
HWND MDI_CreateMDIWindowA(
    LPCSTR lpClassName,
    LPCSTR lpWindowName,
    DWORD dwStyle,
    INT X,
    INT Y,
    INT nWidth,
    INT nHeight,
    HWND hWndParent,
    HINSTANCE hInstance,
    LPARAM lParam)
{
    MDICLIENTINFO* pCi;
    MDICREATESTRUCTA cs;
    WND *pWnd=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(!pWnd){
        ERR(" bad hwnd for MDI-client: %d\n",hWndParent);
        return 0;
    }
    cs.szClass=lpClassName;
    cs.szTitle=lpWindowName;
    cs.hOwner=hInstance;
    cs.x=X;
    cs.y=Y;
    cs.cx=nWidth;
    cs.cy=nHeight;
    cs.style=dwStyle;
    cs.lParam=lParam;

    pCi=(MDICLIENTINFO *)pWnd->wExtra;
    
    retvalue = MDICreateChild(pWnd,pCi,hWndParent,&cs);
    WIN_ReleaseWndPtr(pWnd);
    return retvalue;
}

/***********************************************************************
 * CreateMDIWindowW [USER32.80] Creates a MDI child in new thread
 *
 * RETURNS
 *    Success: Handle to created window
 *    Failure: NULL
 */
HWND WINAPI CreateMDIWindowW(
    LPCWSTR lpClassName,    /* [in] Pointer to registered child class name */
    LPCWSTR lpWindowName,   /* [in] Pointer to window name */
    DWORD dwStyle,         /* [in] Window style */
    INT X,               /* [in] Horizontal position of window */
    INT Y,               /* [in] Vertical position of window */
    INT nWidth,          /* [in] Width of window */
    INT nHeight,         /* [in] Height of window */
    HWND hWndParent,     /* [in] Handle to parent window */
    HINSTANCE hInstance, /* [in] Handle to application instance */
    LPARAM lParam)         /* [in] Application-defined value */
{
    FIXME("(%s,%s,%ld,%d,%d,%d,%d,%x,%d,%ld): stub\n",
          debugstr_w(lpClassName),debugstr_w(lpWindowName),dwStyle,X,Y,
          nWidth,nHeight,hWndParent,hInstance,lParam);
    return (HWND)NULL;
}


/******************************************************************************
 * CreateMDIWindowW [USER32.80]  Creates a MDI child window
 * single threaded version of CreateMDIWindow
 * called by CreateWindowExW(). 
 */
HWND MDI_CreateMDIWindowW(
    LPCWSTR lpClassName,   /* [in] Pointer to registered child class name */
    LPCWSTR lpWindowName,  /* [in] Pointer to window name */
    DWORD dwStyle,         /* [in] Window style */
    INT X,               /* [in] Horizontal position of window */
    INT Y,               /* [in] Vertical position of window */
    INT nWidth,          /* [in] Width of window */
    INT nHeight,         /* [in] Height of window */
    HWND hWndParent,     /* [in] Handle to parent window */
    HINSTANCE hInstance, /* [in] Handle to application instance */
    LPARAM lParam)         /* [in] Application-defined value */
{
    FIXME("(%s,%s,%ld,%d,%d,%d,%d,%x,%d,%ld): stub\n",
          debugstr_w(lpClassName),debugstr_w(lpWindowName),dwStyle,X,Y,
          nWidth,nHeight,hWndParent,hInstance,lParam);
    return (HWND)NULL;
}


/**********************************************************************
 *             TranslateMDISysAccel   (USER32.555)
 */
BOOL WINAPI TranslateMDISysAccel( HWND hwndClient, LPMSG msg )
{
    MSG16 msg16;
 
    STRUCT32_MSG32to16(msg,&msg16);
    /* MDICLIENTINFO is still the same for win32 and win16 ... */
    return TranslateMDISysAccel16(hwndClient,&msg16);
}


/**********************************************************************
 *             TranslateMDISysAccel16   (USER.451)
 */
BOOL16 WINAPI TranslateMDISysAccel16( HWND16 hwndClient, LPMSG16 msg )
{

    if( IsWindow(hwndClient) && (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN))
    {
	MDICLIENTINFO	*ci = NULL;
	HWND		wnd;
        WND             *clientWnd = WIN_FindWndPtr(hwndClient);

	ci = (MDICLIENTINFO*) clientWnd->wExtra;
        wnd = ci->hwndActiveChild;

        WIN_ReleaseWndPtr(clientWnd);

        if( IsWindow(wnd) && !(GetWindowLongA(wnd,GWL_STYLE) & WS_DISABLED) )
	{
	    WPARAM16	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);
	        SendMessage16( ci->hwndActiveChild, WM_SYSCOMMAND, 
					wParam, (LPARAM)msg->wParam);
	        return 1;
	    }
	}
    }
    return 0; /* failure */
}


/***********************************************************************
 *           CalcChildScroll   (USER.462)
 */
void WINAPI CalcChildScroll16( HWND16 hwnd, WORD scroll )
{
    SCROLLINFO info;
    RECT childRect, clientRect;
    INT  vmin, vmax, hmin, hmax, vpos, hpos;
    WND *pWnd, *Wnd;

    if (!(pWnd = WIN_FindWndPtr( hwnd ))) return;
    Wnd = WIN_FindWndPtr(hwnd);
    GetClientRect( hwnd, &clientRect );
    SetRectEmpty( &childRect );

    for ( WIN_UpdateWndPtr(&pWnd,pWnd->child); pWnd; WIN_UpdateWndPtr(&pWnd,pWnd->next))
    {
	  if( pWnd->dwStyle & WS_MAXIMIZE )
	  {
	      ShowScrollBar(hwnd, SB_BOTH, FALSE);
              WIN_ReleaseWndPtr(pWnd);
              WIN_ReleaseWndPtr(Wnd);
	      return;
	  }
	  UnionRect( &childRect, &pWnd->rectWindow, &childRect );
    } 
    WIN_ReleaseWndPtr(pWnd);
    UnionRect( &childRect, &clientRect, &childRect );

    hmin = childRect.left; hmax = childRect.right - clientRect.right;
    hpos = clientRect.left - childRect.left;
    vmin = childRect.top; vmax = childRect.bottom - clientRect.bottom;
    vpos = clientRect.top - childRect.top;

    switch( scroll )
    {
	case SB_HORZ:
			vpos = hpos; vmin = hmin; vmax = hmax;
	case SB_VERT:
			info.cbSize = sizeof(info);
			info.nMax = vmax; info.nMin = vmin; info.nPos = vpos;
			info.fMask = SIF_POS | SIF_RANGE;
			SetScrollInfo(hwnd, scroll, &info, TRUE);
			break;
	case SB_BOTH:
			SCROLL_SetNCSbState( Wnd, vmin, vmax, vpos,
						  hmin, hmax, hpos);
    }    
    WIN_ReleaseWndPtr(Wnd);
}


/***********************************************************************
 *           ScrollChildren16   (USER.463)
 */
void WINAPI ScrollChildren16(HWND16 hWnd, UINT16 uMsg, WPARAM16 wParam, LPARAM lParam)
{
    ScrollChildren( hWnd, uMsg, wParam, lParam );
}


/***********************************************************************
 *           ScrollChildren   (USER32.448)
 */
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;

    if( !wndPtr ) return;

    if( uMsg == WM_HSCROLL )
    {
	GetScrollRange(hWnd,SB_HORZ,&minPos,&maxPos);
	curPos = GetScrollPos(hWnd,SB_HORZ);
	length = (wndPtr->rectClient.right - wndPtr->rectClient.left)/2;
	shift = GetSystemMetrics(SM_CYHSCROLL);
    }
    else if( uMsg == WM_VSCROLL )
    {
	GetScrollRange(hWnd,SB_VERT,&minPos,&maxPos);
	curPos = GetScrollPos(hWnd,SB_VERT);
	length = (wndPtr->rectClient.bottom - wndPtr->rectClient.top)/2;
	shift = GetSystemMetrics(SM_CXVSCROLL);
    }
    else
    {
        WIN_ReleaseWndPtr(wndPtr);
        return;
    }

    WIN_ReleaseWndPtr(wndPtr);
    switch( wParam )
    {
	case SB_LINEUP:	
		        newPos = curPos - shift;
			break;
	case SB_LINEDOWN:    
			newPos = curPos + shift;
			break;
	case SB_PAGEUP:	
			newPos = curPos - length;
			break;
	case SB_PAGEDOWN:    
			newPos = curPos + length;
			break;

	case SB_THUMBPOSITION: 
			newPos = LOWORD(lParam);
			break;

	case SB_THUMBTRACK:  
			return;

	case SB_TOP:		
			newPos = minPos;
			break;
	case SB_BOTTOM:	
			newPos = maxPos;
			break;
	case SB_ENDSCROLL:
			CalcChildScroll16(hWnd,(uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ);
			return;
    }

    if( newPos > maxPos )
	newPos = maxPos;
    else 
	if( newPos < minPos )
	    newPos = minPos;

    SetScrollPos(hWnd, (uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ , newPos, TRUE);

    if( uMsg == WM_VSCROLL )
	ScrollWindowEx(hWnd ,0 ,curPos - newPos, NULL, NULL, 0, NULL, 
			SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
    else
	ScrollWindowEx(hWnd ,curPos - newPos, 0, NULL, NULL, 0, NULL,
			SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
}


/******************************************************************************
 * CascadeWindows [USER32.21] Cascades MDI child windows
 *
 * RETURNS
 *    Success: Number of cascaded windows.
 *    Failure: 0
 */
WORD WINAPI
CascadeWindows (HWND hwndParent, UINT wFlags, const LPRECT lpRect,
		UINT cKids, const HWND *lpKids)
{
    FIXME("(0x%08x,0x%08x,...,%u,...): stub\n",
	   hwndParent, wFlags, cKids);

    return 0;
}


/******************************************************************************
 * TileWindows [USER32.545] Tiles MDI child windows
 *
 * RETURNS
 *    Success: Number of tiled windows.
 *    Failure: 0
 */
WORD WINAPI
TileWindows (HWND hwndParent, UINT wFlags, const LPRECT lpRect,
	     UINT cKids, const HWND *lpKids)
{
    FIXME("(0x%08x,0x%08x,...,%u,...): stub\n",
	   hwndParent, wFlags, cKids);

    return 0;
}

/************************************************************************
 *              "More Windows..." functionality
 */

/*              MDI_MoreWindowsDlgProc
 *
 *    This function will process the messages sent to the "More Windows..."
 *    dialog.
 *    Return values:  0    = cancel pressed
 *                    HWND = ok pressed or double-click in the list...
 *
 */

static BOOL WINAPI MDI_MoreWindowsDlgProc (HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    switch (iMsg)
    {
       case WM_INITDIALOG:
       {
           WND  *pWnd;
           UINT widest       = 0;
           UINT length;
           UINT i;
           WND  *pParentWnd  = (WND *)lParam;
           MDICLIENTINFO *ci = (MDICLIENTINFO*)pParentWnd->wExtra;
           HWND hListBox = GetDlgItem(hDlg, MDI_IDC_LISTBOX);

           /* Fill the list, sorted by id... */
           for (i = 0; i < ci->nActiveChildren; i++)
           {

               /* Find the window with the current ID */
               for (pWnd = WIN_LockWndPtr(pParentWnd->child); pWnd; WIN_UpdateWndPtr(&pWnd, pWnd->next))
                   if (pWnd->wIDmenu == ci->idFirstChild + i)
                       break;

               SendMessageW(hListBox, LB_ADDSTRING, 0, (LPARAM) pWnd->text);
               SendMessageA(hListBox, LB_SETITEMDATA, i, (LPARAM) pWnd);
               length = lstrlenW(pWnd->text);
               WIN_ReleaseWndPtr(pWnd);

               if (length > widest)
                   widest = length;
           }
           /* Make sure the horizontal scrollbar scrolls ok */
           SendMessageA(hListBox, LB_SETHORIZONTALEXTENT, widest * 6, 0);

           /* Set the current selection */
           SendMessageA(hListBox, LB_SETCURSEL, MDI_MOREWINDOWSLIMIT, 0);
           return TRUE;
       }

       case WM_COMMAND:
           switch (LOWORD(wParam))
           {
                case IDOK:
                {
                    /*  windows are sorted by menu ID, so we must return the
                     *  window associated to the given id
                     */
                    HWND hListBox     = GetDlgItem(hDlg, MDI_IDC_LISTBOX);
                    UINT index        = SendMessageA(hListBox, LB_GETCURSEL, 0, 0);
                    WND* pWnd         = (WND*) SendMessageA(hListBox, LB_GETITEMDATA, index, 0);

                    EndDialog(hDlg, pWnd->hwndSelf);
                    return TRUE;
                }
                case IDCANCEL:
                    EndDialog(hDlg, 0);
                    return TRUE;

                default:
                    switch (HIWORD(wParam))
                    {
                        case LBN_DBLCLK:
                        {
                            /*  windows are sorted by menu ID, so we must return the
                             *  window associated to the given id
                             */
                            HWND hListBox     = GetDlgItem(hDlg, MDI_IDC_LISTBOX);
                            UINT index        = SendMessageA(hListBox, LB_GETCURSEL, 0, 0);
                            WND* pWnd         = (WND*) SendMessageA(hListBox, LB_GETITEMDATA, index, 0);

                            EndDialog(hDlg, pWnd->hwndSelf);
                            return TRUE;
                        }
                    }
                    break;
           }
           break;
    }
    return FALSE;
}

/*
 *
 *                      MDI_MoreWindowsDialog
 *
 *     Prompts the user with a listbox containing the opened
 *     documents. The user can then choose a windows and click
 *     on OK to set the current window to the one selected, or
 *     CANCEL to cancel. The function returns a handle to the
 *     selected window.
 */

static HWND MDI_MoreWindowsDialog(WND* wndPtr)
{
    LPCVOID template;
    HRSRC hRes;
    HANDLE hDlgTmpl;

    hRes = FindResourceA(GetModuleHandleA("USER32"), "MDI_MOREWINDOWS", RT_DIALOGA);

    if (hRes == 0)
        return 0;

    hDlgTmpl = LoadResource(GetModuleHandleA("USER32"), hRes );

    if (hDlgTmpl == 0)
        return 0;

    template = LockResource( hDlgTmpl );

    if (template == 0)
        return 0;

    return (HWND) DialogBoxIndirectParamA(GetModuleHandleA("USER32"),
                                          (LPDLGTEMPLATEA) template,
                                          wndPtr->hwndSelf,
                                          (DLGPROC) MDI_MoreWindowsDlgProc,
                                          (LPARAM) wndPtr);
}

/*
 *
 *                      MDI_SwapMenuItems
 *
 *      Will swap the menu IDs for the given 2 positions.
 *      pos1 and pos2 are menu IDs
 *     
 *    
 */

static void MDI_SwapMenuItems(WND *parentWnd, UINT pos1, UINT pos2)
{
    WND *pWnd;

    for (pWnd = WIN_LockWndPtr(parentWnd->child); pWnd; WIN_UpdateWndPtr(&pWnd,pWnd->next))
    {
        if (pWnd->wIDmenu == pos1)
            pWnd->wIDmenu = pos2;
        else
            if (pWnd->wIDmenu == pos2)
                pWnd->wIDmenu = pos1;
    }

    WIN_ReleaseWndPtr(pWnd);
}

