Release 960309

Fri Mar  8 19:07:18 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [configure.in]
	Quote '[' and ']' in the test program for the strength-reduce
	bug. This should work much better...

	* [files/file.c]
	Augmented DOS_FILE structure. Most internal functions now return a
	DOS_FILE* instead of a Unix handle.
	Added a local file array to replace the PDB list upon startup, to
	allow using file I/O functions before the first task is created.
	Added FILE_SetDateTime() and FILE_Sync() functions.
	
	* [loader/module.c]
	Use the DOS file I/O functions in MODULE_LoadExeHeader().

	* [objects/bitblt.c]
	Use visible region instead of GC clip region to clip source
	area. This fixes the card drawing bug in freecell.

	* [objects/region.c]
	Fixed CombineRgn() to allow src and dest regions to be the same.

Fri Mar  8 16:32:23 1996  Frans van Dorsselaer <dorssel@rulhm1.leidenuniv.nl>

	* [controls/EDIT.TODO]
	Updated so it reflects the current status.

	* [controls/edit.c]
	Implemented internal EDIT_WordBreakProc().
	Implemented ES_READONLY.
	Implemented WM_LBUTTONDBLCLK to select whole words.
	Fixed a lot of types in the function definitions.

Wed Mar  6 19:55:00 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>

	* [debugger/info.c]
	Added "walk window" command to walk window list. 

	* [windows/mdi.c]
	Added proper(?) WM_MDISETMENU message handling.

Wed Mar  6 09:27:12 1996  Martin von Loewis <loewis@informatik.hu-berlin.de>

	* [if1632/callback.c][if1632/relay32.c]
	RELAY32_CallWindowProcConvStruct: new function.

	* [win32/struct32.c][win32/Makefile.in][win32/param.c][win32/user32.c]
	struct32.c: new file. Moved all structure conversions into that file
	PARAM32_POINT32to16,MSG16to32,USER32_RECT32to16: 
	renamed to STRUCT32_POINT32to16, ...
	WIN32_POINT,WIN32_MSG,WIN32_RECT,WIN32_PAINTSTRUCT: renamed to
	POINT32, ...
	New conversion functions for NCCALCSIZE_PARAMS, WINDOWPOS,
 	CREATESTRUCT.

	* [include/windows.h][misc/exec.c]
	WINHELP, MULTIKEYHELP, HELPWININFO: new structures
	WinHelp: Reimplemented. Thanks to Peter Balch
 	(100710.2566@compuserve.com) for his valuable research.

	* [win32/winprocs.c]
	WIN32_CallWindowProcTo16: new function, call in
 	USER32_DefWindowProcA,...

Mon Mar  4 23:22:40 1996  Jim Peterson <jspeter@birch.ee.vt.edu>

	* [include/wintypes.h]
	Added "#define __export".

	* [objects/bitblt.c]
	Put in a few hacks to make bitblt-ing work when upside-down and/or
	mirrored.  BITBLT_StretchImage should really be checked over
	thoroughly.

	* [programs/progman/main.c]
	Added "#include <resource.h>" for definition of HAVE_WINE_CONSTRUCTOR.

	* [rc/parser.h] [rc/parser.l] [rc/parser.y] [rc/winerc.c]
	Eliminated shift/reduce conflict in style definition.
	Added crude error message support: "stdin:%d: parse error before '%s'".
	Implemented string table support to the best of my ability (it works
	with LoadString() calls).

	* [windows/nonclient.c]
	Fixed bug in NC_DoSizeMove() that made system menu pop up when title
	bar of non-iconized window was clicked (checked for iconization).

Mon Mar 04 20:55:19 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [if1632/lzexpand.spec] [if1632/relay.c]
	  [include/lzexpand.h][misc/lzexpand.c]
	LZEXPAND.DLL added.

Sun Mar 03 18:10:22 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [windows/win.c]
	Prevent usage of invalid HWNDs in WIN_EnumChildWin(),
	this prevents too early termination of EnumChildWindows().
diff --git a/windows/mdi.c b/windows/mdi.c
index 7ed6727..37ba8f7 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -20,6 +20,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <math.h>
+#include "xmalloc.h"
 #include "windows.h"
 #include "win.h"
 #include "nonclient.h"
@@ -117,7 +118,7 @@
  MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
  WND    	*wndPtr     = WIN_FindWndPtr(hWndChild);
  LPSTR		 lpWndText;
- INT		 index      = 0,id,n;
+ UINT		 index      = 0,id,n;
 
  if( !clientInfo->nActiveChildren ||
      !clientInfo->hWindowMenu ) return 0;
