Release 960428

Sun Apr 28 14:32:43 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [Makefile.in]
	Subdir memory is now also compiled for Winelib, in order to get
	the Win32 heap functions.

	* [if1632/Makefile.in]
	Renamed winprocs and winprocs32 to wprocs and wprocs32 to avoid
	DLL names > 8 characters.

	* [loader/builtin.c] (New file)
	Grouped all built-in DLLs code in a single file.

	* [memory/global.c]
	Use the Win32 heap code instead of malloc() to allocate linear
	memory. This will help test the heap code.

	* [memory/local.c]
	Fixed FreeSelector() to clear DS and ES correctly for huge blocks.

	* [tools/build.c] [if1632/relay.c]
	Removed 'id' directive in spec files. For relay debugging, the DLL
	entry point is now computed from the CS:IP entry point address.
	Added 'heap' directive to specifiy a local heap for the DLL. USER
	and GDI heap are now created this way.

	* [windows/class.c] [include/class.h]
	Changed the class structure to use pointers instead of handles.
	Changed Get/SetClassWord/Long to use a switch statement; this
	allows changing the layout of the CLASS structure.

	* [windows/win.c] [include/win.h]
	Use a CLASS * instead of a handle for the window class.

Sat Apr 27 18:10:11 Martin von Loewis <loewis@informatik.hu-berlin.de>

	* [if1632/kernel32.spec] [memory/global.c]
	  [win32/memory.c] [win32/process.c]
	GetProcessAffinityMask,GlobalLock,IsBadReadPtr,IsBadWritePtr,
	LocalLock,SetThreadAffinityMask: new relays.

	* [win32/cursoricon32.c]
	Return same handle if a cursor is loaded multiple times.

Sat Apr 27 15:13:37 1996  Bang Jun Young <bangjy@nownuri.nowcom.co.kr>

	* [resources/sysres_Ko.rc]
        Added support for Korean [Ko] language.

Fri Apr 26 00:49:05 1996  Huw D. M. Davies <h.davies1@physics.oxford.ac.uk>

	* [objects/dc.c] [objects/font.c]
	Fixed problem with SaveDC()/RestoreDC() and font cache 'used' count.

	* [objects/metafile.c] [objects/dcvalues.c]
	Fixed broken SetTextAlign() on metafiles.

	* [objects/metafile.c]
	Delete objects in handle table at end of PlayMetaFile().

Wed Apr 24 19:21:01  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [if1632/ver.spec] [misc/ver.c] [include/ver.h] (New files)
	VER.DLL (partially) implemented (VerFindFile,VerInstallFile)
	[If it doesn't work for you, use -dll -ver and report it to me]

	* [if1632/user32.spec] [if1632/kernel32.spec] [if1632/shell.spec]
	  [if1632/shell32.spec] [misc/ole2nls.c] [windows/message.c]
	  [windows/graphics.c]
	Simple win32 functions, where we can just use the win16 counterpart.
	Misc. stubs. 

	* [misc/lstr.c]
	Someone reported a _lstrlen(NULL). NULL is a valid argument. Fixed.

	* [misc/registry.c]
	Some alloclens were off by 1, one double fclose() fixed.
	Requesting value 0 of a key with no values returns an error 
	(should we always return a made up value NULL? what does win3.1?)

Tue Apr 23 17:00:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu>

	* [misc/shell.c]
	Implemented FindEnvironmentString(), DoEnvironmentSubst(),
	ExtractIcon(), InternalExtractIcon() and ExtractAssociatedIcon().

	* [misc/user.c]
	Do extensive cleanup on application exit.

	* [windows/hook.c] [windows/win.c] [windows/class.c]
	Added miscellaneous cleanup routines.

	* [controls/menu.c]
	More efficient popup menu window handling.

Mon Apr 22 21:35:22 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [include/windows.h][objects/oembitmap.c][include/bitmaps/obm_trtype]
	Added "TT-bitmap" for later usage in a ChooseFont() ownerdraw combobox.
diff --git a/controls/menu.c b/controls/menu.c
index 78e991d..eecb575 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -18,6 +18,7 @@
 #include "windows.h"
 #include "syscolor.h"
 #include "sysmetrics.h"
+#include "task.h"
 #include "win.h"
 #include "menu.h"
 #include "module.h"
@@ -65,6 +66,12 @@
 static HBITMAP hStdCheck = 0;
 static HBITMAP hStdMnArrow = 0;
 
+/* we _can_ use global popup window because there's no way 2 menues can
+ * be tracked at the same time.
+ */ 
+
+static WND* pTopPWnd   = 0;
+static UINT uSubPWndLevel = 0;
 
 /***********************************************************************
  *           MENU_Init
@@ -678,6 +685,23 @@
     return lppop->Height;
 } 
 
+/***********************************************************************
+ *	     MENU_SwitchTPWndTo
+ */
+BOOL MENU_SwitchTPWndTo( HTASK hTask)
+{
+  /* This is supposed to be called when popup is hidden */
+
+  TDB* task = (TDB*)GlobalLock(hTask);
+
+  if( !task ) return 0;
+
+  /* if this task got as far as menu tracking it must have a queue */
+
+  pTopPWnd->hInstance = task->hInstance;
+  pTopPWnd->hmemTaskQ = task->hQueue;
+  return 1;
+}
 
 /***********************************************************************
  *           MENU_ShowPopup
@@ -686,7 +710,9 @@
  */
 static BOOL MENU_ShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, int x, int y)
 {
-    POPUPMENU *menu;
+    POPUPMENU 	*menu;
+    WND 	*wndPtr = NULL;
+    BOOL	 skip_init = 0;
 
     if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu ))) return FALSE;
     if (menu->FocusedItem != NO_SELECTED_ITEM)
@@ -698,21 +724,47 @@
     SendMessage( hwndOwner, WM_INITMENUPOPUP, (WPARAM)hmenu,
 		 MAKELONG( id, (menu->wFlags & MF_SYSMENU) ? 1 : 0 ));
     MENU_PopupMenuCalcSize( menu, hwndOwner );
-    if (!menu->hWnd)
+
+    wndPtr = WIN_FindWndPtr( hwndOwner );
+    if (!wndPtr) return FALSE;
+
+    if (!pTopPWnd)
     {
-	WND *wndPtr = WIN_FindWndPtr( hwndOwner );
-	if (!wndPtr) return FALSE;
-	menu->hWnd = CreateWindow( POPUPMENU_CLASS_ATOM, (SEGPTR)0,
-				   WS_POPUP | WS_BORDER, x, y, 
-				   menu->Width + 2*SYSMETRICS_CXBORDER,
-				   menu->Height + 2*SYSMETRICS_CYBORDER,
-				   0, 0, wndPtr->hInstance, (SEGPTR)hmenu );
-	if (!menu->hWnd) return FALSE;
+	pTopPWnd = WIN_FindWndPtr(CreateWindow( POPUPMENU_CLASS_ATOM, (SEGPTR)0,
+				   		WS_POPUP | WS_BORDER, x, y, 
+				   		menu->Width + 2*SYSMETRICS_CXBORDER,
+				   		menu->Height + 2*SYSMETRICS_CYBORDER,
+				   		0, 0, wndPtr->hInstance, (SEGPTR)hmenu ));
+	if (!pTopPWnd) return FALSE;
+	skip_init = TRUE;
     }
-    else SetWindowPos( menu->hWnd, 0, x, y,
-		       menu->Width + 2*SYSMETRICS_CXBORDER,
-		       menu->Height + 2*SYSMETRICS_CYBORDER,
-		       SWP_NOACTIVATE | SWP_NOZORDER );
+
+    if( uSubPWndLevel )
+    {
+	/* create new window for the submenu */
+	HWND  hWnd = CreateWindow( POPUPMENU_CLASS_ATOM, (SEGPTR)0,
+                                   WS_POPUP | WS_BORDER, x, y,
+                                   menu->Width + 2*SYSMETRICS_CXBORDER,
+                                   menu->Height + 2*SYSMETRICS_CYBORDER,
+                                   menu->hWnd, 0, wndPtr->hInstance, (SEGPTR)hmenu );
+	if( !hWnd ) return FALSE;
+	menu->hWnd = hWnd;
+    }
+    else 
+    {
+	if( !skip_init )
+	  {
+            MENU_SwitchTPWndTo(GetCurrentTask());
+	    SendMessage( pTopPWnd->hwndSelf, WM_USER, (WPARAM)hmenu, 0L);
+	  }
+	menu->hWnd = pTopPWnd->hwndSelf;
+    }
+
+    uSubPWndLevel++;
+
+    SetWindowPos(menu->hWnd, 0, x, y, menu->Width + 2*SYSMETRICS_CXBORDER, 
+				      menu->Height + 2*SYSMETRICS_CYBORDER,
+		  		      SWP_NOACTIVATE | SWP_NOZORDER );
 
       /* Display the window */
 
@@ -1095,7 +1147,16 @@
     }
     submenu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hsubmenu );
     MENU_HideSubPopups( hwndOwner, hsubmenu );
-    if (submenu->hWnd) ShowWindow( submenu->hWnd, SW_HIDE );
+    if (submenu->hWnd == pTopPWnd->hwndSelf ) 
+      {
+	ShowWindow( submenu->hWnd, SW_HIDE );
+	uSubPWndLevel = 0;
+      }
+    else
+      {
+	DestroyWindow( submenu->hWnd );
+	submenu->hWnd = 0;
+      }
     MENU_SelectItem( hwndOwner, hsubmenu, NO_SELECTED_ITEM );
 }
 
@@ -1596,7 +1657,11 @@
     USER_HEAP_FREE( hMsg );
     ReleaseCapture();
     MENU_HideSubPopups( hwnd, hmenu );
-    if (menu->wFlags & MF_POPUP) ShowWindow( menu->hWnd, SW_HIDE );
+    if (menu->wFlags & MF_POPUP) 
+       {
+         ShowWindow( menu->hWnd, SW_HIDE );
+	 uSubPWndLevel = 0;
+       }
     MENU_SelectItem( hwnd, hmenu, NO_SELECTED_ITEM );
     SendMessage( hwnd, WM_MENUSELECT, 0, MAKELONG( 0xffff, 0 ) );
     fEndMenuCalled = FALSE;
@@ -1743,6 +1808,25 @@
 	    return 0;
 	}
 
+    case WM_DESTROY:
+	    /* zero out global pointer in case system popup
+	     * was destroyed by AppExit 
+	     */
+
+	    if( hwnd == pTopPWnd->hwndSelf )
+		pTopPWnd = 0;
+	    else
+		uSubPWndLevel--;
+	    break;
+
+    case WM_USER:
+	if( wParam )
+#ifdef WINELIB32
+            SetWindowLong( hwnd, 0, (HMENU)wParam );
+#else
+            SetWindowWord( hwnd, 0, (HMENU)wParam );
+#endif
+        break;
     default:
 	return DefWindowProc(hwnd, message, wParam, lParam);
     }
@@ -2139,7 +2223,7 @@
     lppop = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu);
     if (!lppop || (lppop->wMagic != MENU_MAGIC)) return FALSE;
     lppop->wMagic = 0;  /* Mark it as destroyed */
-    if ((lppop->wFlags & MF_POPUP) && lppop->hWnd)
+    if ((lppop->wFlags & MF_POPUP) && lppop->hWnd && lppop->hWnd != pTopPWnd->hwndSelf )
         DestroyWindow( lppop->hWnd );
 
     if (lppop->hItems)