Release 950319

Sun Mar 19 16:30:20 1995  Alexandre Julliard  (julliard@sunsite.unc.edu)

	* [*/*]
	Implemented a new memory mapping scheme. There's no longer a
	one-to-one mapping between 16-bit and 32-bit pointers. Please see
	file DEVELOPERS-HINTS for technical details.

	* [controls/scroll.c]
	Fixed bug when dragging mouse in horizontal scrollbars.

	* [tools/build.c] [if1632/*.spec]
	Removed support for C callback functions and for re-ordering
	of the 32-bit arguments, as these were never used. This should
	allow a more efficient callback scheme to be implemented.

	* [if1632/olecli.spec]
	Reduced the number of entries to make the 16-bit code fit in 64k.
	This limitation will soon be removed.

	* [loader/ldt.c]
	Rewrote LDT manipulation functions and implemented LDT_GetEntry().

	* [memory/global.c]
	Rewrote Global*() routines to use the new selector allocation
	mechanism.

	* [memory/local.c]
	Rewrote local heap handling to use a Windows-compatible layout
	(not really finished yet).
	Implemented TOOLHELP heap-walking routines.

	* [memory/selector.c]
	Implemented LDT manipulation API functions.

Tue Mar 14 19:50:28 EST 1995 William Magro (wmagro@tc.cornell.edu)

	* [windows/defdlg.c]
	Fixed problem where dialogs closed using the System menu 
        ('Close' item or double click on close box) would
	hang Wine.

Sun Mar 12 14:28:13 1995  Michael Patra <micky@marie.physik.TU-Berlin.DE>

	* [controls/listbox.c]
	Removed most of the statements for sending a notification message
	ListBoxDirectory(), DlgDirSelect(), DlgDirList(): Improved the
	code; Borland's standard file open dialog will work now.
	
	* [misc/main.c], [misc/file.c], [miscemu/int21.c]
	Added support for new command line option "-allowreadonly". If set
	an attempt to open a read only file in write mode will be converted 
	to opening it read only (many programs try to open all files in 
	read/write mode even if they only intend to read it - this might 
	cause a few under problems under an unix-like environment where most 
	files are read only for a "normal" user)

	* [loader/selector.c]
	GetMemoryReference(): Added support for __AHIncr and __AHShift

	* [misc/dos_fs.c]
	DOS_SimplifyPath(): This routine simplifies path names ( e.g., it
	will change "/usr///local/bin/../lib//a" to "/usr/local/lib/a" )
	match(): rewritten
	
	* [objects/text.c]
	TEXT_NextLine(): Removed a bug in the handling of LF's

	* [miscemu/int21.c]
	GetFileDateTime(): Fixed. SetFileDateTime() is still broken.

Sat Mar 11 19:46:19 1995  Martin von Loewis  <loewis@informatik.hu-berlin.de>

	* [controls/menu.c]
	ChangeMenu: defaults to MF_INSERT
	InsertMenu: allow insertion even if position is one after last item

	* [if1632/Imakefile] [if1632/compobj.spec] [if1632/relay.c]
	  [if1632/storage.spec] [include/dlls.h]
	Added stubs for STORAGE.DLL and COMPOBJ.DLL

	* [if1632/user.spec] [windows/message.c]
	InSendMessage: new function

	* [include/neexe.h][include/ne_image.c]
	NE_FixupSegment: fixed handling of additive records

	* [loader/selector.c]
	GetEntryDLLName: return NULL instead of pointer to DLL.0 if not found

	* [loader/signal.c]
	win_fault: Enter debugger on SIGFPE, too

Wed Mar  1 21:47:42 1995  Cameron Heide  (heide@ee.ualberta.ca)

        * [miscemu/int*.c]
        Various minor modifications to the clock tick counter,
        FindFirst/FindNext funcs, and DPB handling.
diff --git a/controls/button.c b/controls/button.c
index 32b8fed..f15d5ff 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -180,7 +180,7 @@
                 break;
 
         case WM_SETTEXT:
-		DEFWND_SetText( hWnd, (LPSTR)lParam );
+		DEFWND_SetText( hWnd, (LPSTR)PTR_SEG_TO_LIN(lParam) );
                 PAINT_BUTTON( hWnd, style, ODA_DRAWENTIRE );
 		return 0;
 
@@ -306,7 +306,7 @@
     else GRAPH_DrawReliefRect( hDC, &rc, 2, 2, FALSE );
     
     /* draw button label, if any: */
-    text = USER_HEAP_ADDR( wndPtr->hText );
+    text = USER_HEAP_LIN_ADDR( wndPtr->hText );
     if (text[0])
     {
         SetTextColor( hDC, (wndPtr->dwStyle & WS_DISABLED) ?
@@ -356,7 +356,7 @@
 
     GetTextMetrics(hDC, &tm);
     delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
-    text = USER_HEAP_ADDR( wndPtr->hText );
+    text = USER_HEAP_LIN_ADDR( wndPtr->hText );
     textlen = strlen( text );
 
       /* Draw the check-box bitmap */
@@ -433,7 +433,7 @@
     LineTo( hDC, rc.left, rc.bottom-1 );
     LineTo( hDC, rc.left, rc.top+2 );
 
-    text = USER_HEAP_ADDR( wndPtr->hText );
+    text = USER_HEAP_LIN_ADDR( wndPtr->hText );
     GetTextExtentPoint(hDC, text, strlen(text), &size);
     rc.left  += 10;
     rc.right  = rc.left + size.cx + 1;
@@ -481,9 +481,8 @@
     WND *wndPtr = WIN_FindWndPtr( hWnd );
     BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
 
-    if (!(hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT))))
-        return;
-    lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis);
+    if (!(hDis = USER_HEAP_ALLOC( sizeof(DRAWITEMSTRUCT) ))) return;
+    lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_LIN_ADDR(hDis);
     lpdis->CtlType    = ODT_BUTTON;
     lpdis->CtlID      = wndPtr->wIDmenu;
     lpdis->itemID     = 0;
@@ -495,7 +494,7 @@
     lpdis->hDC        = hDC;
     GetClientRect( hWnd, &lpdis->rcItem );
     lpdis->itemData   = 0;
-    SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis); 
+    SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, USER_HEAP_SEG_ADDR(hDis) );
     USER_HEAP_FREE(hDis);
 }
 
diff --git a/controls/combo.c b/controls/combo.c
index 34cece2..f61d8e4 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -14,7 +14,6 @@
 #include "windows.h"
 #include "combo.h"
 #include "user.h"
-#include "heap.h"
 #include "win.h"
 #include "stddebug.h"
 /* #define DEBUG_COMBO */
@@ -40,10 +39,11 @@
 	LPHEADCOMBO lphc;
 	HDC		hDC;
 	BITMAP	bm;
-	char	str[128];
 	PAINTSTRUCT paintstruct;
 	LPDRAWITEMSTRUCT lpdis;
 	DWORD       dwStyle;
+        HANDLE hStr;
+
 	switch(message) {
 		case WM_CREATE:
 			wndPtr = WIN_FindWndPtr(hwnd);
@@ -95,7 +95,7 @@
 			lphc->hWndLBox = CreateWindow("LISTBOX", "", dwStyle,
 				rect.left, rect.top + bm.bmHeight,
 				width, height, wndPtr->hwndParent, 0,
-				wndPtr->hInstance, (LPSTR)MAKELONG(0, hwnd));
+				wndPtr->hInstance, (SEGPTR)MAKELONG(0, hwnd));
 			ShowWindow(lphc->hWndLBox, SW_HIDE);
 			dprintf_combo(stddeb,"Combo Creation LBox=%X!\n", lphc->hWndLBox);
 			return 0;
@@ -126,15 +126,16 @@
 		lphc = ComboGetStorageHeader(hwnd);
 		if (lphc == NULL || wndPtr == NULL) return 0;
 		if (LOWORD(lParam) == lphc->hWndLBox) {
+                    hStr = USER_HEAP_ALLOC( 256 );
 			switch(HIWORD(lParam)) {
 				case LBN_SELCHANGE:
 					lphc->dwState = lphc->dwState & (CB_SHOWDROPDOWN ^ 0xFFFFFFFFL);
 					ShowWindow(lphc->hWndLBox, SW_HIDE);
 					y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
 					if (y != LB_ERR) {
-						SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
+						SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
 						if (lphc->hWndEdit != 0) 
-							SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
+							SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
 						else {
 							InvalidateRect(hwnd, NULL, TRUE);
 							UpdateWindow(hwnd);
@@ -148,6 +149,7 @@
 										MAKELONG(hwnd, CBN_DBLCLK));
 					break;
 	        	}
+                    USER_HEAP_FREE( hStr );
             }
 		break;
     case WM_LBUTTONDOWN:
@@ -174,9 +176,11 @@
 			dprintf_combo(stddeb,"before Combo List GetCurSel !\n");
 			y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
 			if (y != LB_ERR) {
+                                hStr = USER_HEAP_ALLOC( 256 );
 				dprintf_combo(stddeb,"before Combo List GetText !\n");
-				SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
-				SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
+				SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
+				SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
+                                USER_HEAP_FREE( hStr );
 				}
 			dprintf_combo(stddeb,"End of Combo List Hide !\n");
 			}
@@ -211,9 +215,11 @@
 				ShowWindow(lphc->hWndLBox, SW_HIDE);
 				y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
 				if (y != LB_ERR) {
-					SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
+                                        hStr = USER_HEAP_ALLOC( 256 );
+					SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
 					if (lphc->hWndEdit != 0) 
-						SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
+						SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
+                                        USER_HEAP_FREE( hStr );
 					}
 				}
 		    }
@@ -236,11 +242,13 @@
 			if (y >= count) y = count - 1;
 			lphc->LastSel = y;
 			SendMessage(lphc->hWndLBox, LB_SETCURSEL, y, 0L);
-			SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
+                        hStr = USER_HEAP_ALLOC( 256 );
+			SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
 			if (lphc->hWndEdit != 0) 
-				SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
+				SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
 			SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
 			MAKELONG(hwnd, CBN_SELCHANGE));
+                        USER_HEAP_FREE( hStr );
 			}
 		break;
     case WM_MEASUREITEM:
@@ -258,7 +266,7 @@
 		dprintf_combo(stddeb,"ComboBoxWndProc // WM_DRAWITEM w=%04X l=%08lX\n", wParam, lParam);
 		wndPtr = WIN_FindWndPtr(hwnd);
 		if (wndPtr == NULL) break;
-		lpdis = (LPDRAWITEMSTRUCT)lParam;
+		lpdis = (LPDRAWITEMSTRUCT)PTR_SEG_TO_LIN(lParam);
 		if (lpdis == NULL) break;
 		lpdis->CtlType = ODT_COMBOBOX;
 		lpdis->CtlID = wndPtr->wIDmenu;
@@ -299,13 +307,15 @@
 		ShowWindow(lphc->hWndLBox, SW_HIDE);
 		y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
 		if (y != LB_ERR) {
-			SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
-			if (lphc->hWndEdit != 0)
-				SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
+                        hStr = USER_HEAP_ALLOC( 256 );
+			SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
+			if (lphc->hWndEdit != 0) 
+				SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
+                        USER_HEAP_FREE( hStr );
 			}
 		break;
 	case CB_ADDSTRING:
-		dprintf_combo(stddeb,"CB_ADDSTRING '%s' !\n", (LPSTR)lParam);
+		dprintf_combo(stddeb,"CB_ADDSTRING '%s' !\n", (LPSTR)PTR_SEG_TO_LIN(lParam));
 		lphc = ComboGetStorageHeader(hwnd);
 		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_ADDSTRING, wParam, lParam));
@@ -320,7 +330,7 @@
 		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_GETTEXTLEN, wParam, lParam));
     case CB_INSERTSTRING:
-		dprintf_combo(stddeb,"CB_INSERTSTRING '%s' !\n",(LPSTR)lParam);
+		dprintf_combo(stddeb,"CB_INSERTSTRING '%s' !\n",(LPSTR)PTR_SEG_TO_LIN(lParam));
 		lphc = ComboGetStorageHeader(hwnd);
 		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam));
@@ -463,7 +473,6 @@
 	HDC     hDC;
 	HBRUSH  hBrush;
 	short   y;
-	char    str[64];
 	LPSTR   ptr = NULL;
 	HANDLE  hTemp;
 	WND       *wndPtr;
@@ -471,7 +480,6 @@
 	dprintf_combo(stddeb,"ComboBoxStaticOwnerDraw(%04X, %p) !\n", hWnd, lphc);
 	y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
 	if (y != LB_ERR) {
-		SendMessage(lphc->hWndLBox, LB_GETTEXT, y, (LPARAM)str);
 		ptr = (LPSTR)SendMessage(lphc->hWndLBox, LB_GETITEMDATA, y, 0L);
 		}
 	hDC = GetDC(hWnd);
@@ -480,8 +488,8 @@
 	if (hBrush == (HBRUSH)NULL)  hBrush = GetStockObject(WHITE_BRUSH);
 	wndPtr = WIN_FindWndPtr(hWnd);
 	if (wndPtr == NULL) return;
-	hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT));
-	lpdis = (LPDRAWITEMSTRUCT) USER_HEAP_ADDR(hTemp);
+	hTemp = USER_HEAP_ALLOC( sizeof(DRAWITEMSTRUCT) );
+	lpdis = (LPDRAWITEMSTRUCT) USER_HEAP_LIN_ADDR(hTemp);
 	if (lpdis == NULL) {
 		printf("ComboBox Ownerdraw // Error allocating DRAWITEMSTRUCT !\n");
                 ReleaseDC( hWnd, hDC );
@@ -495,7 +503,7 @@
 	lpdis->itemAction = ODA_DRAWENTIRE;
 	lpdis->CtlType = ODT_COMBOBOX;
 	lpdis->CtlID = wndPtr->wIDmenu;
-	SendMessage(GetParent(hWnd), WM_DRAWITEM, y, (LPARAM)lpdis);
+	SendMessage(GetParent(hWnd), WM_DRAWITEM, y,USER_HEAP_SEG_ADDR(hTemp));
 	USER_HEAP_FREE(hTemp);
 	ReleaseDC(hWnd, hDC);
 }
@@ -515,13 +523,13 @@
 /************************************************************************
  * 					DlgDirListComboBox     [USER.195]
  */
-int DlgDirListComboBox(HWND hDlg, LPSTR lpPathSpec, 
+int DlgDirListComboBox(HWND hDlg, SEGPTR lpPathSpec, 
 	int nIDLBox, int nIDStat, WORD wType)
 {
 	HWND		hWnd;
 	LPHEADCOMBO lphc;
 	dprintf_combo(stddeb,"DlgDirListComboBox(%04X, '%s', %d, %d, %04X) \n",
-			hDlg, lpPathSpec, nIDLBox, nIDStat, wType);
+			hDlg, (char *)PTR_SEG_TO_LIN(lpPathSpec), nIDLBox, nIDStat, wType);
 	hWnd = GetDlgItem(hDlg, nIDLBox);
 	lphc = ComboGetStorageHeader(hWnd);
 	if (lphc == NULL) return 0;
diff --git a/controls/edit.c b/controls/edit.c
index 42981bd..5a42a13 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -12,7 +12,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <windows.h>
-#include <heap.h>
+#include "local.h"
 #include "win.h"
 #include "class.h"
 #include "user.h"
@@ -231,7 +231,7 @@
 	break;
 
     case EM_GETRECT:
-	GetWindowRect(hwnd, (LPRECT)lParam);
+	GetWindowRect(hwnd, (LPRECT)PTR_SEG_TO_LIN(lParam));
 	break;
 
     case EM_GETSEL:
@@ -359,7 +359,7 @@
 	textPtr = EDIT_HeapAddr(hwnd, es->hText);
 	if ((int)wParam > (len = strlen(textPtr)))
 	{
-	    strcpy((char *)lParam, textPtr);
+	    strcpy((char *)PTR_SEG_TO_LIN(lParam), textPtr);
 	    lResult = (DWORD)len ;
 	}
 	else
@@ -469,7 +469,7 @@
 
 long EDIT_NCCreateMsg(HWND hwnd, LONG lParam)
 {
-    CREATESTRUCT *createStruct = (CREATESTRUCT *)lParam;
+    CREATESTRUCT *createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
     WND *wndPtr = WIN_FindWndPtr(hwnd);
     EDITSTATE *es;
     unsigned int *textPtrs;
@@ -477,6 +477,7 @@
 
     /* store pointer to local or global heap in window structure so that */
     /* EDITSTATE structure itself can be stored on local heap  */
+#if 0
     if (HEAP_LocalFindHeap(createStruct->hInstance)!=NULL)
       (MDESC **)*(LONG *)(wndPtr->wExtra + 2) = 
 	&HEAP_LocalFindHeap(createStruct->hInstance)->free_list;
@@ -486,6 +487,7 @@
 	  GlobalLock(createStruct->hInstance);
 	/* GlobalUnlock(createStruct->hInstance); */
       }
+#endif
     /* allocate space for state variable structure */
     (HANDLE)(*(wndPtr->wExtra)) = EDIT_HeapAlloc(hwnd, sizeof(EDITSTATE));
     es = (EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
@@ -507,21 +509,21 @@
     }
     else
     {
-	if (strlen(createStruct->lpszName) < EditBufLen(wndPtr))
+        char *windowName = (char *)PTR_SEG_TO_LIN( createStruct->lpszName );
+	if (strlen(windowName) < EditBufLen(wndPtr))
 	{
 	    es->textlen = EditBufLen(wndPtr) + 1;
 	    es->hText = EDIT_HeapAlloc(hwnd, EditBufLen(wndPtr) + 2);
 	    text = EDIT_HeapAddr(hwnd, es->hText);
-	    strcpy(text, createStruct->lpszName);
+	    strcpy(text, windowName);
 	    *(text + es->textlen) = '\0';
 	}
 	else
 	{
-	    es->hText = EDIT_HeapAlloc(hwnd, 
-				       strlen(createStruct->lpszName) + 2);
+	    es->hText = EDIT_HeapAlloc(hwnd, strlen(windowName) + 2);
 	    text = EDIT_HeapAddr(hwnd, es->hText);
-	    strcpy(text, createStruct->lpszName);
-	    es->textlen = strlen(createStruct->lpszName) + 1;
+	    strcpy(text, windowName);
+	    es->textlen = strlen(windowName) + 1;
 	}
 	*(text + es->textlen + 1) = '\0';
 	EDIT_BuildTextPointers(hwnd);
@@ -970,10 +972,10 @@
 	    }
 	}
     }
-    else
+    else 
 	EDIT_WriteText(hwnd, lp, off, len, y - es->wtop, rc.left, &rc,
 		       TRUE, FALSE);
-	      
+
     EDIT_HeapFree(hwnd, hLine);
 }
 
@@ -998,7 +1000,7 @@
     HDC hdc;
     HANDLE hStr;
     char *str, *cp, *cp1;
-    int diff, num_spaces, tabwidth, scol;
+    int diff=0, num_spaces, tabwidth, scol;
     HRGN hrgnClip;
     COLORREF oldTextColor, oldBkgdColor;
     HFONT oldfont;
@@ -1010,6 +1012,12 @@
 
     dprintf_edit(stddeb,"EDIT_WriteText lp=%s, off=%d, len=%d, row=%d, col=%d, reverse=%d\n", lp, off, len, row, col, reverse);
 
+    if( off < 0 ) {
+      len += off;
+      col -= off;
+      off = 0;
+    }
+	
     hdc = GetDC(hwnd);
     hStr = EDIT_GetStr(hwnd, lp, off, len, &diff);
     str = (char *)EDIT_HeapAddr(hwnd, hStr);
@@ -1166,7 +1174,7 @@
 	break;
 
     default:
-	if (wParam >= 20 && wParam <= 126)
+	if (wParam >= 20 && wParam <= 254 && wParam != 127 )
 	    EDIT_KeyTyped(hwnd, wParam);
 	break;
     }
@@ -2232,15 +2240,15 @@
     EDITSTATE *es = 
 	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
-    if (strlen((char *)lParam) <= es->MaxTextLen)
+    if (strlen((char *)PTR_SEG_TO_LIN(lParam)) <= es->MaxTextLen)
     {
-	len = ( lParam? strlen((char *)lParam) : 0 );
+	len = ( lParam? strlen((char *)PTR_SEG_TO_LIN(lParam)) : 0 );
 	EDIT_ClearText(hwnd);
 	es->textlen = len;
 	es->hText = EDIT_HeapReAlloc(hwnd, es->hText, len + 3);
 	text = EDIT_HeapAddr(hwnd, es->hText);
 	if (lParam)
-	    strcpy(text, (char *)lParam);
+	    strcpy(text, (char *)PTR_SEG_TO_LIN(lParam));
 	text[len]     = '\0';
 	text[len + 1] = '\0';
 	text[len + 2] = '\0';
@@ -2392,7 +2400,7 @@
 	(unsigned int *)EDIT_HeapAddr(hwnd, es->hTextPtrs);
 
     /* check for (0,0) */
-    if (!off)
+    if (!off || !es->wlines)
     {
 	*line = 0;
 	*col = 0;
@@ -2739,7 +2747,8 @@
 void EDIT_ReplaceSel(HWND hwnd, LONG lParam)
 {
     EDIT_DeleteSel(hwnd);
-    EDIT_InsertText(hwnd, (char *)lParam, strlen((char *)lParam));
+    EDIT_InsertText(hwnd, (char *)PTR_SEG_TO_LIN(lParam),
+                    strlen((char *)PTR_SEG_TO_LIN(lParam)));
     InvalidateRect(hwnd, NULL, TRUE);
     UpdateWindow(hwnd);
 }
@@ -3000,9 +3009,8 @@
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
     unsigned int ret;
-    ret = ((unsigned int)HEAP_Alloc((MDESC **)
-				     *(LONG *)(wndPtr->wExtra + 2), 
-				     GMEM_MOVEABLE, bytes) & 0xffff);
+
+    ret = LOCAL_Alloc( wndPtr->hInstance, LMEM_FIXED, bytes );
     if (ret == 0)
       printf("EDIT_HeapAlloc: Out of heap-memory\n");
     return ret;
@@ -3018,10 +3026,7 @@
 void *EDIT_HeapAddr(HWND hwnd, unsigned int handle)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-
-    return ((void *)((handle) ? ((handle) | ((unsigned int)
-		    (*(MDESC **)*(LONG *)(wndPtr->wExtra + 2))   
-		     & 0xffff0000)) : 0));
+    return handle ? PTR_SEG_OFF_TO_LIN( wndPtr->hInstance, handle ) : 0;
 }
 
 
@@ -3035,10 +3040,7 @@
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
 
-    return ((unsigned int)HEAP_ReAlloc((MDESC **)
-				       *(LONG *)(wndPtr->wExtra + 2), 
-				       EDIT_HeapAddr(hwnd, handle),
-				       bytes, GMEM_MOVEABLE) & 0xffff);
+    return LOCAL_ReAlloc( wndPtr->hInstance, handle, bytes, LMEM_FIXED );
 }
 
 
@@ -3052,8 +3054,7 @@
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
 
-    HEAP_Free((MDESC **)*(LONG *)(wndPtr->wExtra + 2), 
-	      EDIT_HeapAddr(hwnd, handle));
+    LOCAL_Free( wndPtr->hInstance, handle );
 }
 
 
@@ -3067,7 +3068,10 @@
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
 
+#if 0
     return HEAP_LocalSize((MDESC **)*(LONG *)(wndPtr->wExtra + 2), handle);
+#endif
+    return LOCAL_Size( wndPtr->hInstance, handle );
 }
 
 
diff --git a/controls/listbox.c b/controls/listbox.c
index 14bed8f..ebfab3a 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -8,11 +8,12 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include "windows.h"
 #include "user.h"
-#include "heap.h"
 #include "win.h"
 #include "msdos.h"
 #include "listbox.h"
@@ -47,16 +48,24 @@
 	LPHEADLIST lphl, LPLISTSTRUCT lpls);
 int ListBoxFindNextMatch(HWND hwnd, WORD wChar);
 int ListMaxFirstVisible(LPHEADLIST lphl);
+void ListBoxSendNotification(HWND hwnd, WORD code);
 
 #define HasStrings(wndPtr) ( \
   ( ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) != LBS_OWNERDRAWFIXED) && \
     ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) != LBS_OWNERDRAWVARIABLE) ) || \
   ((wndPtr->dwStyle & LBS_HASSTRINGS) == LBS_HASSTRINGS) )
 
+#if 0
 #define LIST_HEAP_ALLOC(lphl,f,size) ((int)HEAP_Alloc(&lphl->Heap,f,size) & 0xffff)
 #define LIST_HEAP_FREE(lphl,handle) (HEAP_Free(&lphl->Heap,LIST_HEAP_ADDR(lphl,handle)))
 #define LIST_HEAP_ADDR(lphl,handle) \
     ((void *)((handle) ? ((handle) | ((int)lphl->Heap & 0xffff0000)) : 0))
+#else
+#define LIST_HEAP_ALLOC(lphl,f,size) USER_HEAP_ALLOC(size)
+#define LIST_HEAP_FREE(lphl,handle)  USER_HEAP_FREE(handle)
+#define LIST_HEAP_ADDR(lphl,handle)  USER_HEAP_LIN_ADDR(handle)
+#endif
+
 #define LIST_HEAP_SIZE 0x10000
 
 /***********************************************************************
@@ -79,7 +88,7 @@
 		lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
 		dprintf_listbox(stddeb,"ListBox WM_CREATE %p !\n", lphl);
 		if (lphl == NULL) return 0;
-		createStruct = (CREATESTRUCT *)lParam;
+		createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
 		if (HIWORD(createStruct->lpCreateParams) != 0)
 			lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams);
 		else
@@ -198,12 +207,10 @@
 		    wRet = ListBoxGetSel(hwnd, y);
 		    ListBoxSetSel(hwnd, y, !wRet);
 		    }
-		else {
+		else
 		    ListBoxSetCurSel(hwnd, y);
-		    if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
-				SendMessage(lphl->hWndLogicParent, WM_COMMAND, 
-	    	    wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
-		    }
+		if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL)
+		  ListBoxSendNotification( hwnd, LBN_SELCHANGE );
 		ListBoxGetItemRect(hwnd, y, &rectsel);
 		InvalidateRect(hwnd, NULL, TRUE);
 		UpdateWindow(hwnd);
@@ -213,8 +220,7 @@
 		lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
 		if (lphl == NULL) return 0;
 		if (lphl->PrevFocused != lphl->ItemFocused)
-			SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu,
-											MAKELONG(hwnd, LBN_SELCHANGE));
+		  ListBoxSendNotification( hwnd, LBN_SELCHANGE );
 		return 0;
 	case WM_RBUTTONUP:
 	case WM_LBUTTONDBLCLK:
@@ -252,13 +258,10 @@
 					wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam));
 					if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
 						lphl->ItemFocused = wRet;
+						ListBoxSendNotification(hwnd, LBN_SELCHANGE);
 						}
-					else {
+					else
 						ListBoxSetCurSel(hwnd, wRet);
-					    if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
-							SendMessage(lphl->hWndLogicParent, WM_COMMAND, 
-				    	    wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
-						}
 					ListBoxGetItemRect(hwnd, wRet, &rectsel);
 					InvalidateRect(hwnd, NULL, TRUE);
 					UpdateWindow(hwnd);
@@ -325,9 +328,7 @@
 		if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
 		if ((wndPtr->dwStyle & LBS_MULTIPLESEL) != LBS_MULTIPLESEL) {
 			ListBoxSetCurSel(hwnd, lphl->ItemFocused);
-		    if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
-				SendMessage(lphl->hWndLogicParent, WM_COMMAND, 
-	    	    wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
+			ListBoxSendNotification(hwnd, LBN_SELCHANGE);
 			}
                 SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
 		InvalidateRect(hwnd, NULL, TRUE);
@@ -376,25 +377,29 @@
 		return 0;
     case LB_DIR:
 		dprintf_listbox(stddeb,"ListBox LB_DIR !\n");
-		wRet = ListBoxDirectory(hwnd, wParam, (LPSTR)lParam);
+		wRet = ListBoxDirectory(hwnd, wParam,
+                                        (LPSTR)PTR_SEG_TO_LIN(lParam));
 		InvalidateRect(hwnd, NULL, TRUE);
 		UpdateWindow(hwnd);
 		return wRet;
 	case LB_ADDSTRING:
-		wRet = ListBoxAddString(hwnd, (LPSTR)lParam);
+		wRet = ListBoxAddString(hwnd, (LPSTR)PTR_SEG_TO_LIN(lParam));
 		return wRet;
 	case LB_GETTEXT:
 		dprintf_listbox(stddeb, "LB_GETTEXT  wParam=%d\n",wParam);
-		wRet = ListBoxGetText(hwnd, wParam, (LPSTR)lParam, FALSE);
+		wRet = ListBoxGetText(hwnd, wParam,
+                                      (LPSTR)PTR_SEG_TO_LIN(lParam), FALSE);
                 return wRet;
 	case LB_INSERTSTRING:
-		wRet = ListBoxInsertString(hwnd, wParam, (LPSTR)lParam);
+		wRet = ListBoxInsertString(hwnd, wParam,
+                                           (LPSTR)PTR_SEG_TO_LIN(lParam));
 		return wRet;
 	case LB_DELETESTRING:
 		wRet = ListBoxDeleteString(hwnd, wParam);
 		return wRet;
 	case LB_FINDSTRING:
-		wRet = ListBoxFindString(hwnd, wParam, (LPSTR)lParam);
+		wRet = ListBoxFindString(hwnd, wParam,
+                                         (LPSTR)PTR_SEG_TO_LIN(lParam));
 		return wRet;
 	case LB_GETCARETINDEX:
 		return wRet;
@@ -410,13 +415,14 @@
 		return wRet;
 	case LB_GETITEMDATA:
 		dprintf_listbox(stddeb, "LB_GETITEMDATA wParam=%x\n", wParam);
-		lRet = ListBoxGetText(hwnd, wParam, (LPSTR)lParam, TRUE);
+		lRet = ListBoxGetText(hwnd, wParam,
+                                      (LPSTR)PTR_SEG_TO_LIN(lParam), TRUE);
 		return lRet;
 	case LB_GETITEMHEIGHT:
                 ListBoxGetItemRect(hwnd, wParam, &rect);
                 return (rect.bottom - rect.top);
 	case LB_GETITEMRECT:
-                ListBoxGetItemRect(hwnd, wParam, (LPRECT)lParam);
+                ListBoxGetItemRect(hwnd,wParam,(LPRECT)PTR_SEG_TO_LIN(lParam));
                 return 0;
 	case LB_GETSEL:
 		wRet = ListBoxGetSel(hwnd, wParam);
@@ -601,6 +607,7 @@
 	HDC 	hdc;
 	RECT 	rect;
 	int     i, h, h2, maxwidth;
+        HANDLE hDrawItemStruct;
 	h = 0;
 	hdc = BeginPaint(hwnd, &ps);
 	if (!IsWindowVisible(hwnd)) {
@@ -621,6 +628,7 @@
 	lpls = lphl->lpFirst;
 	if (lpls == NULL) goto EndOfPaint;
 	lphl->ItemsVisible = 0;
+        hDrawItemStruct = USER_HEAP_ALLOC( sizeof(DRAWITEMSTRUCT) );
 	for (i = 1; i <= lphl->ItemsCount; i++) {
 	    if (i >= lphl->FirstVisible) {
 		lpls->dis.hDC = hdc;
@@ -655,8 +663,10 @@
 			itemData = lpls->dis.itemData;
 			lpls->dis.itemData = (DWORD)lpls->itemText;
 			}
+                memcpy( USER_HEAP_LIN_ADDR(hDrawItemStruct), &lpls->dis,
+                        sizeof(DRAWITEMSTRUCT) );
 		SendMessage(lphl->hWndLogicParent, WM_DRAWITEM, 
-							i-1, (LPARAM)&lpls->dis);
+                            i-1, (LPARAM)USER_HEAP_SEG_ADDR(hDrawItemStruct));
 		if (HasStrings(wndPtr))
 			lpls->dis.itemData = itemData;
 
@@ -667,11 +677,12 @@
 		lphl->ItemsVisible++;
 		/* if (h > rect.bottom) goto EndOfPaint;*/
 		}
-	    if (lpls->lpNext == NULL) goto EndOfPaint;
+	    if (lpls->lpNext == NULL) break;
 	    lpls = (LPLISTSTRUCT)lpls->lpNext;
 	}
+        USER_HEAP_FREE( hDrawItemStruct );
 EndOfPaint:
-    EndPaint( hwnd, &ps );
+        EndPaint( hwnd, &ps );
 }
 
 
@@ -717,8 +728,6 @@
 {
 	WND  *wndPtr;
 	LPHEADLIST lphl;
-	int HeapHandle;
-	void *HeapBase;
 	wndPtr = WIN_FindWndPtr(hwnd);
 	lphl = (LPHEADLIST)malloc(sizeof(HEADLIST));
 	lphl->lpFirst = NULL;
@@ -734,9 +743,11 @@
 	lphl->SelCount = 0;
 	lphl->DrawCtlType = ODT_LISTBOX;
 	lphl->bRedrawFlag = TRUE;
+#if 0
 	HeapHandle = GlobalAlloc(GMEM_FIXED, LIST_HEAP_SIZE);
 	HeapBase = GlobalLock(HeapHandle);
 	HEAP_Init(&lphl->Heap, HeapBase, LIST_HEAP_SIZE);
+#endif
 	return TRUE;
 }
 
@@ -744,8 +755,8 @@
 void ListBoxAskMeasure(WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls)  
 {
 	MEASUREITEMSTRUCT 	*lpmeasure;
-	HANDLE hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(MEASUREITEMSTRUCT));
-	lpmeasure = (MEASUREITEMSTRUCT *) USER_HEAP_ADDR(hTemp);
+	HANDLE hTemp = USER_HEAP_ALLOC( sizeof(MEASUREITEMSTRUCT) );
+	lpmeasure = (MEASUREITEMSTRUCT *) USER_HEAP_LIN_ADDR(hTemp);
 	if (lpmeasure == NULL) {
 		fprintf(stderr,"ListBoxAskMeasure() // Bad allocation of Measure struct !\n");
 		return;
@@ -759,7 +770,8 @@
 		lpmeasure->itemData = (DWORD)lpls->itemText;
 	else
 		lpmeasure->itemData = lpls->dis.itemData;
-	SendMessage(lphl->hWndLogicParent, WM_MEASUREITEM, 0, (DWORD)lpmeasure);
+	SendMessage(lphl->hWndLogicParent, WM_MEASUREITEM,
+                    0, USER_HEAP_SEG_ADDR(hTemp));
 	lpls->dis.rcItem.right = lpls->dis.rcItem.left + lpmeasure->itemWidth;
 	lpls->dis.rcItem.bottom = lpls->dis.rcItem.top + lpmeasure->itemHeight;
 	USER_HEAP_FREE(hTemp);			
@@ -1002,9 +1014,6 @@
     lphl->ItemsCount = 0;
     lphl->ItemFocused = -1;
     lphl->PrevFocused = -1;
-    if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
-	SendMessage(lphl->hWndLogicParent, WM_COMMAND, 
-    	    wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
     SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE);
     if (lphl->ItemsPerColumn != 0)
 	SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / 
@@ -1023,6 +1032,8 @@
     UINT	i;
     lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
     if (lphl == NULL) return LB_ERR;
+    if( (wIndex != (WORD)(-1)) && (wIndex > lphl->ItemsCount) )
+      return LB_ERR;
     lphl->ItemFocused = LB_ERR; 
     if (wIndex >= lphl->ItemsCount) return LB_ERR;
     lpls = lphl->lpFirst;
@@ -1038,10 +1049,7 @@
 	if (lpls == NULL)  break;
     }
     lphl->ItemFocused = wIndex;
-    if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
-	SendMessage(lphl->hWndLogicParent, WM_COMMAND, 
-    	    wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
-    return LB_ERR;
+    return wIndex;
 }
 
 
@@ -1093,57 +1101,85 @@
 
 int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec)
 {
-	struct dosdirent *dp;
-	int	x, wRet = LB_OKAY;
-	BOOL    OldFlag;
-	char 	temp[256];
-    LPHEADLIST 	lphl;
-	dprintf_listbox(stddeb,"ListBoxDirectory: %s, %4x\n",filespec,attrib);
-    lphl = ListBoxGetStorageHeader(hwnd);
-    if (lphl == NULL) return LB_ERR;
-	if ((dp = (struct dosdirent *)DOS_opendir(filespec)) ==NULL) return 0;
-	OldFlag = lphl->bRedrawFlag;
-	lphl->bRedrawFlag = FALSE;
-	while ((dp = (struct dosdirent *)DOS_readdir(dp))) {
-		if (!dp->inuse) break;
-		dprintf_listbox(stddeb,"ListBoxDirectory %p '%s' !\n", dp->filename, dp->filename);
-		if (dp->attribute & FA_DIREC) {
-			if (attrib & DDL_DIRECTORY &&
-					strcmp(dp->filename, ".")) {
-				sprintf(temp, "[%s]", dp->filename);
-				if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) break;
-				}
-			} 
-		else {
-			if (attrib & DDL_EXCLUSIVE) {
-				if (attrib & (DDL_READWRITE | DDL_READONLY | DDL_HIDDEN | 
-					    DDL_SYSTEM) )
-					if ( (wRet = ListBoxAddString(hwnd, dp->filename)) 
-					    == LB_ERR) break;
-				} 
-			else {
-				if ( (wRet = ListBoxAddString(hwnd, dp->filename)) 
-					== LB_ERR) break;
-				}
-			}
-		}
-	DOS_closedir(dp);
+  struct dosdirent *dp, *dp_old;
+  int	x, wRet = LB_OKAY;
+  BOOL    OldFlag;
+  char 	temp[256];
+  LPHEADLIST 	lphl;
+  int drive;
 
-	if (attrib & DDL_DRIVES) {
-		for (x=0;x!=MAX_DOS_DRIVES;x++) {
-			if (DOS_ValidDrive(x)) {
-				sprintf(temp, "[-%c-]", 'a'+x);
-				if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) break;
-				}		
-			}
-		}
-	lphl->bRedrawFlag = OldFlag;
-	if (OldFlag) {
-		InvalidateRect(hwnd, NULL, TRUE);
-		UpdateWindow(hwnd);
-		}
-	dprintf_listbox(stddeb,"End of ListBoxDirectory !\n");
-	return wRet;
+  dprintf_listbox(stddeb,"ListBoxDirectory: %s, %4x\n",filespec,attrib);
+
+  if( strchr( filespec, '\\' ) || strchr( filespec, ':' ) ) {
+    drive = DOS_GetDefaultDrive();
+    if( filespec[1] == ':' ) {
+      drive = toupper(filespec[0]) - 'A';
+      filespec += 2;
+    }
+    if( !strchr( filespec, '\\' ) ) 
+      DOS_SetDefaultDrive( drive );
+    else {
+      int i;
+      strcpy( temp, filespec );
+      for( i=0; i<strlen(temp); i++ )
+	if( temp[i] == '\\' ) {
+	  temp[i] = 0;
+	  filespec += ( i+1 );
+	  break;
+	}
+      DOS_ChangeDir( drive, temp );
+      DOS_SetDefaultDrive( drive );
+    }
+    dprintf_listbox(stddeb,"Changing directory to %c:%s, filemask is %s\n",
+		    drive+'A', temp, filespec );
+  }
+  lphl = ListBoxGetStorageHeader(hwnd);
+  if (lphl == NULL) return LB_ERR;
+  if ((dp = (struct dosdirent *)DOS_opendir(filespec)) ==NULL) return 0;
+  dp_old = dp;
+  OldFlag = lphl->bRedrawFlag;
+  lphl->bRedrawFlag = FALSE;
+  while ((dp = (struct dosdirent *)DOS_readdir(dp))) {
+    if (!dp->inuse) break;
+    dprintf_listbox( stddeb, "ListBoxDirectory %p '%s' !\n", dp->filename, 
+		    dp->filename);
+    if (dp->attribute & FA_DIREC) {
+      if (attrib & DDL_DIRECTORY &&
+	  strcmp(dp->filename, ".")) {
+	sprintf(temp, "[%s]", dp->filename);
+	if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) break;
+      }
+    } 
+    else {
+      if (attrib & DDL_EXCLUSIVE) {
+	if (attrib & (DDL_READWRITE | DDL_READONLY | DDL_HIDDEN | 
+		      DDL_SYSTEM) )
+	  if ( (wRet = ListBoxAddString(hwnd, dp->filename)) 
+	      == LB_ERR) break;
+      } 
+      else {
+	if ( (wRet = ListBoxAddString(hwnd, dp->filename)) 
+	    == LB_ERR) break;
+      }
+    }
+  }
+  DOS_closedir(dp_old);
+  
+  if (attrib & DDL_DRIVES) {
+    for (x=0;x!=MAX_DOS_DRIVES;x++) {
+      if (DOS_ValidDrive(x)) {
+	sprintf(temp, "[-%c-]", 'a'+x);
+	if((wRet = ListBoxInsertString(hwnd, (UINT)-1, temp)) == LB_ERR) break;
+      }		
+    }
+  }
+  lphl->bRedrawFlag = OldFlag;
+  if (OldFlag) {
+    InvalidateRect(hwnd, NULL, TRUE);
+    UpdateWindow(hwnd);
+  }
+  dprintf_listbox(stddeb,"End of ListBoxDirectory !\n");
+  return 1;  /* FIXME: Should be 0 if "filespec" is invalid */
 }
 
 
@@ -1290,8 +1326,40 @@
  */
 BOOL DlgDirSelect(HWND hDlg, LPSTR lpStr, int nIDLBox)
 {
-	fprintf(stdnimp,"DlgDirSelect(%04X, '%s', %d) \n", hDlg, lpStr, nIDLBox);
-	return FALSE;
+  HWND hwnd;
+  LPHEADLIST lphl;
+  char s[130];
+
+  dprintf_listbox( stddeb, "DlgDirSelect(%04X, '%s', %d) \n", hDlg, lpStr, 
+		  nIDLBox );
+
+  hwnd = GetDlgItem(hDlg, nIDLBox);
+  lphl = ListBoxGetStorageHeader(hwnd);
+  if( lphl->ItemFocused == -1 ) {
+    dprintf_listbox( stddeb, "Nothing selected!\n" );
+    return FALSE;
+  }
+  ListBoxGetText(hwnd, lphl->ItemFocused, (LPSTR)s, FALSE);
+  dprintf_listbox( stddeb, "Selection is %s\n", s );
+  if( s[0] == '[' ) {
+    if( s[1] == '-' ) {
+      strncpy( lpStr, s+2, strlen(s)-4 );    /* device name */
+      lpStr[ strlen(s)-4 ] = 0;
+      strcat( lpStr, ":" );
+    }
+    else {
+      strncpy( lpStr, s+1, strlen(s)-2 );    /* directory name */
+      lpStr[ strlen(s)-2 ] = 0;
+      strcat( lpStr, "\\" );
+    }
+    dprintf_listbox( stddeb, "Returning %s\n", lpStr );
+    return TRUE;
+  }
+  else {
+    strcpy( lpStr, s );                     /* file name */
+    dprintf_listbox( stddeb, "Returning %s\n", lpStr );
+    return FALSE;
+  }
 }
 
 
@@ -1318,9 +1386,20 @@
 	if (nIDStat)
 	  {
 	    int drive;
+	    char temp[255];
 	    drive = DOS_GetDefaultDrive();
-	    SendDlgItemMessage(hDlg, nIDStat, WM_SETTEXT, 0, 
-			       (LONG) DOS_GetCurrentDir(drive) );
+	    strcpy( temp+3, DOS_GetCurrentDir(drive) );
+	    if( temp[3] == '\\' ) {
+	      temp[1] = 'A'+drive;
+	      temp[2] = ':';
+	      SendDlgItemMessage(hDlg, nIDStat, WM_SETTEXT, 0, (LONG)(temp+1));
+	    }
+	    else {
+	      temp[0] = 'A'+drive;
+	      temp[1] = ':';
+	      temp[2] = '\\';
+	      SendDlgItemMessage(hDlg, nIDStat, WM_SETTEXT, 0, (LONG) temp );
+	    }
 	  } 
 	return ret;
 }
@@ -1331,3 +1410,16 @@
     int m = lphl->ItemsCount-lphl->ItemsVisible+1;
     return (m < 1) ? 1 : m;
 }
+
+
+/* Send notification "code" as part of a WM_COMMAND-message if hwnd
+   has the LBS_NOTIFY style */
+void ListBoxSendNotification(HWND hwnd, WORD code)
+{
+  WND  *wndPtr;
+  LPHEADLIST  lphl;
+  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
+  if( wndPtr && ( (wndPtr->dwStyle && LBS_NOTIFY) != 0) )
+    SendMessage(lphl->hWndLogicParent, WM_COMMAND,
+		wndPtr->wIDmenu, MAKELONG(hwnd, code));
+} 
diff --git a/controls/menu.c b/controls/menu.c
index bfe0fbf..ac118e9 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -141,8 +141,8 @@
     MENUITEM *item;
     int i;
 
-    if (!(menu = (POPUPMENU *) USER_HEAP_ADDR(*hmenu))) return NULL;
-    item = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+    if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR(*hmenu))) return NULL;
+    item = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
     if (wFlags & MF_BYPOSITION)
     {
 	if (*nPos >= menu->nItems) return NULL;
@@ -187,7 +187,7 @@
     if (!(wndPtr = WIN_FindWndPtr( menu->hWnd ))) return NULL;
     x -= wndPtr->rectWindow.left;
     y -= wndPtr->rectWindow.top;
-    item = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+    item = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
     for (i = 0; i < menu->nItems; i++, item++)
     {
 	if ((x >= item->rect.left) && (x < item->rect.right) &&
@@ -214,8 +214,8 @@
     int i;
     LONG menuchar;
 
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
-    lpitem = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
+    lpitem = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
     key = toupper(key);
     for (i = 0; i < menu->nItems; i++, lpitem++)
     {
@@ -308,7 +308,7 @@
 
     lppop->Width = lppop->Height = 0;
     if (lppop->nItems == 0) return;
-    items = (MENUITEM *)USER_HEAP_ADDR( lppop->hItems );
+    items = (MENUITEM *)USER_HEAP_LIN_ADDR( lppop->hItems );
     hdc = GetDC( 0 );
     maxX = start = 0;
     while (start < lppop->nItems)
@@ -363,7 +363,7 @@
     if (lppop->nItems == 0) return;
 	dprintf_menucalc(stddeb,"MenuBarCalcSize left=%d top=%d right=%d bottom=%d !\n", 
 		lprect->left, lprect->top, lprect->right, lprect->bottom);
-    items = (MENUITEM *)USER_HEAP_ADDR( lppop->hItems );
+    items = (MENUITEM *)USER_HEAP_LIN_ADDR( lppop->hItems );
     lppop->Width  = lprect->right - lprect->left;
     lppop->Height = 0;
     maxY = lprect->top;
@@ -562,9 +562,9 @@
 
     GetClientRect( hwnd, &rect );
     FillRect( hdc, &rect, sysColorObjects.hbrushMenu );
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     if (!menu || !menu->nItems) return;
-    item = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+    item = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
     for (i = menu->nItems; i > 0; i--, item++)
 	MENU_DrawMenuItem( hdc, item, menu->Height, FALSE );
 }
@@ -582,7 +582,7 @@
     int i;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     
-    lppop = (LPPOPUPMENU) USER_HEAP_ADDR( wndPtr->wIDmenu );
+    lppop = (LPPOPUPMENU) USER_HEAP_LIN_ADDR( wndPtr->wIDmenu );
     if (lppop == NULL || lprect == NULL) return SYSMETRICS_CYMENU;
     dprintf_menu(stddeb,"MENU_DrawMenuBar(%04X, %p, %p); !\n", 
 		 hDC, lprect, lppop);
@@ -596,7 +596,7 @@
     LineTo( hDC, lprect->right, lprect->bottom );
 
     if (lppop->nItems == 0) return SYSMETRICS_CYMENU;
-    lpitem = (MENUITEM *) USER_HEAP_ADDR( lppop->hItems );
+    lpitem = (MENUITEM *) USER_HEAP_LIN_ADDR( lppop->hItems );
     for (i = 0; i < lppop->nItems; i++, lpitem++)
     {
 	MENU_DrawMenuItem( hDC, lpitem, lppop->Height, TRUE );
@@ -614,10 +614,10 @@
 {
     POPUPMENU *menu;
 
-    if (!(menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu ))) return FALSE;
+    if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu ))) return FALSE;
     if (menu->FocusedItem != NO_SELECTED_ITEM)
     {
-	MENUITEM *item = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+	MENUITEM *item = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
 	item[menu->FocusedItem].item_flags &= ~(MF_HILITE | MF_MOUSESELECT);
 	menu->FocusedItem = NO_SELECTED_ITEM;
     }
@@ -632,8 +632,7 @@
 				   WS_POPUP | WS_BORDER, x, y, 
 				   menu->Width + 2*SYSMETRICS_CXBORDER,
 				   menu->Height + 2*SYSMETRICS_CYBORDER,
-				   0, 0, wndPtr->hInstance,
-				   (LPSTR)(DWORD)hmenu );
+				   0, 0, wndPtr->hInstance, (SEGPTR)hmenu );
 	if (!menu->hWnd) return FALSE;
     }
     else SetWindowPos( menu->hWnd, 0, x, y,
@@ -659,9 +658,9 @@
     LPPOPUPMENU lppop;
     HDC hdc;
 
-    lppop = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    lppop = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     if (!lppop->nItems) return;
-    items = (MENUITEM *) USER_HEAP_ADDR( lppop->hItems );
+    items = (MENUITEM *) USER_HEAP_LIN_ADDR( lppop->hItems );
     if ((wIndex != NO_SELECTED_ITEM) && 
 	(wIndex != SYSMENU_SELECTED) &&
 	(items[wIndex].item_flags & MF_SEPARATOR))
@@ -712,9 +711,9 @@
     MENUITEM *items;
     POPUPMENU *menu;
 
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     if (!menu->nItems) return;
-    items = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+    items = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
     if ((menu->FocusedItem != NO_SELECTED_ITEM) &&
 	(menu->FocusedItem != SYSMENU_SELECTED))
     {
@@ -753,9 +752,9 @@
     MENUITEM *items;
     POPUPMENU *menu;
 
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     if (!menu->nItems) return;
-    items = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+    items = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
     if ((menu->FocusedItem != NO_SELECTED_ITEM) &&
 	(menu->FocusedItem != SYSMENU_SELECTED))
     {
@@ -795,12 +794,12 @@
     POPUPMENU *menu;
     MENUITEM *item;
 
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     if (menu->FocusedItem == NO_SELECTED_ITEM) return 0;
     else if (menu->FocusedItem == SYSMENU_SELECTED)
 	return GetSystemMenu( menu->hWnd, FALSE );
 
-    item = ((MENUITEM *)USER_HEAP_ADDR( menu->hItems )) + menu->FocusedItem;
+    item = ((MENUITEM *)USER_HEAP_LIN_ADDR(menu->hItems)) + menu->FocusedItem;
     if (!(item->item_flags & MF_POPUP) || !(item->item_flags & MF_MOUSESELECT))
 	return 0;
     return item->item_id;
@@ -818,7 +817,7 @@
     POPUPMENU *menu, *submenu;
     HMENU hsubmenu;
 
-    if (!(menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu ))) return;
+    if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu ))) return;
     if (menu->FocusedItem == NO_SELECTED_ITEM) return;
     if (menu->FocusedItem == SYSMENU_SELECTED)
     {
@@ -826,13 +825,13 @@
     }
     else
     {
-	item = ((MENUITEM *)USER_HEAP_ADDR(menu->hItems)) + menu->FocusedItem;
+	item = ((MENUITEM *)USER_HEAP_LIN_ADDR(menu->hItems)) + menu->FocusedItem;
 	if (!(item->item_flags & MF_POPUP) ||
 	    !(item->item_flags & MF_MOUSESELECT)) return;
 	item->item_flags &= ~MF_MOUSESELECT;
 	hsubmenu = item->item_id;
     }
-    submenu = (POPUPMENU *) USER_HEAP_ADDR( hsubmenu );
+    submenu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hsubmenu );
     MENU_HideSubPopups( hsubmenu );
     if (submenu->hWnd) ShowWindow( submenu->hWnd, SW_HIDE );
     MENU_SelectItem( hsubmenu, NO_SELECTED_ITEM );
@@ -851,7 +850,7 @@
     MENUITEM *item;
     WND *wndPtr;
 
-    if (!(menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu ))) return hmenu;
+    if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu ))) return hmenu;
     if (!(wndPtr = WIN_FindWndPtr( menu->hWnd ))) return hmenu;
     if (menu->FocusedItem == NO_SELECTED_ITEM) return hmenu;
     if (menu->FocusedItem == SYSMENU_SELECTED)
@@ -861,7 +860,7 @@
 	if (selectFirst) MENU_SelectNextItem( wndPtr->hSysMenu );
 	return wndPtr->hSysMenu;
     }
-    item = ((MENUITEM *)USER_HEAP_ADDR( menu->hItems )) + menu->FocusedItem;
+    item = ((MENUITEM *)USER_HEAP_LIN_ADDR(menu->hItems)) + menu->FocusedItem;
     if (!(item->item_flags & MF_POPUP) ||
 	(item->item_flags & (MF_GRAYED | MF_DISABLED))) return hmenu;
     item->item_flags |= MF_MOUSESELECT;
@@ -895,7 +894,7 @@
     if (!(hwnd = WindowFromPoint( pt ))) return 0;
     while (hmenu)
     {
-	menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+	menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
 	if (menu->hWnd == hwnd)
 	{
 	    if (!(menu->wFlags & MF_POPUP))
@@ -929,10 +928,10 @@
 				  HMENU *hmenuCurrent )
 {
     MENUITEM *item;
-    POPUPMENU *menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    POPUPMENU *menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     if (!menu || !menu->nItems || (menu->FocusedItem == NO_SELECTED_ITEM) ||
 	(menu->FocusedItem == SYSMENU_SELECTED)) return TRUE;
-    item = ((MENUITEM *)USER_HEAP_ADDR( menu->hItems )) + menu->FocusedItem;
+    item = ((MENUITEM *)USER_HEAP_LIN_ADDR(menu->hItems)) + menu->FocusedItem;
     if (!(item->item_flags & MF_POPUP))
     {
 	if (!(item->item_flags & (MF_GRAYED | MF_DISABLED)))
@@ -966,7 +965,7 @@
     WORD id;
 
     if (!hmenu) return FALSE;  /* Outside all menus */
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     item = MENU_FindItemByCoords( menu, pt.x, pt.y, &id );
     if (!item)  /* Maybe in system menu */
     {
@@ -1017,7 +1016,7 @@
     WORD id;
 
     if (!hmenu) return FALSE;  /* Outside all menus */
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     item = MENU_FindItemByCoords( menu, pt.x, pt.y, &id );
     if (!item)  /* Maybe in system menu */
     {
@@ -1054,7 +1053,7 @@
 			    POINT pt )
 {
     MENUITEM *item;
-    POPUPMENU *menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    POPUPMENU *menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     WORD id = NO_SELECTED_ITEM;
 
     if (hmenu)
@@ -1092,7 +1091,7 @@
     POPUPMENU *menu;
     HMENU hmenutmp, hmenuprev;
 
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     hmenuprev = hmenutmp = hmenu;
     while (hmenutmp != *hmenuCurrent)
     {
@@ -1126,7 +1125,7 @@
     POPUPMENU *menu;
     HMENU hmenutmp;
 
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
 
     if ((menu->wFlags & MF_POPUP) || (*hmenuCurrent != hmenu))
     {
@@ -1175,32 +1174,36 @@
 static BOOL MENU_TrackMenu( HMENU hmenu, WORD wFlags, int x, int y,
 			    HWND hwnd, LPRECT lprect )
 {
-    MSG msg;
+    MSG *msg;
+    HLOCAL hMsg;
     POPUPMENU *menu;
     HMENU hmenuCurrent = hmenu;
-    BOOL fClosed = FALSE;
+    BOOL fClosed = FALSE, fRemove;
     WORD pos;
 
     fEndMenuCalled = FALSE;
-    if (!(menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu ))) return FALSE;
+    if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu ))) return FALSE;
     if (x && y)
     {
 	POINT pt = { x, y };
 	MENU_ButtonDown( hwnd, hmenu, &hmenuCurrent, pt );
     }
     SetCapture( hwnd );
-
+    hMsg = USER_HEAP_ALLOC( sizeof(MSG) );
+    msg = (MSG *)USER_HEAP_LIN_ADDR( hMsg );
     while (!fClosed)
     {
-	if (!MSG_InternalGetMessage( &msg, 0, hwnd, MSGF_MENU, 0, TRUE ))
+	if (!MSG_InternalGetMessage( USER_HEAP_SEG_ADDR(hMsg), 0,
+                                     hwnd, MSGF_MENU, 0, TRUE ))
 	    break;
 
-	if ((msg.message >= WM_MOUSEFIRST) && (msg.message <= WM_MOUSELAST))
+        fRemove = FALSE;
+	if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
 	{
 	      /* Find the sub-popup for this mouse event (if any) */
-	    HMENU hsubmenu = MENU_FindMenuByCoords( hmenu, msg.pt );
+	    HMENU hsubmenu = MENU_FindMenuByCoords( hmenu, msg->pt );
 
-	    switch(msg.message)
+	    switch(msg->message)
 	    {
 	    case WM_RBUTTONDOWN:
 	    case WM_NCRBUTTONDOWN:
@@ -1209,7 +1212,7 @@
 	    case WM_LBUTTONDOWN:
 	    case WM_NCLBUTTONDOWN:
 		fClosed = !MENU_ButtonDown( hwnd, hsubmenu,
-					    &hmenuCurrent, msg.pt );
+					    &hmenuCurrent, msg->pt );
 		break;
 		
 	    case WM_RBUTTONUP:
@@ -1219,28 +1222,30 @@
 	    case WM_LBUTTONUP:
 	    case WM_NCLBUTTONUP:
 		  /* If outside all menus but inside lprect, ignore it */
-		if (!hsubmenu && lprect && PtInRect( lprect, msg.pt )) break;
+		if (!hsubmenu && lprect && PtInRect( lprect, msg->pt )) break;
 		fClosed = !MENU_ButtonUp( hwnd, hsubmenu,
-					  &hmenuCurrent, msg.pt );
+					  &hmenuCurrent, msg->pt );
+                fRemove = TRUE;  /* Remove event even if outside menu */
 		break;
 		
 	    case WM_MOUSEMOVE:
 	    case WM_NCMOUSEMOVE:
-		if ((msg.wParam & MK_LBUTTON) ||
-		    ((wFlags & TPM_RIGHTBUTTON) && (msg.wParam & MK_RBUTTON)))
+		if ((msg->wParam & MK_LBUTTON) ||
+		    ((wFlags & TPM_RIGHTBUTTON) && (msg->wParam & MK_RBUTTON)))
 		{
 		    fClosed = !MENU_MouseMove( hwnd, hsubmenu,
-					       &hmenuCurrent, msg.pt );
+					       &hmenuCurrent, msg->pt );
 		}
 		break;
 	    }
 	}
-	else if ((msg.message >= WM_KEYFIRST) && (msg.message <= WM_KEYLAST))
+	else if ((msg->message >= WM_KEYFIRST) && (msg->message <= WM_KEYLAST))
 	{
-	    switch(msg.message)
+            fRemove = TRUE;  /* Keyboard messages are always removed */
+	    switch(msg->message)
 	    {
 	    case WM_KEYDOWN:
-		switch(msg.wParam)
+		switch(msg->wParam)
 		{
 		case VK_HOME:
 		    MENU_SelectItem( hmenuCurrent, NO_SELECTED_ITEM );
@@ -1288,7 +1293,7 @@
 		break;  /* WM_KEYDOWN */
 
 	    case WM_SYSKEYDOWN:
-		switch(msg.wParam)
+		switch(msg->wParam)
 		{
 		case VK_MENU:
 		    fClosed = TRUE;
@@ -1301,8 +1306,8 @@
 		{
 		      /* Hack to avoid control chars. */
 		      /* We will find a better way real soon... */
-		    if ((msg.wParam <= 32) || (msg.wParam >= 127)) break;
-		    pos = MENU_FindItemByKey( hwnd, hmenuCurrent, msg.wParam );
+		    if ((msg->wParam <= 32) || (msg->wParam >= 127)) break;
+		    pos = MENU_FindItemByKey( hwnd, hmenuCurrent, msg->wParam );
 		    if (pos == (WORD)-2) fClosed = TRUE;
 		    else if (pos == (WORD)-1) MessageBeep(0);
 		    else
@@ -1314,17 +1319,19 @@
 		    }
 		}		    
 		break;  /* WM_CHAR */
-	    }  /* switch(msg.message) */
+	    }  /* switch(msg->message) */
 	}
 	else
 	{
-	    DispatchMessage( &msg );
+	    DispatchMessage( msg );
 	}
 	if (fEndMenuCalled) fClosed = TRUE;
+	if (!fClosed) fRemove = TRUE;
 
-	if (!fClosed)  /* Remove the message from the queue */
-	    PeekMessage( &msg, 0, 0, 0, PM_REMOVE );
+        if (fRemove)  /* Remove the message from the queue */
+	    PeekMessage( msg, 0, msg->message, msg->message, PM_REMOVE );
     }
+    USER_HEAP_FREE( hMsg );
     ReleaseCapture();
     MENU_HideSubPopups( hmenu );
     if (menu->wFlags & MF_POPUP) ShowWindow( menu->hWnd, SW_HIDE );
@@ -1388,7 +1395,7 @@
     {
     case WM_CREATE:
 	{
-	    CREATESTRUCT *createStruct = (CREATESTRUCT *)lParam;
+	    CREATESTRUCT *createStruct = (CREATESTRUCT*)PTR_SEG_TO_LIN(lParam);
 	    HMENU hmenu = (HMENU) ((int)createStruct->lpCreateParams & 0xffff);
 	    SetWindowWord( hwnd, 0, hmenu );
 	    return 0;
@@ -1427,7 +1434,7 @@
     LPPOPUPMENU lppop;
 
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
-    if (!(lppop = (LPPOPUPMENU)USER_HEAP_ADDR( wndPtr->wIDmenu ))) return 0;
+    if (!(lppop = (LPPOPUPMENU)USER_HEAP_LIN_ADDR(wndPtr->wIDmenu))) return 0;
     hdc = GetDC( hwnd );
     SetRect( &rectBar, orgX, orgY, orgX+menubarWidth, orgY+SYSMETRICS_CYMENU );
     MENU_MenuBarCalcSize( hdc, &rectBar, lppop, hwnd );
@@ -1442,17 +1449,18 @@
 BOOL ChangeMenu(HMENU hMenu, WORD nPos, LPSTR lpNewItem, 
 			WORD wItemID, WORD wFlags)
 {
+	dprintf_menu(stddeb,"ChangeMenu(%04X, %X, '%s', %X, %X)\n",
+		hMenu, nPos, lpNewItem, wItemID, wFlags);
 	if (wFlags & MF_APPEND)
 		return AppendMenu(hMenu, wFlags, wItemID, lpNewItem);
 	if (wFlags & MF_DELETE)
 		return DeleteMenu(hMenu, wItemID, wFlags);
-	if (wFlags & MF_INSERT) 
-		return InsertMenu(hMenu, nPos, wFlags, wItemID, lpNewItem);
 	if (wFlags & MF_CHANGE) 
 		return ModifyMenu(hMenu, nPos, wFlags, wItemID, lpNewItem);
 	if (wFlags & MF_REMOVE) 
 		return RemoveMenu(hMenu, wItemID, wFlags);
-	return FALSE;
+	/* Default: MF_INSERT */
+	return InsertMenu(hMenu, nPos, wFlags, wItemID, lpNewItem);
 }
 
 
@@ -1534,7 +1542,7 @@
     dprintf_menu(stddeb,"HiliteMenuItem(%04X, %04X, %04X, %04X);\n", 
 						hWnd, hMenu, wItemID, wHilite);
     if (!(lpitem = MENU_FindItem( &hMenu, &wItemID, wHilite ))) return FALSE;
-    if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return FALSE;
+    if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return FALSE;
     if (menu->FocusedItem == wItemID) return TRUE;
     MENU_HideSubPopups( hMenu );
     MENU_SelectItem( hMenu, wItemID );
@@ -1553,7 +1561,7 @@
     if (!(lpitem = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return -1;
     if (lpitem->item_flags & MF_POPUP)
     {
-	POPUPMENU *menu = (POPUPMENU *) USER_HEAP_ADDR( lpitem->item_id );
+	POPUPMENU *menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( lpitem->item_id );
 	if (!menu) return -1;
 	else return (menu->nItems << 8) | (menu->wFlags & 0xff);
     }
@@ -1568,7 +1576,7 @@
 {
 	LPPOPUPMENU	menu;
 	dprintf_menu(stddeb,"GetMenuItemCount(%04X);\n", hMenu);
-	menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu);
+	menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu);
 	if (menu == NULL) return (WORD)-1;
 	dprintf_menu(stddeb,"GetMenuItemCount(%04X) return %d \n", 
 		     hMenu, menu->nItems);
@@ -1585,9 +1593,9 @@
     MENUITEM *item;
 
     dprintf_menu(stddeb,"GetMenuItemID(%04X, %d);\n", hMenu, nPos);
-    if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return -1;
+    if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return -1;
     if ((nPos < 0) || (nPos >= menu->nItems)) return -1;
-    item = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+    item = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
     if (item[nPos].item_flags & MF_POPUP) return -1;
     return item[nPos].item_id;
 }
@@ -1613,28 +1621,45 @@
 
       /* Find where to insert new item */
 
-    if ((wFlags & MF_BYPOSITION) && (nPos == (WORD)-1))
+    if ((wFlags & MF_BYPOSITION) && 
+        ((nPos == (WORD)-1) || (nPos == GetMenuItemCount(hMenu))))
     {
-	  /* Special case: append to menu */
-	if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return FALSE;
-	nPos = menu->nItems;
+          /* Special case: append to menu 
+             Some programs specify the menu length to do that */
+        if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) 
+        {
+            dprintf_menu(stddeb,"InsertMenu: %04X not a menu handle\n", hMenu);
+            return FALSE;
+        }
+        nPos = menu->nItems;
     }
     else
     {
-	if (!MENU_FindItem( &hMenu, &nPos, wFlags )) return FALSE;
-	if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return FALSE;
+        if (!MENU_FindItem( &hMenu, &nPos, wFlags )) 
+        {
+            dprintf_menu(stddeb,"InsertMenu: Item %X not found\n", nPos);
+            return FALSE;
+        }
+        if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu)))
+        {
+            dprintf_menu(stddeb,"InsertMenu: %04X not a menu handle\n", hMenu);
+            return FALSE;
+        }
     }
 
       /* Create new items array */
 
-    hNewItems = USER_HEAP_ALLOC( GMEM_MOVEABLE,
-				 sizeof(MENUITEM) * (menu->nItems+1) );
-    if (!hNewItems) return FALSE;
-    newItems = (MENUITEM *) USER_HEAP_ADDR( hNewItems );
+    hNewItems = USER_HEAP_ALLOC( sizeof(MENUITEM) * (menu->nItems+1) );
+    if (!hNewItems)
+    {
+        dprintf_menu(stddeb,"InsertMenu: allocation failed\n");
+        return FALSE;
+    }
+    newItems = (MENUITEM *) USER_HEAP_LIN_ADDR( hNewItems );
     if (menu->nItems > 0)
     {
 	  /* Copy the old array into the new */
-	MENUITEM *oldItems = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+	MENUITEM *oldItems = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
 	if (nPos > 0) memcpy( newItems, oldItems, nPos * sizeof(MENUITEM) );
 	if (nPos < menu->nItems) memcpy( &newItems[nPos+1], &oldItems[nPos],
 					(menu->nItems-nPos)*sizeof(MENUITEM) );
@@ -1658,15 +1683,15 @@
 	    lpitem->item_flags |= MF_HELP;
 	    lpNewItem++;
 	}
-	lpitem->hText = USER_HEAP_ALLOC( GMEM_MOVEABLE, strlen(lpNewItem)+1 );
-	lpitem->item_text = (char *)USER_HEAP_ADDR( lpitem->hText );
+	lpitem->hText = USER_HEAP_ALLOC( strlen(lpNewItem)+1 );
+	lpitem->item_text = (char *)USER_HEAP_LIN_ADDR( lpitem->hText );
 	strcpy( lpitem->item_text, lpNewItem );
     }
     else if (wFlags & MF_BITMAP) lpitem->hText = LOWORD((DWORD)lpNewItem);
     else lpitem->item_text = lpNewItem;
 
     if (wFlags & MF_POPUP)  /* Set the MF_POPUP flag on the popup-menu */
-	((POPUPMENU *)USER_HEAP_ADDR(wItemID))->wFlags |= MF_POPUP;
+	((POPUPMENU *)USER_HEAP_LIN_ADDR(wItemID))->wFlags |= MF_POPUP;
 
     SetRectEmpty( &lpitem->rect );
     lpitem->hCheckBit   = hStdCheck;
@@ -1694,7 +1719,7 @@
 	dprintf_menu(stddeb,"RemoveMenu (%04X, %04X, %04X) !\n", 
 		     hMenu, nPos, wFlags);
     if (!(lpitem = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE;
-    if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return FALSE;
+    if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return FALSE;
     
       /* Remove item */
 
@@ -1713,8 +1738,7 @@
 	    nPos++;
 	}
 	menu->hItems = USER_HEAP_REALLOC( menu->hItems,
-					  menu->nItems * sizeof(MENUITEM),
-					  GMEM_MOVEABLE );
+					  menu->nItems * sizeof(MENUITEM) );
     }
     return TRUE;
 }
@@ -1754,8 +1778,8 @@
 
     if (IS_STRING_ITEM(wFlags))
     {
-	lpitem->hText = USER_HEAP_ALLOC( GMEM_MOVEABLE, strlen(lpNewItem)+1 );
-	lpitem->item_text = (char *)USER_HEAP_ADDR( lpitem->hText );
+	lpitem->hText = USER_HEAP_ALLOC( strlen(lpNewItem)+1 );
+	lpitem->item_text = (char *)USER_HEAP_LIN_ADDR( lpitem->hText );
 	strcpy( lpitem->item_text, lpNewItem );
     }
     else if (wFlags & MF_BITMAP) lpitem->hText = LOWORD((DWORD)lpNewItem);
@@ -1774,7 +1798,7 @@
     POPUPMENU *menu;
 
     if (!(hmenu = CreateMenu())) return 0;
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     menu->wFlags |= MF_POPUP;
     return hmenu;
 }
@@ -1825,9 +1849,9 @@
     HMENU hMenu;
     LPPOPUPMENU menu;
     dprintf_menu(stddeb,"CreateMenu !\n");
-    if (!(hMenu = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(POPUPMENU) )))
+    if (!(hMenu = USER_HEAP_ALLOC( sizeof(POPUPMENU) )))
 	return 0;
-    menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu);
+    menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu);
     menu->hNext  = 0;
     menu->wFlags = 0;
     menu->wMagic = MENU_MAGIC;
@@ -1851,7 +1875,7 @@
 	LPPOPUPMENU lppop;
 	dprintf_menu(stddeb,"DestroyMenu (%04X) !\n", hMenu);
 	if (hMenu == 0) return FALSE;
-	lppop = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu);
+	lppop = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu);
 	if (lppop == NULL) return FALSE;
 	if ((lppop->wFlags & MF_POPUP) && lppop->hWnd)
             DestroyWindow( lppop->hWnd );
@@ -1859,7 +1883,7 @@
 	if (lppop->hItems)
 	{
 	    int i;
-	    MENUITEM *item = (MENUITEM *) USER_HEAP_ADDR( lppop->hItems );
+	    MENUITEM *item = (MENUITEM *) USER_HEAP_LIN_ADDR( lppop->hItems );
 	    for (i = lppop->nItems; i > 0; i--, item++)
 	    {
 		if (item->item_flags & MF_POPUP)
@@ -1929,7 +1953,7 @@
 	wndPtr->wIDmenu = hMenu;
 	if (hMenu != 0)
 	{
-	    lpmenu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu);
+	    lpmenu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu);
 	    if (lpmenu == NULL) {
 		fprintf(stderr,"SetMenu(%04X, %04X) // Bad menu handle !\n", 
 			hWnd, hMenu);
@@ -1954,9 +1978,9 @@
     LPPOPUPMENU lppop;
     LPMENUITEM 	lpitem;
     dprintf_menu(stddeb,"GetSubMenu (%04X, %04X) !\n", hMenu, nPos);
-    if (!(lppop = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return 0;
+    if (!(lppop = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return 0;
     if ((WORD)nPos >= lppop->nItems) return 0;
-    lpitem = (MENUITEM *) USER_HEAP_ADDR( lppop->hItems );
+    lpitem = (MENUITEM *) USER_HEAP_LIN_ADDR( lppop->hItems );
     if (!(lpitem[nPos].item_flags & MF_POPUP)) return 0;
     return lpitem[nPos].item_id;
 }
@@ -1975,7 +1999,7 @@
 		wndPtr->wIDmenu != 0) {
 		dprintf_menu(stddeb,"DrawMenuBar wIDmenu=%04X \n", 
 			     wndPtr->wIDmenu);
-		lppop = (LPPOPUPMENU) USER_HEAP_ADDR(wndPtr->wIDmenu);
+		lppop = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(wndPtr->wIDmenu);
 		if (lppop == NULL) return;
 
 		lppop->Height = 0; /* Make sure we call MENU_MenuBarCalcSize */
@@ -2035,7 +2059,7 @@
 	dprintf_menu(stddeb,"No SYSMENU\n");
 	return 0;
     }
-    menu = (POPUPMENU*) USER_HEAP_ADDR(hMenu);
+    menu = (POPUPMENU*) USER_HEAP_LIN_ADDR(hMenu);
     menu->wFlags |= MF_SYSMENU|MF_POPUP;
     dprintf_menu(stddeb,"CopySysMenu hMenu=%04X !\n", hMenu);
     return hMenu;
@@ -2088,6 +2112,6 @@
 BOOL IsMenu( HMENU hmenu )
 {
     LPPOPUPMENU menu;
-    if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR( hmenu ))) return FALSE;
+    if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR( hmenu ))) return FALSE;
     return (menu->wMagic == MENU_MAGIC);
 }
diff --git a/controls/scroll.c b/controls/scroll.c
index e335ade..b6a7e3c 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -109,9 +109,9 @@
 
     if (!handle)  /* Create the info structure if needed */
     {
-        if ((handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(SCROLLINFO) )))
+        if ((handle = USER_HEAP_ALLOC( sizeof(SCROLLINFO) )))
         {
-            SCROLLINFO *infoPtr = (SCROLLINFO *) USER_HEAP_ADDR( handle );
+            SCROLLINFO *infoPtr = (SCROLLINFO *) USER_HEAP_LIN_ADDR( handle );
             infoPtr->MinVal = infoPtr->CurVal = 0;
             infoPtr->MaxVal = 100;
             infoPtr->flags  = ESB_ENABLE_BOTH;
@@ -120,7 +120,7 @@
         }
         if (!hUpArrow) SCROLL_LoadBitmaps();
     }
-    return (SCROLLINFO *) USER_HEAP_ADDR( handle );
+    return (SCROLLINFO *) USER_HEAP_LIN_ADDR( handle );
 }
 
 
@@ -204,7 +204,7 @@
  * from the top of the scroll-bar.
  */
 static UINT SCROLL_GetThumbVal( SCROLLINFO *infoPtr, RECT *rect,
-                                WORD arrowSize, BOOL vertical, WORD pos )
+                                BOOL vertical, WORD pos )
 {
     int pixels = vertical ? rect->bottom-rect->top : rect->right-rect->left;
     if ((pixels -= 3*SYSMETRICS_CXVSCROLL+1) <= 0) return infoPtr->MinVal;
@@ -631,7 +631,7 @@
                 SCROLL_DrawMovingThumb( hdc, &rect, vertical, arrowSize,
                                        trackThumbPos + pos - lastClickPos );
                 lastMousePos = pos;
-                val = SCROLL_GetThumbVal( infoPtr, &rect, vertical, arrowSize,
+                val = SCROLL_GetThumbVal( infoPtr, &rect, vertical,
                                  trackThumbPos + lastMousePos - lastClickPos );
                 SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                              SB_THUMBTRACK, MAKELONG( val, hwndCtl ));
@@ -673,7 +673,7 @@
     {
         if (trackHitTest == SCROLL_THUMB)
         {
-            UINT val = SCROLL_GetThumbVal( infoPtr, &rect, vertical, arrowSize,
+            UINT val = SCROLL_GetThumbVal( infoPtr, &rect, vertical,
                                  trackThumbPos + lastMousePos - lastClickPos );
             SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                          SB_THUMBPOSITION, MAKELONG( val, hwndCtl ) );
@@ -697,7 +697,7 @@
     {
     case WM_CREATE:
         {
-	    CREATESTRUCT *lpCreat = (CREATESTRUCT *)lParam;
+	    CREATESTRUCT *lpCreat = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
             if (lpCreat->style & SBS_SIZEBOX)
             {
                 fprintf( stdnimp, "Unimplemented style SBS_SIZEBOX.\n" );
diff --git a/controls/static.c b/controls/static.c
index 3191604..063ad23 100644
--- a/controls/static.c
+++ b/controls/static.c
@@ -88,10 +88,10 @@
         case WM_NCCREATE:
 	    if (style == SS_ICON)
             {
-		CREATESTRUCT * createStruct = (CREATESTRUCT *)lParam;
+		CREATESTRUCT * createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
 		if (createStruct->lpszName)
                     STATIC_SetIcon( hWnd, LoadIcon( createStruct->hInstance,
-                                                    createStruct->lpszName ));
+                                             (SEGPTR)createStruct->lpszName ));
                 return 1;
             }
             return DefWindowProc(hWnd, uMsg, wParam, lParam);
@@ -136,9 +136,9 @@
 	case WM_SETTEXT:
 	    if (style == SS_ICON)
                 STATIC_SetIcon( hWnd, LoadIcon( wndPtr->hInstance,
-                                                (LPSTR)lParam ) );
+                                                (SEGPTR)lParam ));
             else
-                DEFWND_SetText( hWnd, (LPSTR)lParam );
+                DEFWND_SetText( hWnd, (LPSTR)PTR_SEG_TO_LIN(lParam) );
 	    InvalidateRect( hWnd, NULL, FALSE );
 	    UpdateWindow( hWnd );
 	    break;
@@ -192,7 +192,7 @@
     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
 
     GetClientRect(hwnd, &rc);
-    text = USER_HEAP_ADDR( wndPtr->hText );
+    text = USER_HEAP_LIN_ADDR( wndPtr->hText );
 
     switch (style & 0x0000000F)
     {
diff --git a/controls/widgets.c b/controls/widgets.c
index 932594e..20e22dc 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -13,6 +13,7 @@
 #include "desktop.h"
 #include "mdi.h"
 #include "gdi.h"
+#include "user.h"
 
 LONG ListBoxWndProc  ( HWND hwnd, WORD message, WORD wParam, LONG lParam );
 LONG ComboBoxWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam );
@@ -34,7 +35,7 @@
       0, 0, 0, 0, NULL, "LISTBOX" },
     { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, ComboBoxWndProc, 0, 8,
       0, 0, 0, 0, NULL, "COMBOBOX" },
-    { CS_GLOBALCLASS | CS_PARENTDC, EditWndProc, 0, 4, 
+    { CS_GLOBALCLASS | CS_PARENTDC, EditWndProc, 0, sizeof(WORD), 
       0, 0, 0, 0, NULL, "EDIT" },
     { CS_GLOBALCLASS | CS_SAVEBITS, PopupMenuWndProc, 0, 8,
       0, 0, 0, 0, NULL, POPUPMENU_CLASS_NAME },
@@ -58,12 +59,19 @@
 BOOL WIDGETS_Init(void)
 {
     int i;
+    HANDLE hName;
+    char *name;
     WNDCLASS *class = WIDGETS_BuiltinClasses;
 
+    if (!(hName = USER_HEAP_ALLOC( 20 ))) return FALSE;
+    name = USER_HEAP_LIN_ADDR( hName );
     for (i = 0; i < NB_BUILTIN_CLASSES; i++, class++)
     {
+        strcpy( name, class->lpszClassName );
+        class->lpszClassName = (LPSTR)USER_HEAP_SEG_ADDR( hName );
 	class->hCursor = LoadCursor( 0, IDC_ARROW );
 	if (!RegisterClass( class )) return FALSE;
     }
+    USER_HEAP_FREE( hName );
     return TRUE;
 }