@@ -198,17 +199,71 @@
 
 /**********************************************************************
  *					MDISetMenu
- * FIXME: This is not complete.
  */
 HMENU MDISetMenu(HWND hwnd, BOOL fRefresh, HMENU hmenuFrame, HMENU hmenuWindow)
 {
-    dprintf_mdi(stddeb, "WM_MDISETMENU: "NPFMT" %04x "NPFMT" "NPFMT"\n", hwnd, fRefresh, hmenuFrame, hmenuWindow);
-    if (!fRefresh) {
+    WND           *w         = WIN_FindWndPtr(hwnd);
+    MDICLIENTINFO *ci;
+
+    dprintf_mdi(stddeb, "WM_MDISETMENU: "NPFMT" %04x "NPFMT" "NPFMT"\n",
+                hwnd, fRefresh, hmenuFrame, hmenuWindow);
+
+    ci = (MDICLIENTINFO *) w->wExtra;
+
+    if (!fRefresh) 
+       {
 	HWND hwndFrame = GetParent(hwnd);
 	HMENU oldFrameMenu = GetMenu(hwndFrame);
-	SetMenu(hwndFrame, hmenuFrame);
-	return oldFrameMenu;
-    }
+        
+	if( ci->flagChildMaximized && hmenuFrame && hmenuFrame!=oldFrameMenu )
+	    MDI_RestoreFrameMenu(w->hwndParent, ci->flagChildMaximized );
+
+	if( hmenuWindow && 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;
+
+            AppendMenu(hmenuWindow,MF_SEPARATOR,0,(SEGPTR)0);
+
+	    if( ci->nActiveChildren )
+	      {
+	        INT  j = i - ci->nActiveChildren + 1;
+		char buffer[100];
+		UINT id,state;
+
+		for( ; i >= j ; i-- )
+		   {
+		     id = GetMenuItemID(ci->hWindowMenu,i );
+		     state = GetMenuState(ci->hWindowMenu,i,MF_BYPOSITION); 
+
+		     GetMenuString(ci->hWindowMenu, i, buffer, 100, MF_BYPOSITION);
+
+		     DeleteMenu(ci->hWindowMenu, i , MF_BYPOSITION);
+		     InsertMenu(hmenuWindow, pos, MF_BYPOSITION | MF_STRING,
+					     id, MAKE_SEGPTR(buffer));
+		     CheckMenuItem(hmenuWindow ,pos , MF_BYPOSITION | (state & MF_CHECKED));
+		   }
+	      }
+
+	    /* remove separator */
+	    DeleteMenu(ci->hWindowMenu, i, MF_BYPOSITION); 
+
+	    ci->hWindowMenu = hmenuWindow;
+	  } 
+
+	if( hmenuFrame && hmenuFrame!=oldFrameMenu)
+	  {
+	    SetMenu(hwndFrame, hmenuFrame);
+	    if( ci->flagChildMaximized )
+	        MDI_AugmentFrameMenu(ci, 
+                    w->hwndParent, ci->flagChildMaximized );
+	    return oldFrameMenu;
+	  }
+
+       }
     return 0;
 }
 
@@ -236,11 +291,12 @@
     HWND hwnd;
     WORD	     wIDmenu = ci->idFirstChild + ci->nActiveChildren;
     int spacing;
-    char	     chDef = '\0';
+    char*	     lpstrDef="junk!";
 
     /*
      * Create child window
      */
+
     cs->style &= (WS_MINIMIZE | WS_MAXIMIZE | WS_HSCROLL | WS_VSCROLL);
 
 				/* The child windows should probably  */
@@ -250,8 +306,10 @@
     cs->y = ci->nActiveChildren * spacing;
 
     /* this menu is needed to set a check mark in MDI_ChildActivate */
-    AppendMenu(ci->hWindowMenu ,MF_STRING ,wIDmenu, MAKE_SEGPTR(&chDef) );
+    AppendMenu(ci->hWindowMenu ,MF_STRING ,wIDmenu, MAKE_SEGPTR(lpstrDef) );
 
+    ci->nActiveChildren++;
+ 
     hwnd = CreateWindow( cs->szClass, cs->szTitle,
 			  WS_CHILD | WS_BORDER | WS_CAPTION | WS_CLIPSIBLINGS |
 			  WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU |
@@ -262,12 +320,14 @@
 
     if (hwnd)
     {
-	ci->nActiveChildren++;
 	MDI_MenuModifyItem(w ,hwnd); 
-
+        dprintf_mdi(stddeb, "MDICreateChild: created child - "NPFMT"\n",hwnd);
     }
     else
+    {
+       ci->nActiveChildren--;
 	DeleteMenu(ci->hWindowMenu,wIDmenu,MF_BYCOMMAND);
+    }
 	
     return hwnd;
 }
@@ -373,7 +433,7 @@
 	
         ci->nActiveChildren--;
 
-	/* WM_MDISETMENU ? */
+        dprintf_mdi(stddeb,"MDIDestroyChild: child destroyed - "NPFMT"\n",child);
 
         if (flagDestroy)
 	   {
@@ -499,22 +559,8 @@
     childWnd  =  WIN_FindWndPtr( listTop->hChild );
     while( childWnd && childWnd->hwndNext )
     {
-	listNext = (MDIWCL*)malloc(sizeof(MDIWCL));
+	listNext = (MDIWCL*)xmalloc(sizeof(MDIWCL));
 	
-	if( !listNext )
-	{
-	    /* quit gracefully */
-	    listNext = listTop->prev;
-	    while( listTop )
-	    {
-                listNext = listTop->prev;
-                free(listTop);
-                listTop  = listNext;
-	    }
-	    dprintf_mdi(stddeb,"MDICascade: allocation failed\n");
-	    return NULL;
-	}
-    
 	if( (childWnd->dwStyle & WS_DISABLED) ||
 	    (childWnd->dwStyle & WS_MINIMIZE) ||
 	    !(childWnd->dwStyle & WS_VISIBLE)   )
@@ -921,6 +967,7 @@
 	ci->hWindowMenu         = ccs->hWindowMenu;
 	ci->idFirstChild        = ccs->idFirstChild;
 	ci->flagChildMaximized  = 0;
+	ci->nActiveChildren	= 0;
 	ci->hFrameTitle		= frameWnd->hText;
 	ci->sbStop		= 0;
 	ci->self		= hwnd;
@@ -937,6 +984,8 @@
 	NC_HandleNCCalcSize(hwnd, (NCCALCSIZE_PARAMS*) &rect);
 	w->rectClient = rect;
 
+	dprintf_mdi(stddeb,"MDI: Client created - hwnd = "NPFMT", idFirst = %u\n",hwnd,ci->idFirstChild);
+
 	return 0;
       
       case WM_DESTROY: