From 2c69f6d8e970734572d9da9ad06028155b6d0b84 Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard@winehq.org>
Date: Sat, 28 Sep 1996 18:11:01 +0000
Subject: [PATCH] Release 960928

Fri Sep 27 14:18:42 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [controls/button.c]
	Fixed focus rectangle size and clipping.

	* [controls/scroll.c]
	Converted to Win32 and added support for scroll page.
	Completed SetScrollInfo() and implemented other Win32 functions.

	* [files/file.c]
	Removed FILE_Read() (use _lread32 instead).

	* [objects/dce.c] [include/dce.h]
	Allocate DCE on the Win32 heap, and use pointers instead of
	handles.
	Implemented Win32 version of DC functions.

	* [windows/painting.c]
	Attempt to make CS_PARENTDC style work again.

Wed Sep 25 23:40:52 1996 Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [windows/dce.c] [windows/winpos.c]
	Override SaveUnder attribute when painting took place
	in a window below. Force X to raise activated window
	in seamless mode.

	* [misc/clipboard.c] [windows/event.c]
	Translation between DOS and Unix text formats and several
	other fixes for the sudden selection loss.

	* [windows/message.c]
	Apply "first" and "last" when checking for WM_QUIT in
        MSG_PeekMessage().

	* [windows/win.c]
	Rearranged DestroyWindow() to fit "Windows Internals"
	description.

	* [windows/win.c] [windows/winpos.c] [windows/nonclient.c]
	Misc. fixes to CBT hook calls.

	* [controls/menu.c] [misc/user.c]
	Fixup resident popup menu window so that it doesn't get
	destroyed by USER_AppExit().

	* [loader/module.c] [loader/task.c] [windows/event.c]
	Process "unsafe" X events outside the scheduler to prevent
	deadlocks.

	* [windows/message.c] [windows/queue.c] [windows/winpos.c]
	Lots of fixes for better Win16 multitasking.

Wed Sep 25 20:36:30 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [include/windows.h]
	Added some missing HOOK defines.

	* [misc/shell.c][if1632/shell32.spec][include/shell.h]
	SHGetFileInfoA stub added (win95 mplayer.exe /play bla.avi).

	* [win32/console.c][include/wincon.h]
	GetConsoleScreenBufferInfo, GetLargestConsoleWindowSize added.

	* [misc/registry.c]
	Some null ptr fixes.

	* [loader/pe_image.c]
	Fixed exported function lookup. (msvcrt20.dll)
	Add debugsyms for entrypoint, exported functions and sections.

	* [multimedia/mmsystem.c]
	MCIOpen: support for element opens (mplayer.exe /play bla.avi).

	* [several]
	Added several missing things/stubs/simple thunks from win32
	to win16 code.

Sat Sep 21 17:27:44 1996  O.Flebbe  <flebbe@science-computing.uni-tuebingen.de>

	* [windows/property.c]
	Fixed debugging of 16 Bit RemoveProp().

	* [debugger/memory.c]
	Added DEBUG_checkmap_bad() for linux.

Thu Sep 19 20:48:31 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [windows/event.c] [windows/hook.c]
	Use EnableHardwareInput() for JournalPlayback hook.

	* [controls/listbox.c]
	Changed handling of LB_GETITEMRECT in empty listboxes.

Thu Sep 19 13:34:35 1996  Slaven Rezic  <eserte@cs.tu-berlin.de>

	* [misc/main.c]
	Fixes to X resources handling.

Wed Sep 18 00:31:15 1996  Huw D. M. Davies <h.davies1@physics.oxford.ac.uk>

	* [objects/metafile.c] [include/gdi.h] [objects/dc.c]
	Individual handle table created for each metafile. Fixed
 	GlobalReAlloc() bug in MF_AddHandleDC() (was MF_AddHandleInternal).

	* [windows/graphics.c] [objects/dc.c]
	Rectangle() changed to work better with wide pens and PS_NULL.
	Use JoinMiter.

	* [windows/winpos.c]
	Make the whole (non X) window invalid on resize if CS_[VH]REDRAW
 	is set.

	* [windows/nonclient.c]
	AdjustWindowRectEx() should perform calculations even if the
 	window is minimized.

	* [windows/mdi.c]
	Better handling of system button painting. Maximized windows can
 	contain scroll bars. Icons now maximize properly.

	* [windows/defwnd.c] [windows/nonclient.c] [controls/menu.c]
	Improved greying of items in system menu. WM_INITMEMUPOPUP no
 	longer caught in DefWndProc, DEFWND_InitSysMenuPopup moved to
 	menu.c.

Mon Sep 16 21:30:00 1996  Uwe Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>

	* [several files]
	Fix missing includes and wrong printing arguments.

	* [controls/listbox.c]
	Don't sort drives in ListBoxDirectory().

Sat Sep 14 09:05:47 1996  Petri Tuomola <ptuomola@xs4all.nl>

	* [windows/dialog.c]
	Fixed handling of Shift-TAB in dialogs.

Thu Sep 12 18:31:00 1996  Thomas Sandford <t.d.g.sandford@prds-grn.demon.co.uk>

	* [if1632/gdi32.spec]
	Added SelectClipRgn - call win16 version.

	* [if1632/user32.spec]
	Added GetAsyncKeyState, GetMenuItemID and GetMenuStringA.

	* [include/wincon.h]
	Added COORD and SMALL_RECT typedefs, moved CONSOLE_SCREEN_BUFFER_INFO
	out of #if 0 protected portion of file.

	* [loader/pe_image.c]
	PE_InitTEB() - Tidy up, bug fix to stack pointer value (Borland
	programs now work better)

	* [win32/console.c]
	Added stub functions for GetConsoleScreenBufferInfo and
	GetLargestConsoleWindowSize

	* [win32/findfile.c]
	FindFirstFile32A() - removed erroneous strcpy

	* [windows/keyboard.c]
	GetAsyncKeyState() - bug fix - now returns value as per Microsoft
	specification. NB - I still have doubts about some other functions
	in this file.
---
 ANNOUNCE              |  16 +-
 ChangeLog             | 168 +++++++++
 controls/button.c     | 119 +++---
 controls/combo.c      |  22 +-
 controls/desktop.c    |  64 ++--
 controls/edit.c       |  30 +-
 controls/listbox.c    |  72 ++--
 controls/menu.c       |  90 +++--
 controls/scroll.c     | 832 ++++++++++++++++++++++++++----------------
 controls/status.c     |  13 +-
 controls/widgets.c    |   8 +-
 debugger/memory.c     |  80 +++-
 files/directory.c     |  48 ++-
 files/dos_fs.c        |  12 +
 files/file.c          |  37 +-
 files/profile.c       |   2 +-
 if1632/crtdll.spec    |   2 +-
 if1632/gdi32.spec     |  10 +-
 if1632/kernel.spec    |   2 +-
 if1632/kernel32.spec  |  28 +-
 if1632/shell32.spec   |   4 +-
 if1632/user.spec      |  34 +-
 if1632/user32.spec    |  56 +--
 include/class.h       |   4 +-
 include/clipboard.h   |   4 +-
 include/dce.h         |  20 +-
 include/dde_mem.h     |   8 +-
 include/debug.h       |  69 ++--
 include/desktop.h     |  10 +-
 include/directory.h   |  10 +-
 include/file.h        |   1 -
 include/gdi.h         |   4 +-
 include/graphics.h    |  12 +-
 include/listbox.h     |   1 +
 include/menu.h        |   1 +
 include/message.h     |   2 +-
 include/module.h      |   2 +
 include/queue.h       |  23 +-
 include/scroll.h      |  20 +-
 include/shell.h       |  42 +++
 include/stddebug.h    |   2 +
 include/win.h         |   6 +-
 include/wincon.h      |  84 +++--
 include/windows.h     | 157 +++++---
 ipc/dde_proc.c        |   2 +-
 ipc/wine_test_stub.c  |   2 +-
 loader/builtin.c      |   2 +-
 loader/module.c       |  31 +-
 loader/pe_image.c     | 109 ++++--
 loader/task.c         |  61 +++-
 misc/clipboard.c      | 446 +++++++++++++++-------
 misc/comm.c           |   4 +-
 misc/commdlg.c        |  68 ++--
 misc/lstr.c           |   3 +-
 misc/lzexpand.c       |   8 +-
 misc/main.c           |  39 +-
 misc/ole2nls.c        |   5 +
 misc/registry.c       |  28 +-
 misc/shell.c          |  27 +-
 misc/spy.c            |  13 +-
 misc/user.c           |   7 +-
 misc/winsocket.c      |   2 +-
 miscemu/dpmi.c        |  15 +-
 multimedia/mmsystem.c |  48 ++-
 objects/bitmap.c      |  34 +-
 objects/cursoricon.c  |   8 +-
 objects/dc.c          |   4 +-
 objects/gdiobj.c      |   4 +-
 objects/metafile.c    |  89 ++---
 objects/palette.c     |  10 +-
 objects/text.c        |   4 +-
 win32/console.c       |  40 ++
 win32/cursoricon32.c  |   6 +-
 win32/file.c          |   7 +-
 win32/findfile.c      |   2 -
 win32/memory.c        |  15 +-
 win32/newfns.c        |   8 +
 win32/thread.c        |   5 +
 windows/caret.c       |   6 +-
 windows/class.c       |  10 +-
 windows/dce.c         | 223 +++++------
 windows/defwnd.c      |  34 +-
 windows/dialog.c      |   9 +-
 windows/event.c       | 159 ++++++--
 windows/graphics.c    |  31 +-
 windows/hook.c        |  54 +--
 windows/keyboard.c    |   4 +-
 windows/mdi.c         |  35 +-
 windows/message.c     | 194 ++++++----
 windows/msgbox.c      |   6 +-
 windows/nonclient.c   |  85 +++--
 windows/painting.c    |  56 ++-
 windows/property.c    |   7 +-
 windows/queue.c       | 180 +++++----
 windows/scroll.c      |  14 +-
 windows/win.c         | 284 ++++++++++----
 windows/winpos.c      | 344 ++++++++++-------
 97 files changed, 3358 insertions(+), 1764 deletions(-)

diff --git a/ANNOUNCE b/ANNOUNCE
index 0712204e104..9eb3ba970dc 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,12 +1,14 @@
-This is release 960913 of Wine, the MS Windows emulator.  This is still a
+This is release 960928 of Wine, the MS Windows emulator.  This is still a
 developer's only release.  There are many bugs and many unimplemented API
 features.  Most applications still do not work correctly.
 
 Patches should be submitted to "julliard@lrc.epfl.ch".  Please don't
 forget to include a ChangeLog entry.
 
-WHAT'S NEW with Wine-960913: (see ChangeLog for details)
-	- Better Win32 file handling.
+WHAT'S NEW with Wine-960928: (see ChangeLog for details)
+	- Intertask messaging improved.
+	- Many painting fixes.
+	- Still more Win32 support.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -15,10 +17,10 @@ Because of lags created by using mirror, this message may reach you before
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-960913.tar.gz
-  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-960913.tar.gz
-  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-960913.tar.gz
-  ftp://aris.com/pub/linux/ALPHA/Wine/development/Wine-960913.tar.gz
+  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-960928.tar.gz
+  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-960928.tar.gz
+  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-960928.tar.gz
+  ftp://aris.com/pub/linux/ALPHA/Wine/development/Wine-960928.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/ChangeLog b/ChangeLog
index 4db62be9d87..c5086157483 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,171 @@
+----------------------------------------------------------------------
+Fri Sep 27 14:18:42 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [controls/button.c]
+	Fixed focus rectangle size and clipping.
+
+	* [controls/scroll.c]
+	Converted to Win32 and added support for scroll page.
+	Completed SetScrollInfo() and implemented other Win32 functions.
+
+	* [files/file.c]
+	Removed FILE_Read() (use _lread32 instead).
+
+	* [objects/dce.c] [include/dce.h]
+	Allocate DCE on the Win32 heap, and use pointers instead of
+	handles.
+	Implemented Win32 version of DC functions.
+
+	* [windows/painting.c]
+	Attempt to make CS_PARENTDC style work again.
+
+Wed Sep 25 23:40:52 1996 Alex Korobka <alex@trantor.pharm.sunysb.edu>
+
+	* [windows/dce.c] [windows/winpos.c]
+	Override SaveUnder attribute when painting took place
+	in a window below. Force X to raise activated window 
+	in seamless mode.
+
+	* [misc/clipboard.c] [windows/event.c]
+	Translation between DOS and Unix text formats and several
+	other fixes for the sudden selection loss.
+
+	* [windows/message.c]
+	Apply "first" and "last" when checking for WM_QUIT in 
+        MSG_PeekMessage().
+
+	* [windows/win.c]
+	Rearranged DestroyWindow() to fit "Windows Internals"
+	description.
+
+	* [windows/win.c] [windows/winpos.c] [windows/nonclient.c]
+	Misc. fixes to CBT hook calls.
+
+	* [controls/menu.c] [misc/user.c]
+	Fixup resident popup menu window so that it doesn't get
+	destroyed by USER_AppExit().
+
+	* [loader/module.c] [loader/task.c] [windows/event.c]
+	Process "unsafe" X events outside the scheduler to prevent
+	deadlocks.
+
+	* [windows/message.c] [windows/queue.c] [windows/winpos.c]
+	Lots of fixes for better Win16 multitasking.
+
+Wed Sep 25 20:36:30 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
+
+	* [include/windows.h]
+	Added some missing HOOK defines.
+
+	* [misc/shell.c][if1632/shell32.spec][include/shell.h]
+	SHGetFileInfoA stub added (win95 mplayer.exe /play bla.avi).
+
+	* [win32/console.c][include/wincon.h]
+	GetConsoleScreenBufferInfo, GetLargestConsoleWindowSize added.
+
+	* [misc/registry.c]
+	Some null ptr fixes.
+
+	* [loader/pe_image.c]
+	Fixed exported function lookup. (msvcrt20.dll)
+	Add debugsyms for entrypoint, exported functions and sections.
+
+	* [multimedia/mmsystem.c]
+	MCIOpen: support for element opens (mplayer.exe /play bla.avi).
+
+	* [several]
+	Added several missing things/stubs/simple thunks from win32
+	to win16 code.
+
+Sat Sep 21 17:27:44 1996  O.Flebbe  <flebbe@science-computing.uni-tuebingen.de>
+
+	* [windows/property.c]
+	Fixed debugging of 16 Bit RemoveProp().
+
+	* [debugger/memory.c]
+	Added DEBUG_checkmap_bad() for linux.
+
+Thu Sep 19 20:48:31 1996  Albrecht Kleine  <kleine@ak.sax.de>
+
+	* [windows/event.c] [windows/hook.c]
+	Use EnableHardwareInput() for JournalPlayback hook.
+
+	* [controls/listbox.c]
+	Changed handling of LB_GETITEMRECT in empty listboxes.
+
+Thu Sep 19 13:34:35 1996  Slaven Rezic  <eserte@cs.tu-berlin.de>
+
+	* [misc/main.c]
+	Fixes to X resources handling.	
+
+Wed Sep 18 00:31:15 1996  Huw D. M. Davies <h.davies1@physics.oxford.ac.uk>
+
+	* [objects/metafile.c] [include/gdi.h] [objects/dc.c]
+	Individual handle table created for each metafile. Fixed
+ 	GlobalReAlloc() bug in MF_AddHandleDC() (was MF_AddHandleInternal).
+
+	* [windows/graphics.c] [objects/dc.c]
+	Rectangle() changed to work better with wide pens and PS_NULL.
+	Use JoinMiter.
+
+	* [windows/winpos.c]
+	Make the whole (non X) window invalid on resize if CS_[VH]REDRAW
+ 	is set.
+
+	* [windows/nonclient.c]
+	AdjustWindowRectEx() should perform calculations even if the
+ 	window is minimized.
+
+	* [windows/mdi.c]
+	Better handling of system button painting. Maximized windows can
+ 	contain scroll bars. Icons now maximize properly.
+
+	* [windows/defwnd.c] [windows/nonclient.c] [controls/menu.c]
+	Improved greying of items in system menu. WM_INITMEMUPOPUP no
+ 	longer caught in DefWndProc, DEFWND_InitSysMenuPopup moved to
+ 	menu.c.
+
+Mon Sep 16 21:30:00 1996  Uwe Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>
+
+	* [several files]
+	Fix missing includes and wrong printing arguments.
+
+	* [controls/listbox.c]
+	Don't sort drives in ListBoxDirectory().
+	
+Sat Sep 14 09:05:47 1996  Petri Tuomola <ptuomola@xs4all.nl>
+
+	* [windows/dialog.c]
+	Fixed handling of Shift-TAB in dialogs.
+
+Thu Sep 12 18:31:00 1996  Thomas Sandford <t.d.g.sandford@prds-grn.demon.co.uk>
+
+	* [if1632/gdi32.spec]
+	Added SelectClipRgn - call win16 version.
+
+	* [if1632/user32.spec]
+	Added GetAsyncKeyState, GetMenuItemID and GetMenuStringA.
+
+	* [include/wincon.h]
+	Added COORD and SMALL_RECT typedefs, moved CONSOLE_SCREEN_BUFFER_INFO
+	out of #if 0 protected portion of file.
+
+	* [loader/pe_image.c]
+	PE_InitTEB() - Tidy up, bug fix to stack pointer value (Borland
+	programs now work better)
+
+	* [win32/console.c]
+	Added stub functions for GetConsoleScreenBufferInfo and 
+	GetLargestConsoleWindowSize
+
+	* [win32/findfile.c]
+	FindFirstFile32A() - removed erroneous strcpy
+
+	* [windows/keyboard.c]
+	GetAsyncKeyState() - bug fix - now returns value as per Microsoft
+	specification. NB - I still have doubts about some other functions
+	in this file.
+
 ----------------------------------------------------------------------
 Wed Sep 11 18:08:30 1996  Albrecht Kleine  <kleine@ak.sax.de>
 
diff --git a/controls/button.c b/controls/button.c
index cfe649068c8..d224256c964 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -10,12 +10,12 @@
 #include "graphics.h"
 #include "button.h"
 
-static void PB_Paint( WND *wndPtr, HDC hDC, WORD action );
-static void PB_PaintGrayOnGray(HDC hDC,HFONT hFont,RECT16 *rc,char *text);
-static void CB_Paint( WND *wndPtr, HDC hDC, WORD action );
-static void GB_Paint( WND *wndPtr, HDC hDC, WORD action );
-static void UB_Paint( WND *wndPtr, HDC hDC, WORD action );
-static void OB_Paint( WND *wndPtr, HDC hDC, WORD action );
+static void PB_Paint( WND *wndPtr, HDC32 hDC, WORD action );
+static void PB_PaintGrayOnGray(HDC32 hDC,HFONT hFont,RECT32 *rc,char *text);
+static void CB_Paint( WND *wndPtr, HDC32 hDC, WORD action );
+static void GB_Paint( WND *wndPtr, HDC32 hDC, WORD action );
+static void UB_Paint( WND *wndPtr, HDC32 hDC, WORD action );
+static void OB_Paint( WND *wndPtr, HDC32 hDC, WORD action );
 static void BUTTON_CheckAutoRadioButton( WND *wndPtr );
 
 #define MAX_BTN_TYPE  12
@@ -36,7 +36,7 @@ static const WORD maxCheckState[MAX_BTN_TYPE] =
     BUTTON_UNCHECKED    /* BS_OWNERDRAW */
 };
 
-typedef void (*pfPaint)( WND *wndPtr, HDC hdc, WORD action );
+typedef void (*pfPaint)( WND *wndPtr, HDC32 hdc, WORD action );
 
 static const pfPaint btnPaintFunc[MAX_BTN_TYPE] =
 {
@@ -56,9 +56,9 @@ static const pfPaint btnPaintFunc[MAX_BTN_TYPE] =
 
 #define PAINT_BUTTON(wndPtr,style,action) \
      if (btnPaintFunc[style]) { \
-         HDC hdc = GetDC( (wndPtr)->hwndSelf ); \
+         HDC32 hdc = GetDC32( (wndPtr)->hwndSelf ); \
          (btnPaintFunc[style])(wndPtr,hdc,action); \
-         ReleaseDC( (wndPtr)->hwndSelf, hdc ); }
+         ReleaseDC32( (wndPtr)->hwndSelf, hdc ); }
 
 #define BUTTON_SEND_CTLCOLOR(wndPtr,hdc) \
     SendMessage32A( GetParent32((wndPtr)->hwndSelf), WM_CTLCOLORBTN, \
@@ -124,7 +124,7 @@ LRESULT ButtonWndProc(HWND32 hWnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
     case WM_LBUTTONDOWN:
         SendMessage32A( hWnd, BM_SETSTATE32, TRUE, 0 );
         SetFocus32( hWnd );
-        SetCapture( hWnd );
+        SetCapture32( hWnd );
         break;
 
     case WM_LBUTTONUP:
@@ -155,7 +155,7 @@ LRESULT ButtonWndProc(HWND32 hWnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
         break;
 
     case WM_MOUSEMOVE:
-        if (GetCapture() == hWnd)
+        if (GetCapture32() == hWnd)
         {
             GetClientRect16( hWnd, &rect );
             SendMessage32A( hWnd, BM_SETSTATE32,
@@ -249,16 +249,14 @@ LRESULT ButtonWndProc(HWND32 hWnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
  *       Push Button Functions
  */
 
-static void PB_Paint( WND *wndPtr, HDC hDC, WORD action )
+static void PB_Paint( WND *wndPtr, HDC32 hDC, WORD action )
 {
-    RECT16 rc;
+    RECT32 rc;
     HPEN16 hOldPen;
     HBRUSH hOldBrush;
-    DWORD dwTextSize;
-    TEXTMETRIC16 tm;
     BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
 
-    GetClientRect16(wndPtr->hwndSelf, &rc);
+    GetClientRect32( wndPtr->hwndSelf, &rc );
 
       /* Send WM_CTLCOLOR to allow changing the font (the colors are fixed) */
     if (infoPtr->hFont) SelectObject( hDC, infoPtr->hFont );
@@ -274,12 +272,12 @@ static void PB_Paint( WND *wndPtr, HDC hDC, WORD action )
         SetPixel( hDC, rc.right-1, rc.top, GetSysColor(COLOR_WINDOW) );
         SetPixel( hDC, rc.right-1, rc.bottom-1, GetSysColor(COLOR_WINDOW) );
     }
-    InflateRect16( &rc, -1, -1 );
+    InflateRect32( &rc, -1, -1 );
 
     if ((wndPtr->dwStyle & 0x000f) == BS_DEFPUSHBUTTON)
     {
         Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
-        InflateRect16( &rc, -1, -1 );
+        InflateRect32( &rc, -1, -1 );
     }
 
     if (infoPtr->state & BUTTON_HIGHLIGHTED)
@@ -296,32 +294,34 @@ static void PB_Paint( WND *wndPtr, HDC hDC, WORD action )
     /* draw button label, if any: */
     if (wndPtr->text && wndPtr->text[0])
     {
-     LOGBRUSH16 lb;
-     GetObject16( sysColorObjects.hbrushBtnFace, sizeof(lb), &lb );
-     if (wndPtr->dwStyle & WS_DISABLED &&
-         GetSysColor(COLOR_GRAYTEXT)==lb.lbColor)
-         /* don't write gray text on gray bkg */
-         PB_PaintGrayOnGray(hDC,infoPtr->hFont,&rc,wndPtr->text);
-     else
-     {
-        SetTextColor( hDC, (wndPtr->dwStyle & WS_DISABLED) ?
-                     GetSysColor(COLOR_GRAYTEXT) : GetSysColor(COLOR_BTNTEXT));
-        DrawText16( hDC, wndPtr->text, -1, &rc,
-                    DT_SINGLELINE | DT_CENTER | DT_VCENTER );
-        /* do we have the focus? */
-        if (infoPtr->state & BUTTON_HASFOCUS)
+        LOGBRUSH16 lb;
+        GetObject16( sysColorObjects.hbrushBtnFace, sizeof(lb), &lb );
+        if (wndPtr->dwStyle & WS_DISABLED &&
+            GetSysColor(COLOR_GRAYTEXT)==lb.lbColor)
+            /* don't write gray text on gray bkg */
+            PB_PaintGrayOnGray(hDC,infoPtr->hFont,&rc,wndPtr->text);
+        else
         {
-            short xdelta, ydelta;
-            dwTextSize = GetTextExtent(hDC,wndPtr->text,strlen(wndPtr->text));
-            GetTextMetrics16( hDC, &tm );
-            xdelta = ((rc.right - rc.left) - LOWORD(dwTextSize) - 1) / 2;
-            ydelta = ((rc.bottom - rc.top) - tm.tmHeight - 1) / 2;
-            if (xdelta < 0) xdelta = 0;
-            if (ydelta < 0) ydelta = 0;
-            InflateRect16( &rc, -xdelta, -ydelta );
-            DrawFocusRect16( hDC, &rc );
-        }
-     }   
+            SetTextColor( hDC, (wndPtr->dwStyle & WS_DISABLED) ?
+                     GetSysColor(COLOR_GRAYTEXT) : GetSysColor(COLOR_BTNTEXT));
+            DrawText32A( hDC, wndPtr->text, -1, &rc,
+                         DT_SINGLELINE | DT_CENTER | DT_VCENTER );
+            /* do we have the focus? */
+            if (infoPtr->state & BUTTON_HASFOCUS)
+            {
+                RECT32 r = { 0, 0, 0, 0 };
+                INT32 xdelta, ydelta;
+
+                DrawText32A( hDC, wndPtr->text, -1, &r,
+                             DT_SINGLELINE | DT_CALCRECT );
+                xdelta = ((rc.right - rc.left) - (r.right - r.left) - 1) / 2;
+                ydelta = ((rc.bottom - rc.top) - (r.bottom - r.top) - 1) / 2;
+                if (xdelta < 0) xdelta = 0;
+                if (ydelta < 0) ydelta = 0;
+                InflateRect32( &rc, -xdelta, -ydelta );
+                DrawFocusRect32( hDC, &rc );
+            }
+        }   
     }
 
     SelectObject( hDC, hOldPen );
@@ -334,17 +334,17 @@ static void PB_Paint( WND *wndPtr, HDC hDC, WORD action )
  *   using a raster brush to avoid gray text on gray background
  */
 
-void PB_PaintGrayOnGray(HDC hDC,HFONT hFont,RECT16 *rc,char *text)
+void PB_PaintGrayOnGray(HDC32 hDC,HFONT hFont,RECT32 *rc,char *text)
 {
     static int Pattern[] = {0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55};
     HBITMAP hbm  = CreateBitmap(8, 8, 1, 1, Pattern);
     HDC hdcMem   = CreateCompatibleDC(hDC);
     HBITMAP hbmMem;
     HBRUSH hBr;
-    RECT16 rect,rc2;
+    RECT32 rect,rc2;
 
     rect=*rc;
-    DrawText16( hDC, text, -1, &rect, DT_SINGLELINE | DT_CALCRECT);
+    DrawText32A( hDC, text, -1, &rect, DT_SINGLELINE | DT_CALCRECT);
     rc2=rect;
     rect.left=(rc->right-rect.right)/2;       /* for centering text bitmap */
     rect.top=(rc->bottom-rect.bottom)/2;
@@ -354,7 +354,7 @@ void PB_PaintGrayOnGray(HDC hDC,HFONT hFont,RECT16 *rc,char *text)
     DeleteObject( hbm);
     PatBlt( hdcMem,0,0,rect.right,rect.bottom,WHITENESS);
     if (hFont) SelectObject( hdcMem, hFont);
-    DrawText16( hdcMem, text, -1, &rc2, DT_SINGLELINE);  
+    DrawText32A( hdcMem, text, -1, &rc2, DT_SINGLELINE);  
     PatBlt( hdcMem,0,0,rect.right,rect.bottom,0xFA0089);
     DeleteObject( SelectObject( hdcMem,hBr));
     BitBlt( hDC,rect.left,rect.top,rect.right,rect.bottom,hdcMem,0,0,0x990000);
@@ -367,13 +367,12 @@ void PB_PaintGrayOnGray(HDC hDC,HFONT hFont,RECT16 *rc,char *text)
  *       Check Box & Radio Button Functions
  */
 
-static void CB_Paint( WND *wndPtr, HDC hDC, WORD action )
+static void CB_Paint( WND *wndPtr, HDC32 hDC, WORD action )
 {
     RECT16 rc;
     HBRUSH hBrush;
     int textlen, delta, x, y;
     TEXTMETRIC16 tm;
-    SIZE16 size;
     BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
 
     GetClientRect16(wndPtr->hwndSelf, &rc);
@@ -404,20 +403,22 @@ static void CB_Paint( WND *wndPtr, HDC hDC, WORD action )
         if (wndPtr->dwStyle & WS_DISABLED)
             SetTextColor( hDC, GetSysColor(COLOR_GRAYTEXT) );
         DrawText16( hDC, wndPtr->text, textlen, &rc,
-                    DT_SINGLELINE | DT_VCENTER );
+                    DT_SINGLELINE | DT_VCENTER | DT_NOCLIP );
     }
     
     if ((action == ODA_FOCUS) ||
         ((action == ODA_DRAWENTIRE) && (infoPtr->state & BUTTON_HASFOCUS)))
     {
-        GetTextExtentPoint16( hDC, wndPtr->text, textlen, &size );
+        RECT16 rect = { 0, 0, 0, 0 };
+        DrawText16( hDC, wndPtr->text, textlen, &rect,
+                    DT_SINGLELINE | DT_CALCRECT );
         if (delta > 1)
         {
             rc.top += delta - 1;
             rc.bottom -= delta + 1;
         }
         rc.left--;
-        rc.right = MIN( rc.left + size.cx + 2, rc.right );
+        rc.right = rc.left + rect.right + 2;
         DrawFocusRect16( hDC, &rc );
     }
 }
@@ -444,10 +445,9 @@ static void BUTTON_CheckAutoRadioButton( WND *wndPtr )
  *       Group Box Functions
  */
 
-static void GB_Paint( WND *wndPtr, HDC hDC, WORD action )
+static void GB_Paint( WND *wndPtr, HDC32 hDC, WORD action )
 {
     RECT16 rc;
-    SIZE16 size;
     BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
 
     if (action != ODA_DRAWENTIRE) return;
@@ -465,13 +465,10 @@ static void GB_Paint( WND *wndPtr, HDC hDC, WORD action )
     LineTo( hDC, rc.left, rc.top+2 );
 
     if (!wndPtr->text) return;
-    GetTextExtentPoint16( hDC, wndPtr->text, strlen(wndPtr->text), &size );
-    rc.left  += 10;
-    rc.right  = rc.left + size.cx + 1;
-    rc.bottom = size.cy;
     if (wndPtr->dwStyle & WS_DISABLED)
         SetTextColor( hDC, GetSysColor(COLOR_GRAYTEXT) );
-    DrawText16( hDC, wndPtr->text, -1, &rc, DT_SINGLELINE );
+    rc.left += 10;
+    DrawText16( hDC, wndPtr->text, -1, &rc, DT_SINGLELINE | DT_NOCLIP );
 }
 
 
@@ -479,7 +476,7 @@ static void GB_Paint( WND *wndPtr, HDC hDC, WORD action )
  *       User Button Functions
  */
 
-static void UB_Paint( WND *wndPtr, HDC hDC, WORD action )
+static void UB_Paint( WND *wndPtr, HDC32 hDC, WORD action )
 {
     RECT16 rc;
     HBRUSH hBrush;
@@ -503,7 +500,7 @@ static void UB_Paint( WND *wndPtr, HDC hDC, WORD action )
  *       Ownerdrawn Button Functions
  */
 
-static void OB_Paint( WND *wndPtr, HDC hDC, WORD action )
+static void OB_Paint( WND *wndPtr, HDC32 hDC, WORD action )
 {
     BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
     DRAWITEMSTRUCT32 dis;
diff --git a/controls/combo.c b/controls/combo.c
index 0904e8b1da9..412fb2e32e6 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -87,7 +87,7 @@ void ComboUpdateWindow(HWND hwnd, LPHEADLIST lphl, LPHEADCOMBO lphc, BOOL repain
   WND *wndPtr = WIN_FindWndPtr(hwnd);
 
   if (wndPtr->dwStyle & WS_VSCROLL) 
-    SetScrollRange(lphc->hWndLBox,SB_VERT,0,ListMaxFirstVisible(lphl),TRUE);
+    SetScrollRange32(lphc->hWndLBox,SB_VERT,0,ListMaxFirstVisible(lphl),TRUE);
   if (repaint && lphl->bRedrawFlag) InvalidateRect32( hwnd, NULL, TRUE );
 }
 
@@ -240,7 +240,11 @@ static LRESULT CBPaint(HWND hwnd, WPARAM wParam, LPARAM lParam)
   {
     Rectangle(hdc,lphc->RectButton.left-1,lphc->RectButton.top-1,
 	      lphc->RectButton.right+1,lphc->RectButton.bottom+1);
-    GRAPH_DrawReliefRect(hdc, &lphc->RectButton, 2, 2, FALSE);
+    {
+        RECT32 r;
+        CONV_RECT16TO32( &lphc->RectButton, &r );
+        GRAPH_DrawReliefRect(hdc, &r, 2, 2, FALSE);
+    }
     GRAPH_DrawBitmap(hdc, hComboBit,
 		     lphc->RectButton.left + 2,lphc->RectButton.top + 2,
 		     0, 0, CBitWidth, CBitHeight );
@@ -889,7 +893,7 @@ static LRESULT CBLKeyDown( HWND hwnd, WPARAM wParam, LPARAM lParam )
   SendMessage16(GetParent16(hwnd), WM_COMMAND,ID_CLB,MAKELONG(0,CBN_SELCHANGE));
   lphl->ItemFocused = newFocused;
   ListBoxScrollToFocus(lphl);
-  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+  SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
   InvalidateRect32( hwnd, NULL, TRUE );
   return 0;
 }
@@ -971,7 +975,7 @@ static LRESULT CBLPaint( HWND hwnd, WPARAM wParam, LPARAM lParam )
   }
 
   if (wndPtr->dwStyle & WS_VSCROLL) 
-      SetScrollRange(hwnd, SB_VERT, 0, ListMaxFirstVisible(lphl), TRUE);
+      SetScrollRange32(hwnd, SB_VERT, 0, ListMaxFirstVisible(lphl), TRUE);
 
   SelectObject(hdc,hOldFont);
   EndPaint16( hwnd, &ps );
@@ -1008,7 +1012,7 @@ static LRESULT CBLLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam )
   RECT16     rectsel;
 
 /*  SetFocus32(hwnd); */
-  SetCapture(hwnd);
+  SetCapture32(hwnd);
 
   lphl->PrevFocused = lphl->ItemFocused;
 
@@ -1030,7 +1034,7 @@ static LRESULT CBLLButtonUp( HWND hwnd, WPARAM wParam, LPARAM lParam )
 {
   LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
 
-  if (GetCapture() == hwnd) ReleaseCapture();
+  if (GetCapture32() == hwnd) ReleaseCapture();
 
   if(!lphl)
      {
@@ -1070,7 +1074,7 @@ hwnd,wParam,lParam,y,lphl->ItemFocused,wRet,rectsel.left,rectsel.top,rectsel.rig
     if (y < CBLMM_EDGE) {
       if (lphl->FirstVisible > 0) {
 	lphl->FirstVisible--;
-	SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+	SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
 	ListBoxSetCurSel(lphl, wRet);
 	InvalidateRect32( hwnd, NULL, TRUE );
 	return 0;
@@ -1079,7 +1083,7 @@ hwnd,wParam,lParam,y,lphl->ItemFocused,wRet,rectsel.left,rectsel.top,rectsel.rig
     else if (y >= (rect.bottom-CBLMM_EDGE)) {
       if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) {
 	lphl->FirstVisible++;
-	SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+	SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
 	ListBoxSetCurSel(lphl, wRet);
 	InvalidateRect32( hwnd, NULL, TRUE );
 	return 0;
@@ -1136,7 +1140,7 @@ static LRESULT CBLVScroll( HWND hwnd, WPARAM wParam, LPARAM lParam )
     lphl->FirstVisible = ListMaxFirstVisible(lphl);
 
   if (y != lphl->FirstVisible) {
-    SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+    SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
     InvalidateRect32( hwnd, NULL, TRUE );
   }
 
diff --git a/controls/desktop.c b/controls/desktop.c
index 810dd5c255f..f7529e8c61c 100644
--- a/controls/desktop.c
+++ b/controls/desktop.c
@@ -4,13 +4,13 @@
  * Copyright 1994 Alexandre Julliard
  */
 
+#define NO_TRANSITION_TYPES  /* This file is Win32-clean */
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
 #include "win.h"
 #include "desktop.h"
 #include "directory.h"
-#include "file.h"
 #include "graphics.h"
 #include "heap.h"
 
@@ -20,11 +20,11 @@
  *
  * Load a bitmap from a file. Used by SetDeskWallPaper().
  */
-static HBITMAP DESKTOP_LoadBitmap( HDC hdc, const char *filename )
+static HBITMAP32 DESKTOP_LoadBitmap( HDC32 hdc, const char *filename )
 {
     BITMAPFILEHEADER *fileHeader;
     BITMAPINFO *bitmapInfo;
-    HBITMAP hbitmap;
+    HBITMAP32 hbitmap;
     HFILE file;
     LPSTR buffer;
     LONG size;
@@ -33,10 +33,10 @@ static HBITMAP DESKTOP_LoadBitmap( HDC hdc, const char *filename )
 
     if ((file = _lopen( filename, OF_READ )) == HFILE_ERROR)
     {
-        UINT32 len = GetWindowsDirectory( NULL, 0 );
+        UINT32 len = GetWindowsDirectory32A( NULL, 0 );
         if (!(buffer = HeapAlloc( SystemHeap, 0, len + strlen(filename) + 2 )))
             return 0;
-        GetWindowsDirectory( buffer, len + 1 );
+        GetWindowsDirectory32A( buffer, len + 1 );
         strcat( buffer, "\\" );
         strcat( buffer, filename );
         file = _lopen( buffer, OF_READ );
@@ -50,7 +50,7 @@ static HBITMAP DESKTOP_LoadBitmap( HDC hdc, const char *filename )
 	return 0;
     }
     _llseek( file, 0, 0 );
-    size = FILE_Read( file, buffer, size );
+    size = _lread32( file, buffer, size );
     _lclose( file );
     fileHeader = (BITMAPFILEHEADER *)buffer;
     bitmapInfo = (BITMAPINFO *)(buffer + sizeof(BITMAPFILEHEADER));
@@ -74,15 +74,16 @@ static HBITMAP DESKTOP_LoadBitmap( HDC hdc, const char *filename )
  *
  * Handle the WM_ERASEBKGND message.
  */
-static LONG DESKTOP_DoEraseBkgnd( HWND hwnd, HDC hdc, DESKTOPINFO *infoPtr )
+static LRESULT DESKTOP_DoEraseBkgnd( HWND32 hwnd, HDC32 hdc,
+                                     DESKTOPINFO *infoPtr )
 {
-    RECT16 rect;
+    RECT32 rect;
     WND*   Wnd = WIN_FindWndPtr( hwnd );
 
     if( Wnd->hrgnUpdate > 1 ) DeleteObject( Wnd->hrgnUpdate );
     Wnd->hrgnUpdate = 0;
 
-    GetClientRect16( hwnd, &rect );    
+    GetClientRect32( hwnd, &rect );    
 
     /* Paint desktop pattern (only if wall paper does not cover everything) */
 
@@ -93,14 +94,14 @@ static LONG DESKTOP_DoEraseBkgnd( HWND hwnd, HDC hdc, DESKTOPINFO *infoPtr )
 	  /* Set colors in case pattern is a monochrome bitmap */
 	SetBkColor( hdc, RGB(0,0,0) );
 	SetTextColor( hdc, GetSysColor(COLOR_BACKGROUND) );
-	FillRect16( hdc, &rect, infoPtr->hbrushPattern );
+	FillRect32( hdc, &rect, infoPtr->hbrushPattern );
     }
 
       /* Paint wall paper */
 
     if (infoPtr->hbitmapWallPaper)
     {
-	int x, y;
+	INT32 x, y;
 
 	if (infoPtr->fTileWallPaper)
 	{
@@ -147,12 +148,12 @@ LRESULT DesktopWndProc( HWND32 hwnd, UINT32 message,
 	infoPtr->hbrushPattern = 0;
 	infoPtr->hbitmapWallPaper = 0;
 	SetDeskPattern();
-	SetDeskWallPaper( (LPSTR)-1 );
+	SetDeskWallPaper32( (LPSTR)-1 );
 	break;
 	
     case WM_ERASEBKGND:
 	if (rootWindow == DefaultRootWindow(display)) return 1;
-	return DESKTOP_DoEraseBkgnd( hwnd, (HDC)wParam, infoPtr );
+	return DESKTOP_DoEraseBkgnd( hwnd, (HDC32)wParam, infoPtr );
 
     case WM_SYSCOMMAND:
 	if ((wParam & 0xfff0) != SC_CLOSE) return 0;
@@ -169,7 +170,7 @@ LRESULT DesktopWndProc( HWND32 hwnd, UINT32 message,
 /***********************************************************************
  *           SetDeskPattern   (USER.279)
  */
-BOOL SetDeskPattern(void)
+BOOL16 SetDeskPattern(void)
 {
     char buffer[100];
     GetProfileString( "desktop", "Pattern", "(None)", buffer, 100 );
@@ -178,14 +179,25 @@ BOOL SetDeskPattern(void)
 
 
 /***********************************************************************
- *           SetDeskWallPaper   (USER.285)
+ *           SetDeskWallPaper16   (USER.285)
  */
-BOOL SetDeskWallPaper( LPCSTR filename )
+BOOL16 SetDeskWallPaper16( LPCSTR filename )
 {
-    HBITMAP hbitmap;
-    HDC hdc;
+    return SetDeskWallPaper32( filename );
+}
+
+
+/***********************************************************************
+ *           SetDeskWallPaper32   (USER32.475)
+ *
+ * FIXME: is there a unicode version?
+ */
+BOOL32 SetDeskWallPaper32( LPCSTR filename )
+{
+    HBITMAP32 hbitmap;
+    HDC32 hdc;
     char buffer[256];
-    WND *wndPtr = WIN_FindWndPtr( GetDesktopWindow() );
+    WND *wndPtr = WIN_GetDesktop();
     DESKTOPINFO *infoPtr = (DESKTOPINFO *)wndPtr->wExtra;
 
     if (filename == (LPSTR)-1)
@@ -193,16 +205,16 @@ BOOL SetDeskWallPaper( LPCSTR filename )
 	GetProfileString( "desktop", "WallPaper", "(None)", buffer, 256 );
 	filename = buffer;
     }
-    hdc = GetDC( 0 );
+    hdc = GetDC32( 0 );
     hbitmap = DESKTOP_LoadBitmap( hdc, filename );
-    ReleaseDC( 0, hdc );
+    ReleaseDC32( 0, hdc );
     if (infoPtr->hbitmapWallPaper) DeleteObject( infoPtr->hbitmapWallPaper );
     infoPtr->hbitmapWallPaper = hbitmap;
     infoPtr->fTileWallPaper = GetProfileInt( "desktop", "TileWallPaper", 0 );
     if (hbitmap)
     {
-	BITMAP16 bmp;
-	GetObject16( hbitmap, sizeof(bmp), &bmp );
+	BITMAP32 bmp;
+	GetObject32A( hbitmap, sizeof(bmp), &bmp );
 	infoPtr->bitmapSize.cx = (bmp.bmWidth != 0) ? bmp.bmWidth : 1;
 	infoPtr->bitmapSize.cy = (bmp.bmHeight != 0) ? bmp.bmHeight : 1;
     }
@@ -215,9 +227,9 @@ BOOL SetDeskWallPaper( LPCSTR filename )
  *
  * Set the desktop pattern.
  */
-BOOL DESKTOP_SetPattern(char *pattern )
+BOOL32 DESKTOP_SetPattern( LPCSTR pattern )
 {
-    WND *wndPtr = WIN_FindWndPtr( GetDesktopWindow() );
+    WND *wndPtr = WIN_GetDesktop();
     DESKTOPINFO *infoPtr = (DESKTOPINFO *)wndPtr->wExtra;
     int pat[8];
 
@@ -228,7 +240,7 @@ BOOL DESKTOP_SetPattern(char *pattern )
 			   &pat[4], &pat[5], &pat[6], &pat[7] ))
     {
 	WORD pattern[8];
-	HBITMAP hbitmap;
+	HBITMAP32 hbitmap;
 	int i;
 
 	for (i = 0; i < 8; i++) pattern[i] = pat[i] & 0xffff;
diff --git a/controls/edit.c b/controls/edit.c
index 939e1009c1d..fb87a798273 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -14,7 +14,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <windows.h>
+#include "windows.h"
 #include "win.h"
 #include "local.h"
 #include "stddebug.h"
@@ -503,7 +503,7 @@ static void EDIT_BuildLineDefs(WND *wndPtr)
 	EDITSTATE *es = EDITSTATEPTR(wndPtr);
 	char *text = EDIT_GetPasswordPointer(wndPtr);
 	int ww = EDIT_GetWndWidth(wndPtr);
-	HDC hdc;
+	HDC32 hdc;
 	HFONT hFont;
 	HFONT oldFont = 0;
 	char *start, *cp;
@@ -512,7 +512,7 @@ static void EDIT_BuildLineDefs(WND *wndPtr)
 	int length;
 	LINE_END ending;
 
-	hdc = GetDC(wndPtr->hwndSelf);
+	hdc = GetDC32(wndPtr->hwndSelf);
 	hFont = (HFONT)EDIT_WM_GetFont(wndPtr, 0, 0L);
 	if (hFont)
 		oldFont = SelectObject(hdc, hFont);
@@ -598,7 +598,7 @@ static void EDIT_BuildLineDefs(WND *wndPtr)
 	}
 	if (hFont)
 		SelectObject(hdc, oldFont);
-	ReleaseDC(wndPtr->hwndSelf, hdc);
+	ReleaseDC32(wndPtr->hwndSelf, hdc);
 
 	free(text);
 }
@@ -1441,7 +1441,7 @@ static INT EDIT_WndXFromCol(WND *wndPtr, UINT line, UINT col)
 	EDITSTATE *es = EDITSTATEPTR(wndPtr);
 	char *text = EDIT_GetPasswordPointer(wndPtr);
 	INT ret;
-	HDC hdc;
+	HDC32 hdc;
 	HFONT hFont;
 	HFONT oldFont = 0;
 	UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L);
@@ -1449,7 +1449,7 @@ static INT EDIT_WndXFromCol(WND *wndPtr, UINT line, UINT col)
 	UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, li, 0L);
 	UINT xoff = EDIT_GetXOffset(wndPtr);
 
-	hdc = GetDC(wndPtr->hwndSelf);
+	hdc = GetDC32(wndPtr->hwndSelf);
 	hFont = (HFONT)EDIT_WM_GetFont(wndPtr, 0, 0L);
 	if (hFont)
 		oldFont = SelectObject(hdc, hFont);
@@ -1460,7 +1460,7 @@ static INT EDIT_WndXFromCol(WND *wndPtr, UINT line, UINT col)
 			es->NumTabStops, es->TabStops)) - xoff;
 	if (hFont)
 		SelectObject(hdc, oldFont);
-	ReleaseDC(wndPtr->hwndSelf, hdc);
+	ReleaseDC32(wndPtr->hwndSelf, hdc);
 	free(text);
 	return ret;
 }
@@ -1859,10 +1859,10 @@ static LRESULT EDIT_EM_LineScroll(WND *wndPtr, WPARAM wParam, LPARAM lParam)
 		es->FirstVisibleLine = nfv;
 		es->XOffset = nxoff;
 		if (IsVScrollBar(wndPtr))
-			SetScrollPos(wndPtr->hwndSelf, SB_VERT,
+			SetScrollPos32(wndPtr->hwndSelf, SB_VERT,
 				EDIT_WM_VScroll(wndPtr, EM_GETTHUMB, 0L), TRUE);
 		if (IsHScrollBar(wndPtr))
-			SetScrollPos(wndPtr->hwndSelf, SB_HORZ,
+			SetScrollPos32(wndPtr->hwndSelf, SB_HORZ,
 				EDIT_WM_HScroll(wndPtr, EM_GETTHUMB, 0L), TRUE);
 		if (wndPtr->hwndSelf == GetFocus32()) {
 			GetCaretPos16(&pos);
@@ -2604,7 +2604,7 @@ static LRESULT EDIT_WM_LButtonDown(WND *wndPtr, WPARAM wParam, LPARAM lParam)
 	UINT li;
 
 	SetFocus32(wndPtr->hwndSelf);
-	SetCapture(wndPtr->hwndSelf);
+	SetCapture32(wndPtr->hwndSelf);
 	l = MIN(fv + vlc - 1, MAX(fv, l));
 	x = MIN(EDIT_GetWndWidth(wndPtr), MAX(0, x));
 	c = EDIT_ColFromWndX(wndPtr, l, x);
@@ -2626,7 +2626,7 @@ static LRESULT EDIT_WM_LButtonDown(WND *wndPtr, WPARAM wParam, LPARAM lParam)
  */
 static LRESULT EDIT_WM_LButtonUp(WND *wndPtr, WPARAM wParam, LPARAM lParam)
 {
-	if (GetCapture() == wndPtr->hwndSelf)
+	if (GetCapture32() == wndPtr->hwndSelf)
 		ReleaseCapture();
 	return 0L;
 }
@@ -2648,7 +2648,7 @@ static LRESULT EDIT_WM_MouseMove(WND *wndPtr, WPARAM wParam, LPARAM lParam)
 	UINT vlc;
 	UINT li;
 
-	if (GetCapture() == wndPtr->hwndSelf) {
+	if (GetCapture32() == wndPtr->hwndSelf) {
 		x = (INT)LOWORD(lParam);
 		y = (INT)HIWORD(lParam);
 		fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L);
@@ -2775,11 +2775,11 @@ static LRESULT EDIT_WM_SetFont(WND *wndPtr, WPARAM wParam, LPARAM lParam)
 	TEXTMETRIC16 tm;
 	EDITSTATE *es = EDITSTATEPTR(wndPtr);
 	LPARAM sel = EDIT_EM_GetSel(wndPtr, 0, 0L);
-	HDC hdc;
+	HDC32 hdc;
 	HFONT oldFont = 0;
 
 	es->hFont = (HFONT)wParam;
-	hdc = GetDC(wndPtr->hwndSelf);
+	hdc = GetDC32(wndPtr->hwndSelf);
 	if (es->hFont)
 		oldFont = SelectObject(hdc, es->hFont);
 	GetTextMetrics16(hdc, &tm);
@@ -2787,7 +2787,7 @@ static LRESULT EDIT_WM_SetFont(WND *wndPtr, WPARAM wParam, LPARAM lParam)
 	es->AveCharWidth = tm.tmAveCharWidth;
 	if (es->hFont)
 		SelectObject(hdc, oldFont);
-	ReleaseDC(wndPtr->hwndSelf, hdc);
+	ReleaseDC32(wndPtr->hwndSelf, hdc);
 	EDIT_BuildLineDefs(wndPtr);
 	if ((BOOL)lParam && EDIT_GetRedraw(wndPtr))
 		InvalidateRect32( wndPtr->hwndSelf, NULL, TRUE );
diff --git a/controls/listbox.c b/controls/listbox.c
index 5a16e4af7c8..4abf763f4b2 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -64,7 +64,7 @@ static void ListBoxInitialize(LPHEADLIST lphl)
 void CreateListBoxStruct(HWND hwnd, WORD CtlType, LONG styles, HWND parent)
 {
   LPHEADLIST lphl;
-  HDC         hdc;
+  HDC32         hdc;
 
   lphl = (LPHEADLIST)xmalloc(sizeof(HEADLIST));
   SetWindowLong32A(hwnd, 0, (LONG)lphl);
@@ -87,14 +87,14 @@ void CreateListBoxStruct(HWND hwnd, WORD CtlType, LONG styles, HWND parent)
   lphl->HasStrings     = (styles & LBS_HASSTRINGS) || !lphl->OwnerDrawn;
 
   /* create dummy hdc to set text height */
-  if ((hdc = GetDC(0)))
+  if ((hdc = GetDC32(0)))
   {
       TEXTMETRIC16 tm;
       GetTextMetrics16( hdc, &tm );
       lphl->StdItemHeight = tm.tmHeight;
       dprintf_listbox(stddeb,"CreateListBoxStruct:  font height %d\n",
                       lphl->StdItemHeight);
-      ReleaseDC( 0, hdc );
+      ReleaseDC32( 0, hdc );
   }
 
   if (lphl->OwnerDrawn)
@@ -148,9 +148,9 @@ int ListMaxFirstVisible(LPHEADLIST lphl)
 void ListBoxUpdateWindow(HWND hwnd, LPHEADLIST lphl, BOOL repaint)
 {
   if (lphl->dwStyle & WS_VSCROLL)
-    SetScrollRange(hwnd, SB_VERT, 0, ListMaxFirstVisible(lphl), TRUE);
+    SetScrollRange32(hwnd, SB_VERT, 0, ListMaxFirstVisible(lphl), TRUE);
   if ((lphl->dwStyle & WS_HSCROLL) && (lphl->ItemsPerColumn != 0))
-    SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible /
+    SetScrollRange32(hwnd, SB_HORZ, 1, lphl->ItemsVisible /
 		   lphl->ItemsPerColumn + 1, TRUE);
 
   if (repaint && lphl->bRedrawFlag) InvalidateRect32( hwnd, NULL, TRUE );
@@ -811,12 +811,16 @@ LONG ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPCSTR filespec)
     if (attrib & DDL_DRIVES)
     {
         int x;
+	DWORD oldstyle = lphl->dwStyle;
+	    
+	lphl->dwStyle &= ~LBS_SORT;
         strcpy( temp, "[-a-]" );
         for (x = 0; x < MAX_DOS_DRIVES; x++, temp[2]++)
         {
             if (DRIVE_IsValid(x))
                 if ((ret = ListBoxAddString(lphl, SEGPTR_GET(temp))) == LB_ERR) break;
         }
+	lphl->dwStyle = oldstyle;
     }
 
     free( path );
@@ -831,8 +835,22 @@ int ListBoxGetItemRect(LPHEADLIST lphl, WORD wIndex, LPRECT16 lprect)
 {
   LPLISTSTRUCT lpls = ListBoxGetItem(lphl,wIndex);
 
-  if (lpls == NULL) return LB_ERR;
-  *lprect = lpls->itemRect;
+  dprintf_listbox(stddeb,"ListBox LB_GETITEMRECT %i %p", wIndex,lpls);
+  if (lpls == NULL)
+  {
+    if (lphl->dwStyle & LBS_OWNERDRAWVARIABLE)
+      return LB_ERR;
+    else 
+    {
+     GetClientRect16(lphl->hSelf,lprect);
+     lprect->bottom=lphl->StdItemHeight;
+     if (lprect->right<0) lprect->right=0;
+    }
+  }
+  else
+   *lprect = lpls->itemRect;
+  dprintf_listbox(stddeb," = %d,%d  %d,%d\n", lprect->left,lprect->top,
+                                              lprect->right,lprect->bottom);
   return 0;
 }
 
@@ -897,9 +915,9 @@ static LONG LBCreate(HWND hwnd, WORD wParam, LONG lParam)
   lphl->ColumnsWidth = rect.right - rect.left;
 
   if (dwStyle & WS_VSCROLL) 
-    SetScrollRange(hwnd, SB_VERT, 0, ListMaxFirstVisible(lphl), TRUE);
+    SetScrollRange32(hwnd, SB_VERT, 0, ListMaxFirstVisible(lphl), TRUE);
   if (dwStyle & WS_HSCROLL) 
-    SetScrollRange(hwnd, SB_HORZ, 1, 1, TRUE);
+    SetScrollRange32(hwnd, SB_HORZ, 1, 1, TRUE);
 
   return 0;
 }
@@ -974,7 +992,7 @@ static LONG LBVScroll(HWND hwnd, WORD wParam, LONG lParam)
     lphl->FirstVisible = ListMaxFirstVisible(lphl);
 
   if (y != lphl->FirstVisible) {
-    SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+    SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
     InvalidateRect32( hwnd, NULL, TRUE );
   }
   return 0;
@@ -1029,7 +1047,7 @@ static LONG LBHScroll(HWND hwnd, WORD wParam, LONG lParam)
     lphl->FirstVisible = lphl->FirstVisible /
       lphl->ItemsPerColumn * lphl->ItemsPerColumn + 1;
     if (y != lphl->FirstVisible) {
-      SetScrollPos(hwnd, SB_HORZ, lphl->FirstVisible / 
+      SetScrollPos32(hwnd, SB_HORZ, lphl->FirstVisible / 
 		   lphl->ItemsPerColumn + 1, TRUE);
       InvalidateRect32( hwnd, NULL, TRUE );
     }
@@ -1048,7 +1066,7 @@ static LONG LBLButtonDown(HWND hwnd, WORD wParam, LONG lParam)
   RECT16     rectsel;
 
   SetFocus32(hwnd);
-  SetCapture(hwnd);
+  SetCapture32(hwnd);
 
   lphl->PrevFocused = lphl->ItemFocused;
 
@@ -1122,7 +1140,7 @@ static LONG LBLButtonUp(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
-  if (GetCapture() == hwnd) ReleaseCapture();
+  if (GetCapture32() == hwnd) ReleaseCapture();
 
   if (lphl->PrevFocused != lphl->ItemFocused)
     ListBoxSendNotification(lphl, LBN_SELCHANGE);
@@ -1158,7 +1176,7 @@ static LONG LBMouseMove(HWND hwnd, WORD wParam, LONG lParam)
     if (y < LBMM_EDGE) {
       if (lphl->FirstVisible > 0) {
 	lphl->FirstVisible--;
-	SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+	SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
 	InvalidateRect32( hwnd, NULL, TRUE );
 	return 0;
       }
@@ -1167,7 +1185,7 @@ static LONG LBMouseMove(HWND hwnd, WORD wParam, LONG lParam)
     if (y >= (rect.bottom-LBMM_EDGE)) {
       if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) {
 	lphl->FirstVisible++;
-	SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+	SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
 	InvalidateRect32( hwnd, NULL, TRUE );
 	return 0;
       }
@@ -1322,7 +1340,7 @@ static LONG LBKeyDown(HWND hwnd, WORD wParam, LONG lParam)
           }
     }
 
-  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+  SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
 
   return 0;
 }
@@ -1358,7 +1376,7 @@ static LONG LBChar(HWND hwnd, WORD wParam, LONG lParam)
 
   lphl->ItemFocused = newFocused;
   ListBoxScrollToFocus(lphl);
-  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+  SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
 
   InvalidateRect32( hwnd, NULL, TRUE );
 
@@ -1385,7 +1403,7 @@ static LONG LBSetRedraw(HWND hwnd, WORD wParam, LONG lParam)
 static LONG LBSetFont(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST  lphl = ListBoxGetStorageHeader(hwnd);
-  HDC hdc;
+  HDC32 hdc;
 
   if (wParam == 0)
     lphl->hFont = GetStockObject(SYSTEM_FONT);
@@ -1395,14 +1413,14 @@ static LONG LBSetFont(HWND hwnd, WPARAM wParam, LPARAM lParam)
   /* a new font means possible new text height */
   /* does this mean the height of each entry must be separately changed? */
   /* or are we guaranteed to get a LBSetFont before the first insert/add? */
-  if ((hdc = GetDC(0)))
+  if ((hdc = GetDC32(0)))
   {
       TEXTMETRIC16 tm;
       GetTextMetrics16( hdc, &tm );
       lphl->StdItemHeight = tm.tmHeight;
       dprintf_listbox(stddeb,"LBSetFont:  new font %d with height %d\n",
                       lphl->hFont, lphl->StdItemHeight);
-      ReleaseDC( 0, hdc );
+      ReleaseDC32( 0, hdc );
   }
 
   return 0;
@@ -1517,7 +1535,7 @@ static LONG LBSetFocus(HWND hwnd, WORD wParam, LONG lParam)
   if(!(lphl->dwStyle & LBS_MULTIPLESEL) )
        if( lphl->ItemsCount && lphl->ItemFocused != -1)
          {
-           HDC          hDC = GetDC(hwnd);
+           HDC32        hDC = GetDC32(hwnd);
            HFONT        hOldFont = SelectObject(hDC, lphl->hFont);
            LPLISTSTRUCT lpls;
 
@@ -1526,7 +1544,7 @@ static LONG LBSetFocus(HWND hwnd, WORD wParam, LONG lParam)
 
            ListBoxDrawItem(hwnd,lphl,hDC,lpls,&lpls->itemRect, ODA_FOCUS, lpls->itemState);
            SelectObject(hDC, hOldFont);
-           ReleaseDC(hwnd,hDC);
+           ReleaseDC32(hwnd,hDC);
          }
 
   ListBoxSendNotification(lphl, LBN_SETFOCUS);
@@ -1547,7 +1565,7 @@ static LONG LBKillFocus(HWND hwnd, WORD wParam, LONG lParam)
        if( lphl->ItemsCount )
            if( lphl->ItemFocused != -1 )
              {
-              HDC          hDC = GetDC(hwnd);
+              HDC32        hDC = GetDC32(hwnd);
               HFONT        hOldFont = SelectObject(hDC, lphl->hFont);
               LPLISTSTRUCT lpls;
 
@@ -1556,7 +1574,7 @@ static LONG LBKillFocus(HWND hwnd, WORD wParam, LONG lParam)
 
               ListBoxDrawItem(hwnd,lphl,hDC,lpls,&lpls->itemRect, ODA_FOCUS, lpls->itemState);
               SelectObject(hDC, hOldFont);
-              ReleaseDC(hwnd,hDC);
+              ReleaseDC32(hwnd,hDC);
              }
            else
              dprintf_listbox(stddeb,"LBKillFocus: no focused item!\n");
@@ -1905,7 +1923,7 @@ static LONG LBSetCaretIndex(HWND hwnd, WORD wParam, LONG lParam)
   lphl->ItemFocused = wParam;
   i = ListBoxScrollToFocus (lphl);
 
-  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+  SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
   if(i)
     InvalidateRect32( hwnd, NULL, TRUE );
  
@@ -1988,7 +2006,7 @@ static LONG LBSetCurSel(HWND hwnd, WORD wParam, LONG lParam)
 
   wRet = ListBoxSetCurSel(lphl, wParam);
 
-  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+  SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
   InvalidateRect32( hwnd, NULL, TRUE );
 
   return wRet;
@@ -2034,7 +2052,7 @@ static LONG LBSetTopIndex(HWND hwnd, WORD wParam, LONG lParam)
   dprintf_listbox(stddeb,"ListBox LB_SETTOPINDEX wParam=%x !\n",
 		  wParam);
   lphl->FirstVisible = wParam;
-  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+  SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
 
   InvalidateRect32( hwnd, NULL, TRUE );
 
diff --git a/controls/menu.c b/controls/menu.c
index bc1a6ac7d5c..d18b3ca320d 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -87,8 +87,9 @@ static BOOL fEndMenuCalled = FALSE;
 #define IS_STRING_ITEM(flags) (!((flags) & (MF_BITMAP | MF_OWNERDRAW | \
 			     MF_MENUBARBREAK | MF_MENUBREAK | MF_SEPARATOR)))
 
-extern void NC_DrawSysButton(HWND hwnd, HDC hdc, BOOL down);  /* nonclient.c */
-extern BOOL NC_GetSysPopupPos(WND* wndPtr, RECT16* rect);
+extern void  NC_DrawSysButton(HWND hwnd, HDC hdc, BOOL down); /* nonclient.c */
+extern BOOL  NC_GetSysPopupPos(WND* wndPtr, RECT16* rect);
+extern HTASK TASK_GetNextTask(HTASK);
 
 static HBITMAP hStdCheck = 0;
 static HBITMAP hStdMnArrow = 0;
@@ -209,6 +210,30 @@ static BOOL MENU_IsInSysMenu( POPUPMENU *menu, POINT16 pt )
 }
 
 
+/***********************************************************************
+ *           MENU_InitSysMenuPopup
+ *
+ * Grey the appropriate items in System menu.
+ */
+void MENU_InitSysMenuPopup(HMENU hmenu, DWORD style, DWORD clsStyle)
+{
+    BOOL gray;
+
+    gray = !(style & WS_THICKFRAME) || (style & (WS_MAXIMIZE | WS_MINIMIZE));
+    EnableMenuItem( hmenu, SC_SIZE, (gray ? MF_GRAYED : MF_ENABLED) );
+    gray = ((style & WS_MAXIMIZE) != 0);
+    EnableMenuItem( hmenu, SC_MOVE, (gray ? MF_GRAYED : MF_ENABLED) );
+    gray = !(style & WS_MINIMIZEBOX) || (style & WS_MINIMIZE);
+    EnableMenuItem( hmenu, SC_MINIMIZE, (gray ? MF_GRAYED : MF_ENABLED) );
+    gray = !(style & WS_MAXIMIZEBOX) || (style & WS_MAXIMIZE);
+    EnableMenuItem( hmenu, SC_MAXIMIZE, (gray ? MF_GRAYED : MF_ENABLED) );
+    gray = !(style & (WS_MAXIMIZE | WS_MINIMIZE));
+    EnableMenuItem( hmenu, SC_RESTORE, (gray ? MF_GRAYED : MF_ENABLED) );
+    gray = (clsStyle & CS_NOCLOSE) != 0;
+    EnableMenuItem( hmenu, SC_CLOSE, (gray ? MF_GRAYED : MF_ENABLED) );
+}
+
+
 /***********************************************************************
  *           MENU_FindItem
  *
@@ -407,13 +432,13 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner,
 static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop, HWND hwndOwner )
 {
     MENUITEM *lpitem;
-    HDC hdc;
+    HDC32 hdc;
     int start, i;
     int orgX, orgY, maxX, maxTab, maxTabWidth;
 
     lppop->Width = lppop->Height = 0;
     if (lppop->nItems == 0) return;
-    hdc = GetDC( 0 );
+    hdc = GetDC32( 0 );
     maxX = start = 0;
     while (start < lppop->nItems)
     {
@@ -450,7 +475,7 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop, HWND hwndOwner )
     }
 
     lppop->Width  = maxX;
-    ReleaseDC( 0, hdc );
+    ReleaseDC32( 0, hdc );
 }
 
 
@@ -731,12 +756,25 @@ UINT MENU_DrawMenuBar(HDC hDC, LPRECT16 lprect, HWND hwnd, BOOL suppress_draw)
 /***********************************************************************
  *	     MENU_SwitchTPWndTo
  */
-static BOOL MENU_SwitchTPWndTo( HTASK hTask)
+BOOL32 MENU_SwitchTPWndTo( HTASK hTask)
 {
-  /* This is supposed to be called when popup is hidden */
+  /* This is supposed to be called when popup is hidden. 
+   * AppExit() calls with hTask == 0, so we get the next to current.
+   */
+
+  TDB* task;
+
+  if( !pTopPWnd ) return 0;
 
-  TDB* task = (TDB*)GlobalLock16(hTask);
+  if( !hTask )
+  {
+    task = (TDB*)GlobalLock16( (hTask = GetCurrentTask()) );
+    if( task && task->hQueue == pTopPWnd->hmemTaskQ )
+	hTask = TASK_GetNextTask(hTask); 
+    else return 0;
+  }
 
+  task = (TDB*)GlobalLock16(hTask);
   if( !task ) return 0;
 
   /* if this task got as far as menu tracking it must have a queue */
@@ -802,7 +840,7 @@ static BOOL MENU_ShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, int x, int y,
 	pTopPWnd = WIN_FindWndPtr(CreateWindow16( POPUPMENU_CLASS_ATOM, NULL,
                                           WS_POPUP | WS_BORDER, x, y,
                                           width, height,
-                                          0, 0, wndPtr->hInstance,
+                                          hwndOwner, 0, wndPtr->hInstance,
                                           (LPVOID)(HMENU32)hmenu ));
 	if (!pTopPWnd) return FALSE;
 	skip_init = TRUE;
@@ -851,7 +889,7 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex,
                              BOOL sendMenuSelect )
 {
     LPPOPUPMENU lppop;
-    HDC hdc;
+    HDC32 hdc;
 
     lppop = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     if (!lppop->nItems) return;
@@ -860,8 +898,8 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex,
 	(lppop->items[wIndex].item_flags & MF_SEPARATOR))
 	wIndex = NO_SELECTED_ITEM;
     if (lppop->FocusedItem == wIndex) return;
-    if (lppop->wFlags & MF_POPUP) hdc = GetDC( lppop->hWnd );
-    else hdc = GetDCEx( lppop->hWnd, 0, DCX_CACHE | DCX_WINDOW);
+    if (lppop->wFlags & MF_POPUP) hdc = GetDC32( lppop->hWnd );
+    else hdc = GetDCEx32( lppop->hWnd, 0, DCX_CACHE | DCX_WINDOW);
 
       /* Clear previous highlighted item */
     if (lppop->FocusedItem != NO_SELECTED_ITEM) 
@@ -903,7 +941,7 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex,
         SendMessage16( hwndOwner, WM_MENUSELECT, hmenu,
                        MAKELONG( lppop->wFlags | MF_MOUSESELECT, hmenu ) );
 
-    ReleaseDC( lppop->hWnd, hdc );
+    ReleaseDC32( lppop->hWnd, hdc );
 }
 
 
@@ -1187,6 +1225,8 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu, BOOL selectFirst )
     if (menu->FocusedItem == NO_SELECTED_ITEM) return hmenu;
     if (menu->FocusedItem == SYSMENU_SELECTED)
     {
+	MENU_InitSysMenuPopup(wndPtr->hSysMenu, wndPtr->dwStyle,
+				wndPtr->class->style);
 	MENU_ShowPopup(hwndOwner, wndPtr->hSysMenu, 0, wndPtr->rectClient.left,
 		wndPtr->rectClient.top - menu->Height - 2*SYSMETRICS_CYBORDER,
 		SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE );
@@ -1445,23 +1485,21 @@ static LRESULT MENU_DoNextMenu( HWND* hwndOwner, HMENU* hmenu, HMENU *hmenuCurre
 
     if( (menu->wFlags & (MF_POPUP | MF_SYSMENU)) == (MF_POPUP | MF_SYSMENU) )
 	{
-	  HDC hdc;
-
 	  ShowWindow( menu->hWnd, SW_HIDE );
 	  uSubPWndLevel = 0;
 
 	  if( !IsIconic( *hwndOwner ) )
 	  { 
-	    hdc = GetDCEx( *hwndOwner, 0, DCX_CACHE | DCX_WINDOW);
+	    HDC32 hdc = GetDCEx32( *hwndOwner, 0, DCX_CACHE | DCX_WINDOW);
 	    NC_DrawSysButton( *hwndOwner, hdc, FALSE );
-	    ReleaseDC( *hwndOwner, hdc );
+	    ReleaseDC32( *hwndOwner, hdc );
 	  }
 	}
 
     ReleaseCapture(); 
    *hwndOwner = HIWORD(l);
    *hmenu = LOWORD(l);
-    SetCapture( *hwndOwner );
+    SetCapture32( *hwndOwner );
 
     menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( *hmenu );
 
@@ -1484,9 +1522,9 @@ static LRESULT MENU_DoNextMenu( HWND* hwndOwner, HMENU* hmenu, HMENU *hmenuCurre
 
              if( !IsIconic( *hwndOwner ) )
              {
-               HDC hdc =  GetDCEx( *hwndOwner, 0, DCX_CACHE | DCX_WINDOW);
+               HDC32 hdc =  GetDCEx32( *hwndOwner, 0, DCX_CACHE | DCX_WINDOW);
                NC_DrawSysButton( *hwndOwner, hdc, TRUE );
-               ReleaseDC( *hwndOwner, hdc );
+               ReleaseDC32( *hwndOwner, hdc );
              }
 	  }
 	}
@@ -1618,7 +1656,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, int x, int y,
 	POINT16 pt = { x, y };
 	MENU_ButtonDown( hwnd, hmenu, &hmenuCurrent, pt );
     }
-    SetCapture( hwnd );
+    SetCapture32( hwnd );
     while (!fClosed)
     {
 	if (!MSG_InternalGetMessage( &msg, 0, hwnd, MSGF_MENU, 0, TRUE ))
@@ -1918,7 +1956,7 @@ LRESULT PopupMenuWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
 	     */
 
 	    if( hwnd == pTopPWnd->hwndSelf )
-		pTopPWnd = 0;
+	    {	pTopPWnd = NULL; uSubPWndLevel = 0; }
 	    else
 		uSubPWndLevel--;
 	    break;
@@ -1940,7 +1978,7 @@ LRESULT PopupMenuWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  */
 UINT MENU_GetMenuBarHeight( HWND hwnd, UINT menubarWidth, int orgX, int orgY )
 {
-    HDC hdc;
+    HDC32 hdc;
     RECT16 rectBar;
     WND *wndPtr;
     LPPOPUPMENU lppop;
@@ -1948,10 +1986,10 @@ UINT MENU_GetMenuBarHeight( HWND hwnd, UINT menubarWidth, int orgX, int orgY )
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
     if (!(lppop = (LPPOPUPMENU)USER_HEAP_LIN_ADDR((HMENU)wndPtr->wIDmenu)))
       return 0;
-    hdc = GetDCEx( hwnd, 0, DCX_CACHE | DCX_WINDOW );
+    hdc = GetDCEx32( hwnd, 0, DCX_CACHE | DCX_WINDOW );
     SetRect16(&rectBar, orgX, orgY, orgX+menubarWidth, orgY+SYSMETRICS_CYMENU);
     MENU_MenuBarCalcSize( hdc, &rectBar, lppop, hwnd );
-    ReleaseDC( hwnd, hdc );
+    ReleaseDC32( hwnd, hdc );
     return lppop->Height;
 }
 
@@ -2522,7 +2560,7 @@ BOOL SetMenu(HWND hWnd, HMENU hMenu)
 		return FALSE;
 		}
 	dprintf_menu(stddeb,"SetMenu(%04x, %04x);\n", hWnd, hMenu);
-	if (GetCapture() == hWnd) ReleaseCapture();
+	if (GetCapture32() == hWnd) ReleaseCapture();
 	wndPtr->wIDmenu = (UINT)hMenu;
 	if (hMenu != 0)
 	{
diff --git a/controls/scroll.c b/controls/scroll.c
index 8b6fb07dd45..34497fc95c2 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -1,13 +1,11 @@
 /*		
- * Interface code to SCROLLBAR widget
+ * Scrollbar control
  *
- * Copyright  Martin Ayotte, 1993
- * Copyright  Alexandre Julliard, 1994
- *
- * Small fixes and implemented SB_THUMBPOSITION
- * by Peter Broadhurst, 940611
+ * Copyright 1993 Martin Ayotte
+ * Copyright 1994, 1996 Alexandre Julliard
  */
 
+#define NO_TRANSITION_TYPES  /* This file is Win32-clean */
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/types.h>
@@ -23,18 +21,18 @@
 #include "debug.h"
 
 
-static HBITMAP hUpArrow = 0;
-static HBITMAP hDnArrow = 0;
-static HBITMAP hLfArrow = 0;
-static HBITMAP hRgArrow = 0;
-static HBITMAP hUpArrowD = 0;
-static HBITMAP hDnArrowD = 0;
-static HBITMAP hLfArrowD = 0;
-static HBITMAP hRgArrowD = 0;
-static HBITMAP hUpArrowI = 0;
-static HBITMAP hDnArrowI = 0;
-static HBITMAP hLfArrowI = 0;
-static HBITMAP hRgArrowI = 0;
+static HBITMAP32 hUpArrow = 0;
+static HBITMAP32 hDnArrow = 0;
+static HBITMAP32 hLfArrow = 0;
+static HBITMAP32 hRgArrow = 0;
+static HBITMAP32 hUpArrowD = 0;
+static HBITMAP32 hDnArrowD = 0;
+static HBITMAP32 hLfArrowD = 0;
+static HBITMAP32 hRgArrowD = 0;
+static HBITMAP32 hUpArrowI = 0;
+static HBITMAP32 hDnArrowI = 0;
+static HBITMAP32 hLfArrowI = 0;
+static HBITMAP32 hRgArrowI = 0;
 
 #define TOP_ARROW(flags,pressed) \
    (((flags)&ESB_DISABLE_UP) ? hUpArrowI : ((pressed) ? hUpArrowD:hUpArrow))
@@ -49,6 +47,9 @@ static HBITMAP hRgArrowI = 0;
   /* Minimum size of the rectangle between the arrows */
 #define SCROLL_MIN_RECT  4  
 
+  /* Minimum size of the thumb in pixels */
+#define SCROLL_MIN_THUMB 4
+
   /* Delay (in ms) before first repetition when holding the button down */
 #define SCROLL_FIRST_DELAY   200
 
@@ -70,34 +71,38 @@ enum SCROLL_HITTEST
 };
 
  /* Thumb-tracking info */
-static HWND hwndTracking = 0;
-static int nBarTracking = 0;
-static UINT uTrackingPos = 0;
+static HWND32 SCROLL_TrackingWin = 0;
+static INT32  SCROLL_TrackingBar = 0;
+static INT32  SCROLL_TrackingPos = 0;
+static INT32  SCROLL_TrackingVal = 0;
+
+/* Is the moving thumb being displayed? */
+static BOOL32 SCROLL_MovingThumb = FALSE;
 
 /***********************************************************************
  *           SCROLL_LoadBitmaps
  */
 static void SCROLL_LoadBitmaps(void)
 {
-    hUpArrow  = LoadBitmap16((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_UPARROW));
-    hDnArrow  = LoadBitmap16((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_DNARROW));
-    hLfArrow  = LoadBitmap16((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_LFARROW));
-    hRgArrow  = LoadBitmap16((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RGARROW));
-    hUpArrowD = LoadBitmap16((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_UPARROWD));
-    hDnArrowD = LoadBitmap16((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_DNARROWD));
-    hLfArrowD = LoadBitmap16((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_LFARROWD));
-    hRgArrowD = LoadBitmap16((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RGARROWD));
-    hUpArrowI = LoadBitmap16((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_UPARROWI));
-    hDnArrowI = LoadBitmap16((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_DNARROWI));
-    hLfArrowI = LoadBitmap16((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_LFARROWI));
-    hRgArrowI = LoadBitmap16((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RGARROWI));
+    hUpArrow  = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_UPARROW) );
+    hDnArrow  = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_DNARROW) );
+    hLfArrow  = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_LFARROW) );
+    hRgArrow  = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_RGARROW) );
+    hUpArrowD = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_UPARROWD) );
+    hDnArrowD = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_DNARROWD) );
+    hLfArrowD = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_LFARROWD) );
+    hRgArrowD = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_RGARROWD) );
+    hUpArrowI = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_UPARROWI) );
+    hDnArrowI = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_DNARROWI) );
+    hLfArrowI = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_LFARROWI) );
+    hRgArrowI = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_RGARROWI) );
 }
 
 
 /***********************************************************************
  *           SCROLL_GetPtrScrollInfo
  */
-static SCROLLBAR_INFO *SCROLL_GetPtrScrollInfo( WND* wndPtr, int nBar )
+static SCROLLBAR_INFO *SCROLL_GetPtrScrollInfo( WND* wndPtr, INT32 nBar )
 {
     SCROLLBAR_INFO *infoPtr;
 
@@ -114,7 +119,7 @@ static SCROLLBAR_INFO *SCROLL_GetPtrScrollInfo( WND* wndPtr, int nBar )
     {
         if ((infoPtr = HeapAlloc( SystemHeap, 0, sizeof(SCROLLBAR_INFO) )))
         {
-            infoPtr->MinVal = infoPtr->CurVal = 0;
+            infoPtr->MinVal = infoPtr->CurVal = infoPtr->Page = 0;
             infoPtr->MaxVal = 100;
             infoPtr->flags  = ESB_ENABLE_BOTH;
             if (nBar == SB_HORZ) wndPtr->pHScroll = infoPtr;
@@ -129,7 +134,7 @@ static SCROLLBAR_INFO *SCROLL_GetPtrScrollInfo( WND* wndPtr, int nBar )
 /***********************************************************************
  *           SCROLL_GetScrollInfo
  */
-static SCROLLBAR_INFO *SCROLL_GetScrollInfo( HWND hwnd, int nBar )
+static SCROLLBAR_INFO *SCROLL_GetScrollInfo( HWND32 hwnd, INT32 nBar )
 {
    WND *wndPtr = WIN_FindWndPtr( hwnd );
    return SCROLL_GetPtrScrollInfo( wndPtr, nBar );
@@ -141,16 +146,18 @@ static SCROLLBAR_INFO *SCROLL_GetScrollInfo( HWND hwnd, int nBar )
  *
  * Compute the scroll bar rectangle, in drawing coordinates (i.e. client
  * coords for SB_CTL, window coords for SB_VERT and SB_HORZ).
- * 'arrowSize' returns the width or height of an arrow (depending on the
- * orientation of the scrollbar), and 'thumbPos' returns the position of
- * the thumb relative to the left or to the top.
+ * 'arrowSize' returns the width or height of an arrow (depending on
+ * the orientation of the scrollbar), 'thumbSize' returns the size of
+ * the thumb, and 'thumbPos' returns the position of the thumb
+ * relative to the left or to the top.
  * Return TRUE if the scrollbar is vertical, FALSE if horizontal.
  */
-static BOOL SCROLL_GetScrollBarRect( HWND hwnd, int nBar, RECT16 *lprect,
-                                     WORD *arrowSize, WORD *thumbPos )
+static BOOL32 SCROLL_GetScrollBarRect( HWND32 hwnd, INT32 nBar, RECT32 *lprect,
+                                       INT32 *arrowSize, INT32 *thumbSize,
+                                       INT32 *thumbPos )
 {
-    int pixels;
-    BOOL vertical;
+    INT32 pixels;
+    BOOL32 vertical;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
     switch(nBar)
@@ -172,7 +179,7 @@ static BOOL SCROLL_GetScrollBarRect( HWND hwnd, int nBar, RECT16 *lprect,
 	break;
 
       case SB_CTL:
-	GetClientRect16( hwnd, lprect );
+	GetClientRect32( hwnd, lprect );
         vertical = ((wndPtr->dwStyle & SBS_VERT) != 0);
 	break;
 
@@ -183,28 +190,44 @@ static BOOL SCROLL_GetScrollBarRect( HWND hwnd, int nBar, RECT16 *lprect,
     if (vertical) pixels = lprect->bottom - lprect->top;
     else pixels = lprect->right - lprect->left;
 
-    if (pixels > 2*SYSMETRICS_CXVSCROLL + SCROLL_MIN_RECT)
-    {
-        *arrowSize = SYSMETRICS_CXVSCROLL;
-    }
-    else if (pixels > SCROLL_MIN_RECT)
+    if (pixels <= 2*SYSMETRICS_CXVSCROLL + SCROLL_MIN_RECT)
     {
-        *arrowSize = (pixels - SCROLL_MIN_RECT) / 2;
+        if (pixels > SCROLL_MIN_RECT)
+            *arrowSize = (pixels - SCROLL_MIN_RECT) / 2;
+        else
+            *arrowSize = 0;
+        *thumbPos = *thumbSize = 0;
     }
-    else *arrowSize = 0;
-    
-    if ((pixels -= 3*SYSMETRICS_CXVSCROLL+1) > 0)
+    else
     {
         SCROLLBAR_INFO *info = SCROLL_GetPtrScrollInfo( wndPtr, nBar );
-        if ((info->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH)
-            *thumbPos = 0;
-        else if (info->MinVal == info->MaxVal)
-            *thumbPos = *arrowSize;
+
+        *arrowSize = SYSMETRICS_CXVSCROLL;
+        pixels -= 2 * SYSMETRICS_CXVSCROLL;
+
+        if (info->Page)
+        {
+            *thumbSize = pixels * info->Page / (info->MaxVal-info->MinVal+1);
+            if (*thumbSize < SCROLL_MIN_THUMB) *thumbSize = SCROLL_MIN_THUMB;
+        }
+        else *thumbSize = SYSMETRICS_CXVSCROLL;
+
+        if (((pixels -= *thumbSize + 1) < 0) ||
+            ((info->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH))
+        {
+            /* Rectangle too small or scrollbar disabled -> no thumb */
+            *thumbPos = *thumbSize = 0;
+        }
         else
-            *thumbPos = *arrowSize + pixels * (info->CurVal - info->MinVal) /
-                                              (info->MaxVal - info->MinVal);
+        {
+            INT32 max = info->MaxVal - MAX( info->Page-1, 0 );
+            if (info->MinVal >= max)
+                *thumbPos = *arrowSize;
+            else
+                *thumbPos = *arrowSize + pixels * (info->CurVal-info->MinVal) /
+                                                  (max - info->MinVal);
+        }
     }
-    else *thumbPos = 0;
     return vertical;
 }
 
@@ -215,20 +238,29 @@ static BOOL SCROLL_GetScrollBarRect( HWND hwnd, int nBar, RECT16 *lprect,
  * Compute the current scroll position based on the thumb position in pixels
  * from the top of the scroll-bar.
  */
-static UINT SCROLL_GetThumbVal( SCROLLBAR_INFO *infoPtr, RECT16 *rect,
-                                BOOL vertical, WORD pos )
+static UINT32 SCROLL_GetThumbVal( SCROLLBAR_INFO *infoPtr, RECT32 *rect,
+                                  BOOL32 vertical, INT32 pos )
 {
-    int pixels = vertical ? rect->bottom-rect->top : rect->right-rect->left;
-    if ((pixels -= 3*SYSMETRICS_CXVSCROLL+1) <= 0) return infoPtr->MinVal;
+    INT32 thumbSize;
+    INT32 pixels = vertical ? rect->bottom-rect->top : rect->right-rect->left;
+
+    if ((pixels -= 2*SYSMETRICS_CXVSCROLL) <= 0) return infoPtr->MinVal;
+
+    if (infoPtr->Page)
+    {
+        thumbSize = pixels * infoPtr->Page/(infoPtr->MaxVal-infoPtr->MinVal+1);
+        if (thumbSize < SCROLL_MIN_THUMB) thumbSize = SCROLL_MIN_THUMB;
+    }
+    else thumbSize = SYSMETRICS_CXVSCROLL;
+
+    if ((pixels -= thumbSize + 1) <= 0) return infoPtr->MinVal;
+
     pos = MAX( 0, pos - SYSMETRICS_CXVSCROLL );
     if (pos > pixels) pos = pixels;
-    dprintf_scroll(stddeb,"GetThumbVal: pos=%d ret=%d\n", pos,
-                   (infoPtr->MinVal
-            + (UINT)(((int)pos * (infoPtr->MaxVal-infoPtr->MinVal) + pixels/2)
-                     / pixels)) );
-    return (infoPtr->MinVal
-            + (UINT)(((int)pos * (infoPtr->MaxVal-infoPtr->MinVal) + pixels/2)
-                     / pixels));
+
+    if (!infoPtr->Page) pos *= infoPtr->MaxVal - infoPtr->MinVal;
+    else pos *= infoPtr->MaxVal - infoPtr->MinVal - infoPtr->Page + 1;
+    return infoPtr->MinVal + ((pos + pixels / 2) / pixels);
 }
 
 
@@ -237,14 +269,15 @@ static UINT SCROLL_GetThumbVal( SCROLLBAR_INFO *infoPtr, RECT16 *rect,
  *
  * Scroll-bar hit testing (don't confuse this with WM_NCHITTEST!).
  */
-static enum SCROLL_HITTEST SCROLL_HitTest( HWND hwnd, int nBar, POINT16 pt )
+static enum SCROLL_HITTEST SCROLL_HitTest( HWND32 hwnd, INT32 nBar,
+                                           POINT32 pt )
 {
-    WORD arrowSize, thumbPos;
-    RECT16 rect;
+    INT32 arrowSize, thumbSize, thumbPos;
+    RECT32 rect;
 
-    BOOL vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
-                                             &arrowSize, &thumbPos );
-    if (!PtInRect16( &rect, pt )) return SCROLL_NOWHERE;
+    BOOL32 vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
+                                           &arrowSize, &thumbSize, &thumbPos );
+    if (!PtInRect32( &rect, pt )) return SCROLL_NOWHERE;
 
     if (vertical)
     {
@@ -252,8 +285,8 @@ static enum SCROLL_HITTEST SCROLL_HitTest( HWND hwnd, int nBar, POINT16 pt )
         if (pt.y >= rect.bottom - arrowSize) return SCROLL_BOTTOM_ARROW;
         if (!thumbPos) return SCROLL_TOP_RECT;
         pt.y -= rect.top;
-        if (pt.y < (INT)thumbPos) return SCROLL_TOP_RECT;
-        if (pt.y > thumbPos+SYSMETRICS_CYHSCROLL) return SCROLL_BOTTOM_RECT;
+        if (pt.y < thumbPos) return SCROLL_TOP_RECT;
+        if (pt.y > thumbPos + thumbSize) return SCROLL_BOTTOM_RECT;
         return SCROLL_THUMB;
     }
     else  /* horizontal */
@@ -262,8 +295,8 @@ static enum SCROLL_HITTEST SCROLL_HitTest( HWND hwnd, int nBar, POINT16 pt )
         if (pt.x >= rect.right - arrowSize) return SCROLL_BOTTOM_ARROW;
         if (!thumbPos) return SCROLL_TOP_RECT;
         pt.x -= rect.left;
-        if (pt.x < (INT)thumbPos) return SCROLL_TOP_RECT;
-        if (pt.x > thumbPos+SYSMETRICS_CXVSCROLL) return SCROLL_BOTTOM_RECT;
+        if (pt.x < thumbPos) return SCROLL_TOP_RECT;
+        if (pt.x > thumbPos + thumbSize) return SCROLL_BOTTOM_RECT;
         return SCROLL_THUMB;
     }
 }
@@ -274,12 +307,12 @@ static enum SCROLL_HITTEST SCROLL_HitTest( HWND hwnd, int nBar, POINT16 pt )
  *
  * Draw the scroll bar arrows.
  */
-static void SCROLL_DrawArrows( HDC hdc, SCROLLBAR_INFO *infoPtr, RECT16 *rect,
-                               WORD arrowSize, BOOL vertical,
-                               BOOL top_pressed, BOOL bottom_pressed )
+static void SCROLL_DrawArrows( HDC32 hdc, SCROLLBAR_INFO *infoPtr,
+                               RECT32 *rect, INT32 arrowSize, BOOL32 vertical,
+                               BOOL32 top_pressed, BOOL32 bottom_pressed )
 {
-    HDC hdcMem = CreateCompatibleDC( hdc );
-    HBITMAP hbmpPrev = SelectObject( hdcMem, vertical ?
+    HDC32 hdcMem = CreateCompatibleDC( hdc );
+    HBITMAP32 hbmpPrev = SelectObject( hdcMem, vertical ?
                                     TOP_ARROW(infoPtr->flags, top_pressed)
                                     : LEFT_ARROW(infoPtr->flags, top_pressed));
     SetStretchBltMode( hdc, STRETCH_DELETESCANS );
@@ -315,28 +348,29 @@ static void SCROLL_DrawArrows( HDC hdc, SCROLLBAR_INFO *infoPtr, RECT16 *rect,
  *
  * Draw the moving thumb rectangle.
  */
-static void SCROLL_DrawMovingThumb( HDC hdc, RECT16 *rect, BOOL vertical,
-                                    WORD arrowSize, WORD thumbPos )
+static void SCROLL_DrawMovingThumb( HDC32 hdc, RECT32 *rect, BOOL32 vertical,
+                                    INT32 arrowSize, INT32 thumbSize )
 {
-    RECT16 r = *rect;
+    RECT32 r = *rect;
     if (vertical)
     {
-        r.top += thumbPos;
+        r.top += SCROLL_TrackingPos;
         if (r.top < rect->top + arrowSize) r.top = rect->top + arrowSize;
-        if (r.top + SYSMETRICS_CYHSCROLL >= rect->bottom - arrowSize)
-            r.top = rect->bottom - arrowSize - SYSMETRICS_CYHSCROLL - 1;
-        r.bottom = r.top + SYSMETRICS_CYHSCROLL + 1;
+        if (r.top + thumbSize >= rect->bottom - arrowSize)
+            r.top = rect->bottom - arrowSize - thumbSize - 1;
+        r.bottom = r.top + thumbSize + 1;
     }
     else
     {
-        r.left += thumbPos;
+        r.left += SCROLL_TrackingPos;
         if (r.left < rect->left + arrowSize) r.left = rect->left + arrowSize;
-        if (r.left + SYSMETRICS_CXVSCROLL >= rect->right - arrowSize)
-            r.left = rect->right - arrowSize - SYSMETRICS_CXVSCROLL - 1;
-        r.right = r.left + SYSMETRICS_CXVSCROLL + 1;
+        if (r.left + thumbSize >= rect->right - arrowSize)
+            r.left = rect->right - arrowSize - thumbSize - 1;
+        r.right = r.left + thumbSize + 1;
     }
-    InflateRect16( &r, -1, -1 );
-    DrawFocusRect16( hdc, &r );
+    InflateRect32( &r, -1, -1 );
+    DrawFocusRect32( hdc, &r );
+    SCROLL_MovingThumb = !SCROLL_MovingThumb;
 }
 
 
@@ -345,12 +379,13 @@ static void SCROLL_DrawMovingThumb( HDC hdc, RECT16 *rect, BOOL vertical,
  *
  * Draw the scroll bar interior (everything except the arrows).
  */
-static void SCROLL_DrawInterior( HWND hwnd, HDC hdc, int nBar, RECT16 *rect,
-                                 WORD arrowSize, WORD thumbPos, WORD flags,
-                                 BOOL vertical, BOOL top_selected,
-                                 BOOL bottom_selected )
+static void SCROLL_DrawInterior( HWND32 hwnd, HDC32 hdc, INT32 nBar, 
+                                 RECT32 *rect, INT32 arrowSize,
+                                 INT32 thumbSize, INT32 thumbPos,
+                                 UINT32 flags, BOOL32 vertical,
+                                 BOOL32 top_selected, BOOL32 bottom_selected )
 {
-    RECT16 r;
+    RECT32 r;
 
       /* Select the correct brush and pen */
 
@@ -364,8 +399,8 @@ static void SCROLL_DrawInterior( HWND hwnd, HDC hdc, int nBar, RECT16 *rect,
     {
         if (nBar == SB_CTL)  /* Only scrollbar controls send WM_CTLCOLOR */
         {
-            HBRUSH hbrush = SendMessage32A( GetParent32(hwnd),
-                                            WM_CTLCOLORSCROLLBAR, hdc, hwnd );
+            HBRUSH32 hbrush = SendMessage32A(GetParent32(hwnd),
+                                             WM_CTLCOLORSCROLLBAR, hdc, hwnd );
             SelectObject( hdc, hbrush );
         }
         else SelectObject( hdc, sysColorObjects.hbrushScrollbar );
@@ -409,11 +444,11 @@ static void SCROLL_DrawInterior( HWND hwnd, HDC hdc, int nBar, RECT16 *rect,
                 thumbPos - arrowSize,
                 top_selected ? 0x0f0000 : PATCOPY );
         r.top += thumbPos - arrowSize;
-        PatBlt( hdc, r.left + 1, r.top + SYSMETRICS_CYHSCROLL + 1,
+        PatBlt( hdc, r.left + 1, r.top + thumbSize + 1,
                 r.right - r.left - 2,
-                r.bottom - r.top - SYSMETRICS_CYHSCROLL - 2,
+                r.bottom - r.top - thumbSize - 2,
                 bottom_selected ? 0x0f0000 : PATCOPY );
-        r.bottom = r.top + SYSMETRICS_CYHSCROLL + 1;
+        r.bottom = r.top + thumbSize + 1;
     }
     else  /* horizontal */
     {
@@ -422,21 +457,26 @@ static void SCROLL_DrawInterior( HWND hwnd, HDC hdc, int nBar, RECT16 *rect,
                 r.bottom - r.top - 2,
                 top_selected ? 0x0f0000 : PATCOPY );
         r.left += thumbPos - arrowSize;
-        PatBlt( hdc, r.left + SYSMETRICS_CYHSCROLL + 1, r.top + 1,
-                r.right - r.left - SYSMETRICS_CYHSCROLL - 2,
+        PatBlt( hdc, r.left + thumbSize + 1, r.top + 1,
+                r.right - r.left - thumbSize - 2,
                 r.bottom - r.top - 2,
                 bottom_selected ? 0x0f0000 : PATCOPY );
-        r.right = r.left + SYSMETRICS_CXVSCROLL + 1;
+        r.right = r.left + thumbSize + 1;
     }
 
       /* Draw the thumb */
 
     SelectObject( hdc, sysColorObjects.hbrushBtnFace );
     Rectangle( hdc, r.left, r.top, r.right, r.bottom );
-    InflateRect16( &r, -1, -1 );
+    InflateRect32( &r, -1, -1 );
     GRAPH_DrawReliefRect( hdc, &r, 1, 2, FALSE );
-    if ((hwndTracking == hwnd) && (nBarTracking == nBar))
-        SCROLL_DrawMovingThumb( hdc, rect, vertical, arrowSize, uTrackingPos);
+    if (SCROLL_MovingThumb &&
+        (SCROLL_TrackingWin == hwnd) &&
+        (SCROLL_TrackingBar == nBar))
+    {
+        SCROLL_DrawMovingThumb( hdc, rect, vertical, arrowSize, thumbSize );
+        SCROLL_MovingThumb = TRUE;
+    }
 }
 
 
@@ -445,11 +485,11 @@ static void SCROLL_DrawInterior( HWND hwnd, HDC hdc, int nBar, RECT16 *rect,
  *
  * Redraw the whole scrollbar.
  */
-void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, int nBar )
+void SCROLL_DrawScrollBar( HWND32 hwnd, HDC32 hdc, INT32 nBar, BOOL32 arrows )
 {
-    WORD arrowSize, thumbPos;
-    RECT16 rect;
-    BOOL vertical;
+    INT32 arrowSize, thumbSize, thumbPos;
+    RECT32 rect;
+    BOOL32 vertical;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     SCROLLBAR_INFO *infoPtr = SCROLL_GetPtrScrollInfo( wndPtr, nBar );
 
@@ -458,14 +498,14 @@ void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, int nBar )
         ((nBar == SB_HORZ) && !(wndPtr->dwStyle & WS_HSCROLL))) return;
 
     vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
-                                        &arrowSize, &thumbPos );
+                                        &arrowSize, &thumbSize, &thumbPos );
       /* Draw the arrows */
 
-    if (arrowSize) SCROLL_DrawArrows( hdc, infoPtr, &rect, arrowSize,
-                                      vertical, FALSE, FALSE );
+    if (arrows && arrowSize) SCROLL_DrawArrows( hdc, infoPtr, &rect, arrowSize,
+                                                vertical, FALSE, FALSE );
     
-    SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbPos,
-                         infoPtr->flags, vertical, FALSE, FALSE );
+    SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbSize,
+                         thumbPos, infoPtr->flags, vertical, FALSE, FALSE );
 }
 
 
@@ -475,26 +515,13 @@ void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, int nBar )
  * Repaint the scroll bar interior after a SetScrollRange() or
  * SetScrollPos() call.
  */
-static void SCROLL_RefreshScrollBar( HWND hwnd, int nBar )
+static void SCROLL_RefreshScrollBar( HWND32 hwnd, INT32 nBar, BOOL32 arrows )
 {
-    WORD arrowSize, thumbPos;
-    RECT16 rect;
-    BOOL vertical;
-    HDC hdc;
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-    SCROLLBAR_INFO *infoPtr = SCROLL_GetPtrScrollInfo( wndPtr, nBar );
-
-    if (!wndPtr || !infoPtr ||
-        ((nBar == SB_VERT) && !(wndPtr->dwStyle & WS_VSCROLL)) ||
-        ((nBar == SB_HORZ) && !(wndPtr->dwStyle & WS_HSCROLL))) return;
-
-    vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
-                                        &arrowSize, &thumbPos );
-    hdc = GetDCEx( hwnd, 0, DCX_CACHE | ((nBar == SB_CTL) ? 0 : DCX_WINDOW) );
+    HDC32 hdc = GetDCEx32( hwnd, 0,
+                           DCX_CACHE | ((nBar == SB_CTL) ? 0 : DCX_WINDOW) );
     if (!hdc) return;
-    SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbPos,
-                         infoPtr->flags, vertical, FALSE, FALSE );
-    ReleaseDC( hwnd, hdc );
+    SCROLL_DrawScrollBar( hwnd, hdc, nBar, arrows );
+    ReleaseDC32( hwnd, hdc );
 }
 
 
@@ -503,10 +530,10 @@ static void SCROLL_RefreshScrollBar( HWND hwnd, int nBar )
  *
  * Handle a keyboard event (only for SB_CTL scrollbars).
  */
-static void SCROLL_HandleKbdEvent( HWND hwnd, WORD wParam )
+static void SCROLL_HandleKbdEvent( HWND32 hwnd, WPARAM32 wParam )
 {
     WND *wndPtr = WIN_FindWndPtr( hwnd );
-    WPARAM msg;
+    WPARAM32 msg;
     
     switch(wParam)
     {
@@ -532,33 +559,33 @@ static void SCROLL_HandleKbdEvent( HWND hwnd, WORD wParam )
  * 'pt' is the location of the mouse event in client (for SB_CTL) or
  * windows coordinates.
  */
-void SCROLL_HandleScrollEvent( HWND hwnd, int nBar, WORD msg, POINT16 pt )
+void SCROLL_HandleScrollEvent( HWND32 hwnd, INT32 nBar, UINT32 msg, POINT32 pt)
 {
       /* Previous mouse position for timer events */
-    static POINT16 prevPt;
+    static POINT32 prevPt;
       /* Hit test code of the last button-down event */
     static enum SCROLL_HITTEST trackHitTest;
       /* Thumb position when tracking started. */
-    static UINT trackThumbPos;
+    static UINT32 trackThumbPos;
       /* Position in the scroll-bar of the last button-down event. */
-    static int lastClickPos;
+    static INT32 lastClickPos;
       /* Position in the scroll-bar of the last mouse event. */
-    static int lastMousePos;
+    static INT32 lastMousePos;
 
     enum SCROLL_HITTEST hittest;
-    HWND hwndOwner, hwndCtl;
-    BOOL vertical;
-    WORD arrowSize, thumbPos;
-    RECT16 rect;
-    HDC hdc;
+    HWND32 hwndOwner, hwndCtl;
+    BOOL32 vertical;
+    INT32 arrowSize, thumbSize, thumbPos;
+    RECT32 rect;
+    HDC32 hdc;
 
     SCROLLBAR_INFO *infoPtr = SCROLL_GetScrollInfo( hwnd, nBar );
     if (!infoPtr) return;
     if ((trackHitTest == SCROLL_NOWHERE) && (msg != WM_LBUTTONDOWN)) return;
 
-    hdc = GetDCEx( hwnd, 0, DCX_CACHE | ((nBar == SB_CTL) ? 0 : DCX_WINDOW) );
+    hdc = GetDCEx32( hwnd, 0, DCX_CACHE | ((nBar == SB_CTL) ? 0 : DCX_WINDOW));
     vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
-                                        &arrowSize, &thumbPos );
+                                        &arrowSize, &thumbSize, &thumbPos );
     hwndOwner = (nBar == SB_CTL) ? GetParent32(hwnd) : hwnd;
     hwndCtl   = (nBar == SB_CTL) ? hwnd : 0;
 
@@ -570,7 +597,7 @@ void SCROLL_HandleScrollEvent( HWND hwnd, int nBar, WORD msg, POINT16 pt )
           lastMousePos  = lastClickPos;
           trackThumbPos = thumbPos;
           prevPt = pt;
-          SetCapture( hwnd );
+          SetCapture32( hwnd );
           if (nBar == SB_CTL) SetFocus32( hwnd );
           break;
 
@@ -619,8 +646,8 @@ void SCROLL_HandleScrollEvent( HWND hwnd, int nBar, WORD msg, POINT16 pt )
         break;
 
     case SCROLL_TOP_RECT:
-        SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbPos,
-                             infoPtr->flags, vertical,
+        SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbSize,
+                             thumbPos, infoPtr->flags, vertical,
                              (hittest == trackHitTest), FALSE );
         if (hittest == trackHitTest)
         {
@@ -639,43 +666,46 @@ void SCROLL_HandleScrollEvent( HWND hwnd, int nBar, WORD msg, POINT16 pt )
     case SCROLL_THUMB:
         if (msg == WM_LBUTTONDOWN)
         {
-            SCROLL_DrawMovingThumb( hdc, &rect, vertical, arrowSize,
-                                 trackThumbPos + lastMousePos - lastClickPos );
-            hwndTracking = hwnd;
-            nBarTracking = nBar;
+            SCROLL_TrackingWin = hwnd;
+            SCROLL_TrackingBar = nBar;
+            SCROLL_TrackingPos = trackThumbPos + lastMousePos - lastClickPos;
+            SCROLL_DrawMovingThumb(hdc, &rect, vertical, arrowSize, thumbSize);
         }
         else if (msg == WM_LBUTTONUP)
         {
-            hwndTracking = 0;
-            SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbPos,
-                                 infoPtr->flags, vertical, FALSE, FALSE );
+            SCROLL_TrackingWin = 0;
+            SCROLL_MovingThumb = FALSE;
+            SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbSize,
+                                 thumbPos, infoPtr->flags, vertical,
+                                 FALSE, FALSE );
         }
         else  /* WM_MOUSEMOVE */
         {
-            UINT pos, val;
+            UINT32 pos;
 
-            if (!PtInRect16( &rect, pt )) pos = lastClickPos;
+            if (!PtInRect32( &rect, pt )) pos = lastClickPos;
             else pos = vertical ? (pt.y - rect.top) : (pt.x - rect.left);
             if (pos != lastMousePos)
             {
-                SCROLL_DrawMovingThumb( hdc, &rect, vertical, arrowSize,
-                                 trackThumbPos + lastMousePos - lastClickPos );
+                SCROLL_DrawMovingThumb( hdc, &rect, vertical,
+                                        arrowSize, thumbSize );
                 lastMousePos = pos;
-                val = SCROLL_GetThumbVal( infoPtr, &rect, vertical,
-                                 trackThumbPos + lastMousePos - lastClickPos );
-                /* Save tracking info */
-                uTrackingPos = trackThumbPos + pos - lastClickPos;
+                SCROLL_TrackingPos = trackThumbPos + pos - lastClickPos;
+                SCROLL_TrackingVal = SCROLL_GetThumbVal( infoPtr, &rect,
+                                                         vertical,
+                                                         SCROLL_TrackingPos );
                 SendMessage32A( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
-                                MAKEWPARAM( SB_THUMBTRACK, val ), hwndCtl );
+                                MAKEWPARAM( SB_THUMBTRACK, SCROLL_TrackingVal),
+                                hwndCtl );
                 SCROLL_DrawMovingThumb( hdc, &rect, vertical,
-                                        arrowSize, uTrackingPos );
+                                        arrowSize, thumbSize );
             }
         }
         break;
         
     case SCROLL_BOTTOM_RECT:
-        SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbPos,
-                             infoPtr->flags, vertical,
+        SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbSize,
+                             thumbPos, infoPtr->flags, vertical,
                              FALSE, (hittest == trackHitTest) );
         if (hittest == trackHitTest)
         {
@@ -713,7 +743,7 @@ void SCROLL_HandleScrollEvent( HWND hwnd, int nBar, WORD msg, POINT16 pt )
     {
         if (trackHitTest == SCROLL_THUMB)
         {
-            UINT val = SCROLL_GetThumbVal( infoPtr, &rect, vertical,
+            UINT32 val = SCROLL_GetThumbVal( infoPtr, &rect, vertical,
                                  trackThumbPos + lastMousePos - lastClickPos );
             SendMessage32A( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                             MAKEWPARAM( SB_THUMBPOSITION, val ), hwndCtl );
@@ -724,20 +754,21 @@ void SCROLL_HandleScrollEvent( HWND hwnd, int nBar, WORD msg, POINT16 pt )
         trackHitTest = SCROLL_NOWHERE;  /* Terminate tracking */
     }
 
-    ReleaseDC( hwnd, hdc );
+    ReleaseDC32( hwnd, hdc );
 }
 
 
 /***********************************************************************
  *           ScrollBarWndProc
  */
-LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+LRESULT ScrollBarWndProc( HWND32 hwnd, UINT32 message, WPARAM32 wParam,
+                          LPARAM lParam )
 {
     switch(message)
     {
     case WM_CREATE:
         {
-	    CREATESTRUCT16 *lpCreat = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
+	    CREATESTRUCT32A *lpCreat = (CREATESTRUCT32A *)lParam;
             if (lpCreat->style & SBS_SIZEBOX)
             {
                 fprintf( stdnimp, "Unimplemented style SBS_SIZEBOX.\n" );
@@ -775,7 +806,11 @@ LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
     case WM_LBUTTONUP:
     case WM_MOUSEMOVE:
     case WM_SYSTIMER:
-        SCROLL_HandleScrollEvent( hwnd, SB_CTL, message, MAKEPOINT16(lParam) );
+        {
+            POINT32 pt;
+            CONV_POINT16TO32( (POINT16 *)&lParam, &pt );
+            SCROLL_HandleScrollEvent( hwnd, SB_CTL, message, pt );
+        }
         break;
 
     case WM_KEYDOWN:
@@ -790,97 +825,302 @@ LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
 
     case WM_PAINT:
         {
-            PAINTSTRUCT16 ps;
-            HDC16 hdc = BeginPaint16( hwnd, &ps );
-            SCROLL_DrawScrollBar( hwnd, hdc, SB_CTL );
-            EndPaint16( hwnd, &ps );
+            PAINTSTRUCT32 ps;
+            HDC32 hdc = BeginPaint32( hwnd, &ps );
+            SCROLL_DrawScrollBar( hwnd, hdc, SB_CTL, TRUE );
+            EndPaint32( hwnd, &ps );
         }
         break;
 
-    case SBM_SETSCROLLPOS:
-        return SetScrollPos( hwnd, SB_CTL, wParam, (BOOL)lParam );
+    case SBM_SETPOS16:
+    case SBM_SETPOS32:
+        return SetScrollPos32( hwnd, SB_CTL, wParam, (BOOL32)lParam );
 
-    case SBM_GETSCROLLPOS:
-        return GetScrollPos( hwnd, SB_CTL );
+    case SBM_GETPOS16:
+    case SBM_GETPOS32:
+        return GetScrollPos32( hwnd, SB_CTL );
 
-    case SBM_SETSCROLLRANGE:
-        SetScrollRange( hwnd, SB_CTL, LOWORD(lParam), HIWORD(lParam),
-                        wParam  /* FIXME: Is this correct? */ );
+    case SBM_SETRANGE16:
+        SetScrollRange32( hwnd, SB_CTL, LOWORD(lParam), HIWORD(lParam),
+                          wParam  /* FIXME: Is this correct? */ );
         return 0;
 
-    case SBM_ENABLE:
-        return EnableScrollBar( hwnd, SB_CTL, wParam ); /* FIXME: lParam? */
+    case SBM_SETRANGE32:
+        SetScrollRange32( hwnd, SB_CTL, wParam, lParam, FALSE );
+        return 0;  /* FIXME: return previous position */
 
-    case 0x403: /* SBM_REDRAW */
-        fprintf(stdnimp,"ScrollBarWndProc: undocumented message %04x, please report\n", message );
+    case SBM_GETRANGE16:
+        /* FIXME */
+        fprintf( stderr, "ScrollBar: don't know how to handle SBM_GETRANGE16 (wp=%04x,lp=%08lx)\n",
+                 wParam, lParam );
+        return 0;
+
+    case SBM_GETRANGE32:
+        GetScrollRange32( hwnd, SB_CTL, (LPINT32)wParam, (LPINT32)lParam );
+        return 0;
+
+    case SBM_ENABLE_ARROWS16:
+    case SBM_ENABLE_ARROWS32:
+        return EnableScrollBar32( hwnd, SB_CTL, wParam );
+
+    case SBM_SETRANGEREDRAW32:
+        SetScrollRange32( hwnd, SB_CTL, wParam, lParam, TRUE );
+        return 0;  /* FIXME: return previous position */
+        
+    case SBM_SETSCROLLINFO32:
+        return SetScrollInfo32( hwnd, SB_CTL, (SCROLLINFO *)lParam, wParam );
+
+    case SBM_GETSCROLLINFO32:
+        return GetScrollInfo32( hwnd, SB_CTL, (SCROLLINFO *)lParam );
+
+    case 0x00e5:
+    case 0x00e7:
+    case 0x00e8:
+    case 0x00eb:
+    case 0x00ec:
+    case 0x00ed:
+    case 0x00ee:
+    case 0x00ef:
+        fprintf(stderr, "ScrollBar: unknown Win32 msg %04x wp=%08x lp=%08lx\n",
+                message, wParam, lParam );
         break;
 
     default:
-        return DefWindowProc16( hwnd, message, wParam, lParam );
+        if (message >= WM_USER)
+            fprintf( stderr, "ScrollBar: unknown msg %04x wp=%04x lp=%08lx\n",
+                     message, wParam, lParam );
+        return DefWindowProc32A( hwnd, message, wParam, lParam );
     }
     return 0;
 }
 
 
 /*************************************************************************
- *           SetScrollPos   (USER.62)
+ *           SetScrollInfo16   (USER.475)
  */
-int SetScrollPos( HWND hwnd, int nBar, int nPos, BOOL bRedraw )
+INT16 SetScrollInfo16( HWND16 hwnd, INT16 nBar, const SCROLLINFO *info,
+                       BOOL16 bRedraw )
+{
+    return (INT16)SetScrollInfo32( hwnd, nBar, info, bRedraw );
+}
+
+
+/*************************************************************************
+ *           SetScrollInfo32   (USER32.500)
+ */
+INT32 SetScrollInfo32( HWND32 hwnd, INT32 nBar, const SCROLLINFO *info,
+                       BOOL32 bRedraw )
 {
     SCROLLBAR_INFO *infoPtr;
-    INT oldPos;
+    UINT32 new_flags;
+    BOOL32 repaint_arrows = FALSE;
 
-    if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, nBar ))) return 0;
+    if (!(infoPtr = SCROLL_GetScrollInfo(hwnd, nBar))) return 0;
+    if (info->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL)) return 0;
+    if ((info->cbSize != sizeof(*info)) &&
+        (info->cbSize != sizeof(*info)-sizeof(info->nTrackPos))) return 0;
 
-    dprintf_scroll( stddeb,"SetScrollPos min=%d max=%d pos=%d\n", 
-                    infoPtr->MinVal, infoPtr->MaxVal, nPos );
+    dprintf_scroll( stddeb, "SetScrollInfo: hwnd=%04x bar=%d", hwnd, nBar );
 
-    if (nPos < infoPtr->MinVal) nPos = infoPtr->MinVal;
-    else if (nPos > infoPtr->MaxVal) nPos = infoPtr->MaxVal;
-    oldPos = infoPtr->CurVal;
-    infoPtr->CurVal = nPos;
-    if (bRedraw) SCROLL_RefreshScrollBar( hwnd, nBar );
-    return oldPos;
+    /* Set the page size */
+
+    if (info->fMask & SIF_PAGE)
+    {
+        dprintf_scroll( stddeb, " page=%d", info->nPage );
+        infoPtr->Page = info->nPage;
+    }
+
+    /* Set the scroll pos */
+
+    if (info->fMask & SIF_POS)
+    {
+        dprintf_scroll( stddeb, " pos=%d", info->nPos );
+        infoPtr->CurVal = info->nPos;
+    }
+
+    /* Set the scroll range */
+
+    if (info->fMask & SIF_RANGE)
+    {
+        dprintf_scroll( stddeb, " min=%d max=%d", info->nMin, info->nMax );
+
+        /* Invalid range -> range is set to (0,0) */
+        if ((info->nMin > info->nMax) ||
+            ((UINT32)(info->nMax - info->nMin) >= 0x80000000))
+        {
+            infoPtr->MinVal = 0;
+            infoPtr->MaxVal = 0;
+        }
+        else
+        {
+            infoPtr->MinVal = info->nMin;
+            infoPtr->MaxVal = info->nMax;
+        }
+    }
+
+    /* Make sure the page size is valid */
+
+    if (infoPtr->Page < 0) infoPtr->Page = 0;
+    else if (infoPtr->Page > infoPtr->MaxVal - infoPtr->MinVal + 1 )
+        infoPtr->Page = infoPtr->MaxVal - infoPtr->MinVal + 1;
+
+    /* Make sure the pos is inside the range */
+
+    if (infoPtr->CurVal < infoPtr->MinVal)
+        infoPtr->CurVal = infoPtr->MinVal;
+    else if (infoPtr->CurVal > infoPtr->MaxVal - MAX( infoPtr->Page-1, 0 ))
+        infoPtr->CurVal = infoPtr->MaxVal - MAX( infoPtr->Page-1, 0 );
+
+    dprintf_scroll( stddeb, "\n   new values: page=%d pos=%d min=%d max=%d\n",
+                    infoPtr->Page, infoPtr->CurVal,
+                    infoPtr->MinVal, infoPtr->MaxVal );
+
+    /* Check if the scrollbar should be hidden or disabled */
+
+    new_flags = infoPtr->flags;
+    if (infoPtr->MinVal >= infoPtr->MaxVal - MAX( infoPtr->Page-1, 0 ))
+    {
+        /* Hide or disable scroll-bar */
+        if (info->fMask & SIF_DISABLENOSCROLL) new_flags = ESB_DISABLE_BOTH;
+        else if (nBar != SB_CTL)
+        {
+            ShowScrollBar32( hwnd, nBar, FALSE );
+            bRedraw = FALSE;  /* No need to repaint anything */
+        }
+    }
+    else  /* Show and enable scroll-bar */
+    {
+        new_flags = 0;
+        if (nBar != SB_CTL) ShowScrollBar32( hwnd, nBar, TRUE );
+    }
+
+    if (infoPtr->flags != new_flags)
+    {
+        infoPtr->flags = new_flags;
+        repaint_arrows = TRUE;
+    }
+
+    if (bRedraw || repaint_arrows)
+        SCROLL_RefreshScrollBar( hwnd, nBar, repaint_arrows );
+
+    /* Return current position */
+
+    return infoPtr->CurVal;
+}
+
+
+/*************************************************************************
+ *           GetScrollInfo16   (USER.476)
+ */
+BOOL16 GetScrollInfo16( HWND16 hwnd, INT16 nBar, LPSCROLLINFO info )
+{
+    return GetScrollInfo32( hwnd, nBar, info );
+}
+
+
+/*************************************************************************
+ *           GetScrollInfo32   (USER32.283)
+ */
+BOOL32 GetScrollInfo32( HWND32 hwnd, INT32 nBar, LPSCROLLINFO info )
+{
+    SCROLLBAR_INFO *infoPtr;
+
+    if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, nBar ))) return FALSE;
+    if (info->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL)) return FALSE;
+    if ((info->cbSize != sizeof(*info)) &&
+        (info->cbSize != sizeof(*info)-sizeof(info->nTrackPos))) return FALSE;
+
+    if (info->fMask & SIF_PAGE) info->nPage = infoPtr->Page;
+    if (info->fMask & SIF_POS) info->nPos = infoPtr->CurVal;
+    if ((info->fMask & SIF_TRACKPOS) && (info->cbSize == sizeof(*info)))
+        info->nTrackPos = (SCROLL_TrackingWin==hwnd) ? SCROLL_TrackingVal : 0;
+    if (info->fMask & SIF_RANGE)
+    {
+	info->nMin = infoPtr->MinVal;
+	info->nMax = infoPtr->MaxVal;
+    }
+    return (info->fMask & SIF_ALL) != 0;
+}
+
+
+/*************************************************************************
+ *           SetScrollPos16   (USER.62)
+ */
+INT16 SetScrollPos16( HWND16 hwnd, INT16 nBar, INT16 nPos, BOOL16 bRedraw )
+{
+    return (INT16)SetScrollPos32( hwnd, nBar, nPos, bRedraw );
 }
 
 
 /*************************************************************************
- *           GetScrollPos   (USER.63)
+ *           SetScrollPos32   (USER32.501)
  */
-int GetScrollPos( HWND hwnd, int nBar )
+INT32 SetScrollPos32( HWND32 hwnd, INT32 nBar, INT32 nPos, BOOL32 bRedraw )
 {
+    SCROLLINFO info;
     SCROLLBAR_INFO *infoPtr;
+    INT32 oldPos;
 
     if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, nBar ))) return 0;
-    return infoPtr->CurVal;
+    oldPos      = infoPtr->CurVal;
+    info.cbSize = sizeof(info);
+    info.nPos   = nPos;
+    info.fMask  = SIF_POS;
+    SetScrollInfo32( hwnd, nBar, &info, bRedraw );
+    return oldPos;
+}
+
+
+/*************************************************************************
+ *           GetScrollPos16   (USER.63)
+ */
+INT16 GetScrollPos16( HWND16 hwnd, INT16 nBar )
+{
+    return (INT16)GetScrollPos32( hwnd, nBar );
 }
 
 
 /*************************************************************************
- *           SetScrollRange   (USER.64)
+ *           GetScrollPos32   (USER32.284)
  */
-void SetScrollRange(HWND hwnd, int nBar, int MinVal, int MaxVal, BOOL bRedraw)
+INT32 GetScrollPos32( HWND32 hwnd, INT32 nBar )
 {
     SCROLLBAR_INFO *infoPtr;
 
-    if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, nBar ))) return;
+    if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, nBar ))) return 0;
+    return infoPtr->CurVal;
+}
+
+
+/*************************************************************************
+ *           SetScrollRange16   (USER.64)
+ */
+void SetScrollRange16( HWND16 hwnd, INT16 nBar, INT16 MinVal, INT16 MaxVal,
+                       BOOL16 bRedraw )
+{
+    /* Invalid range -> range is set to (0,0) */
+    if ((INT32)MaxVal - (INT32)MinVal > 0x7fff) MinVal = MaxVal = 0;
+    SetScrollRange32( hwnd, nBar, MinVal, MaxVal, bRedraw );
+}
 
-    dprintf_scroll( stddeb,"SetScrollRange hwnd=%04x bar=%d min=%d max=%d\n",
-                    hwnd, nBar, MinVal, MaxVal );
 
-      /* Invalid range -> range is set to (0,0) */
-    if ((MinVal > MaxVal) || ((long)MaxVal - MinVal > 32767L))
-        MinVal = MaxVal = 0;
-    if (infoPtr->CurVal < MinVal) infoPtr->CurVal = MinVal;
-    else if (infoPtr->CurVal > MaxVal) infoPtr->CurVal = MaxVal;
-    infoPtr->MinVal = MinVal;
-    infoPtr->MaxVal = MaxVal;
+/*************************************************************************
+ *           SetScrollRange32   (USER32.502)
+ */
+BOOL32 SetScrollRange32( HWND32 hwnd, INT32 nBar, INT32 MinVal, INT32 MaxVal,
+                         BOOL32 bRedraw )
+{
+    SCROLLINFO info;
 
-      /* Non-client scroll-bar is hidden if min==max */
-    if (nBar != SB_CTL) ShowScrollBar( hwnd, nBar, (MinVal != MaxVal) );
-    if (bRedraw) SCROLL_RefreshScrollBar( hwnd, nBar );
+    info.cbSize = sizeof(info);
+    info.nMin   = MinVal;
+    info.nMax   = MaxVal;
+    info.fMask  = SIF_RANGE;
+    SetScrollInfo32( hwnd, nBar, &info, bRedraw );
+    return TRUE;
 }
 
+
 /*************************************************************************
  *	     SCROLL_SetNCSbState
  *
@@ -914,44 +1154,74 @@ DWORD SCROLL_SetNCSbState(WND* wndPtr, int vMin, int vMax, int vPos,
   return wndPtr->dwStyle & (WS_VSCROLL | WS_HSCROLL);
 }
 
+
 /*************************************************************************
- *           GetScrollRange   (USER.65)
+ *           GetScrollRange16   (USER.65)
  */
-void GetScrollRange(HWND hwnd, int nBar, LPINT16 lpMin, LPINT16 lpMax)
+BOOL16 GetScrollRange16( HWND16 hwnd, INT16 nBar, LPINT16 lpMin, LPINT16 lpMax)
+{
+    INT32 min, max;
+    BOOL16 ret = GetScrollRange32( hwnd, nBar, &min, &max );
+    if (lpMin) *lpMin = min;
+    if (lpMax) *lpMax = max;
+    return ret;
+}
+
+
+/*************************************************************************
+ *           GetScrollRange32   (USER32.285)
+ */
+BOOL32 GetScrollRange32( HWND32 hwnd, INT32 nBar, LPINT32 lpMin, LPINT32 lpMax)
 {
     SCROLLBAR_INFO *infoPtr;
 
-    if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, nBar ))) return;
+    if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, nBar )))
+    {
+        if (lpMin) lpMin = 0;
+        if (lpMax) lpMax = 0;
+        return FALSE;
+    }
     if (lpMin) *lpMin = infoPtr->MinVal;
     if (lpMax) *lpMax = infoPtr->MaxVal;
+    return TRUE;
+}
+
+
+/*************************************************************************
+ *           ShowScrollBar16   (USER.267)
+ */
+void ShowScrollBar16( HWND16 hwnd, INT16 nBar, BOOL16 fShow )
+{
+    ShowScrollBar32( hwnd, nBar, fShow );
 }
 
 
 /*************************************************************************
- *           ShowScrollBar   (USER.267)
+ *           ShowScrollBar32   (USER32.531)
  */
-void ShowScrollBar( HWND hwnd, WORD wBar, BOOL fShow )
+BOOL32 ShowScrollBar32( HWND32 hwnd, INT32 nBar, BOOL32 fShow )
 {
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
-    if (!wndPtr) return;
-    dprintf_scroll( stddeb, "ShowScrollBar: hwnd=%04x bar=%d on=%d\n", hwnd, wBar, fShow );
+    if (!wndPtr) return FALSE;
+    dprintf_scroll( stddeb, "ShowScrollBar: hwnd=%04x bar=%d on=%d\n",
+                    hwnd, nBar, fShow );
 
-    switch(wBar)
+    switch(nBar)
     {
     case SB_CTL:
         ShowWindow( hwnd, fShow ? SW_SHOW : SW_HIDE );
-        return;
+        return TRUE;
 
     case SB_HORZ:
         if (fShow)
         {
-            if (wndPtr->dwStyle & WS_HSCROLL) return;
+            if (wndPtr->dwStyle & WS_HSCROLL) return TRUE;
             wndPtr->dwStyle |= WS_HSCROLL;
         }
         else  /* hide it */
         {
-            if (!(wndPtr->dwStyle & WS_HSCROLL)) return;
+            if (!(wndPtr->dwStyle & WS_HSCROLL)) return TRUE;
             wndPtr->dwStyle &= ~WS_HSCROLL;
         }
         break;
@@ -959,12 +1229,12 @@ void ShowScrollBar( HWND hwnd, WORD wBar, BOOL fShow )
     case SB_VERT:
         if (fShow)
         {
-            if (wndPtr->dwStyle & WS_VSCROLL) return;
+            if (wndPtr->dwStyle & WS_VSCROLL) return TRUE;
             wndPtr->dwStyle |= WS_VSCROLL;
         }
         else  /* hide it */
         {
-            if (!(wndPtr->dwStyle & WS_VSCROLL)) return;
+            if (!(wndPtr->dwStyle & WS_VSCROLL)) return TRUE;
             wndPtr->dwStyle &= ~WS_VSCROLL;
         }
         break;
@@ -973,98 +1243,50 @@ void ShowScrollBar( HWND hwnd, WORD wBar, BOOL fShow )
         if (fShow)
         {
             if ((wndPtr->dwStyle & WS_HSCROLL)
-                && (wndPtr->dwStyle & WS_VSCROLL)) return;
+                && (wndPtr->dwStyle & WS_VSCROLL)) return TRUE;
             wndPtr->dwStyle |= WS_HSCROLL | WS_VSCROLL;
         }
         else  /* hide it */
         {
             if (!(wndPtr->dwStyle & WS_HSCROLL)
-                && !(wndPtr->dwStyle & WS_HSCROLL)) return;
+                && !(wndPtr->dwStyle & WS_HSCROLL)) return TRUE;
             wndPtr->dwStyle &= ~(WS_HSCROLL | WS_VSCROLL);
         }
         break;
 
     default:
-        return;  /* Nothing to do! */
+        return TRUE;  /* Nothing to do! */
     }
     SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE
                  | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
-}
-
-
-/*************************************************************************
- *           EnableScrollBar   (USER.482)
- */
-BOOL EnableScrollBar( HWND hwnd, UINT nBar, UINT flags )
-{
-    SCROLLBAR_INFO *infoPtr;
-    HDC hdc;
-
-    if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, nBar ))) return FALSE;
-    dprintf_scroll( stddeb, "EnableScrollBar: %04x %d %d\n", hwnd, nBar, flags );
-    flags &= ESB_DISABLE_BOTH;
-    if (infoPtr->flags == flags) return FALSE;
-    infoPtr->flags = flags;
-
-      /* Redraw the whole scroll bar */
-    hdc = GetDCEx( hwnd, 0, DCX_CACHE | ((nBar == SB_CTL) ? 0 : DCX_WINDOW) );
-    SCROLL_DrawScrollBar( hwnd, hdc, nBar );
-    ReleaseDC( hwnd, hdc );
     return TRUE;
 }
 
 
 /*************************************************************************
- *           SetScrollInfo32   (USER32.500)
+ *           EnableScrollBar16   (USER.482)
  */
-INT32 SetScrollInfo32( HWND32 hwnd, INT32 nBar, LPSCROLLINFO32 lpsi,
-                       BOOL32 bRedraw )
+BOOL16 EnableScrollBar16( HWND16 hwnd, INT16 nBar, UINT16 flags )
 {
-    SCROLLBAR_INFO *infoPtr;
-
-    if (!(infoPtr = SCROLL_GetScrollInfo(hwnd, nBar))) return 0;
-
-    if (lpsi->fMask & SIF_PAGE) {
-	/* fixme: The page size isn't used in the current
-	 * scrolling code - it's new for win32
-	 */
-	infoPtr->Page = lpsi->nPage;
-    }
-    if (lpsi->fMask & SIF_POS)
-        SetScrollPos(hwnd, nBar, lpsi->nPos, FALSE);
-    if (lpsi->fMask & SIF_RANGE)
-        SetScrollRange(hwnd, nBar, lpsi->nMin, lpsi->nMax, FALSE);
-    if (lpsi->fMask & SIF_DISABLENOSCROLL) {
-	/* fixme: Disable scroll bar if the new parameters make
-	 * the scroll bar unneeded
-	 */
-	dprintf_scroll(stddeb, "SetScrollInfo: SIF_DISABLENOSCROLL not supported yet\n");
-    }
-
-    if (bRedraw) SCROLL_RefreshScrollBar(hwnd, nBar);
-
-    /* return current thumb position */
-    return (infoPtr->CurVal);
+    return EnableScrollBar32( hwnd, nBar, flags );
 }
 
 
 /*************************************************************************
- *           GetScrollInfo32   (USER32.283)
+ *           EnableScrollBar32   (USER32.170)
  */
-BOOL32 GetScrollInfo32( HWND32 hwnd, INT32 nBar, LPSCROLLINFO32 lpsi )
+BOOL32 EnableScrollBar32( HWND32 hwnd, INT32 nBar, UINT32 flags )
 {
     SCROLLBAR_INFO *infoPtr;
 
     if (!(infoPtr = SCROLL_GetScrollInfo( hwnd, nBar ))) return FALSE;
+    dprintf_scroll( stddeb, "EnableScrollBar: %04x %d %d\n",
+                    hwnd, nBar, flags );
+    flags &= ESB_DISABLE_BOTH;
+    if (infoPtr->flags == flags) return FALSE;
+    infoPtr->flags = flags;
 
-    if (lpsi->fMask & SIF_PAGE) lpsi->nPage = infoPtr->Page;
-    if (lpsi->fMask & SIF_POS) lpsi->nPos = infoPtr->CurVal;
-    if (lpsi->fMask & SIF_TRACKPOS)
-        lpsi->nTrackPos = hwndTracking ? uTrackingPos : 0;
-    if (lpsi->fMask & SIF_RANGE)
-    {
-	lpsi->nMin = infoPtr->MinVal;
-	lpsi->nMax = infoPtr->MaxVal;
-    }
+    /* Redraw the whole scroll bar */
+    SCROLL_RefreshScrollBar( hwnd, nBar, TRUE );
     return TRUE;
 }
diff --git a/controls/status.c b/controls/status.c
index 3217b2bf894..7996a26dfe3 100644
--- a/controls/status.c
+++ b/controls/status.c
@@ -4,6 +4,7 @@
  * Copyright 1996 Bruce Milner
  */
 
+#define NO_TRANSITION_TYPES  /* This file is Win32-clean */
 #include <stdio.h>
 #include <stdlib.h>
 #include "windows.h"
@@ -226,9 +227,9 @@ SW_SetParts(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
     }
     SW_SetPartBounds(hwnd, self);
 
-    hdc = GetDC(hwnd);
+    hdc = GetDC32(hwnd);
     SW_Refresh(hwnd, hdc, self);
-    ReleaseDC(hwnd, hdc);
+    ReleaseDC32(hwnd, hdc);
     return TRUE;
 }
 
@@ -272,11 +273,11 @@ SW_Create(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
     self->part0.style = 0;
 
     height = 40;
-    if ((hdc = GetDC(0))) {
+    if ((hdc = GetDC32(0))) {
 	TEXTMETRIC32A tm;
 	GetTextMetrics32A(hdc, &tm);
 	self->textHeight = tm.tmHeight;
-	ReleaseDC(0, hdc);
+	ReleaseDC32(0, hdc);
     }
 
     parent = GetParent32(hwnd);
@@ -369,9 +370,9 @@ SW_Simple(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
 
     simple = (BOOL32) wParam;
     self->simple = simple;
-    hdc = GetDC(hwnd);
+    hdc = GetDC32(hwnd);
     SW_Refresh(hwnd, hdc, self);
-    ReleaseDC(hwnd, hdc);
+    ReleaseDC32(hwnd, hdc);
     return TRUE;
 }
 
diff --git a/controls/widgets.c b/controls/widgets.c
index 74956652005..0235053771b 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -29,8 +29,6 @@ static const BUILTIN_CLASS_INFO16 WIDGETS_BuiltinClasses16[] =
 {
     { CS_GLOBALCLASS | CS_PARENTDC,
        sizeof(STATICINFO), 0, "StaticWndProc", "STATIC" },
-    { CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC,
-      sizeof(SCROLLBAR_INFO), 0, "ScrollBarWndProc", "SCROLLBAR" },
     { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS,
       8, 0, "ListBoxWndProc", "LISTBOX" },
     { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS,
@@ -54,9 +52,11 @@ static const BUILTIN_CLASS_INFO16 WIDGETS_BuiltinClasses16[] =
 static WNDCLASS32A WIDGETS_BuiltinClasses32[] =
 {
     { CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC,
-          ButtonWndProc, 0, sizeof(BUTTONINFO), 0, 0, 0, 0, 0, "BUTTON" },
+      ButtonWndProc, 0, sizeof(BUTTONINFO), 0, 0, 0, 0, 0, "BUTTON" },
+    { CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC,
+      ScrollBarWndProc, 0, sizeof(SCROLLBAR_INFO), 0, 0, 0, 0, 0, "SCROLLBAR"},
     { CS_GLOBALCLASS, DesktopWndProc, 0, sizeof(DESKTOPINFO),
-          0, 0, 0, 0, 0, DESKTOP_CLASS_NAME }
+      0, 0, 0, 0, 0, DESKTOP_CLASS_NAME }
 };
 
 #define NB_BUILTIN_CLASSES32 \
diff --git a/debugger/memory.c b/debugger/memory.c
index 81ce74d39da..a51e9159c46 100644
--- a/debugger/memory.c
+++ b/debugger/memory.c
@@ -11,6 +11,64 @@
 #include "debugger.h"
 
 
+/************************************************************
+ *   
+ *  Check if linear pointer in [addr, addr+size[
+ *     read  (rwflag == 1)
+ *   or
+ *     write (rwflag == 0)
+ ************************************************************/
+
+#ifdef linux
+BOOL32 DEBUG_checkmap_bad( const char *addr, size_t size, int rwflag)
+{
+  FILE *fp;
+  char buf[80];      /* temporary line buffer */
+  char prot[5];      /* protection string */
+  char *start, *end;
+  int ret = TRUE;
+
+  /* 
+     The entries in /proc/self/maps are of the form:
+     08000000-08002000 r-xp 00000000 03:41 2361
+     08002000-08003000 rw-p 00001000 03:41 2361
+     08003000-08005000 rwxp 00000000 00:00 0
+     40000000-40005000 r-xp 00000000 03:41 67219
+     40005000-40006000 rw-p 00004000 03:41 67219
+     40006000-40007000 rw-p 00000000 00:00 0
+     ...
+      start    end     perm   ???    major:minor inode
+
+     Only permissions start and end are used here
+     */
+  
+  if (!(fp = fopen("/proc/self/maps", "r")))
+    return FALSE; 
+
+  while (fgets( buf, 79, fp)) {
+    sscanf(buf, "%x-%x %3s", (int *) &start, (int *) &end, prot);
+    if ( end < addr)
+      continue;
+    if (start <= addr && addr+size < end) {
+      if (rwflag) 
+	ret = (prot[0] != 'r'); /* test for reading */
+      else
+	ret = (prot[1] != 'w'); /* test for writing */
+    }
+    break;
+  }
+  fclose( fp);
+  return ret;
+}
+#else  /* linux */
+/* FIXME: code needed for BSD et al. */
+BOOL32 DEBUG_checkmap_bad(char *addr, size_t size, int rwflag)
+{
+    return FALSE;
+}
+#endif  /* linux */
+
+
 /***********************************************************************
  *           DEBUG_IsBadReadPtr
  *
@@ -19,11 +77,12 @@
 BOOL32 DEBUG_IsBadReadPtr( const DBG_ADDR *address, int size )
 {
     if (address->seg)  /* segmented addr */
-        return IsBadReadPtr16( (SEGPTR)MAKELONG( (WORD)address->off,
-                                                 (WORD)address->seg ), size );
-        /* FIXME: should check if resulting linear addr is readable */
-    else  /* linear address */
-        return FALSE;  /* FIXME: should do some checks here */
+    {
+        if (IsBadReadPtr16( (SEGPTR)MAKELONG( (WORD)address->off,
+                                              (WORD)address->seg ), size ))
+            return TRUE;
+    }
+    return DEBUG_checkmap_bad( DBG_ADDR_TO_LIN(address), size, 1);
 }
 
 
@@ -35,13 +94,14 @@ BOOL32 DEBUG_IsBadReadPtr( const DBG_ADDR *address, int size )
 BOOL32 DEBUG_IsBadWritePtr( const DBG_ADDR *address, int size )
 {
     if (address->seg)  /* segmented addr */
+    {
         /* Note: we use IsBadReadPtr here because we are */
         /* always allowed to write to read-only segments */
-        return IsBadReadPtr16( (SEGPTR)MAKELONG( (WORD)address->off,
-                                                 (WORD)address->seg ), size );
-        /* FIXME: should check if resulting linear addr is writable */
-    else  /* linear address */
-        return FALSE;  /* FIXME: should do some checks here */
+        if (IsBadReadPtr16( (SEGPTR)MAKELONG( (WORD)address->off,
+                                              (WORD)address->seg ), size ))
+            return TRUE;
+    }
+    return DEBUG_checkmap_bad( DBG_ADDR_TO_LIN(address), size, 0);
 }
 
 
diff --git a/files/directory.c b/files/directory.c
index 07049f6a648..5d12ef2890b 100644
--- a/files/directory.c
+++ b/files/directory.c
@@ -15,10 +15,8 @@
 #include "msdos.h"
 #include "options.h"
 #include "xmalloc.h"
-#include "string32.h"
 #include "stddebug.h"
 #include "debug.h"
-#include "string32.h"
 
 #define MAX_PATH_ELEMENTS 20
 
@@ -200,18 +198,15 @@ UINT32 GetTempPath32A( UINT32 count, LPSTR path )
  */
 UINT32 GetTempPath32W( UINT32 count, LPWSTR path )
 {
-    LPSTR tmp = (char*)xmalloc(count);
-    UINT32 len = GetTempPath32A( count, tmp );
-    if (path) STRING32_AnsiToUni( path, tmp );
-    free(tmp);
-    return len;
+    if (path) lstrcpynAtoW( path, DIR_TempDosDir, count );
+    return strlen( DIR_TempDosDir );
 }
 
 
 /***********************************************************************
  *           DIR_GetTempUnixDir
  */
-UINT DIR_GetTempUnixDir( LPSTR path, UINT count )
+UINT32 DIR_GetTempUnixDir( LPSTR path, UINT32 count )
 {
     if (path) lstrcpyn32A( path, DIR_TempUnixDir, count );
     return strlen( DIR_TempUnixDir );
@@ -221,7 +216,7 @@ UINT DIR_GetTempUnixDir( LPSTR path, UINT count )
 /***********************************************************************
  *           DIR_GetWindowsUnixDir
  */
-UINT DIR_GetWindowsUnixDir( LPSTR path, UINT count )
+UINT32 DIR_GetWindowsUnixDir( LPSTR path, UINT32 count )
 {
     if (path) lstrcpyn32A( path, DIR_WindowsUnixDir, count );
     return strlen( DIR_WindowsUnixDir );
@@ -231,7 +226,7 @@ UINT DIR_GetWindowsUnixDir( LPSTR path, UINT count )
 /***********************************************************************
  *           DIR_GetSystemUnixDir
  */
-UINT DIR_GetSystemUnixDir( LPSTR path, UINT count )
+UINT32 DIR_GetSystemUnixDir( LPSTR path, UINT32 count )
 {
     if (path) lstrcpyn32A( path, DIR_SystemUnixDir, count );
     return strlen( DIR_SystemUnixDir );
@@ -241,7 +236,7 @@ UINT DIR_GetSystemUnixDir( LPSTR path, UINT count )
 /***********************************************************************
  *           DIR_GetDosPath
  */
-UINT DIR_GetDosPath( int element, LPSTR path, UINT count )
+UINT32 DIR_GetDosPath( INT32 element, LPSTR path, UINT32 count )
 {
     if ((element < 0) || (element >= DIR_PathElements)) return 0;
     if (path) lstrcpyn32A( path, DIR_DosPath[element], count );
@@ -272,16 +267,36 @@ UINT32 WIN16_GetTempDrive( BYTE ignored )
     return MAKELONG( GetTempDrive(ignored) | (':' << 8), 1 );
 }
 
+
 /***********************************************************************
- *           GetWindowsDirectory   (KERNEL.134)
+ *           GetWindowsDirectory16   (KERNEL.134)
  */
-UINT GetWindowsDirectory( LPSTR path, UINT count )
+UINT16 GetWindowsDirectory16( LPSTR path, UINT16 count )
+{
+    return (UINT16)GetWindowsDirectory32A( path, count );
+}
+
+
+/***********************************************************************
+ *           GetWindowsDirectory32A   (KERNEL32.311)
+ */
+UINT32 GetWindowsDirectory32A( LPSTR path, UINT32 count )
 {
     if (path) lstrcpyn32A( path, DIR_WindowsDosDir, count );
     return strlen( DIR_WindowsDosDir );
 }
 
 
+/***********************************************************************
+ *           GetWindowsDirectory32W   (KERNEL32.312)
+ */
+UINT32 GetWindowsDirectory32W( LPWSTR path, UINT32 count )
+{
+    if (path) lstrcpynAtoW( path, DIR_WindowsDosDir, count );
+    return strlen( DIR_WindowsDosDir );
+}
+
+
 /***********************************************************************
  *           GetSystemDirectory16   (KERNEL.135)
  */
@@ -306,11 +321,6 @@ UINT32 GetSystemDirectory32A( LPSTR path, UINT32 count )
  */
 UINT32 GetSystemDirectory32W( LPWSTR path, UINT32 count )
 {
-    if (path)
-    {
-        LPWSTR tmp = STRING32_DupAnsiToUni( DIR_SystemDosDir );
-        lstrcpyn32W( path, tmp, count );
-	free (tmp);
-    }
+    if (path) lstrcpynAtoW( path, DIR_SystemDosDir, count );
     return strlen( DIR_SystemDosDir );
 }
diff --git a/files/dos_fs.c b/files/dos_fs.c
index 376368a3b21..4ed1544fc60 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -777,3 +777,15 @@ DWORD GetShortPathName32W( LPCWSTR longpath, LPWSTR shortpath, DWORD shortlen )
     lstrcpynAtoW( shortpath, dostruename, shortlen );
     return strlen(dostruename);
 }
+
+/***********************************************************************
+ *           GetFullPathNameA   (KERNEL32.272)
+ */
+DWORD GetFullPathName32A( LPCSTR fn, DWORD buflen, LPSTR buf, LPSTR *lastpart) {
+	dprintf_file(stddeb,"GetFullPathNameA(%s)\n",fn);
+	/* FIXME */
+	lstrcpyn32A(buf,fn,buflen);
+	if (lastpart)
+		*lastpart=strrchr(buf,'\\');
+	return strlen(fn);
+}
diff --git a/files/file.c b/files/file.c
index ee4a7e88f75..2d786f24aa8 100644
--- a/files/file.c
+++ b/files/file.c
@@ -541,23 +541,6 @@ HFILE FILE_Dup2( HFILE hFile1, HFILE hFile2 )
 }
 
 
-/***********************************************************************
- *           FILE_Read
- */
-INT32 FILE_Read( HFILE hFile, LPVOID buffer, UINT32 count )
-{
-    DOS_FILE *file;
-    INT32 result;
-
-    dprintf_file( stddeb, "FILE_Read: %d %p %d\n", hFile, buffer, count );
-    if (!(file = FILE_GetFile( hFile ))) return -1;
-    if (!count) return 0;
-    if ((result = read( file->unix_handle, buffer, count )) == -1)
-        FILE_SetDosError();
-    return result;
-}
-
-
 /***********************************************************************
  *           GetTempFileName16   (KERNEL.97)
  */
@@ -735,7 +718,7 @@ HFILE OpenFile( LPCSTR name, OFSTRUCT *ofs, UINT32 mode )
 
     /* Try the Windows directory */
 
-    GetWindowsDirectory( ofs->szPathName, len );
+    GetWindowsDirectory32A( ofs->szPathName, len );
     strcat( ofs->szPathName, "\\" );
     strcat( ofs->szPathName, name );
     if ((unixName = DOSFS_GetUnixFileName( ofs->szPathName, TRUE )) != NULL)
@@ -893,7 +876,7 @@ DWORD SearchPath32A(
         goto found;
 
     /* Try the Windows directory */
-    GetWindowsDirectory(testpath,len);
+    GetWindowsDirectory32A(testpath,len);
     strcat(testpath,"\\");
     strcat(testpath,name);
     if ((unixName = DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL)
@@ -991,7 +974,7 @@ LONG WIN16_hread( HFILE hFile, SEGPTR buffer, LONG count )
     /* Some programs pass a count larger than the allocated buffer */
     maxlen = GetSelectorLimit( SELECTOROF(buffer) ) - OFFSETOF(buffer) + 1;
     if (count > maxlen) count = maxlen;
-    return FILE_Read( hFile, PTR_SEG_TO_LIN(buffer), count );
+    return _lread32( hFile, PTR_SEG_TO_LIN(buffer), count );
 }
 
 
@@ -1009,7 +992,15 @@ UINT16 WIN16_lread( HFILE hFile, SEGPTR buffer, UINT16 count )
  */
 UINT32 _lread32( HFILE hFile, LPVOID buffer, UINT32 count )
 {
-    return (UINT32)FILE_Read( hFile, buffer, (LONG)count );
+    DOS_FILE *file;
+    UINT32 result;
+
+    dprintf_file( stddeb, "_lread32: %d %p %d\n", hFile, buffer, count );
+    if (!(file = FILE_GetFile( hFile ))) return -1;
+    if (!count) return 0;
+    if ((result = read( file->unix_handle, buffer, count )) == -1)
+        FILE_SetDosError();
+    return result;
 }
 
 
@@ -1018,7 +1009,7 @@ UINT32 _lread32( HFILE hFile, LPVOID buffer, UINT32 count )
  */
 UINT16 _lread16( HFILE hFile, LPVOID buffer, UINT16 count )
 {
-    return (UINT16)FILE_Read( hFile, buffer, (LONG)count );
+    return (UINT16)_lread32( hFile, buffer, (LONG)count );
 }
 
 
@@ -1131,7 +1122,7 @@ UINT32 _lwrite32( HFILE hFile, LPCSTR buffer, UINT32 count )
  */
 LONG _hread( HFILE hFile, LPVOID buffer, LONG count)
 {
-    return FILE_Read( hFile, buffer, count );
+    return _lread32( hFile, buffer, count );
 }
 
 
diff --git a/files/profile.c b/files/profile.c
index b7c059549dd..4570b5e510f 100644
--- a/files/profile.c
+++ b/files/profile.c
@@ -382,7 +382,7 @@ static BOOL PROFILE_Open( const char *filename )
     }
     else
     {
-        GetWindowsDirectory( buffer, sizeof(buffer) );
+        GetWindowsDirectory32A( buffer, sizeof(buffer) );
         strcat( buffer, "\\" );
         strcat( buffer, filename );
         if (!(dos_name = DOSFS_GetDosTrueName( buffer, FALSE ))) return FALSE;
diff --git a/if1632/crtdll.spec b/if1632/crtdll.spec
index b290cb0ca9b..bd0723409ea 100644
--- a/if1632/crtdll.spec
+++ b/if1632/crtdll.spec
@@ -483,7 +483,7 @@ base	1
 478 stub strtod
 479 stub strtok
 480 stub strtol
-481 stub strtoul
+481 cdecl strtoul(ptr ptr long) strtoul
 482 stub strxfrm
 483 stub swprintf
 484 stub swscanf
diff --git a/if1632/gdi32.spec b/if1632/gdi32.spec
index d70567eb703..443043b0fd0 100644
--- a/if1632/gdi32.spec
+++ b/if1632/gdi32.spec
@@ -283,7 +283,7 @@ base	1
 0276 stub Polyline
 0277 stub PolylineTo
 0278 stdcall PtInRegion(long long long) PtInRegion
-0279 stub PtVisible
+0279 stdcall PtVisible(long long long) PtVisible
 0280 stdcall RealizePalette(long) RealizePalette
 0281 stdcall RectInRegion(long ptr) RectInRegion32
 0282 stdcall RectVisible(long ptr) RectVisible32
@@ -301,7 +301,7 @@ base	1
 0294 stdcall ScaleWindowExtEx(long long long long long ptr) ScaleWindowExtEx32
 0295 stub SelectBrushLocal
 0296 stub SelectClipPath
-0297 stub SelectClipRgn
+0297 stdcall SelectClipRgn(long long) SelectClipRgn
 0298 stub SelectFontLocal
 0299 stdcall SelectObject(long long) SelectObject
 0300 stdcall SelectPalette(long long long) SelectPalette
@@ -356,7 +356,8 @@ base	1
 0348 stub StartDocW
 0349 stub StartPage
 0350 stdcall StretchBlt(long long long long long long long long long long long) StretchBlt
-0351 stub StretchDIBits
+0351 stdcall StretchDIBits(long long long long long long long
+                               long long long long long long) StretchDIBits
 0352 stub StrokeAndFillPath
 0353 stub StrokePath
 0354 stub SwapBuffers
@@ -392,5 +393,4 @@ base	1
 0383 stub UpdateICMRegKeyA
 0384 stub UpdateICMRegKeyW
 0385 stub gdiPlaySpoolStream
-
-
+0386 return SetObjectOwner 8 0
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index 39c0ca18e2a..604c87c4d0e 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -132,7 +132,7 @@ type	win16
 131 pascal GetDOSEnvironment() GetDOSEnvironment
 132 pascal GetWinFlags() GetWinFlags
 133 pascal16 GetExePtr(word) GetExePtr
-134 pascal16 GetWindowsDirectory(ptr word) GetWindowsDirectory
+134 pascal16 GetWindowsDirectory(ptr word) GetWindowsDirectory16
 135 pascal16 GetSystemDirectory(ptr word) GetSystemDirectory16
 136 pascal16 GetDriveType(byte) GetDriveType16
 137 pascal FatalAppExit(word ptr) FatalAppExit
diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec
index 18d227983ef..ca3fc9b78e7 100644
--- a/if1632/kernel32.spec
+++ b/if1632/kernel32.spec
@@ -192,7 +192,7 @@ base	1
 0187 stub GetConsoleInputWaitHandle
 0188 stub GetConsoleMode
 0189 stub GetConsoleOutputCP
-0190 stub GetConsoleScreenBufferInfo
+0190 stdcall GetConsoleScreenBufferInfo(long ptr) GetConsoleScreenBufferInfo
 0191 stub GetConsoleTitleA
 0192 stub GetConsoleTitleW
 0193 stub GetCurrencyFormatA
@@ -225,10 +225,10 @@ base	1
 0220 stub GetFileSize
 0221 stub GetFileTime
 0222    stdcall GetFileType(long) GetFileType
-0223 stub GetFullPathNameA
+0223 stdcall GetFullPathNameA(ptr long ptr ptr) GetFullPathName32A
 0224 stub GetFullPathNameW
 0225 stub GetHandleInformation
-0226 stub GetLargestConsoleWindowSize
+0226 stdcall GetLargestConsoleWindowSize(long) GetLargestConsoleWindowSize
 0227    stdcall GetLastError() GetLastError
 0228    stdcall GetLocalTime(ptr) GetLocalTime
 0229 stdcall GetLocaleInfoA(long long ptr long) GetLocaleInfoA
@@ -283,7 +283,7 @@ base	1
 0278 stub GetStringTypeExW
 0279 stub GetStringTypeW
 0280 stdcall GetSystemDefaultLCID() GetSystemDefaultLCID
-0281 stub GetSystemDefaultLangID
+0281 stdcall GetSystemDefaultLangID() GetSystemDefaultLangID
 0282 stdcall GetSystemDirectoryA(ptr long) GetSystemDirectory32A
 0283 stdcall GetSystemDirectoryW(ptr long) GetSystemDirectory32W
 0284 stub GetSystemInfo
@@ -306,15 +306,15 @@ base	1
 0301 stub GetTimeFormatW
 0302    stdcall GetTimeZoneInformation(ptr) GetTimeZoneInformation
 0303 stdcall GetUserDefaultLCID() GetUserDefaultLCID
-0304 stub GetUserDefaultLangID
+0304 stdcall GetUserDefaultLangID() GetUserDefaultLangID
 0305 stub GetVDMCurrentDirectories
 0306 stdcall GetVersion() GetVersion32
 0307 stdcall GetVersionExA(ptr) GetVersionEx32A
 0308 stdcall GetVersionExW(ptr) GetVersionEx32W
 0309 stdcall GetVolumeInformationA(ptr ptr long ptr ptr ptr ptr long) GetVolumeInformation32A
 0310 stdcall GetVolumeInformationW(ptr ptr long ptr ptr ptr ptr long) GetVolumeInformation32W
-0311 stdcall GetWindowsDirectoryA(ptr long) GetWindowsDirectory
-0312 stub GetWindowsDirectoryW
+0311 stdcall GetWindowsDirectoryA(ptr long) GetWindowsDirectory32A
+0312 stdcall GetWindowsDirectoryW(ptr long) GetWindowsDirectory32W
 0313 stdcall GlobalAddAtomA(ptr) GlobalAddAtom32A
 0314 stdcall GlobalAddAtomW(ptr) GlobalAddAtom32W
 0315 stdcall GlobalAlloc(long long) GlobalAlloc32
@@ -363,7 +363,7 @@ base	1
 0358 return IsDBCSLeadByte 4 0
 0359 stub IsDBCSLeadByteEx
 0360 stub IsValidCodePage
-0361 stub IsValidLocale
+0361 stdcall IsValidLocale(long long) IsValidLocale
 0362 stub LCMapStringA
 0363 stub LCMapStringW
 0364 stdcall LeaveCriticalSection(ptr)	LeaveCriticalSection
@@ -556,7 +556,7 @@ base	1
 0551 stub VirtualLock
 0552 stub VirtualProtect
 0553 stub VirtualProtectEx
-0554 stub VirtualQuery
+0554 stdcall VirtualQuery(ptr ptr long) VirtualQuery
 0555 stub VirtualQueryEx
 0556 stub VirtualUnlock
 0557 stub WaitCommEvent
@@ -639,3 +639,13 @@ base	1
 0633 stub MakeCriticalSectionGlobal
 #extra late additions
 0634 stdcall ThunkConnect32(ptr ptr ptr ptr ptr ptr) ThunkConnect32
+0636 stub SUnMapLS
+0637 stub SMapLS
+0638 stdcall ReinitializeCriticalSection(ptr) ReinitializeCriticalSection
+0639 stub FT_Thunk
+0640 stub FT_Exit20
+0641 stub SMapLS_IP_EBP_12
+0642 stub SUnMapLS_IP_EBP_12
+0643 stub MapSLFix
+0644 stub UnMapSLFixArray
+0645 stub dprintf
diff --git a/if1632/shell32.spec b/if1632/shell32.spec
index acb26b40659..4b513b4b413 100644
--- a/if1632/shell32.spec
+++ b/if1632/shell32.spec
@@ -56,8 +56,8 @@ base	1
 0051 stub SHFormatDrive
 0052 stub SHFreeNameMappings
 0053 stub SHGetDesktopFolder
-0054 stub SHGetFileInfo
-0055 stub SHGetFileInfoA
+0054 stdcall SHGetFileInfo(ptr long ptr long long) SHGetFileInfo32A
+0055 stdcall SHGetFileInfoA(ptr long ptr long long) SHGetFileInfo32A
 0056 stub SHGetFileInfoW
 0057 stub SHGetInstanceExplorer
 0058 stub SHGetMalloc
diff --git a/if1632/user.spec b/if1632/user.spec
index 7a0520582de..b833439df30 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -17,7 +17,7 @@ heap	65520
 15  pascal   GetCurrentTime() GetCurrentTime
 16  pascal16 ClipCursor(ptr) ClipCursor16
 17  pascal16 GetCursorPos(ptr) GetCursorPos16
-18  pascal16 SetCapture(word) SetCapture
+18  pascal16 SetCapture(word) SetCapture16
 19  pascal16 ReleaseCapture() ReleaseCapture
 20  pascal16 SetDoubleClickTime(word) SetDoubleClickTime
 21  pascal16 GetDoubleClickTime() GetDoubleClickTime
@@ -62,13 +62,13 @@ heap	65520
 59  pascal16 SetActiveWindow(word) SetActiveWindow
 60  pascal16 GetActiveWindow() GetActiveWindow
 61  pascal16 ScrollWindow(word s_word s_word ptr ptr) ScrollWindow
-62  pascal16 SetScrollPos(word word s_word word) SetScrollPos
-63  pascal16 GetScrollPos(word word) GetScrollPos
-64  pascal16 SetScrollRange(word word s_word s_word word) SetScrollRange
-65  pascal16 GetScrollRange(word word ptr ptr) GetScrollRange
-66  pascal16 GetDC(word) GetDC
-67  pascal16 GetWindowDC(word) GetWindowDC
-68  pascal16 ReleaseDC(word word) ReleaseDC
+62  pascal16 SetScrollPos(word word s_word word) SetScrollPos16
+63  pascal16 GetScrollPos(word word) GetScrollPos16
+64  pascal16 SetScrollRange(word word s_word s_word word) SetScrollRange16
+65  pascal16 GetScrollRange(word word ptr ptr) GetScrollRange16
+66  pascal16 GetDC(word) GetDC16
+67  pascal16 GetWindowDC(word) GetWindowDC16
+68  pascal16 ReleaseDC(word word) ReleaseDC16
 69  pascal16 SetCursor(word) SetCursor
 70  pascal16 SetCursorPos(word word) SetCursorPos
 71  pascal16 ShowCursor(word) ShowCursor
@@ -117,7 +117,7 @@ heap	65520
 115 pascal16 ReplyMessage(long) ReplyMessage
 116 pascal16 PostAppMessage(word word word long) PostAppMessage
 118 pascal16 RegisterWindowMessage(segptr) RegisterWindowMessage16
-117 pascal16 WindowFromDC(word) WindowFromDC
+117 pascal16 WindowFromDC(word) WindowFromDC16
 119 pascal   GetMessagePos() GetMessagePos
 120 pascal   GetMessageTime() GetMessageTime
 121 pascal   SetWindowsHook(s_word segptr) SetWindowsHook
@@ -236,7 +236,7 @@ heap	65520
 233 pascal16 SetParent(word word) SetParent
 234 pascal16 UnhookWindowsHook(s_word segptr) UnhookWindowsHook
 235 pascal   DefHookProc(s_word word long ptr) DefHookProc
-236 pascal16 GetCapture() GetCapture
+236 pascal16 GetCapture() GetCapture16
 237 pascal16 GetUpdateRgn(word word word) GetUpdateRgn
 238 pascal16 ExcludeUpdateRgn(word word) ExcludeUpdateRgn
 239 pascal16 DialogBoxParam(word segptr word segptr long) DialogBoxParam16
@@ -270,7 +270,7 @@ heap	65520
 264 pascal16 GetMenuItemID(word word) GetMenuItemID
 265 pascal16 ShowOwnedPopups(word word) ShowOwnedPopups
 266 pascal16 SetMessageQueue(word) SetMessageQueue
-267 pascal16 ShowScrollBar(word word word) ShowScrollBar
+267 pascal16 ShowScrollBar(word word word) ShowScrollBar16
 268 pascal16 GlobalAddAtom(segptr) GlobalAddAtom16
 269 pascal16 GlobalDeleteAtom(word) GlobalDeleteAtom
 270 pascal16 GlobalFindAtom(segptr) GlobalFindAtom16
@@ -288,8 +288,8 @@ heap	65520
 282 pascal16 SelectPalette(word word word) SelectPalette
 283 pascal16 RealizePalette(word) RealizePalette
 284 pascal16 GetFreeSystemResources(word) GetFreeSystemResources
-#285 BEAR285
-286 pascal16 GetDesktopWindow() GetDesktopWindow
+285 pascal16 SetDeskWallPaper(ptr) SetDeskWallPaper16
+286 pascal16 GetDesktopWindow() GetDesktopWindow16
 287 pascal16 GetLastActivePopup(word) GetLastActivePopup
 288 pascal   GetMessageExtraInfo() GetMessageExtraInfo
 #289 KEYB_EVENT
@@ -326,7 +326,7 @@ heap	65520
 356 stub LoadDIBCursorHandler
 357 stub LoadDIBIconHandler
 358 pascal16 IsMenu(word) IsMenu
-359 pascal16 GetDCEx(word word long) GetDCEx
+359 pascal16 GetDCEx(word word long) GetDCEx16
 362 pascal16 DCHook(word word long long) DCHook
 364 stub LookupIconIDFromDirectoryEx
 368 pascal16 CopyIcon(word word) CopyIcon16
@@ -416,14 +416,14 @@ heap	65520
 471 pascal16 lstrcmpi(ptr ptr) lstrcmpi16
 472 pascal   AnsiNext(segptr) AnsiNext
 473 pascal   AnsiPrev(segptr segptr) AnsiPrev
-475 stub SetScrollInfo
-476 stub GetScrollInfo
+475 pascal16 SetScrollInfo(word s_word ptr word) SetScrollInfo16
+476 pascal16 GetScrollInfo(word s_word ptr) GetScrollInfo16
 477 stub GetKeyboardLayoutName
 478 stub LoadKeyboardLayout
 479 stub MenuItemFromPoint
 480 stub GetUserLocalObjType
 #481 HARDWARE_EVENT
-482 pascal16 EnableScrollBar(word word word) EnableScrollBar
+482 pascal16 EnableScrollBar(word word word) EnableScrollBar16
 483 pascal16 SystemParametersInfo(word word ptr word) SystemParametersInfo
 #484 __GP
 # Stubs for Hebrew version
diff --git a/if1632/user32.spec b/if1632/user32.spec
index 01268cb60b0..133cf02eedf 100644
--- a/if1632/user32.spec
+++ b/if1632/user32.spec
@@ -10,7 +10,7 @@ base	1
 0005 stdcall AppendMenuW(long long long ptr) AppendMenu32W
 0006 stub ArrangeIconicWindows
 0007 stub AttachThreadInput
-0008 stub BeginDeferWindowPos
+0008 stdcall BeginDeferWindowPos(long) BeginDeferWindowPos
 0009 stdcall BeginPaint(long ptr) BeginPaint32
 0010 stdcall BringWindowToTop(long) BringWindowToTop
 0011 stub BroadcastSystemMessage
@@ -62,7 +62,7 @@ base	1
 0057 stub CopyAcceleratorTableA
 0058 stub CopyAcceleratorTableW
 0059 stdcall CopyIcon(long) CopyIcon32
-0060 stub CopyImage
+0060 stdcall CopyImage(long long long long long) CopyImage32
 0061 stdcall CopyRect(ptr ptr) CopyRect32
 0062 stub CountClipboardFormats
 0063 stub CreateAcceleratorTableA
@@ -131,7 +131,7 @@ base	1
 0124 stdcall DefMDIChildProcW(long long long long) DefMDIChildProc32W
 0125 stdcall DefWindowProcA(long long long long) DefWindowProc32A
 0126 stdcall DefWindowProcW(long long long long) DefWindowProc32W
-0127 stub DeferWindowPos
+0127 stdcall DeferWindowPos(long long long long long long long long) DeferWindowPos
 0128 stdcall DeleteMenu(long) DeleteMenu
 0129 stub DestroyAcceleratorTable
 0130 stdcall DestroyCaret() DestroyCaret
@@ -174,9 +174,9 @@ base	1
 0167 stub EditWndProc
 0168 stdcall EmptyClipboard()				EmptyClipboard
 0169 stdcall EnableMenuItem(long long long) EnableMenuItem
-0170 stdcall EnableScrollBar(long long long)	EnableScrollBar
-0171 stdcall EnableWindow(long long)		EnableWindow
-0172 stub EndDeferWindowPos
+0170 stdcall EnableScrollBar(long long long) EnableScrollBar32
+0171 stdcall EnableWindow(long long) EnableWindow
+0172 stdcall EndDeferWindowPos(long) EndDeferWindowPos
 0173 stdcall EndDialog(long long) EndDialog
 0174 stub EndMenu
 0175 stdcall EndPaint(long ptr) EndPaint32
@@ -210,8 +210,8 @@ base	1
 0203 stub FreeDDElParam
 0204 stdcall GetActiveWindow() GetActiveWindow
 0205 stdcall GetAppCompatFlags(long) GetAppCompatFlags
-0206 stub GetAsyncKeyState
-0207 stub GetCapture
+0206 stdcall GetAsyncKeyState(long) GetAsyncKeyState
+0207 stdcall GetCapture() GetCapture32
 0208 stdcall GetCaretBlinkTime() GetCaretBlinkTime32
 0209 stdcall GetCaretPos(ptr) GetCaretPos32
 0210 stdcall GetClassInfoA(long ptr ptr) GetClassInfo32A
@@ -233,10 +233,10 @@ base	1
 0226 stub GetCursor
 0227 stub GetCursorInfo
 0228 stdcall GetCursorPos(ptr) GetCursorPos32
-0229 stdcall GetDC(long) GetDC
-0230 stub GetDCEx
-0231 stdcall GetDesktopWindow() GetDesktopWindow
-0232 stub GetDialogBaseUnits
+0229 stdcall GetDC(long) GetDC32
+0230 stdcall GetDCEx(long long long) GetDCEx32
+0231 stdcall GetDesktopWindow() GetDesktopWindow32
+0232 stdcall GetDialogBaseUnits() GetDialogBaseUnits
 0233 stdcall GetDlgCtrlID(long) GetDlgCtrlID
 0234 stdcall GetDlgItem(long long) GetDlgItem
 0235 stdcall GetDlgItemInt(long long long long) GetDlgItemInt
@@ -244,7 +244,7 @@ base	1
 0237 stdcall GetDlgItemTextW(long long ptr long) GetDlgItemText32W
 0238 stub GetDoubleClickTime
 0239 stdcall GetFocus() GetFocus32
-0240 stub GetForegroundWindow
+0240 return GetForegroundWindow 0 0		#FIXME
 0241 stub GetIconInfo
 0242 stub GetInputDesktop
 0243 stub GetInputState
@@ -266,12 +266,12 @@ base	1
 0259 stub GetMenuDefaultItem
 0260 stub GetMenuIndex
 0261 stdcall GetMenuItemCount(long) GetMenuItemCount
-0262 stub GetMenuItemID
+0262 stdcall GetMenuItemID(long long) GetMenuItemID
 0263 stub GetMenuItemInfoA
 0264 stub GetMenuItemInfoW
 0265 stub GetMenuItemRect
-0266 stub GetMenuState
-0267 stub GetMenuStringA
+0266 stdcall GetMenuState(long long long) GetMenuState
+0267 stdcall GetMenuStringA(long long ptr long long) GetMenuString
 0268 stub GetMenuStringW
 0269 stdcall GetMessageA(ptr long long long) USER32_GetMessageA
 0270 stub GetMessageExtraInfo
@@ -288,8 +288,8 @@ base	1
 0281 stdcall GetPropW(long ptr) GetProp32W
 0282 stub GetQueueStatus
 0283 stdcall GetScrollInfo(long long ptr) GetScrollInfo32
-0284 stdcall GetScrollPos(long long) GetScrollPos
-0285 stub GetScrollRange
+0284 stdcall GetScrollPos(long long) GetScrollPos32
+0285 stdcall GetScrollRange(long long ptr ptr) GetScrollRange32
 0286 return GetShellWindow 0 0
 0287 stdcall GetSubMenu(long long) GetSubMenu
 0288 stdcall GetSysColor(long) GetSysColor
@@ -307,7 +307,7 @@ base	1
 0300 stub GetUserObjectSecurity
 0301 stdcall GetWindow(long long) GetWindow
 0302 stub GetWindowContextHelpId
-0303 stdcall GetWindowDC(long) GetWindowDC
+0303 stdcall GetWindowDC(long) GetWindowDC32
 0304 stdcall GetWindowLongA(long long) GetWindowLong32A
 0305 stdcall GetWindowLongW(long long) GetWindowLong32W
 0306 stdcall GetWindowPlacement(long ptr) GetWindowPlacement32
@@ -443,7 +443,7 @@ base	1
 0436 stdcall RegisterWindowMessageA(ptr) RegisterWindowMessage32A
 0437 stdcall RegisterWindowMessageW(ptr) RegisterWindowMessage32W
 0438 stdcall ReleaseCapture() ReleaseCapture
-0439 stdcall ReleaseDC(long long) ReleaseDC
+0439 stdcall ReleaseDC(long long) ReleaseDC32
 0440 stub RemoveMenu
 0441 stdcall RemovePropA(long ptr) RemoveProp32A
 0442 stdcall RemovePropW(long ptr) RemoveProp32W
@@ -467,7 +467,7 @@ base	1
 0460 stub SendNotifyMessageW
 0461 stub ServerSetFunctionPointers
 0462 stub SetActiveWindow
-0463 stdcall SetCapture(long) SetCapture
+0463 stdcall SetCapture(long) SetCapture32
 0464 stdcall SetCaretBlinkTime(long) SetCaretBlinkTime
 0465 stdcall SetCaretPos(long long) SetCaretPos
 0466 stdcall SetClassLongA(long long long) SetClassLong32A
@@ -479,7 +479,7 @@ base	1
 0472 stub SetCursorContents
 0473 stub SetCursorPos
 0474 stub SetDebugErrorLevel
-0475 stub SetDeskWallpaper
+0475 stdcall SetDeskWallPaper(ptr) SetDeskWallPaper32
 0476 stdcall SetDlgItemInt(long long long long) SetDlgItemInt32
 0477 stdcall SetDlgItemTextA(long long ptr) SetDlgItemText32A
 0478 stdcall SetDlgItemTextW(long long ptr) SetDlgItemText32W
@@ -505,8 +505,8 @@ base	1
 0498 stdcall SetRect(ptr long long long long) SetRect32
 0499 stdcall SetRectEmpty(ptr) SetRectEmpty32
 0500 stdcall SetScrollInfo(long long ptr long) SetScrollInfo32
-0501 stdcall SetScrollPos(long long long long) SetScrollPos
-0502 stdcall SetScrollRange(long long long long long) SetScrollRange
+0501 stdcall SetScrollPos(long long long long) SetScrollPos32
+0502 stdcall SetScrollRange(long long long long long) SetScrollRange32
 0503 stub SetShellWindow
 0504 stub SetSysColors
 0505 stub SetSysColorsTemp
@@ -528,19 +528,19 @@ base	1
 0521 stdcall SetWindowTextA(long ptr) SetWindowText32A
 0522 stdcall SetWindowTextW(long ptr) SetWindowText32W
 0523 stdcall SetWindowWord(long long long) SetWindowWord
-0524 stub SetWindowsHookA
+0524 stdcall SetWindowsHookA(long ptr) SetWindowsHook32A
 0525 stdcall SetWindowsHookExA(long long long long) SetWindowsHookEx32A
 0526 stub SetWindowsHookExW
 0527 stub SetWindowsHookW
 0528 stdcall ShowCaret(long) ShowCaret
 0529 stdcall ShowCursor(long) ShowCursor
 0530 stub ShowOwnedPopups
-0531 stdcall ShowScrollBar(long long long) ShowScrollBar
+0531 stdcall ShowScrollBar(long long long) ShowScrollBar32
 0532 stub ShowStartGlass
 0533 stdcall ShowWindow(long long) ShowWindow
 0534 stub ShowWindowAsync
 0535 stdcall SubtractRect(ptr ptr ptr) SubtractRect32
-0536 stub SwapMouseButton
+0536 stdcall SwapMouseButton(long) SwapMouseButton
 0537 stub SwitchDesktop
 0538 stub SwitchToThisWindow
 0539 	stdcall SystemParametersInfoA(long long ptr long) SystemParametersInfo
@@ -584,7 +584,7 @@ base	1
 0577 stub WaitMessage
 0578 stdcall WinHelpA(long ptr long long)	WIN32_WinHelpA
 0579 stub WinHelpW
-0580 stdcall WindowFromDC(long) WindowFromDC
+0580 stdcall WindowFromDC(long) WindowFromDC32
 0581 stdcall WindowFromPoint(long long) WindowFromPoint32
 0582 stub keybd_event
 0583 stub mouse_event
diff --git a/include/class.h b/include/class.h
index 418f72371b2..e02bec715fc 100644
--- a/include/class.h
+++ b/include/class.h
@@ -12,6 +12,8 @@
 
 #define CLASS_MAGIC   ('C' | ('L' << 8) | ('A' << 16) | ('S' << 24))
 
+struct tagDCE;
+
 typedef struct tagCLASS
 {
     struct tagCLASS *next;          /* Next class */
@@ -23,13 +25,13 @@ typedef struct tagCLASS
     INT32            cbWndExtra;    /* Window extra bytes */
     LPSTR            menuNameA;     /* Default menu name (ASCII string) */
     LPWSTR           menuNameW;     /* Default menu name (Unicode) */
+    struct tagDCE   *dce;           /* Class DCE (if CS_CLASSDC) */
     HINSTANCE32      hInstance;     /* Module that created the task */
     HICON16          hIcon;         /* Default icon */
     HICON16          hIconSm;       /* Default small icon */
     HCURSOR16        hCursor;       /* Default cursor */
     HBRUSH16         hbrBackground; /* Default background */
     ATOM             atomName;      /* Name of the class */
-    HANDLE16         hdce;          /* Class DCE (if CS_CLASSDC) */
     LONG             wExtra[1];     /* Class extra bytes */
 } CLASS;
 
diff --git a/include/clipboard.h b/include/clipboard.h
index 62bdcab11db..17cc34090fc 100644
--- a/include/clipboard.h
+++ b/include/clipboard.h
@@ -2,8 +2,8 @@
 #define __WINE_CLIPBOARD_H
 
 void CLIPBOARD_ReadSelection(Window w,Atom prop);
-void CLIPBOARD_ReleaseSelection(HWND hwnd);
-void CLIPBOARD_DisOwn(HWND hWnd);
+void CLIPBOARD_ReleaseSelection(Window w,HWND hwnd);
+void CLIPBOARD_DisOwn(WND* pWnd);
 BOOL CLIPBOARD_IsPresent(WORD wFormat);
 
 #endif /* __WINE_CLIPBOARD_H */
diff --git a/include/dce.h b/include/dce.h
index 43a7ec54084..06ff0629e8e 100644
--- a/include/dce.h
+++ b/include/dce.h
@@ -34,18 +34,18 @@ typedef enum
 
 typedef struct tagDCE
 {
-    HANDLE     hNext;
-    HDC	       hDC;
-    HWND       hwndCurrent;
-    HWND       hwndDC;
-    HRGN       hClipRgn;
-    DCE_TYPE   type;
-    DWORD      DCXflags;
+    struct tagDCE *next;
+    HDC32          hDC;
+    HWND32         hwndCurrent;
+    HWND32         hwndDC;
+    HRGN32         hClipRgn;
+    DCE_TYPE       type;
+    DWORD          DCXflags;
 } DCE;
 
 
-extern void 	DCE_Init(void);
-extern HANDLE 	DCE_AllocDCE( HWND hWnd, DCE_TYPE type );
-extern void 	DCE_FreeDCE( HANDLE hdce );
+extern void DCE_Init(void);
+extern DCE *DCE_AllocDCE( HWND32 hWnd, DCE_TYPE type );
+extern void DCE_FreeDCE( DCE *dce );
 
 #endif  /* DCE_H */
diff --git a/include/dde_mem.h b/include/dde_mem.h
index bdcdf3eb47e..09b382a4b90 100644
--- a/include/dde_mem.h
+++ b/include/dde_mem.h
@@ -25,14 +25,14 @@ typedef struct {
 
 WORD DDE_SyncHandle(HGLOBAL16 handle, WORD sel);
 void *DDE_malloc(unsigned int flags,unsigned long size, SHMDATA *shmdata);
-HANDLE DDE_GlobalReAlloc(WORD,long,WORD);
+HANDLE16 DDE_GlobalReAlloc(WORD,long,WORD);
 HGLOBAL16 DDE_GlobalFree(HGLOBAL16 block);
 void *DDE_AttachHandle(HGLOBAL16 handle, SEGPTR *segptr);
 WORD DDE_GlobalHandleToSel( HGLOBAL16 handle );
 int DDE_GlobalUnlock(int);
-HANDLE DDE_GlobalSize(WORD);
-HANDLE DDE_GlobalHandle(WORD);
-HANDLE DDE_GlobalFlags(WORD);
+HANDLE16 DDE_GlobalSize(WORD);
+HANDLE16 DDE_GlobalHandle(WORD);
+HANDLE16 DDE_GlobalFlags(WORD);
 
 #endif  /* CONFIG_IPC */
 
diff --git a/include/debug.h b/include/debug.h
index 9ccba2b77d2..7906c060cda 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -80,6 +80,7 @@
 #undef DEBUG_SCROLL
 #undef DEBUG_SELECTOR
 #undef DEBUG_SEM
+#undef DEBUG_SENDMSG
 #undef DEBUG_SHM
 #undef DEBUG_STRESS
 #undef DEBUG_SYSCOLOR
@@ -159,6 +160,7 @@
 #define DEBUG_SCROLL
 #define DEBUG_SELECTOR
 #define DEBUG_SEM
+#define DEBUG_SENDMSG
 #define DEBUG_SHM
 #define DEBUG_STRESS
 #define DEBUG_SYSCOLOR
@@ -496,6 +498,11 @@ short debug_msg_enabled[]={
 #else
     0,
 #endif
+#ifdef DEBUG_SENDMSG
+    1,
+#else
+    0,
+#endif
 #ifdef DEBUG_SHM
     1,
 #else
@@ -1396,8 +1403,21 @@ extern short debug_msg_enabled[];
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_shm if(!debug_msg_enabled[64]) ; else fprintf
-#define debugging_shm debug_msg_enabled[64]
+#define dprintf_sendmsg if(!debug_msg_enabled[64]) ; else fprintf
+#define debugging_sendmsg debug_msg_enabled[64]
+#else
+#ifdef DEBUG_SENDMSG
+#define dprintf_sendmsg fprintf
+#define debugging_sendmsg 1
+#else
+#define dprintf_sendmsg while(0) fprintf
+#define debugging_sendmsg 0
+#endif
+#endif
+
+#ifdef DEBUG_RUNTIME
+#define dprintf_shm if(!debug_msg_enabled[65]) ; else fprintf
+#define debugging_shm debug_msg_enabled[65]
 #else
 #ifdef DEBUG_SHM
 #define dprintf_shm fprintf
@@ -1409,8 +1429,8 @@ extern short debug_msg_enabled[];
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_stress if(!debug_msg_enabled[65]) ; else fprintf
-#define debugging_stress debug_msg_enabled[65]
+#define dprintf_stress if(!debug_msg_enabled[66]) ; else fprintf
+#define debugging_stress debug_msg_enabled[66]
 #else
 #ifdef DEBUG_STRESS
 #define dprintf_stress fprintf
@@ -1422,8 +1442,8 @@ extern short debug_msg_enabled[];
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_syscolor if(!debug_msg_enabled[66]) ; else fprintf
-#define debugging_syscolor debug_msg_enabled[66]
+#define dprintf_syscolor if(!debug_msg_enabled[67]) ; else fprintf
+#define debugging_syscolor debug_msg_enabled[67]
 #else
 #ifdef DEBUG_SYSCOLOR
 #define dprintf_syscolor fprintf
@@ -1435,8 +1455,8 @@ extern short debug_msg_enabled[];
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_task if(!debug_msg_enabled[67]) ; else fprintf
-#define debugging_task debug_msg_enabled[67]
+#define dprintf_task if(!debug_msg_enabled[68]) ; else fprintf
+#define debugging_task debug_msg_enabled[68]
 #else
 #ifdef DEBUG_TASK
 #define dprintf_task fprintf
@@ -1448,8 +1468,8 @@ extern short debug_msg_enabled[];
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_text if(!debug_msg_enabled[68]) ; else fprintf
-#define debugging_text debug_msg_enabled[68]
+#define dprintf_text if(!debug_msg_enabled[69]) ; else fprintf
+#define debugging_text debug_msg_enabled[69]
 #else
 #ifdef DEBUG_TEXT
 #define dprintf_text fprintf
@@ -1461,8 +1481,8 @@ extern short debug_msg_enabled[];
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_timer if(!debug_msg_enabled[69]) ; else fprintf
-#define debugging_timer debug_msg_enabled[69]
+#define dprintf_timer if(!debug_msg_enabled[70]) ; else fprintf
+#define debugging_timer debug_msg_enabled[70]
 #else
 #ifdef DEBUG_TIMER
 #define dprintf_timer fprintf
@@ -1474,8 +1494,8 @@ extern short debug_msg_enabled[];
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_toolhelp if(!debug_msg_enabled[70]) ; else fprintf
-#define debugging_toolhelp debug_msg_enabled[70]
+#define dprintf_toolhelp if(!debug_msg_enabled[71]) ; else fprintf
+#define debugging_toolhelp debug_msg_enabled[71]
 #else
 #ifdef DEBUG_TOOLHELP
 #define dprintf_toolhelp fprintf
@@ -1487,8 +1507,8 @@ extern short debug_msg_enabled[];
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_ver if(!debug_msg_enabled[71]) ; else fprintf
-#define debugging_ver debug_msg_enabled[71]
+#define dprintf_ver if(!debug_msg_enabled[72]) ; else fprintf
+#define debugging_ver debug_msg_enabled[72]
 #else
 #ifdef DEBUG_VER
 #define dprintf_ver fprintf
@@ -1500,8 +1520,8 @@ extern short debug_msg_enabled[];
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_vxd if(!debug_msg_enabled[72]) ; else fprintf
-#define debugging_vxd debug_msg_enabled[72]
+#define dprintf_vxd if(!debug_msg_enabled[73]) ; else fprintf
+#define debugging_vxd debug_msg_enabled[73]
 #else
 #ifdef DEBUG_VXD
 #define dprintf_vxd fprintf
@@ -1513,8 +1533,8 @@ extern short debug_msg_enabled[];
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_win if(!debug_msg_enabled[73]) ; else fprintf
-#define debugging_win debug_msg_enabled[73]
+#define dprintf_win if(!debug_msg_enabled[74]) ; else fprintf
+#define debugging_win debug_msg_enabled[74]
 #else
 #ifdef DEBUG_WIN
 #define dprintf_win fprintf
@@ -1526,8 +1546,8 @@ extern short debug_msg_enabled[];
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_win32 if(!debug_msg_enabled[74]) ; else fprintf
-#define debugging_win32 debug_msg_enabled[74]
+#define dprintf_win32 if(!debug_msg_enabled[75]) ; else fprintf
+#define debugging_win32 debug_msg_enabled[75]
 #else
 #ifdef DEBUG_WIN32
 #define dprintf_win32 fprintf
@@ -1539,8 +1559,8 @@ extern short debug_msg_enabled[];
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_winsock if(!debug_msg_enabled[75]) ; else fprintf
-#define debugging_winsock debug_msg_enabled[75]
+#define dprintf_winsock if(!debug_msg_enabled[76]) ; else fprintf
+#define debugging_winsock debug_msg_enabled[76]
 #else
 #ifdef DEBUG_WINSOCK
 #define dprintf_winsock fprintf
@@ -1619,6 +1639,7 @@ static char *debug_msg_name[] = {
     "scroll",
     "selector",
     "sem",
+    "sendmsg",
     "shm",
     "stress",
     "syscolor",
diff --git a/include/desktop.h b/include/desktop.h
index 0de03fa4cb2..44ced367e2b 100644
--- a/include/desktop.h
+++ b/include/desktop.h
@@ -11,13 +11,13 @@
 
 typedef struct
 {
-    HBRUSH   hbrushPattern;
-    HBITMAP  hbitmapWallPaper;
-    SIZE16   bitmapSize;
-    BOOL     fTileWallPaper;
+    HBRUSH32   hbrushPattern;
+    HBITMAP32  hbitmapWallPaper;
+    SIZE32     bitmapSize;
+    BOOL32     fTileWallPaper;
 } DESKTOPINFO;
 
-extern BOOL DESKTOP_SetPattern(char *pattern );
+extern BOOL32 DESKTOP_SetPattern( LPCSTR pattern );
 extern LRESULT DesktopWndProc( HWND32 hwnd, UINT32 message,
                                WPARAM32 wParam, LPARAM lParam );
 
diff --git a/include/directory.h b/include/directory.h
index 28e5d64429e..c9c34a8ffdd 100644
--- a/include/directory.h
+++ b/include/directory.h
@@ -8,10 +8,10 @@
 #define __WINE_DIRECTORY_H
 
 extern int DIR_Init(void);
-extern UINT DIR_GetWindowsUnixDir( LPSTR path, UINT count );
-extern UINT DIR_GetSystemUnixDir( LPSTR path, UINT count );
-extern UINT DIR_GetTempUnixDir( LPSTR path, UINT count );
-extern UINT DIR_GetDosPath( int element, LPSTR path, UINT count );
-extern UINT DIR_GetUnixPath( int element, LPSTR path, UINT count );
+extern UINT32 DIR_GetWindowsUnixDir( LPSTR path, UINT32 count );
+extern UINT32 DIR_GetSystemUnixDir( LPSTR path, UINT32 count );
+extern UINT32 DIR_GetTempUnixDir( LPSTR path, UINT32 count );
+extern UINT32 DIR_GetDosPath( INT32 element, LPSTR path, UINT32 count );
+extern UINT32 DIR_GetUnixPath( INT32 element, LPSTR path, UINT32 count );
 
 #endif  /* __WINE_DIRECTORY_H */
diff --git a/include/file.h b/include/file.h
index cb665c8f260..048383a810d 100644
--- a/include/file.h
+++ b/include/file.h
@@ -22,7 +22,6 @@ extern int FILE_Fstat( HFILE hFile, BYTE *pattr, DWORD *psize,
 extern HFILE FILE_Dup( HFILE hFile );
 extern HFILE FILE_Dup2( HFILE hFile1, HFILE hFile2 );
 extern HFILE FILE_Open( LPCSTR path, INT32 mode );
-extern INT32 FILE_Read( HFILE hFile, LPVOID buffer, UINT32 count );
 extern BOOL32 FILE_SetFileType( HFILE hFile, DWORD type );
 extern HFILE _lcreat_uniq( LPCSTR path, INT32 attr );
 
diff --git a/include/gdi.h b/include/gdi.h
index cd68ba34b6c..5e8820881ff 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -75,7 +75,9 @@ typedef struct
     int           flags;
     const DeviceCaps *devCaps;
 
-    HANDLE16      hMetaFile;
+    HMETAFILE16   hMetaFile;
+    HGLOBAL16     hHT;          /* Handle table for metafile */
+    WORD          HTLen;        /* Handle table length (in entries) */
     HRGN16        hClipRgn;     /* Clip region (may be 0) */
     HRGN16        hVisRgn;      /* Visible region (must never be 0) */
     HRGN16        hGCClipRgn;   /* GC clip region (ClipRgn AND VisRgn) */
diff --git a/include/graphics.h b/include/graphics.h
index a9d4423a1f3..9ffdbb39729 100644
--- a/include/graphics.h
+++ b/include/graphics.h
@@ -8,9 +8,13 @@
 #ifndef __WINE_GRAPHICS_H
 #define __WINE_GRAPHICS_H
 
-extern void GRAPH_DrawReliefRect( HDC hdc, RECT16 *rect, int highlight_size,
-                                  int shadow_size, BOOL pressed );
-extern BOOL GRAPH_DrawBitmap( HDC hdc, HBITMAP hbitmap, int xdest, int ydest,
-                              int xsrc, int ysrc, int width, int height );
+#include "windows.h"
+
+extern void GRAPH_DrawReliefRect( HDC32 hdc, const RECT32 *rect,
+                                  INT32 highlight_size, INT32 shadow_size,
+                                  BOOL32 pressed );
+extern BOOL32 GRAPH_DrawBitmap( HDC32 hdc, HBITMAP32 hbitmap,
+                                int xdest, int ydest, int xsrc, int ysrc,
+                                int width, int height );
 
 #endif /* __WINE_GRAPHICS_H */
diff --git a/include/listbox.h b/include/listbox.h
index 8b9130f2cf4..2dd1101a7f2 100644
--- a/include/listbox.h
+++ b/include/listbox.h
@@ -54,6 +54,7 @@ extern DWORD ListBoxGetItemData(LPHEADLIST lphl, UINT uIndex);
 extern int ListBoxSetItemData(LPHEADLIST lphl, UINT uIndex, DWORD ItemData);
 extern int ListBoxDeleteString(LPHEADLIST lphl, UINT uIndex);
 extern int ListBoxFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr);
+extern int ListBoxFindStringExact(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr);
 extern int ListBoxResetContent(LPHEADLIST lphl);
 extern int ListBoxSetCurSel(LPHEADLIST lphl, WORD wIndex);
 extern int ListBoxSetSel(LPHEADLIST lphl, WORD wIndex, WORD state);
diff --git a/include/menu.h b/include/menu.h
index 4beed852b6c..dfb7ec51a08 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -7,6 +7,7 @@
 
 extern BOOL MENU_Init(void);
 extern HMENU MENU_GetDefSysMenu(void);
+extern void MENU_InitSysMenuPopup(HMENU hmenu, DWORD style, DWORD clsStyle);
 extern UINT MENU_GetMenuBarHeight( HWND hwnd, UINT menubarWidth,
 				   int orgX, int orgY );
 extern void MENU_TrackMouseMenuBar( HWND hwnd, POINT16 pt );
diff --git a/include/message.h b/include/message.h
index 6bb32bc1378..622059a8c40 100644
--- a/include/message.h
+++ b/include/message.h
@@ -27,7 +27,7 @@ extern BOOL32 TIMER_GetTimerMsg( MSG16 *msg, HWND32 hwnd,
                                  HQUEUE16 hQueue, BOOL32 remove );
 
 /* event.c */
-extern BOOL32 EVENT_WaitXEvent( BOOL32 sleep );
+extern BOOL32 EVENT_WaitXEvent( BOOL32 sleep, BOOL32 peek );
 extern void EVENT_Synchronize(void);
 extern void EVENT_ProcessEvent( XEvent *event );
 extern void EVENT_RegisterWindow( WND *pWnd );
diff --git a/include/module.h b/include/module.h
index 322328a2b71..dba95d9bb54 100644
--- a/include/module.h
+++ b/include/module.h
@@ -117,7 +117,9 @@ extern void MODULE_WalkModules(void);
 extern int MODULE_OpenFile( HMODULE16 hModule );
 extern LPSTR MODULE_GetModuleName( HMODULE16 hModule );
 extern void MODULE_RegisterModule( NE_MODULE *pModule );
+extern HMODULE16 MODULE_FindModule( LPCSTR path );
 extern HINSTANCE16 MODULE_GetInstance( HMODULE16 hModule );
+extern HMODULE16 MODULE_CreateDummyModule( const OFSTRUCT *ofs );
 extern WORD MODULE_GetOrdinal( HMODULE16 hModule, const char *name );
 extern FARPROC16 MODULE_GetEntryPoint( HMODULE16 hModule, WORD ordinal );
 extern BOOL16 MODULE_SetEntryPoint( HMODULE16 hModule, WORD ordinal,
diff --git a/include/queue.h b/include/queue.h
index 803019aef10..30107843d39 100644
--- a/include/queue.h
+++ b/include/queue.h
@@ -16,6 +16,12 @@ typedef struct tagQMSG
     MSG16   msg;
 } QMSG;
 
+typedef struct
+{
+  LRESULT   lResult;
+  BOOL16    bPending;
+} QSMCTRL;
+
 #pragma pack(1)
 
 typedef struct tagMESSAGEQUEUE
@@ -40,7 +46,7 @@ typedef struct tagMESSAGEQUEUE
   WORD      wPostQMsg;              /* 2c PostQuitMessage flag */
   WORD      wExitCode;              /* 2e PostQuitMessage exit code */
   WORD      flags;                  /* 30 Queue flags */
-  WORD      reserved3[2];           /* 32 Unknown */
+  QSMCTRL*  smResultInit;           /* 32 1st LRESULT ptr - was: reserved */
   WORD      wWinVersion;            /* 36 Expected Windows version */
   HQUEUE16  InSendMessageHandle;    /* 38 Queue of task that sent a message */
   HTASK16   hSendingTask;           /* 3a Handle of task that sent a message */
@@ -50,21 +56,22 @@ typedef struct tagMESSAGEQUEUE
   WORD      changeBits;             /* 42 Changed wake-up bits */
   WORD      wakeBits;               /* 44 Queue wake-up bits */
   WORD      wakeMask;               /* 46 Queue wake-up mask */
-  WORD      SendMsgReturnPtrs[3];   /* 48 Near ptr to return values (?) */
+  QSMCTRL*  smResultCurrent;        /* 48 ptrs to SendMessage() LRESULT - point to */
+  WORD      SendMsgReturnPtr[1];    /*    values on stack */
   HANDLE16  hCurHook;               /* 4e Current hook */
   HANDLE16  hooks[WH_NB_HOOKS];     /* 50 Task hooks list */
-  WORD      reserved4[3];           /* 68 Unknown */
-  QMSG      messages[1];            /* 6e Queue messages */
+  QSMCTRL*  smResult;               /* 6c 3rd LRESULT ptr - was: reserved */
+  QMSG      messages[1];            /* 70 Queue messages */
 } MESSAGEQUEUE;
 
 #pragma pack(4)
 
-/* Extra (undocumented) queue wake bits; not sure about the values */
-#define QS_SMRESULT      0x0100  /* Queue has a SendMessage() result */
-#define QS_SMPARAMSFREE  0x0200  /* SendMessage() parameters are available */
+/* Extra (undocumented) queue wake bits - see "Undoc. Windows" */
+#define QS_SMRESULT      0x8000  /* Queue has a SendMessage() result */
+#define QS_SMPARAMSFREE  0x4000  /* SendMessage() parameters are available */
 
 /* Queue flags */
-#define QUEUE_FLAG_REPLIED  0x0001  /* Replied to a SendMessage() */
+#define QUEUE_FLAG_XEVENT  0x0001
 
 extern void QUEUE_DumpQueue( HQUEUE16 hQueue );
 extern void QUEUE_WalkQueues(void);
diff --git a/include/scroll.h b/include/scroll.h
index 92d590fea80..90411dc3212 100644
--- a/include/scroll.h
+++ b/include/scroll.h
@@ -12,16 +12,18 @@
 
 typedef struct
 {
-    INT   CurVal;   /* Current scroll-bar value */
-    INT   MinVal;   /* Minimum scroll-bar value */
-    INT   MaxVal;   /* Maximum scroll-bar value */
-    INT   Page;     /* Page size of scroll bar (Win32) */
-    WORD  flags;    /* EnableScrollBar flags */
+    INT32   CurVal;   /* Current scroll-bar value */
+    INT32   MinVal;   /* Minimum scroll-bar value */
+    INT32   MaxVal;   /* Maximum scroll-bar value */
+    INT32   Page;     /* Page size of scroll bar (Win32) */
+    UINT32  flags;    /* EnableScrollBar flags */
 } SCROLLBAR_INFO;
 
-extern LONG ScrollBarWndProc( HWND hwnd, WORD uMsg, WORD wParam, LONG lParam );
-extern void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, int nBar );
-extern void SCROLL_HandleScrollEvent( HWND hwnd, int nBar,
-                                      WORD msg, POINT16 pt );
+extern LRESULT ScrollBarWndProc( HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam,
+                                 LPARAM lParam );
+extern void SCROLL_DrawScrollBar( HWND32 hwnd, HDC32 hdc, INT32 nBar,
+                                  BOOL32 arrows );
+extern void SCROLL_HandleScrollEvent( HWND32 hwnd, INT32 nBar,
+                                      UINT32 msg, POINT32 pt );
 
 #endif  /* SCROLL_H */
diff --git a/include/shell.h b/include/shell.h
index 565dbd01715..41cfb714141 100644
--- a/include/shell.h
+++ b/include/shell.h
@@ -9,6 +9,10 @@
 #include "windows.h"
 #include "winreg.h"
 
+#ifndef MAX_PATH
+#define MAX_PATH 260
+#endif
+
 extern INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff,
                       HICON16 hIcon);
 extern void SHELL_LoadRegistry();
@@ -32,6 +36,44 @@ typedef struct { 	   /* structure for dropped files */
 	/* memory block with filenames follows */     
 } DROPFILESTRUCT, *LPDROPFILESTRUCT; 
 
+typedef struct tagSHFILEINFO32A {
+	HICON32	hIcon;			/* icon */
+	int	iIcon;			/* icon index */
+	DWORD	dwAttributes;		/* SFGAO_ flags */
+	CHAR	szDisplayName[MAX_PATH];/* display name (or path) */
+	CHAR	szTypeName[80];		/* type name */
+} SHFILEINFO32A;
+
+typedef struct tagSHFILEINFO32W {
+	HICON32	hIcon;			/* icon */
+	int	iIcon;			/* icon index */
+	DWORD	dwAttributes;		/* SFGAO_ flags */
+	WCHAR	szDisplayName[MAX_PATH];/* display name (or path) */
+	WCHAR	szTypeName[80];		/* type name */
+} SHFILEINFO32W;
+
+DECL_WINELIB_TYPE_AW(SHFILEINFO);
+
+#define SHGFI_ICON              0x000000100     /* get icon */
+#define SHGFI_DISPLAYNAME       0x000000200     /* get display name */
+#define SHGFI_TYPENAME          0x000000400     /* get type name */
+#define SHGFI_ATTRIBUTES        0x000000800     /* get attributes */
+#define SHGFI_ICONLOCATION      0x000001000     /* get icon location */
+#define SHGFI_EXETYPE           0x000002000     /* return exe type */
+#define SHGFI_SYSICONINDEX      0x000004000     /* get system icon index */
+#define SHGFI_LINKOVERLAY       0x000008000     /* put a link overlay on icon */
+#define SHGFI_SELECTED          0x000010000     /* show icon in selected state */
+#define SHGFI_LARGEICON         0x000000000     /* get large icon */
+#define SHGFI_SMALLICON         0x000000001     /* get small icon */
+#define SHGFI_OPENICON          0x000000002     /* get open icon */
+#define SHGFI_SHELLICONSIZE     0x000000004     /* get shell size icon */
+#define SHGFI_PIDL              0x000000008     /* pszPath is a pidl */
+#define SHGFI_USEFILEATTRIBUTES 0x000000010     /* use passed dwFileAttribute */
+
+DWORD SHGetFileInfo32A(LPCSTR,DWORD,SHFILEINFO32A*,UINT32,UINT32);
+DWORD SHGetFileInfo32W(LPCWSTR,DWORD,SHFILEINFO32W*,UINT32,UINT32);
+#define SHGetFileInfo WINELIB_NAME_AW(SHGetFileInfo)
+
 #define SE_ERR_SHARE            26
 #define SE_ERR_ASSOCINCOMPLETE  27
 #define SE_ERR_DDETIMEOUT       28
diff --git a/include/stddebug.h b/include/stddebug.h
index 331575acf65..d54da523dfa 100644
--- a/include/stddebug.h
+++ b/include/stddebug.h
@@ -140,6 +140,7 @@
 #undef DEBUG_SCROLL
 #undef DEBUG_SELECTOR
 #undef DEBUG_SEM
+#undef DEBUG_SENDMSG
 #undef DEBUG_SHM
 #undef DEBUG_STRESS
 #undef DEBUG_SYSCOLOR
@@ -219,6 +220,7 @@
 #define DEBUG_SCROLL
 #define DEBUG_SELECTOR
 #define DEBUG_SEM
+#define DEBUG_SENDMSG
 #define DEBUG_SHM
 #define DEBUG_STRESS
 #define DEBUG_SYSCOLOR
diff --git a/include/win.h b/include/win.h
index 92653ed67e2..18c3321d4ee 100644
--- a/include/win.h
+++ b/include/win.h
@@ -32,6 +32,8 @@
 #define RDW_C_USEHRGN		0x0001
 #define RDW_C_DELETEHRGN	0x0002
 
+struct tagDCE;
+
 typedef struct tagWND
 {
     struct tagWND *next;          /* Next sibling */
@@ -52,12 +54,12 @@ typedef struct tagWND
     void          *pVScroll;      /* Vertical scroll-bar info */
     void          *pHScroll;      /* Horizontal scroll-bar info */
     void          *pProp;         /* Pointer to properties list */
+    struct tagDCE *dce;           /* Window DCE (if CS_OWNDC or CS_CLASSDC) */
     HGLOBAL16      hmemTaskQ;     /* Task queue global memory handle */
     HRGN16         hrgnUpdate;    /* Update region */
     HWND16         hwndLastActive;/* Last active popup hwnd */
     DWORD          dwStyle;       /* Window style (from CreateWindow) */
     DWORD          dwExStyle;     /* Extended style (from CreateWindowEx) */
-    HANDLE16       hdce;          /* Window DCE (if CS_OWNDC or CS_CLASSDC) */
     UINT16         wIDmenu;       /* ID or hmenu (from CreateWindow) */
     WORD           flags;         /* Misc. flags (see below) */
     Window         window;        /* X window (only for top-level windows) */
@@ -77,6 +79,7 @@ typedef struct tagWND
 #define WIN_NCACTIVATED        0x0080 /* last WM_NCACTIVATE was positive */
 #define WIN_MANAGED            0x0100 /* Window managed by the X wm */
 #define WIN_ISDIALOG           0x0200 /* Window is a dialog */
+#define WIN_SAVEUNDER_OVERRIDE 0x0400
 
   /* Window functions */
 extern WND *WIN_FindWndPtr( HWND32 hwnd );
@@ -89,6 +92,7 @@ extern BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter );
 extern HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue );
 extern void WIN_SendParentNotify( HWND32 hwnd, WORD event,
                                   WORD idChild, LPARAM lValue );
+extern void WIN_DestroyQueueWindows( WND* wnd, HQUEUE16 hQueue );
 extern BOOL32 WIN_CreateDesktopWindow(void);
 extern HWND32 WIN_GetTopParent( HWND32 hwnd );
 extern BOOL32 WIN_IsWindowDrawable(WND*, BOOL32 );
diff --git a/include/wincon.h b/include/wincon.h
index bb5ffd03652..1c612d0a811 100644
--- a/include/wincon.h
+++ b/include/wincon.h
@@ -1,7 +1,57 @@
+#ifndef _WINECON_H_
+#define _WINECON_H_
+
+#define CTRL_C_EVENT 0
+#define CTRL_BREAK_EVENT 1
+#define CTRL_CLOSE_EVENT 2
+#define CTRL_LOGOFF_EVENT 5
+#define CTRL_SHUTDOWN_EVENT 6
+
+typedef BOOL32 HANDLER_ROUTINE(WORD);
+
+/*
+ * Attributes flags:
+ */
+
+#define FOREGROUND_BLUE      0x0001 /* text color contains blue. */
+#define FOREGROUND_GREEN     0x0002 /* text color contains green. */
+#define FOREGROUND_RED       0x0004 /* text color contains red. */
+#define FOREGROUND_INTENSITY 0x0008 /* text color is intensified. */
+#define BACKGROUND_BLUE      0x0010 /* background color contains blue. */
+#define BACKGROUND_GREEN     0x0020 /* background color contains green. */
+#define BACKGROUND_RED       0x0040 /* background color contains red. */
+#define BACKGROUND_INTENSITY 0x0080 /* background color is intensified. */
+
+typedef struct tagCOORD
+{
+    INT16 x;
+    INT16 y;
+} COORD,*LPCOORD;
+
+typedef struct tagSMALL_RECT
+{
+    INT16 Left;
+    INT16 Right;
+    INT16 Top;
+    INT16 Bottom;
+} SMALL_RECT,*LPSMALL_RECT;
+
+typedef struct tagCONSOLE_SCREEN_BUFFER_INFO
+{
+    COORD       dwSize;
+    COORD       dwCursorPosition;
+    WORD        wAttributes;
+    SMALL_RECT  srWindow;
+    COORD       dwMaximumWindowSize;
+} CONSOLE_SCREEN_BUFFER_INFO,*LPCONSOLE_SCREEN_BUFFER_INFO;
+
+
+#endif
+
+#if 0
 #ifndef _WINCON_H_
 #define _WINCON_H_
 
-
 #ifdef UNICODE
 #define FillConsoleOutputCharacter FillConsoleOutputCharacterW
 #define GetConsoleTitle GetConsoleTitleW
@@ -143,29 +193,6 @@ typedef struct
   }
 CHAR_INFO;
 
-
-
-
-#define FOREGROUND_BLUE 0x01
-#define FOREGROUND_GREEN 0x02
-#define FOREGROUND_RED 0x04
-#define FOREGROUND_INTENSITY 0x08
-#define BACKGROUND_BLUE 0x10
-#define BACKGROUND_GREEN 0x20
-#define BACKGROUND_RED 0x40
-#define BACKGROUND_INTENSITY 0x80
-
-
-typedef struct
-  {
-    COORD dwSize;
-    COORD dwCursorPosition;
-    WORD wAttrs;
-    SMALL_RECT srWindow;
-    COORD dwMaximumWindowSize;
-  }
-CONSOLE_SCREEN_BUFFER_INFO;
-
 typedef struct
   {
     DWORD size;
@@ -176,14 +203,6 @@ CONSOLE_CURSOR_INFO;
 #endif
 
 
-#define CTRL_C_EVENT 0
-#define CTRL_BREAK_EVENT 1
-#define CTRL_CLOSE_EVENT 2
-#define CTRL_LOGOFF_EVENT 5
-#define CTRL_SHUTDOWN_EVENT 6
-
-typedef BOOL HANDLER_ROUTINE (WORD ctrltype);
-
 #if 0
 
 #define ENABLE_PROCESSED_INPUT 0x01
@@ -255,3 +274,4 @@ BOOL WriteConsoleOutputCharacterA (HANDLE h, const char * c, DWORD len,
 #endif
 #endif
 
+#endif /* 0 */
diff --git a/include/windows.h b/include/windows.h
index f834039c9a7..28b9c8a9a6c 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -435,6 +435,7 @@ DECL_WINELIB_TYPE(LPNCCALCSIZE_PARAMS);
 /***** Window hooks *****/
 
   /* Hook values */
+#define WH_MIN		    (-1)
 #define WH_MSGFILTER	    (-1)
 #define WH_JOURNALRECORD    0
 #define WH_JOURNALPLAYBACK  1
@@ -447,10 +448,13 @@ DECL_WINELIB_TYPE(LPNCCALCSIZE_PARAMS);
 #define WH_HARDWARE	    8
 #define WH_DEBUG	    9
 #define WH_SHELL            10
+#define WH_FOREGROUNDIDLE   11
+#define WH_CALLWNDPROCRET   12
+#define WH_MAX              12
 
-#define WH_FIRST_HOOK       WH_MSGFILTER
-#define WH_LAST_HOOK        WH_SHELL
-#define WH_NB_HOOKS         (WH_LAST_HOOK-WH_FIRST_HOOK+1)
+#define WH_MINHOOK          WH_MIN
+#define WH_MAXHOOK          WH_MAX
+#define WH_NB_HOOKS         (WH_MAXHOOK-WH_MINHOOK+1)
 
   /* Hook action codes */
 #define HC_ACTION           0
@@ -2546,25 +2550,33 @@ typedef struct
 #define ESB_DISABLE_LTUP    ESB_DISABLE_LEFT
 #define ESB_DISABLE_RTDN    ESB_DISABLE_RIGHT
 
-/* Scrollbar messages (undocumented) */
-#define SBM_SETSCROLLPOS      (WM_USER+0)
-#define SBM_GETSCROLLPOS      (WM_USER+1)
-#define SBM_SETSCROLLRANGE    (WM_USER+2)
-#define SBM_REDRAW            (WM_USER+3)
-#define SBM_ENABLE            (WM_USER+4)
+/* Scrollbar messages */
+#define SBM_SETPOS16             (WM_USER+0)
+#define SBM_SETPOS32             0x00e0
+#define SBM_SETPOS               WINELIB_NAME(SBM_SETPOS)
+#define SBM_GETPOS16             (WM_USER+1)
+#define SBM_GETPOS32             0x00e1
+#define SBM_GETPOS               WINELIB_NAME(SBM_GETPOS)
+#define SBM_SETRANGE16           (WM_USER+2)
+#define SBM_SETRANGE32           0x00e2
+#define SBM_SETRANGE             WINELIB_NAME(SBM_SETRANGE)
+#define SBM_GETRANGE16           (WM_USER+3)
+#define SBM_GETRANGE32           0x00e3
+#define SBM_GETRANGE             WINELIB_NAME(SBM_GETRANGE)
+#define SBM_ENABLE_ARROWS16      (WM_USER+4)
+#define SBM_ENABLE_ARROWS32      0x00e4
+#define SBM_ENABLE_ARROWS        WINELIB_NAME(SBM_ENABLE_ARROWS)
+#define SBM_SETRANGEREDRAW16     WM_NULL  /* Not in Win16 */
+#define SBM_SETRANGEREDRAW32     0x00e6
+#define SBM_SETRANGEREDRAW       WINELIB_NAME(SBM_SETRANGEREDRAW)
+#define SBM_SETSCROLLINFO16      WM_NULL  /* Not in Win16 */
+#define SBM_SETSCROLLINFO32      0x00e9
+#define SBM_SETSCROLLINFO        WINELIB_NAME(SBM_SETSCROLLINFO)
+#define SBM_GETSCROLLINFO16      WM_NULL  /* Not in Win16 */
+#define SBM_GETSCROLLINFO32      0x00ea
+#define SBM_GETSCROLLINFO        WINELIB_NAME(SBM_GETSCROLLINFO)
 
 /* Scrollbar info */
-typedef struct
-{
-    UINT16    cbSize;
-    UINT16    fMask;
-    INT16     nMin;
-    INT16     nMax;
-    UINT16    nPage;
-    INT16     nPos;
-    INT16     nTrackPos;
-} SCROLLINFO16, *LPSCROLLINFO16;
-
 typedef struct
 {
     UINT32    cbSize;
@@ -2574,11 +2586,8 @@ typedef struct
     UINT32    nPage;
     INT32     nPos;
     INT32     nTrackPos;
-} SCROLLINFO32, *LPSCROLLINFO32;
+} SCROLLINFO, *LPSCROLLINFO;
  
-DECL_WINELIB_TYPE(SCROLLINFO);
-DECL_WINELIB_TYPE(LPSCROLLINFO);
-
 /* GetScrollInfo() flags */ 
 #define SIF_RANGE           0x0001
 #define SIF_PAGE            0x0002
@@ -3587,6 +3596,22 @@ typedef struct _ULARGE_INTEGER
 #define	DLL_THREAD_ATTACH	2	/* attach new thread */
 #define	DLL_THREAD_DETACH	3	/* detach thread */
 
+typedef struct _MEMORY_BASIC_INFORMATION
+{
+    LPVOID   BaseAddress;
+    LPVOID   AllocationBase;
+    DWORD    AllocationProtect;
+    DWORD    RegionSize;
+    DWORD    State;
+    DWORD    Protect;
+    DWORD    Type;
+} MEMORY_BASIC_INFORMATION,*LPMEMORY_BASIC_INFORMATION;
+
+typedef DWORD (*LPTHREAD_START_ROUTINE)(LPVOID);
+
+typedef BOOL32 (*CODEPAGE_ENUMPROC32A)(LPSTR);
+typedef BOOL32 (*CODEPAGE_ENUMPROC32W)(LPWSTR);
+DECL_WINELIB_TYPE_AW(CODEPAGE_ENUMPROC);
 
 #pragma pack(4)
 
@@ -3598,6 +3623,7 @@ WORD       AllocSelector(WORD);
 WORD       AllocSelectorArray(WORD);
 INT16      Catch(LPCATCHBUF);
 INT16      CloseComm(INT16);
+BOOL16     EnableHardwareInput(BOOL16);
 HANDLE16   FarGetOwner(HGLOBAL16);
 VOID       FarSetOwner(HGLOBAL16,HANDLE16);
 VOID       FillWindow(HWND16,HWND16,HDC16,HBRUSH16);
@@ -3609,6 +3635,7 @@ INT16      GetCommError(INT16,LPCOMSTAT);
 UINT16     GetCommEventMask(INT16,UINT16);
 HANDLE16   GetCurrentPDB(void);
 HTASK16    GetCurrentTask(void);
+HWND16     GetDesktopHwnd(void);
 HMODULE16  GetExePtr(HANDLE16);
 WORD       GetExeVersion(void);
 BOOL16     GetModuleName(HINSTANCE16,LPSTR,INT16);
@@ -3631,6 +3658,7 @@ WORD       SelectorAccessRights(WORD,WORD,WORD);
 DWORD      SetBitmapDimension(HBITMAP16,INT16,INT16);
 DWORD      SetBrushOrg(HDC16,INT16,INT16);
 UINT16*    SetCommEventMask(INT16,UINT16);
+BOOL16     SetDeskPattern(void);
 WORD       SetSelectorBase(WORD,DWORD);
 WORD       SetSelectorLimit(WORD,DWORD);
 FARPROC16  SetTaskSignalProc(HTASK16,FARPROC16);
@@ -3763,6 +3791,7 @@ BOOL16     PtInRegion(HRGN32,INT32,INT32);
 UINT16     RealizePalette(HDC32);
 DWORD      RegCloseKey(HKEY);
 DWORD      RegFlushKey(HKEY);
+VOID       ReleaseCapture(void);
 LONG       SetBitmapBits(HBITMAP32,LONG,LPCVOID);
 COLORREF   SetBkColor(HDC32,COLORREF);
 BOOL16     SetCaretBlinkTime(UINT32);
@@ -3776,7 +3805,6 @@ VOID       SetRectRgn(HRGN32,INT32,INT32,INT32,INT32);
 COLORREF   SetTextColor(HDC32,COLORREF);
 WORD       SetWindowWord(HWND32,INT32,WORD);
 BOOL16     ShowCaret(HWND32);
-HWND16     WindowFromDC(HDC32);
 LONG       _hread(HFILE,LPVOID,LONG);
 HFILE      _lclose(HFILE);
 HFILE      _lcreat(LPCSTR,INT32);
@@ -3996,6 +4024,9 @@ INT16      DrawText16(HDC16,LPCSTR,INT16,LPRECT16,UINT16);
 INT32      DrawText32A(HDC32,LPCSTR,INT32,LPRECT32,UINT32);
 INT32      DrawText32W(HDC32,LPCWSTR,INT32,LPRECT32,UINT32);
 #define    DrawText WINELIB_NAME_AW(DrawText)
+BOOL16     EnableScrollBar16(HWND16,INT16,UINT16);
+BOOL32     EnableScrollBar32(HWND32,INT32,UINT32);
+#define    EnableScrollBar WINELIB_NAME(EnableScrollBar)
 BOOL16     EndPaint16(HWND16,const PAINTSTRUCT16*);
 BOOL32     EndPaint32(HWND32,const PAINTSTRUCT32*);
 #define    EndPaint WINELIB_NAME(EndPaint)
@@ -4067,6 +4098,9 @@ BOOL32     GetBitmapDimensionEx32(HBITMAP32,LPSIZE32);
 BOOL16     GetBrushOrgEx16(HDC16,LPPOINT16);
 BOOL32     GetBrushOrgEx32(HDC32,LPPOINT32);
 #define    GetBrushOrgEx WINELIB_NAME(GetBrushOrgEx)
+HWND16     GetCapture16(void);
+HWND32     GetCapture32(void);
+#define    GetCapture WINELIB_NAME(GetCapture)
 UINT16     GetCaretBlinkTime16(void);
 UINT32     GetCaretBlinkTime32(void);
 #define    GetCaretBlinkTime WINELIB_NAME(GetCaretBlinkTime)
@@ -4111,6 +4145,15 @@ BOOL32     GetCurrentPositionEx32(HDC32,LPPOINT32);
 void       GetCursorPos16(LPPOINT16);
 void       GetCursorPos32(LPPOINT32);
 #define    GetCursorPos WINELIB_NAME(GetCursorPos)
+HDC16      GetDC16(HWND16);
+HDC32      GetDC32(HWND32);
+#define    GetDC WINELIB_NAME(GetDC)
+HDC16      GetDCEx16(HWND16,HRGN16,DWORD);
+HDC32      GetDCEx32(HWND32,HRGN32,DWORD);
+#define    GetDCEx WINELIB_NAME(GetDCEx)
+HWND16     GetDesktopWindow16(void);
+HWND32     GetDesktopWindow32(void);
+#define    GetDesktopWindow WINELIB_NAME(GetDesktopWindow)
 BOOL16     GetDiskFreeSpace16(LPCSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD);
 BOOL32     GetDiskFreeSpace32A(LPCSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD);
 BOOL32     GetDiskFreeSpace32W(LPCWSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD);
@@ -4165,9 +4208,15 @@ HANDLE32   GetProp32W(HWND32,LPCWSTR);
 INT16      GetRgnBox16(HRGN16,LPRECT16);
 INT32      GetRgnBox32(HRGN32,LPRECT32);
 #define    GetRgnBox WINELIB_NAME(GetRgnBox)
-BOOL16     GetScrollInfo16(HWND16,INT16,LPSCROLLINFO16);
-BOOL32     GetScrollInfo32(HWND32,INT32,LPSCROLLINFO32);
+BOOL16     GetScrollInfo16(HWND16,INT16,LPSCROLLINFO);
+BOOL32     GetScrollInfo32(HWND32,INT32,LPSCROLLINFO);
 #define    GetScrollInfo WINELIB_NAME(GetScrollInfo)
+INT16      GetScrollPos16(HWND16,INT16);
+INT32      GetScrollPos32(HWND32,INT32);
+#define    GetScrollPos WINELIB_NAME(GetScrollPos)
+BOOL16     GetScrollRange16(HWND16,INT16,LPINT16,LPINT16);
+BOOL32     GetScrollRange32(HWND32,INT32,LPINT32,LPINT32);
+#define    GetScrollRange WINELIB_NAME(GetScrollRange)
 DWORD      GetShortPathName32A(LPCSTR,LPSTR,DWORD);
 DWORD      GetShortPathName32W(LPCWSTR,LPWSTR,DWORD);
 #define    GetShortPathName WINELIB_NAME_AW(GetShortPathName)
@@ -4208,6 +4257,9 @@ BOOL32     GetViewportOrgEx32(HDC32,LPPOINT32);
 BOOL32     GetVolumeInformation32A(LPCSTR,LPSTR,DWORD,LPDWORD,LPDWORD,LPDWORD,LPSTR,DWORD);
 BOOL32     GetVolumeInformation32W(LPCWSTR,LPWSTR,DWORD,LPDWORD,LPDWORD,LPDWORD,LPWSTR,DWORD);
 #define    GetVolumeInformation WINELIB_NAME_AW(GetVolumeInformation)
+HDC16      GetWindowDC16(HWND16);
+HDC32      GetWindowDC32(HWND32);
+#define    GetWindowDC WINELIB_NAME(GetWindowDC)
 BOOL16     GetWindowExtEx16(HDC16,LPPOINT16);
 BOOL32     GetWindowExtEx32(HDC32,LPPOINT32);
 #define    GetWindowExtEx WINELIB_NAME(GetWindowExtEx)
@@ -4224,6 +4276,10 @@ BOOL32     GetWindowPlacement32(HWND32,LPWINDOWPLACEMENT32);
 void       GetWindowRect16(HWND16,LPRECT16);
 void       GetWindowRect32(HWND32,LPRECT32);
 #define    GetWindowRect WINELIB_NAME(GetWindowRect)
+UINT16     GetWindowsDirectory16(LPSTR,UINT16);
+UINT32     GetWindowsDirectory32A(LPSTR,UINT32);
+UINT32     GetWindowsDirectory32W(LPWSTR,UINT32);
+#define    GetWindowsDirectory WINELIB_NAME_AW(GetWindowsDirectory)
 HTASK16    GetWindowTask16(HWND16);
 #define    GetWindowTask32(hwnd) ((HTASK32)GetWindowThreadProcessId(hwnd,NULL))
 #define    GetWindowTask WINELIB_NAME(GetWindowTask)
@@ -4521,6 +4577,9 @@ DWORD      RegSetValueEx16(HKEY,LPSTR,DWORD,DWORD,LPBYTE,DWORD);
 DWORD      RegSetValueEx32A(HKEY,LPSTR,DWORD,DWORD,LPBYTE,DWORD);
 DWORD      RegSetValueEx32W(HKEY,LPWSTR,DWORD,DWORD,LPBYTE,DWORD);
 #define    RegSetValueEx WINELIB_NAME_AW(RegSetValueEx)
+INT16      ReleaseDC16(HWND16,HDC16);
+INT32      ReleaseDC32(HWND32,HDC32);
+#define    ReleaseDC WINELIB_NAME(ReleaseDC)
 HANDLE16   RemoveProp16(HWND16,LPCSTR);
 HANDLE32   RemoveProp32A(HWND32,LPCSTR);
 HANDLE32   RemoveProp32W(HWND32,LPCWSTR);
@@ -4549,6 +4608,9 @@ LRESULT    SendMessage32W(HWND32,UINT32,WPARAM32,LPARAM);
 BOOL16     SetBitmapDimensionEx16(HBITMAP16,INT16,INT16,LPSIZE16);
 BOOL32     SetBitmapDimensionEx32(HBITMAP32,INT32,INT32,LPSIZE32);
 #define    SetBitmapDimensionEx WINELIB_NAME(SetBitmapDimensionEx)
+HWND16     SetCapture16(HWND16);
+HWND32     SetCapture32(HWND32);
+#define    SetCapture WINELIB_NAME(SetCapture)
 LONG       SetClassLong16(HWND16,INT16,LONG);
 LONG       SetClassLong32A(HWND32,INT32,LONG);
 LONG       SetClassLong32W(HWND32,INT32,LONG);
@@ -4559,6 +4621,9 @@ BOOL32     SetCommBreak32(INT32);
 INT16      SetCommState16(LPDCB16);
 BOOL32     SetCommState32(INT32,LPDCB32);
 #define    SetCommState WINELIB_NAME(SetCommState)
+BOOL16     SetDeskWallPaper16(LPCSTR);
+BOOL32     SetDeskWallPaper32(LPCSTR);
+#define    SetDeskWallPaper WINELIB_NAME(SetDeskWallPaper)
 void       SetDlgItemInt16(HWND16,INT16,UINT16,BOOL16);
 void       SetDlgItemInt32(HWND32,INT32,UINT32,BOOL32);
 #define    SetDlgItemInt WINELIB_NAME(SetDlgItemInt)
@@ -4592,9 +4657,15 @@ void       SetRect32(LPRECT32,INT32,INT32,INT32,INT32);
 void       SetRectEmpty16(LPRECT16);
 void       SetRectEmpty32(LPRECT32);
 #define    SetRectEmpty WINELIB_NAME(SetRectEmpty)
-INT16      SetScrollInfo16(HWND16,INT16,LPSCROLLINFO16,BOOL16);
-INT32      SetScrollInfo32(HWND32,INT32,LPSCROLLINFO32,BOOL32);
+INT16      SetScrollInfo16(HWND16,INT16,const SCROLLINFO*,BOOL16);
+INT32      SetScrollInfo32(HWND32,INT32,const SCROLLINFO*,BOOL32);
 #define    SetScrollInfo WINELIB_NAME(SetScrollInfo)
+INT16      SetScrollPos16(HWND16,INT16,INT16,BOOL16);
+INT32      SetScrollPos32(HWND32,INT32,INT32,BOOL32);
+#define    SetScrollPos WINELIB_NAME(SetScrollPos)
+void       SetScrollRange16(HWND16,INT16,INT16,INT16,BOOL16);
+BOOL32     SetScrollRange32(HWND32,INT32,INT32,INT32,BOOL32);
+#define    SetScrollRange WINELIB_NAME(SetScrollRange)
 HWND16     SetSysModalWindow16(HWND16);
 #define    SetSysModalWindow32(hwnd) ((HWND32)0)
 #define    SetSysModalWindow WINELIB_NAME(SetSysModalWindow)
@@ -4627,6 +4698,9 @@ void       SetWindowText16(HWND16,SEGPTR);
 void       SetWindowText32A(HWND32,LPCSTR);
 void       SetWindowText32W(HWND32,LPCWSTR);
 #define    SetWindowText WINELIB_NAME_AW(SetWindowText)
+void       ShowScrollBar16(HWND16,INT16,BOOL16);
+BOOL32     ShowScrollBar32(HWND32,INT32,BOOL32);
+#define    ShowScrollBar WINELIB_NAME(ShowScrollBar)
 BOOL16     SubtractRect16(LPRECT16,const RECT16*,const RECT16*);
 BOOL32     SubtractRect32(LPRECT32,const RECT32*,const RECT32*);
 #define    SubtractRect WINELIB_NAME(SubtractRect)
@@ -4669,6 +4743,9 @@ DWORD      VerQueryValue16(SEGPTR,LPCSTR,SEGPTR*,UINT16*);
 DWORD      VerQueryValue32A(LPVOID,LPCSTR,LPVOID*,UINT32*);
 DWORD      VerQueryValue32W(LPVOID,LPCWSTR,LPVOID*,UINT32*);
 #define    VerQueryValue WINELIB_NAME_AW(VerQueryValue)
+HWND16     WindowFromDC16(HDC16);
+HWND32     WindowFromDC32(HDC32);
+#define    WindowFromDC WINELIB_NAME(WindowFromDC)
 HWND16     WindowFromPoint16(POINT16);
 HWND32     WindowFromPoint32(POINT32);
 #define    WindowFromPoint WINELIB_NAME(WindowFromPoint)
@@ -4859,12 +4936,10 @@ void       DrawMenuBar(HWND);
 DWORD      DumpIcon(SEGPTR,WORD*,SEGPTR*,SEGPTR*);
 BOOL       Ellipse(HDC,INT,INT,INT,INT);
 BOOL       EmptyClipboard(void);
-BOOL       EnableHardwareInput(BOOL);
 BOOL       EnableMenuItem(HMENU,UINT,UINT);
-BOOL       EnableScrollBar(HWND,UINT,UINT);
 BOOL       EnableWindow(HWND,BOOL);
 BOOL       EndDeferWindowPos(HDWP16);
-UINT       EnumClipboardFormats(UINT);
+UINT16     EnumClipboardFormats(UINT16);
 INT        EnumFontFamilies(HDC,LPCSTR,FONTENUMPROC16,LPARAM);
 INT        EnumFonts(HDC,LPCSTR,FONTENUMPROC16,LPARAM);
 BOOL       EnumMetaFile(HDC,HMETAFILE16,MFENUMPROC16,LPARAM);
@@ -4891,7 +4966,6 @@ WORD       GetAtomName(ATOM,LPSTR,short);
 COLORREF   GetBkColor(HDC);
 WORD       GetBkMode(HDC);
 DWORD      GetBrushOrg(HDC);
-HWND       GetCapture(void);
 BOOL       GetCharABCWidths(HDC,UINT,UINT,LPABC16);
 BOOL       GetCharWidth(HDC,WORD,WORD,LPINT16);
 HRGN       GetClipRgn(HDC);
@@ -4905,15 +4979,11 @@ HBRUSH     GetControlBrush(HWND,HDC,WORD);
 DWORD      GetCurrentPosition(HDC);
 DWORD      GetCurrentTime(void);
 HCURSOR16  GetCursor(void);
-HDC        GetDC(HWND);
-HDC        GetDCEx(HWND,HRGN,DWORD);
 DWORD      GetDCHook(HDC,FARPROC16*);
 DWORD      GetDCOrg(HDC);
 HDC        GetDCState(HDC);
 int        GetDIBits(HDC,HANDLE,WORD,WORD,LPSTR,LPBITMAPINFO,WORD);
 SEGPTR     GetDOSEnvironment(void);
-HWND       GetDesktopHwnd(void);
-HWND       GetDesktopWindow(void);
 int        GetDeviceCaps(HDC,WORD);
 DWORD      GetDialogBaseUnits(void);
 HWND       GetDlgItem(HWND,WORD);
@@ -4968,8 +5038,6 @@ DWORD      GetQueueStatus(UINT);
 BOOL       GetRasterizerCaps(LPRASTERIZER_STATUS,UINT);
 WORD       GetROP2(HDC);
 WORD       GetRelAbs(HDC);
-int        GetScrollPos(HWND,int);
-void       GetScrollRange(HWND,int,LPINT16,LPINT16);
 HANDLE     GetStockObject(int);
 WORD       GetStretchBltMode(HDC);
 HMENU      GetSubMenu(HMENU,short);
@@ -4994,11 +5062,9 @@ DWORD      GetViewportOrg(HDC);
 BOOL       GetWinDebugInfo(LPWINDEBUGINFO,UINT);
 LONG       GetWinFlags(void);
 HWND       GetWindow(HWND,WORD);
-HDC        GetWindowDC(HWND);
 DWORD      GetWindowExt(HDC);
 DWORD      GetWindowOrg(HDC);
 int        GetWindowTextLength(HWND);
-UINT       GetWindowsDirectory(LPSTR,UINT);
 ATOM       GlobalDeleteAtom(ATOM);
 void       GlobalFix(HGLOBAL16);
 void       GlobalFreeAll(HGLOBAL16);
@@ -5047,6 +5113,7 @@ DWORD      OemKeyScan(WORD);
 BOOL       OemToAnsi(LPCSTR,LPSTR);
 void       OemToAnsiBuff(LPCSTR,LPSTR,INT);
 int        OffsetClipRgn(HDC,short,short);
+void       OldYield(void);
 BOOL       OpenClipboard(HWND);
 BOOL       OpenIcon(HWND);
 int        OpenSound(void);
@@ -5073,8 +5140,6 @@ BOOL       PtVisible(HDC,short,short);
 WORD       RealizeDefaultPalette(HDC);
 BOOL       Rectangle(HDC,INT,INT,INT,INT);
 WORD       RegisterClipboardFormat(LPCSTR);
-void       ReleaseCapture(void);
-int        ReleaseDC(HWND,HDC);
 BOOL       RemoveFontResource(LPSTR);
 BOOL       RemoveMenu(HMENU,UINT,UINT);
 void       ReplyMessage(LRESULT);
@@ -5095,7 +5160,6 @@ HPALETTE16 SelectPalette(HDC,HPALETTE16,BOOL);
 int        SelectVisRgn(HDC,HRGN);
 HWND       SetActiveWindow(HWND);
 WORD       SetBkMode(HDC,WORD);
-HWND       SetCapture(HWND);
 HANDLE     SetClipboardData(WORD,HANDLE);
 HWND       SetClipboardViewer(HWND);
 void       SetConvertHook(BOOL);
@@ -5105,8 +5169,6 @@ HCURSOR16  SetCursor(HCURSOR16);
 void       SetCursorPos(short,short);
 BOOL       SetDCHook(HDC,FARPROC16,DWORD);
 void       SetDCState(HDC,HDC);
-BOOL       SetDeskPattern(void);
-BOOL       SetDeskWallPaper(LPCSTR);
 void       SetDoubleClickTime(WORD);
 int        SetEnvironment(LPCSTR,LPCSTR,WORD);
 UINT       SetErrorMode(UINT);
@@ -5125,8 +5187,6 @@ WORD       SetPolyFillMode(HDC,WORD);
 WORD       SetROP2(HDC,WORD);
 WORD       SetRelAbs(HDC,WORD);
 FARPROC16  SetResourceHandler(HANDLE,LPSTR,FARPROC16);
-int        SetScrollPos(HWND,int,int,BOOL);
-void       SetScrollRange(HWND,int,int,int,BOOL);
 int        SetSoundNoise(int,int);
 WORD       SetStretchBltMode(HDC,WORD);
 LONG       SetSwapAreaSize(WORD);
@@ -5151,7 +5211,6 @@ HHOOK      SetWindowsHookEx(INT16,HOOKPROC16,HINSTANCE,HTASK);
 HINSTANCE  ShellExecute(HWND,LPCSTR,LPCSTR,LPSTR,LPCSTR,INT);
 int        ShowCursor(BOOL);
 void       ShowOwnedPopups(HWND,BOOL);
-void       ShowScrollBar(HWND,WORD,BOOL);
 BOOL       ShowWindow(HWND,int);
 DWORD      SizeofResource(HMODULE16,HRSRC16);
 VOID       Sleep(DWORD); /* Win32 */
diff --git a/ipc/dde_proc.c b/ipc/dde_proc.c
index b78482d25a7..59d8942ce83 100644
--- a/ipc/dde_proc.c
+++ b/ipc/dde_proc.c
@@ -475,7 +475,7 @@ int DDE_GetRemoteMessage()
   }
 
   /* iterate through all the windows */
-  for (wndPtr = WIN_FindWndPtr(GetTopWindow(GetDesktopWindow()));
+  for (wndPtr = WIN_FindWndPtr(GetTopWindow(GetDesktopWindow32()));
        wndPtr != NULL;
        wndPtr = wndPtr->next)
   {
diff --git a/ipc/wine_test_stub.c b/ipc/wine_test_stub.c
index 4ecfa750e7d..0fdb599520f 100644
--- a/ipc/wine_test_stub.c
+++ b/ipc/wine_test_stub.c
@@ -34,7 +34,7 @@ void dummy_usage_of_debug_msg_name()
 }
 
 /* stub */
-HWND GetDesktopWindow()
+HWND32 GetDesktopWindow32()
 {
   printf("GetDesktopWindow\n");
   return 0;
diff --git a/loader/builtin.c b/loader/builtin.c
index 00571c5a6ee..0b67254b513 100644
--- a/loader/builtin.c
+++ b/loader/builtin.c
@@ -145,7 +145,7 @@ static BUILTIN_DLL BuiltinDLLs[] =
     { &W32SYS_Descriptor,   0 },
     /* Win32 DLLs */
     { &ADVAPI32_Descriptor, 0 },
-    { &COMCTL32_Descriptor, 0 },
+    { &COMCTL32_Descriptor, DLL_FLAG_NOT_USED },
     { &COMDLG32_Descriptor, 0 },
     { &CRTDLL_Descriptor,   0 },
     { &OLE32_Descriptor,    0 },
diff --git a/loader/module.c b/loader/module.c
index f8074df58ce..c5ec62b5c03 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -459,15 +459,15 @@ static HMODULE16 MODULE_LoadExeHeader( HFILE hFile, OFSTRUCT *ofs )
          ((offset)+(size) <= fastload_offset+fastload_length)) ? \
         (memcpy( buffer, fastload+(offset)-fastload_offset, (size) ), TRUE) : \
         (_llseek( hFile, mz_header.ne_offset+(offset), SEEK_SET), \
-         FILE_Read( hFile, (buffer), (size) ) == (size)))
+         _lread32( hFile, (buffer), (size) ) == (size)))
 
     _llseek( hFile, 0, SEEK_SET );
-    if ((FILE_Read(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
+    if ((_lread32(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
         (mz_header.mz_magic != MZ_SIGNATURE))
         return (HMODULE16)11;  /* invalid exe */
 
     _llseek( hFile, mz_header.ne_offset, SEEK_SET );
-    if (FILE_Read( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
+    if (_lread32( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
         return (HMODULE16)11;  /* invalid exe */
 
     if (ne_header.ne_magic == PE_SIGNATURE) return (HMODULE16)21;  /* win32 exe */
@@ -517,7 +517,7 @@ static HMODULE16 MODULE_LoadExeHeader( HFILE hFile, OFSTRUCT *ofs )
         if ((fastload = (char *)malloc( fastload_length )) != NULL)
         {
             _llseek( hFile, mz_header.ne_offset + fastload_offset, SEEK_SET );
-            if (FILE_Read( hFile, fastload, fastload_length ) != fastload_length)
+            if (_lread32(hFile, fastload, fastload_length) != fastload_length)
             {
                 free( fastload );
                 fastload = NULL;
@@ -632,7 +632,7 @@ static HMODULE16 MODULE_LoadExeHeader( HFILE hFile, OFSTRUCT *ofs )
         }
         buffer = GlobalLock16( pModule->nrname_handle );
         _llseek( hFile, ne_header.nrname_tab_offset, SEEK_SET );
-        if (FILE_Read( hFile, buffer, ne_header.nrname_tab_length )
+        if (_lread32( hFile, buffer, ne_header.nrname_tab_length )
               != ne_header.nrname_tab_length)
         {
             GlobalFree16( pModule->nrname_handle );
@@ -1165,7 +1165,6 @@ HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
 		  IF1632_Stack32_base = WIN16_GlobalLock16(hInitialStack32);
 
 		}
-                /* FIXME: we probably need a DOS handle here */
                 hf = FILE_DupUnixHandle( MODULE_OpenFile( hModule ) );
 		CallTo16_word_ww( selfloadheader->BootApp, hModule, hf );
                 _lclose(hf);
@@ -1215,6 +1214,7 @@ HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
 
     if (!(pModule->flags & NE_FFLAGS_LIBMODULE) && (paramBlock != (LPVOID)-1))
     {
+	HTASK16 hTask;
         WORD	showcmd;
 
 	/* PowerPoint passes NULL as showCmd */
@@ -1222,10 +1222,13 @@ HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
 		showcmd = *((WORD *)PTR_SEG_TO_LIN(params->showCmd)+1);
 	else
 		showcmd = 0; /* FIXME: correct */
-        TASK_CreateTask( hModule, hInstance, hPrevInstance,
-                         params->hEnvironment,
-                         (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ),
-                         showcmd );
+
+        hTask = TASK_CreateTask( hModule, hInstance, hPrevInstance,
+                                 params->hEnvironment,
+                                (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ),
+                                 showcmd );
+
+	if( hTask && TASK_GetNextTask(hTask)) Yield();
     }
 
     return hInstance;
@@ -1479,14 +1482,8 @@ HANDLE WinExec( LPSTR lpCmdLine, WORD nCmdShow )
 #if 0
     if (handle < (HANDLE)32)	/* Error? */
 	return handle;
-    
-/* FIXME: Yield never returns! 
-   We may want to run more applications or start the debugger
-   before calling Yield. If we don't Yield will be called immdiately
-   after returning.  Why is it needed for Word anyway? */
-    Yield();	/* program is executed immediately ....needed for word */
-
 #endif
+
     return handle;
 }
 
diff --git a/loader/pe_image.c b/loader/pe_image.c
index 6514c18a3ef..8ab35e9f595 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -2,6 +2,7 @@
 /* 
  *  Copyright	1994	Eric Youndale & Erik Bos
  *  Copyright	1995	Martin von Löwis
+ *  Copyright   1996    Marcus Meissner
  *
  *	based on Eric Youndale's pe-test and:
  *
@@ -30,6 +31,7 @@
 #include "registers.h"
 #include "stddebug.h"
 #include "debug.h"
+#include "debugger.h"
 #include "xmalloc.h"
 
 void my_wcstombs(char * result, u_short * source, int len)
@@ -77,34 +79,53 @@ char * xmmap(char * vaddr, unsigned int v_size, unsigned int r_size,
 
 void dump_exports(struct PE_Export_Directory * pe_exports, unsigned int load_addr)
 { 
-  char * Module;
-  int i;
-  u_short * ordinal;
-  u_long * function;
-  u_char ** name, *ename;
-
-  Module = ((char *) load_addr) + pe_exports->Name;
+  char		*Module;
+  int		i;
+  u_short	*ordinal;
+  u_long	*function,*functions;
+  u_char	**name,*ename;
+  char		buffer[1000];
+  DBG_ADDR	daddr;
+
+  daddr.seg = 0;
+  Module = ((char*)load_addr)+pe_exports->Name;
   dprintf_win32(stddeb,"\n*******EXPORT DATA*******\nModule name is %s, %ld functions, %ld names\n", 
 	 Module,
 	 pe_exports->Number_Of_Functions,
 	 pe_exports->Number_Of_Names);
 
-  ordinal = (u_short *) (((char *) load_addr) + (int) pe_exports->Address_Of_Name_Ordinals);
-  function = (u_long *)  (((char *) load_addr) + (int) pe_exports->AddressOfFunctions);
-  name = (u_char **)  (((char *) load_addr) + (int) pe_exports->AddressOfNames);
+  ordinal=(u_short*)(((char*)load_addr)+(int)pe_exports->Address_Of_Name_Ordinals);
+  functions=function=(u_long*)(((char*)load_addr)+(int)pe_exports->AddressOfFunctions);
+  name=(u_char**)(((char*)load_addr)+(int)pe_exports->AddressOfNames);
 
   dprintf_win32(stddeb,"%-32s Ordinal Virt Addr\n", "Function Name");
-  for(i=0; i< pe_exports->Number_Of_Functions; i++) {
+  for (i=0;i<pe_exports->Number_Of_Functions;i++) {
       if (i<pe_exports->Number_Of_Names) {
-	  ename =  (char *) (((char *) load_addr) + (int) *name++);
-	  dprintf_win32(stddeb,"%-32s %4d    %8.8lx\n", ename, *ordinal++, *function++);
+	  ename=(char*)(((char*)load_addr)+(int)*name++);
+	  dprintf_win32(stddeb,"%-32s %4d    %8.8lx (%8.8lx)\n",ename,*ordinal,functions[*ordinal],*function);
+	  sprintf(buffer,"%s.%s",Module,ename);
+	  daddr.off=load_addr+functions[*ordinal];
+	  ordinal++;
+	  function++;
       } else {
       	  /* ordinals/names no longer valid, but we still got functions */
-	  dprintf_win32(stddeb,"%-32s %4s    %8.8lx\n","","",*function++);
+	  dprintf_win32(stddeb,"%-32s %4s    %8s %8.8lx\n","","","",*function);
+	  sprintf(buffer,"%s.%d",Module,i);
+	  daddr.off=load_addr+*functions;
+	  function++;
       }
+      DEBUG_AddSymbol(buffer,&daddr);
   }
 }
 
+/* Look up the specified function or ordinal in the exportlist:
+ * If it is a string:
+ * 	- look up the name in the Name list. 
+ *	- look up the ordinal with that index.
+ *	- use the ordinal as offset into the functionlist
+ * If it is a ordinal:
+ *	- use ordinal-pe_export->Base as offset into the functionlist
+ */
 FARPROC32 PE_FindExportedFunction(struct pe_data *pe, LPCSTR funcName)
 {
 	struct PE_Export_Directory * exports = pe->pe_export;
@@ -114,32 +135,29 @@ FARPROC32 PE_FindExportedFunction(struct pe_data *pe, LPCSTR funcName)
 	u_char ** name, *ename;
 	int i;
 
+	if (HIWORD(funcName))
+		dprintf_win32(stddeb,"PE_FindExportedFunction(%s)\n",funcName);
+	else
+		dprintf_win32(stddeb,"PE_FindExportedFunction(%d)\n",(int)funcName);
 	if (!exports)
 		return NULL;
 	ordinal=(u_short*)(((char*)load_addr)+(int)exports->Address_Of_Name_Ordinals);
 	function=(u_long*)(((char*)load_addr)+(int)exports->AddressOfFunctions);
 	name=(u_char **)(((char*)load_addr)+(int)exports->AddressOfNames);
 	if (HIWORD(funcName)) {
-		for(i=0; i<exports->Number_Of_Names; i++)
-		{
-			ename =  (char *) (((char *) load_addr) + (int) *name);
-			if(strcmp(ename,funcName)==0)
-				return (FARPROC32)(load_addr + *function);
-			function++;
+		for(i=0; i<exports->Number_Of_Names; i++) {
+			ename=(char*)(((char*)load_addr)+(int)*name);
+			if(!strcmp(ename,funcName))
+				return (FARPROC32)(load_addr+function[*ordinal]);
+			ordinal++;
 			name++;
 		}
 	} else {
-		/* if we got no name directory, we use the ordinal as offset */
-		if (!exports->Number_Of_Names) {
-			i = function[(int)funcName-exports->Base];
-			return (FARPROC32)(load_addr+i);
-		}
-		for(i=0; i<exports->Number_Of_Names; i++) {
-			if((int)funcName == (int)*ordinal + exports->Base)
-				return (FARPROC32)(load_addr + *function);
-			function++;
-			ordinal++;
+		if (funcName-exports->Base > exports->Number_Of_Functions) {
+			dprintf_win32(stddeb,"	ordinal %d out of range!\n",funcName);
+			return NULL;
 		}
+		return (FARPROC32)(load_addr+function[(int)funcName-exports->Base]);
 	}
 	return NULL;
 }
@@ -357,6 +375,10 @@ static struct pe_data *PE_LoadImage( int fd, HMODULE16 hModule, WORD offset )
     int i, result;
     unsigned int load_addr;
     struct Directory dir;
+    char	buffer[200];
+    DBG_ADDR	daddr;
+
+	daddr.seg=0;
 
 	pe = xmalloc(sizeof(struct pe_data));
 	memset(pe,0,sizeof(struct pe_data));
@@ -511,9 +533,28 @@ static struct pe_data *PE_LoadImage( int fd, HMODULE16 hModule, WORD offset )
 		dprintf_win32(stdnimp,"Callback directory ignored\n");
 
 
+	if(pe->pe_reloc) do_relocations(pe);
 	if(pe->pe_import) fixup_imports(pe, hModule);
 	if(pe->pe_export) dump_exports(pe->pe_export,load_addr);
-	if(pe->pe_reloc) do_relocations(pe);
+  		
+	if (pe->pe_export) {
+		/* add start of sections as debugsymbols */
+		for(i=0;i<pe->pe_header->coff.NumberOfSections;i++) {
+			sprintf(buffer,"%s.%s",
+				((char*)load_addr)+pe->pe_export->Name,
+				pe->pe_seg[i].Name
+			);
+			daddr.off=load_addr+pe->pe_seg[i].Virtual_Address;
+			DEBUG_AddSymbol(buffer,&daddr);
+		}
+		/* add entry point */
+		sprintf(buffer,"%s.EntryPoint",((char*)load_addr)+pe->pe_export->Name);
+		daddr.off=load_addr+pe->pe_header->opt_coff.AddressOfEntryPoint;
+		DEBUG_AddSymbol(buffer,&daddr);
+		/* add start of DLL */
+		daddr.off=load_addr;
+		DEBUG_AddSymbol(((char*)load_addr)+pe->pe_export->Name,&daddr);
+	}
         return pe;
 }
 
@@ -607,7 +648,7 @@ static void PE_InitDLL(HMODULE16 hModule)
         printf("InitPEDLL() called!\n");
         CallDLLEntryProc32( (FARPROC32)(pe->load_addr + 
                                   pe->pe_header->opt_coff.AddressOfEntryPoint),
-                            hModule, DLL_PROCESS_ATTACH, 0 );
+                            hModule, DLL_PROCESS_ATTACH, (void *)-1 );
     }
 }
 
@@ -631,8 +672,8 @@ void PE_InitTEB(int hTEB)
     TEB *pTEB;
 
     pTask = (TDB *)(GlobalLock16(GetCurrentTask() & 0xffff));
-    pTEB = (TEB *)(PTR_SEG_OFF_TO_LIN(hTEB, 0));
-    pTEB->stack = (void *)(GlobalLock16(pTask->hStack32));
+    pTEB  = (TEB *)(GlobalLock16(hTEB));
+    pTEB->stack = pTask->esp;
     pTEB->Except = (void *)(-1); 
     pTEB->TEBDSAlias = pTEB;
     pTEB->taskid = getpid();
diff --git a/loader/task.c b/loader/task.c
index cd58f36a0b7..098304185b2 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -671,18 +671,42 @@ void TASK_KillCurrentTask( INT16 exitCode )
     Yield();
     /* We should never return from this Yield() */
 
-    fprintf(stderr,"It's alive! Alive!!!\n");
+    fprintf(stderr,"Return of the living dead %04x!!!\n", hCurrentTask);
     exit(1);
 }
 
+/***********************************************************************
+ *           TASK_YieldToSystem
+ *
+ * Scheduler interface, this way we ensure that all "unsafe" events are
+ * processed outside the scheduler.
+ */
+void TASK_YieldToSystem(TDB* pTask)
+{
+  MESSAGEQUEUE*		pQ;
+
+  TASK_SCHEDULE();
+
+  if( pTask )
+  {
+    pQ = (MESSAGEQUEUE*)GlobalLock16(pTask->hQueue);
+    if( pQ && pQ->flags & QUEUE_FLAG_XEVENT )
+    {
+      pQ->flags &= ~QUEUE_FLAG_XEVENT;
+      EVENT_WaitXEvent( FALSE, FALSE );
+    }
+  }
+}
 
 /***********************************************************************
  *           TASK_Reschedule
  *
  * This is where all the magic of task-switching happens!
  *
- * This function should only be called via the TASK_SCHEDULE() macro, to make
- * sure that all the context is saved correctly.
+ * Note: This function should only be called via the TASK_YieldToSystem()
+ *       wrapper, to make sure that all the context is saved correctly.
+ *   
+ *       It must not call functions that may yield control.
  */
 void TASK_Reschedule(void)
 {
@@ -700,22 +724,22 @@ void TASK_Reschedule(void)
         hTaskToKill = 0;
     }
 
-    /* Flush any X events that happened in the meantime */
-
-    EVENT_WaitXEvent( FALSE );
-
     /* Find a task to yield to */
 
     pOldTask = (TDB *)GlobalLock16( hCurrentTask );
     if (pOldTask && pOldTask->hYieldTo)
     {
-        /* If a task is stored in hYieldTo of the current task (put there */
-        /* by DirectedYield), yield to it only if it has events pending.  */
+        /* check for DirectedYield() */
+
         hTask = pOldTask->hYieldTo;
         if (!(pNewTask = (TDB *)GlobalLock16( hTask )) || !pNewTask->nEvents)
             hTask = 0;
     }
 
+    /* extract hardware events only! */
+
+    EVENT_WaitXEvent( FALSE, TRUE );
+
     while (!hTask)
     {
         /* Find a task that has an event pending */
@@ -724,6 +748,9 @@ void TASK_Reschedule(void)
         while (hTask)
         {
             pNewTask = (TDB *)GlobalLock16( hTask );
+
+	    dprintf_task( stddeb, "\ttask = %04x, events = %i\n", hTask, pNewTask->nEvents);
+
             if (pNewTask->nEvents) break;
             hTask = pNewTask->hNext;
         }
@@ -732,11 +759,14 @@ void TASK_Reschedule(void)
 
         /* No task found, wait for some events to come in */
 
-        EVENT_WaitXEvent( TRUE );
+        EVENT_WaitXEvent( TRUE, TRUE );
     }
 
-    if (hTask == hCurrentTask) return;  /* Nothing to do */
-
+    if (hTask == hCurrentTask) 
+    {
+       dprintf_task( stddeb, "returning to the current task(%04x)\n", hTask );
+       return;  /* Nothing to do */
+    }
     pNewTask = (TDB *)GlobalLock16( hTask );
     dprintf_task( stddeb, "Switching to task %04x (%.8s)\n",
                   hTask, pNewTask->module_name );
@@ -843,10 +873,11 @@ BOOL WaitEvent( HTASK hTask )
         pTask->nEvents--;
         return FALSE;
     }
-    TASK_SCHEDULE();
+    TASK_YieldToSystem(pTask);
+
     /* When we get back here, we have an event */
+
     if (pTask->nEvents > 0) pTask->nEvents--;
-    else fprintf( stderr, "WaitEvent: reschedule returned without event\n" );
     return TRUE;
 }
 
@@ -914,7 +945,7 @@ void OldYield(void)
 
     pCurTask = (TDB *)GlobalLock16( hCurrentTask );
     if (pCurTask) pCurTask->nEvents++;  /* Make sure we get back here */
-    TASK_SCHEDULE();
+    TASK_YieldToSystem(pCurTask);
     if (pCurTask) pCurTask->nEvents--;
 }
 
diff --git a/misc/clipboard.c b/misc/clipboard.c
index d25775cd39d..03d80ca70b3 100644
--- a/misc/clipboard.c
+++ b/misc/clipboard.c
@@ -30,7 +30,7 @@ typedef struct tagCLIPFORMAT {
     WORD	wRefCount;
     WORD	wDataPresent;
     LPSTR	Name;
-    HANDLE	hData;
+    HANDLE16	hData;
     DWORD	BufSize;
     struct tagCLIPFORMAT *PrevFormat;
     struct tagCLIPFORMAT *NextFormat;
@@ -47,42 +47,80 @@ static HWND hWndViewer     = 0;		/* start of viewers chain */
 static BOOL bClipChanged  = FALSE;
 static WORD LastRegFormat = CF_REGFORMATBASE;
 
-static Bool wait_for_selection = False;
-static Bool wineOwnsSelection = False;
+static Bool   selectionWait = False;
+static Bool   selectionAcquired = False;
+static Window selectionWindow = None;
+static Window selectionPrevWindow = None;
 
 static CLIPFORMAT ClipFormats[16]  = {
-    { CF_TEXT, 1, 0, "Text", (HANDLE)NULL, 0, NULL, &ClipFormats[1] },
-    { CF_BITMAP, 1, 0, "Bitmap", (HANDLE)NULL, 0, &ClipFormats[0], &ClipFormats[2] },
-    { CF_METAFILEPICT, 1, 0, "MetaFile Picture", (HANDLE)NULL, 0, &ClipFormats[1], &ClipFormats[3] },
-    { CF_SYLK, 1, 0, "Sylk", (HANDLE)NULL, 0, &ClipFormats[2], &ClipFormats[4] },
-    { CF_DIF, 1, 0, "DIF", (HANDLE)NULL, 0, &ClipFormats[3], &ClipFormats[5] },
-    { CF_TIFF, 1, 0, "TIFF", (HANDLE)NULL, 0, &ClipFormats[4], &ClipFormats[6] },
-    { CF_OEMTEXT, 1, 0, "OEM Text", (HANDLE)NULL, 0, &ClipFormats[5], &ClipFormats[7] },
-    { CF_DIB, 1, 0, "DIB", (HANDLE)NULL, 0, &ClipFormats[6], &ClipFormats[8] },
-    { CF_PALETTE, 1, 0, "Palette", (HANDLE)NULL, 0, &ClipFormats[7], &ClipFormats[9] },
-    { CF_PENDATA, 1, 0, "PenData", (HANDLE)NULL, 0, &ClipFormats[8], &ClipFormats[10] },
-    { CF_RIFF, 1, 0, "RIFF", (HANDLE)NULL, 0, &ClipFormats[9], &ClipFormats[11] },
-    { CF_WAVE, 1, 0, "Wave", (HANDLE)NULL, 0, &ClipFormats[10], &ClipFormats[12] },
-    { CF_OWNERDISPLAY, 1, 0, "Owner Display", (HANDLE)NULL, 0, &ClipFormats[11], &ClipFormats[13] },
-    { CF_DSPTEXT, 1, 0, "DSPText", (HANDLE)NULL, 0, &ClipFormats[12], &ClipFormats[14] },
-    { CF_DSPMETAFILEPICT, 1, 0, "DSPMetaFile Picture", (HANDLE)NULL, 0, &ClipFormats[13], &ClipFormats[15] },
-    { CF_DSPBITMAP, 1, 0, "DSPBitmap", (HANDLE)NULL, 0, &ClipFormats[14], NULL }
+    { CF_TEXT, 1, 0, "Text", (HANDLE16)NULL, 0, NULL, &ClipFormats[1] },
+    { CF_BITMAP, 1, 0, "Bitmap", (HANDLE16)NULL, 0, &ClipFormats[0], &ClipFormats[2] },
+    { CF_METAFILEPICT, 1, 0, "MetaFile Picture", (HANDLE16)NULL, 0, &ClipFormats[1], &ClipFormats[3] },
+    { CF_SYLK, 1, 0, "Sylk", (HANDLE16)NULL, 0, &ClipFormats[2], &ClipFormats[4] },
+    { CF_DIF, 1, 0, "DIF", (HANDLE16)NULL, 0, &ClipFormats[3], &ClipFormats[5] },
+    { CF_TIFF, 1, 0, "TIFF", (HANDLE16)NULL, 0, &ClipFormats[4], &ClipFormats[6] },
+    { CF_OEMTEXT, 1, 0, "OEM Text", (HANDLE16)NULL, 0, &ClipFormats[5], &ClipFormats[7] },
+    { CF_DIB, 1, 0, "DIB", (HANDLE16)NULL, 0, &ClipFormats[6], &ClipFormats[8] },
+    { CF_PALETTE, 1, 0, "Palette", (HANDLE16)NULL, 0, &ClipFormats[7], &ClipFormats[9] },
+    { CF_PENDATA, 1, 0, "PenData", (HANDLE16)NULL, 0, &ClipFormats[8], &ClipFormats[10] },
+    { CF_RIFF, 1, 0, "RIFF", (HANDLE16)NULL, 0, &ClipFormats[9], &ClipFormats[11] },
+    { CF_WAVE, 1, 0, "Wave", (HANDLE16)NULL, 0, &ClipFormats[10], &ClipFormats[12] },
+    { CF_OWNERDISPLAY, 1, 0, "Owner Display", (HANDLE16)NULL, 0, &ClipFormats[11], &ClipFormats[13] },
+    { CF_DSPTEXT, 1, 0, "DSPText", (HANDLE16)NULL, 0, &ClipFormats[12], &ClipFormats[14] },
+    { CF_DSPMETAFILEPICT, 1, 0, "DSPMetaFile Picture", (HANDLE16)NULL, 0, &ClipFormats[13], &ClipFormats[15] },
+    { CF_DSPBITMAP, 1, 0, "DSPBitmap", (HANDLE16)NULL, 0, &ClipFormats[14], NULL }
     };
 
+/**************************************************************************
+ *                      CLIPBOARD_CheckSelection
+ */
+void CLIPBOARD_CheckSelection(WND* pWnd)
+{
+  dprintf_clipboard(stddeb,"\tchecking %08x\n", (unsigned)pWnd->window);
+
+  if( selectionAcquired && selectionWindow != None &&
+      pWnd->window == selectionWindow )
+  {
+    selectionPrevWindow = selectionWindow;
+    selectionWindow = None;
+
+    if( pWnd->next ) 
+         selectionWindow = pWnd->next->window;
+    else if( pWnd->parent )
+             if( pWnd->parent->child != pWnd ) 
+                 selectionWindow = pWnd->parent->child->window;
+
+    dprintf_clipboard(stddeb,"\tswitching selection from %08x to %08x\n", 
+                    (unsigned)selectionPrevWindow, (unsigned)selectionWindow);
+
+    if( selectionWindow != None )
+    {
+        XSetSelectionOwner(display, XA_PRIMARY, selectionWindow, CurrentTime);
+        if( XGetSelectionOwner(display, XA_PRIMARY) != selectionWindow )
+            selectionWindow = None;
+    }
+  }
+}
+
 /**************************************************************************
  *			CLIPBOARD_DisOwn
+ *
+ * Called from DestroyWindow().
  */
-void CLIPBOARD_DisOwn(HWND hWnd)
+void CLIPBOARD_DisOwn(WND* pWnd)
 {
   LPCLIPFORMAT lpFormat = ClipFormats;
 
-  if( hWnd != hWndClipOwner || !hWndClipOwner ) return;
+  dprintf_clipboard(stddeb,"DisOwn: clipboard owner = %04x, sw = %08x\n", 
+				hWndClipOwner, (unsigned)selectionWindow);
 
-  SendMessage16(hWndClipOwner,WM_RENDERALLFORMATS,0,0L);
+  if( pWnd->hwndSelf == hWndClipOwner)
+  {
+    SendMessage16(hWndClipOwner,WM_RENDERALLFORMATS,0,0L);
 
-  /* check if all formats were rendered */
+    /* check if all formats were rendered */
 
-  while(lpFormat)
+    while(lpFormat)
     { 
        if( lpFormat->wDataPresent && !lpFormat->hData )
 	 {
@@ -91,8 +129,12 @@ void CLIPBOARD_DisOwn(HWND hWnd)
 	 }
        lpFormat = lpFormat->NextFormat;
     }
+    hWndClipOwner = 0;
+  }
+
+  /* now try to salvage current selection from being destroyed by X */
 
-  hWndClipOwner = 0;
+  CLIPBOARD_CheckSelection(pWnd);
 }
 
 /**************************************************************************
@@ -117,21 +159,31 @@ void CLIPBOARD_DeleteRecord(LPCLIPFORMAT lpFormat)
  */
 BOOL CLIPBOARD_RequestXSelection()
 {
-  HWND hWnd = hWndClipWindow;
+  HWND hWnd = (hWndClipWindow) ? hWndClipWindow : GetActiveWindow();
 
-  if( !hWnd ) hWnd = GetActiveWindow(); 
+  if( !hWnd ) return FALSE;
 
-  wait_for_selection=True;
-  dprintf_clipboard(stddeb,"Requesting selection\n");
+  dprintf_clipboard(stddeb,"Requesting selection...\n");
+
+  /* request data type XA_STRING, later
+   * CLIPBOARD_ReadSelection() will be invoked 
+   * from the SelectionNotify event handler */
 
   XConvertSelection(display,XA_PRIMARY,XA_STRING,
                     XInternAtom(display,"PRIMARY_TEXT",False),
                     WIN_GetXWindow(hWnd),CurrentTime);
 
-  /* TODO: need time-out for broken clients */
-  while(wait_for_selection) EVENT_WaitXEvent( TRUE );
+  /* wait until SelectionNotify is processed */
+
+  selectionWait=True;
+  while(selectionWait) 
+        EVENT_WaitXEvent( TRUE, FALSE );
 
-  return (BOOL)ClipFormats[0].wDataPresent;
+  /* we treat Unix text as CF_OEMTEXT */
+  dprintf_clipboard(stddeb,"\tgot CF_OEMTEXT = %i\n", 
+		    ClipFormats[CF_OEMTEXT-1].wDataPresent);
+
+  return (BOOL)ClipFormats[CF_OEMTEXT-1].wDataPresent;
 }
 
 /**************************************************************************
@@ -141,11 +193,18 @@ BOOL CLIPBOARD_IsPresent(WORD wFormat)
 {
     LPCLIPFORMAT lpFormat = ClipFormats; 
 
+    /* special case */
+
+    if( wFormat == CF_TEXT || wFormat == CF_OEMTEXT )
+        return lpFormat[CF_TEXT-1].wDataPresent | 
+               lpFormat[CF_OEMTEXT-1].wDataPresent;
+
     while(TRUE) {
         if (lpFormat == NULL) return FALSE;
         if (lpFormat->wFormatID == wFormat) break;
         lpFormat = lpFormat->NextFormat;
         }
+
     return (lpFormat->wDataPresent);
 }
 
@@ -203,7 +262,7 @@ BOOL EmptyClipboard()
   
     while(lpFormat) 
       {
-	if ( lpFormat->wDataPresent )
+	if ( lpFormat->wDataPresent || lpFormat->hData )
 	     CLIPBOARD_DeleteRecord( lpFormat );
 
 	lpFormat = lpFormat->NextFormat;
@@ -211,9 +270,15 @@ BOOL EmptyClipboard()
 
     hWndClipOwner = hWndClipWindow;
 
-    if(wineOwnsSelection){
-        dprintf_clipboard(stddeb,"Losing selection\n");
-	wineOwnsSelection=False;
+    if(selectionAcquired)
+    {
+	selectionAcquired	= False;
+	selectionPrevWindow 	= selectionWindow;
+	selectionWindow 	= None;
+
+	dprintf_clipboard(stddeb, "\tgiving up selection (spw = %08x)\n", 
+				 	(unsigned)selectionPrevWindow);
+
 	XSetSelectionOwner(display,XA_PRIMARY,None,CurrentTime);
     }
     return TRUE;
@@ -240,7 +305,7 @@ HANDLE SetClipboardData(WORD wFormat, HANDLE hData)
     Window       owner;
 
     dprintf_clipboard(stddeb,
-		"SetClipboardDate(%04X, %04x) !\n", wFormat, hData);
+		"SetClipboardData(%04X, %04x) !\n", wFormat, hData);
 
     while(TRUE) 
       {
@@ -249,59 +314,138 @@ HANDLE SetClipboardData(WORD wFormat, HANDLE hData)
 	lpFormat = lpFormat->NextFormat;
       }
 
-    /* Acquire X selection:
-     *
-     * doc says we shouldn't use CurrentTime 
-     * should we become owner of CLIPBOARD as well? 
-     */
-
-    owner = WIN_GetXWindow(hWndClipWindow);
+    /* Acquire X selection if text format */
 
-    XSetSelectionOwner(display,XA_PRIMARY,owner,CurrentTime);
-    if( XGetSelectionOwner(display,XA_PRIMARY) == owner )
+    if( !selectionAcquired && 
+	(wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
+    {
+      owner = WIN_GetXWindow(hWndClipWindow);
+      XSetSelectionOwner(display,XA_PRIMARY,owner,CurrentTime);
+      if( XGetSelectionOwner(display,XA_PRIMARY) == owner )
       {
-        wineOwnsSelection = True;
-        dprintf_clipboard(stddeb,"Getting selection\n");
+        selectionAcquired = True;
+	selectionWindow = owner;
+
+        dprintf_clipboard(stddeb,"Grabbed X selection, owner=(%08x)\n", 
+						(unsigned) owner);
       }
+    }
 
-    if ( lpFormat->wDataPresent ) 
-         CLIPBOARD_DeleteRecord(lpFormat);
+    if ( lpFormat->wDataPresent || lpFormat->hData ) 
+    {
+	CLIPBOARD_DeleteRecord(lpFormat);
+
+	/* delete existing CF_TEXT/CF_OEMTEXT aliases */
+
+	if( wFormat == CF_TEXT && ClipFormats[CF_OEMTEXT-1].hData
+	    && !ClipFormats[CF_OEMTEXT-1].wDataPresent )
+	    CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1]);
+        if( wFormat == CF_OEMTEXT && ClipFormats[CF_TEXT-1].hData
+	    && !ClipFormats[CF_TEXT-1].wDataPresent )
+	    CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1]);
+    }
 
     bClipChanged = TRUE;
-    lpFormat->wDataPresent = TRUE;
-    lpFormat->hData = hData;
+    lpFormat->wDataPresent = 1;
+    lpFormat->hData = hData;          /* 0 is legal, see WM_RENDERFORMAT */
 
     return lpFormat->hData;
 }
 
+/**************************************************************************
+ *                      CLIPBOARD_RenderFormat
+ */
+BOOL32 CLIPBOARD_RenderFormat(LPCLIPFORMAT lpFormat)
+{
+ if( lpFormat->wDataPresent && !lpFormat->hData )
+   if( IsWindow(hWndClipOwner) )
+       SendMessage16(hWndClipOwner,WM_RENDERFORMAT,(WPARAM)lpFormat->wFormatID,0L);
+   else
+   {
+       dprintf_clipboard(stddeb,"\thWndClipOwner (%04x) is lost!\n", 
+                                      hWndClipOwner);
+       hWndClipOwner = 0; lpFormat->wDataPresent = 0;
+       return FALSE;
+   }
+ return (lpFormat->hData) ? TRUE : FALSE;
+}
+
+/**************************************************************************
+ *                      CLIPBOARD_RenderText
+ */
+BOOL32 CLIPBOARD_RenderText(LPCLIPFORMAT lpTarget, LPCLIPFORMAT lpSource)
+{
+  UINT		size = GlobalSize16( lpSource->hData );
+  LPCSTR	lpstrS = (LPSTR)GlobalLock16(lpSource->hData);
+  LPSTR		lpstrT;
+
+  if( !lpstrS ) return FALSE;
+  dprintf_clipboard(stddeb,"\tconverting from '%s' to '%s', %i chars\n",
+			   	      lpSource->Name, lpTarget->Name, size);
+
+  lpTarget->hData = GlobalAlloc16(GMEM_ZEROINIT, size); 
+  lpstrT = (LPSTR)GlobalLock16(lpTarget->hData);
+
+  if( lpstrT )
+  {
+    if( lpSource->wFormatID == CF_TEXT )
+	AnsiToOemBuff(lpstrS, lpstrT, size);
+    else
+	OemToAnsiBuff(lpstrS, lpstrT, size);
+    dprintf_clipboard(stddeb,"\tgot %s\n", lpstrT);
+    return TRUE;
+  }
+
+  lpTarget->hData = 0;
+  return FALSE;
+}
 
 /**************************************************************************
  *			GetClipboardData	[USER.142]
  */
 HANDLE GetClipboardData(WORD wFormat)
 {
-    LPCLIPFORMAT lpFormat = ClipFormats; 
-    dprintf_clipboard(stddeb,"GetClipboardData(%04X)\n", wFormat);
+    LPCLIPFORMAT lpRender = ClipFormats; 
+    LPCLIPFORMAT lpUpdate = NULL;
 
     if (!hWndClipWindow) return 0;
 
-    /*  if(wFormat == CF_TEXT && !wineOwnsSelection)
-        CLIPBOARD_RequestXSelection(); 
-     */
+    dprintf_clipboard(stddeb,"GetClipboardData(%04X)\n", wFormat);
 
-    while(TRUE) {
-	if (lpFormat == NULL) return 0;
-	if (lpFormat->wFormatID == wFormat) break;
-	lpFormat = lpFormat->NextFormat;
-	}
+    if( wFormat == CF_TEXT && !lpRender[CF_TEXT-1].wDataPresent 
+			   &&  lpRender[CF_OEMTEXT-1].wDataPresent )
+    {
+	lpRender = &ClipFormats[CF_OEMTEXT-1];
+	lpUpdate = &ClipFormats[CF_TEXT-1];
 
-    if( lpFormat->wDataPresent && !lpFormat->hData )
-      if( IsWindow(hWndClipOwner) )
-	  SendMessage16(hWndClipOwner,WM_RENDERFORMAT,(WPARAM)lpFormat->wFormatID,0L);
-      else
-	  dprintf_clipboard(stddeb,"\thWndClipOwner is lost\n");
-      
-    return lpFormat->hData;
+	dprintf_clipboard(stddeb,"\tOEMTEXT -> TEXT\n");
+    }
+    else if( wFormat == CF_OEMTEXT && !lpRender[CF_OEMTEXT-1].wDataPresent
+				   &&  lpRender[CF_TEXT-1].wDataPresent )
+    {
+        lpRender = &ClipFormats[CF_TEXT-1];
+	lpUpdate = &ClipFormats[CF_OEMTEXT-1];
+	
+	dprintf_clipboard(stddeb,"\tTEXT -> OEMTEXT\n");
+    }
+    else
+    {
+      while(TRUE) 
+      {
+	if (lpRender == NULL) return 0;
+	if (lpRender->wFormatID == wFormat) break;
+	lpRender = lpRender->NextFormat;
+      }
+      lpUpdate = lpRender;
+    }
+   
+    if( !CLIPBOARD_RenderFormat(lpRender) ) return 0; 
+    if( lpUpdate != lpRender &&
+	!lpUpdate->hData ) CLIPBOARD_RenderText(lpUpdate, lpRender);
+
+    dprintf_clipboard(stddeb,"\treturning %04x (type %i)\n", 
+			      lpUpdate->hData, lpUpdate->wFormatID);
+    return lpUpdate->hData;
 }
 
 
@@ -315,6 +459,11 @@ INT CountClipboardFormats()
 
     dprintf_clipboard(stddeb,"CountClipboardFormats()\n");
 
+    if( !selectionAcquired ) CLIPBOARD_RequestXSelection();
+
+    FormatCount += abs(lpFormat[CF_TEXT-1].wDataPresent -
+		       lpFormat[CF_OEMTEXT-1].wDataPresent); 
+
     while(TRUE) {
 	if (lpFormat == NULL) break;
 	if (lpFormat->wDataPresent) 
@@ -334,21 +483,22 @@ INT CountClipboardFormats()
 /**************************************************************************
  *			EnumClipboardFormats	[USER.144]
  */
-UINT EnumClipboardFormats(UINT wFormat)
+UINT16 EnumClipboardFormats(UINT16 wFormat)
 {
     LPCLIPFORMAT lpFormat = ClipFormats; 
 
     dprintf_clipboard(stddeb,"EnumClipboardFormats(%04X)\n", wFormat);
 
-    if( (!wFormat || wFormat == CF_TEXT) && !wineOwnsSelection)
-        CLIPBOARD_RequestXSelection();
+    if( !hWndClipWindow ) return 0;
 
-    if (wFormat == 0) {
-	if (lpFormat->wDataPresent) 
+    if( (!wFormat || wFormat == CF_TEXT || wFormat == CF_OEMTEXT) 
+	 && !selectionAcquired) CLIPBOARD_RequestXSelection();
+
+    if (wFormat == 0)
+	if (lpFormat->wDataPresent || ClipFormats[CF_OEMTEXT-1].wDataPresent) 
 	    return lpFormat->wFormatID;
 	else 
-	    wFormat = lpFormat->wFormatID;
-	}
+	    wFormat = lpFormat->wFormatID; /* and CF_TEXT is not available */
 
     /* walk up to the specified format record */
 
@@ -363,12 +513,12 @@ UINT EnumClipboardFormats(UINT wFormat)
     lpFormat = lpFormat->NextFormat;
     while(TRUE) {
 	if (lpFormat == NULL) return 0;
-	if (lpFormat->wDataPresent ) break;
+	if (lpFormat->wDataPresent ||
+	       (lpFormat->wFormatID == CF_OEMTEXT &&
+		ClipFormats[CF_TEXT-1].wDataPresent)) break;
 	lpFormat = lpFormat->NextFormat;
 	}
 
-    dprintf_clipboard(stddeb, "\t got not empty - Id=%04X hData=%04x !\n",
-				lpFormat->wFormatID, lpFormat->hData);
     return lpFormat->wFormatID;
 }
 
@@ -500,8 +650,8 @@ BOOL IsClipboardFormatAvailable(WORD wFormat)
 {
     dprintf_clipboard(stddeb,"IsClipboardFormatAvailable(%04X) !\n", wFormat);
 
-    if(wFormat == CF_TEXT && !wineOwnsSelection)
-	CLIPBOARD_RequestXSelection();
+    if( (wFormat == CF_TEXT || wFormat == CF_OEMTEXT) &&
+        !selectionAcquired ) CLIPBOARD_RequestXSelection();
 
     return CLIPBOARD_IsPresent(wFormat);
 }
@@ -533,72 +683,112 @@ int GetPriorityClipboardFormat(WORD *lpPriorityList, short nCount)
 /**************************************************************************
  *			CLIPBOARD_ReadSelection
  *
- *	The current selection owner has set prop at our window w
- *	Transfer the property contents into the Clipboard
+ * Called from the SelectionNotify event handler. 
  */
 void CLIPBOARD_ReadSelection(Window w,Atom prop)
 {
-    HANDLE hText;
+    HANDLE16 	 hText = 0;
     LPCLIPFORMAT lpFormat = ClipFormats; 
-    if(prop==None)
-        hText=0;
-    else
-      {
-	Atom atype=None;
-	int aformat;
-	unsigned long nitems,remain;
-	unsigned char *val=NULL;
 
-        dprintf_clipboard(stddeb,"Received prop %s\n",XGetAtomName(display,prop));
+    dprintf_clipboard(stddeb,"ReadSelection callback\n");
+
+    if(prop != None)
+    {
+	Atom		atype=AnyPropertyType;
+	int		aformat;
+	unsigned long 	nitems,remain;
+	unsigned char*	val=NULL;
+
+        dprintf_clipboard(stddeb,"\tgot property %s\n",XGetAtomName(display,prop));
 
         /* TODO: Properties longer than 64K */
 
 	if(XGetWindowProperty(display,w,prop,0,0x3FFF,True,XA_STRING,
-	    &atype, &aformat, &nitems, &remain, &val)!=Success)
-		fprintf(stderr,"couldn't read property\n");
-
-        dprintf_clipboard(stddeb,"Type %s,Format %d,nitems %ld,value %s\n",
-		XGetAtomName(display,atype),aformat,nitems,val);
-
-	if(atype!=XA_STRING || aformat!=8){
-	    fprintf(stderr,"Property not set\n");
-	    hText=0;
-	} else {
-	    dprintf_clipboard(stddeb,"Selection is %s\n",val);
-	    hText=GlobalAlloc16(GMEM_MOVEABLE, nitems+1);
-	    memcpy(GlobalLock16(hText),val,nitems+1);
-	    GlobalUnlock16(hText);
+	    &atype, &aformat, &nitems, &remain, &val) != Success)
+	    dprintf_clipboard(stddeb,"\tcouldn't read property\n");
+	else
+	{
+           dprintf_clipboard(stddeb,"\tType %s,Format %d,nitems %ld,value %s\n",
+		             XGetAtomName(display,atype),aformat,nitems,val);
+
+	   if(atype == XA_STRING && aformat == 8)
+	   {
+	      int 	i,inlcount = 0;
+	      char*	lpstr;
+
+	      dprintf_clipboard(stddeb,"\tselection is '%s'\n",val);
+
+	      for(i=0; i <= nitems; i++)
+		  if( val[i] == '\n' ) inlcount++;
+
+	      if( nitems )
+	      {
+	        hText=GlobalAlloc16(GMEM_MOVEABLE, nitems + inlcount + 1);
+	        if( (lpstr = (char*)GlobalLock16(hText)) )
+	          for(i=0,inlcount=0; i <= nitems; i++)
+	          {
+	  	     if( val[i] == '\n' ) lpstr[inlcount++]='\r';
+		     lpstr[inlcount++]=val[i];
+		  }
+	        else hText = 0;
+	      }
+	   }
+	   XFree(val);
 	}
-	XFree(val);
-      }
+   }
 
-    while(TRUE) {
-	if (lpFormat == NULL) return;
-	if (lpFormat->wFormatID == CF_TEXT) break;
-	lpFormat = lpFormat->NextFormat;
-	}
+   /* delete previous CF_TEXT and CF_OEMTEXT data */
 
-    if (lpFormat->wDataPresent) 
-       CLIPBOARD_DeleteRecord(lpFormat);
+   if( hText )
+   {
+     lpFormat = &ClipFormats[CF_TEXT-1];
+     if (lpFormat->wDataPresent || lpFormat->hData) 
+         CLIPBOARD_DeleteRecord(lpFormat);
+     lpFormat = &ClipFormats[CF_OEMTEXT-1];
+     if (lpFormat->wDataPresent || lpFormat->hData) 
+         CLIPBOARD_DeleteRecord(lpFormat);
 
-    wait_for_selection=False;
+     lpFormat->wDataPresent = 1;
+     lpFormat->hData = hText;
+   }
 
-    lpFormat->wDataPresent = TRUE;
-    lpFormat->hData = hText;
-    dprintf_clipboard(stddeb,"Received selection\n");
+   selectionWait=False;
 }
 
 /**************************************************************************
  *			CLIPBOARD_ReleaseSelection
  *
- *	Wine lost the primary selection.
- *	Empty the clipboard, but don't set the current owner to None.
- *	Make sure current get/put attempts fail.
+ * Wine might have lost XA_PRIMARY selection because of
+ * EmptyClipboard() or other client. 
  */
-void CLIPBOARD_ReleaseSelection(HWND hwnd)
+void CLIPBOARD_ReleaseSelection(Window w, HWND hwnd)
 {
-    wineOwnsSelection=False;
-    OpenClipboard(hwnd);
-    EmptyClipboard();
-    CloseClipboard();
+  /* w is the window that lost selection,
+   * 
+   * selectionPrevWindow is nonzero if CheckSelection() was called. 
+   */
+
+  dprintf_clipboard(stddeb,"\tevent->window = %08x (sw = %08x, spw=%08x)\n", 
+	  (unsigned)w, (unsigned)selectionWindow, (unsigned)selectionPrevWindow );
+
+  if( selectionAcquired )
+    if( w == selectionWindow || selectionPrevWindow == None)
+    {
+      /* alright, we really lost it */
+
+      selectionAcquired = False;
+      selectionWindow = None; 
+
+      /* but we'll keep existing data for internal use */
+    }
+    else if( w == selectionPrevWindow )
+    {
+      w =  XGetSelectionOwner(display, XA_PRIMARY);
+
+      if( w == None )
+        XSetSelectionOwner(display, XA_PRIMARY, selectionWindow, CurrentTime);
+    }
+
+  selectionPrevWindow = None;
 }
+
diff --git a/misc/comm.c b/misc/comm.c
index 8fda4ae4e43..613957ba8f4 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -1576,7 +1576,7 @@ INT16 WriteComm(INT16 fd, LPSTR lpvBuf, INT16 cbWrite)
  *	GetCommTimeouts		(KERNEL32.160)
  */
 BOOL32 GetCommTimeouts(INT32 fd,LPCOMMTIMEOUTS lptimeouts) {
-	dprintf_comm(stddeb,"GetCommTimeouts(%lx,%p), empty stub.\n",
+	dprintf_comm(stddeb,"GetCommTimeouts(%x,%p), empty stub.\n",
 		fd,lptimeouts
 	);
 	return TRUE;
@@ -1586,7 +1586,7 @@ BOOL32 GetCommTimeouts(INT32 fd,LPCOMMTIMEOUTS lptimeouts) {
  *	SetCommTimeouts		(KERNEL32.453)
  */
 BOOL32 SetCommTimeouts(INT32 fd,LPCOMMTIMEOUTS lptimeouts) {
-	dprintf_comm(stddeb,"SetCommTimeouts(%lx,%p), empty stub.\n",
+	dprintf_comm(stddeb,"SetCommTimeouts(%x,%p), empty stub.\n",
 		fd,lptimeouts
 	);
 	return TRUE;
diff --git a/misc/commdlg.c b/misc/commdlg.c
index e356a82371b..cb243351989 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -1475,12 +1475,12 @@ static int CC_CheckDigitsInEdit(HWND hwnd,int maxval)
 static void CC_PaintSelectedColor(HWND hDlg,COLORREF cr)
 {
  RECT16 rect;
- HDC  hdc;
+ HDC32  hdc;
  HBRUSH hBrush;
  HWND hwnd=GetDlgItem(hDlg,0x2c5);
  if (IsWindowVisible(GetDlgItem(hDlg,0x2c6)))   /* if full size */
  {
-  hdc=GetDC(hwnd);
+  hdc=GetDC32(hwnd);
   GetClientRect16 (hwnd, &rect) ;
   hBrush = CreateSolidBrush(cr);
   if (hBrush)
@@ -1496,7 +1496,7 @@ static void CC_PaintSelectedColor(HWND hDlg,COLORREF cr)
     DeleteObject (SelectObject (hdc, hBrush)) ;
    }
   }
-  ReleaseDC(hwnd,hdc);
+  ReleaseDC32(hwnd,hdc);
  }
 }
 
@@ -1505,7 +1505,7 @@ static void CC_PaintSelectedColor(HWND hDlg,COLORREF cr)
  */
 static void CC_PaintTriangle(HWND hDlg,int y)
 {
- HDC hDC;
+ HDC32 hDC;
  long temp;
  int w=GetDialogBaseUnits();
  POINT16 points[3];
@@ -1519,7 +1519,7 @@ static void CC_PaintTriangle(HWND hDlg,int y)
  {
    GetClientRect16(hwnd,&rect);
    height=rect.bottom;
-   hDC=GetDC(hDlg);
+   hDC=GetDC32(hDlg);
 
    points[0].y=rect.top;
    points[0].x=rect.right;           /*  |  /|  */
@@ -1540,7 +1540,7 @@ static void CC_PaintTriangle(HWND hDlg,int y)
    lpp->old3angle.top   =points[2].y-1;
    lpp->old3angle.bottom=points[1].y+1;
    Polygon16(hDC,points,3);
-   ReleaseDC(hDlg,hDC);
+   ReleaseDC32(hDlg,hDC);
  }
 }
 
@@ -1550,7 +1550,7 @@ static void CC_PaintTriangle(HWND hDlg,int y)
  */
 static void CC_PaintCross(HWND hDlg,int x,int y)
 {
- HDC hDC;
+ HDC32 hDC;
  int w=GetDialogBaseUnits();
  HWND hwnd=GetDlgItem(hDlg,0x2c6);
  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
@@ -1561,7 +1561,7 @@ static void CC_PaintCross(HWND hDlg,int x,int y)
  if (IsWindowVisible(GetDlgItem(hDlg,0x2c6)))   /* if full size */
  {
    GetClientRect16(hwnd,&rect);
-   hDC=GetDC(hwnd);
+   hDC=GetDC32(hwnd);
    SelectClipRgn(hDC,CreateRectRgnIndirect16(&rect));   
    hPen=CreatePen(PS_SOLID,2,0);
    hPen=SelectObject(hDC,hPen);
@@ -1582,7 +1582,7 @@ static void CC_PaintCross(HWND hDlg,int x,int y)
    MoveTo(hDC,point.x,point.y-w); 
    LineTo(hDC,point.x,point.y+w);
    DeleteObject(SelectObject(hDC,hPen));
-   ReleaseDC(hwnd,hDC);
+   ReleaseDC32(hwnd,hDC);
  }
 }
 
@@ -1600,12 +1600,12 @@ static void CC_PrepareColorGraph(HWND hDlg)
  HWND hwnd=GetDlgItem(hDlg,0x2c6);
  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER);  
  HBRUSH hbrush;
- HDC hdc ;
+ HDC32 hdc ;
  RECT16 rect,client;
  HCURSOR16 hcursor=SetCursor(LoadCursor16(0,IDC_WAIT));
 
  GetClientRect16(hwnd,&client);
- hdc=GetDC(hwnd);
+ hdc=GetDC32(hwnd);
  lpp->hdcMem = CreateCompatibleDC(hdc);
  lpp->hbmMem = CreateCompatibleBitmap(hdc,client.right,client.bottom);
  SelectObject(lpp->hdcMem,lpp->hbmMem);
@@ -1631,7 +1631,7 @@ static void CC_PrepareColorGraph(HWND hDlg)
   }
   rect.left=rect.right;
  }
- ReleaseDC(hwnd,hdc);
+ ReleaseDC32(hwnd,hdc);
  SetCursor(hcursor);
 }
 
@@ -1642,20 +1642,20 @@ static void CC_PaintColorGraph(HWND hDlg)
 {
  HWND hwnd=GetDlgItem(hDlg,0x2c6);
  struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
- HDC  hDC;
+ HDC32  hDC;
  RECT16 rect;
  if (IsWindowVisible(hwnd))   /* if full size */
  {
   if (!lpp->hdcMem)
    CC_PrepareColorGraph(hDlg);   /* should not be necessary */
 
-  hDC=GetDC(hwnd);
+  hDC=GetDC32(hwnd);
   GetClientRect16(hwnd,&rect);
   if (lpp->hdcMem)
     BitBlt(hDC,0,0,rect.right,rect.bottom,lpp->hdcMem,0,0,SRCCOPY);
   else
     fprintf(stderr,"choose color: hdcMem is not defined\n");
-  ReleaseDC(hwnd,hDC);
+  ReleaseDC32(hwnd,hDC);
  }
 }
 /***********************************************************************
@@ -1667,11 +1667,11 @@ static void CC_PaintLumBar(HWND hDlg,int hue,int sat)
  RECT16 rect,client;
  int lum,ldif,ydif,r,g,b;
  HBRUSH hbrush;
- HDC hDC;
+ HDC32 hDC;
 
  if (IsWindowVisible(hwnd))
  {
-  hDC=GetDC(hwnd);
+  hDC=GetDC32(hwnd);
   GetClientRect16(hwnd,&client);
   rect=client;
 
@@ -1690,7 +1690,7 @@ static void CC_PaintLumBar(HWND hDlg,int hue,int sat)
   }
   GetClientRect16(hwnd,&rect);
   FrameRect16(hDC,&rect,GetStockObject(BLACK_BRUSH));
-  ReleaseDC(hwnd,hDC);
+  ReleaseDC32(hwnd,hDC);
  }
 }
 
@@ -1775,7 +1775,7 @@ static void CC_PaintPredefColorArray(HWND hDlg,int rows,int cols)
 {
  HWND hwnd=GetDlgItem(hDlg,0x2d0);
  RECT16 rect;
- HDC  hdc;
+ HDC32  hdc;
  HBRUSH hBrush;
  int dx,dy,i,j,k;
 
@@ -1784,7 +1784,7 @@ static void CC_PaintPredefColorArray(HWND hDlg,int rows,int cols)
  dy=rect.bottom/rows;
  k=rect.left;
 
- hdc=GetDC(hwnd);
+ hdc=GetDC32(hwnd);
  GetClientRect16 (hwnd, &rect) ;
 
  for (j=0;j<rows;j++)
@@ -1804,7 +1804,7 @@ static void CC_PaintPredefColorArray(HWND hDlg,int rows,int cols)
   rect.top=rect.top+dy;
   rect.left=k;
  }
- ReleaseDC(hwnd,hdc);
+ ReleaseDC32(hwnd,hdc);
  /* FIXME: draw_a_focus_rect */
 }
 /***********************************************************************
@@ -1814,7 +1814,7 @@ static void CC_PaintUserColorArray(HWND hDlg,int rows,int cols,COLORREF* lpcr)
 {
  HWND hwnd=GetDlgItem(hDlg,0x2d1);
  RECT16 rect;
- HDC  hdc;
+ HDC32  hdc;
  HBRUSH hBrush;
  int dx,dy,i,j,k;
 
@@ -1824,7 +1824,7 @@ static void CC_PaintUserColorArray(HWND hDlg,int rows,int cols,COLORREF* lpcr)
  dy=rect.bottom/rows;
  k=rect.left;
 
- hdc=GetDC(hwnd);
+ hdc=GetDC32(hwnd);
  if (hdc)
  {
   for (j=0;j<rows;j++)
@@ -1844,7 +1844,7 @@ static void CC_PaintUserColorArray(HWND hDlg,int rows,int cols,COLORREF* lpcr)
    rect.top=rect.top+dy;
    rect.left=k;
   }
-  ReleaseDC(hwnd,hdc);
+  ReleaseDC32(hwnd,hdc);
  }
  /* FIXME: draw_a_focus_rect */
 }
@@ -1940,7 +1940,7 @@ static LRESULT CC_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
 {
     int r,g,b,i,xx;
     UINT cokmsg;
-    HDC hdc;
+    HDC32 hdc;
     COLORREF *cr;
     struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
     dprintf_commdlg(stddeb,"CC_WMCommand wParam=%x lParam=%lx\n",wParam,lParam);
@@ -2018,9 +2018,9 @@ static LRESULT CC_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
 	       break;
 
           case 0x2c9:              /* resulting color */
-	       hdc=GetDC(hDlg);
+	       hdc=GetDC32(hDlg);
 	       lpp->lpcc->rgbResult=GetNearestColor(hdc,lpp->lpcc->rgbResult);
-	       ReleaseDC(hDlg,hdc);
+	       ReleaseDC32(hDlg,hdc);
 	       CC_EditSetRGB(hDlg,lpp->lpcc->rgbResult);
 	       CC_PaintSelectedColor(hDlg,lpp->lpcc->rgbResult);
 	       r=GetRValue(lpp->lpcc->rgbResult);
@@ -2402,10 +2402,10 @@ INT16 FontStyleEnumProc( SEGPTR logfont, SEGPTR metrics,
 
   if (!SendMessage16(hcmb2,CB_GETCOUNT,0,0))
   {
-       HDC hdc= (lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
+       HDC hdc= (lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC32(hDlg);
        i=SetFontStylesToCombo2(hcmb2,hdc,lplf,lptm);
        if (!(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC))
-         ReleaseDC(hDlg,hdc);
+         ReleaseDC32(hDlg,hdc);
        if (i)
         return 0;  
   }
@@ -2418,7 +2418,7 @@ INT16 FontStyleEnumProc( SEGPTR logfont, SEGPTR metrics,
  */
 LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam)
 {
-  HDC hdc;
+  HDC32 hdc;
   int i,j,res,init=0;
   long l;
   LPLOGFONT16 lpxx;
@@ -2466,7 +2466,7 @@ LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam)
     ShowWindow(GetDlgItem(hDlg,grp1),SW_HIDE);
     ShowWindow(GetDlgItem(hDlg,stc4),SW_HIDE);
   }
-  hdc= (lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
+  hdc= (lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC32(hDlg);
   if (hdc)
   {
     if (!EnumFontFamilies (hdc, NULL,FontFamilyEnumProc,(LPARAM)GetDlgItem(hDlg,cmb1)))
@@ -2520,7 +2520,7 @@ LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam)
   }
 
   if (!(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC))
-    ReleaseDC(hDlg,hdc);
+    ReleaseDC32(hDlg,hdc);
   res=TRUE;
   if (CFn_HookCallChk(lpcf))
     res=CallWindowProc16(lpcf->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
@@ -2670,7 +2670,7 @@ LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
   {
 	case cmb1:if (HIWORD(lParam)==CBN_SELCHANGE)
 		  {
-		    hdc=(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
+		    hdc=(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC32(hDlg);
 		    if (hdc)
 		    {
                       SendDlgItemMessage16(hDlg,cmb2,CB_RESETCONTENT,0,0); 
@@ -2689,7 +2689,7 @@ LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
                         SEGPTR_FREE(str);
 		      }
 		      if (!(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC))
- 		        ReleaseDC(hDlg,hdc);
+ 		        ReleaseDC32(hDlg,hdc);
  		    }
  		    else
                     {
diff --git a/misc/lstr.c b/misc/lstr.c
index 318e3dab018..33b65d8690c 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -697,6 +697,7 @@ FormatMessage32A(
 				char	*fmtstr,*sprintfbuf,*x;
 				DWORD	*argliststart;
 
+				fmtstr = NULL;
 				f++;
 				if (!*f) {
 					ADD_TO_T('%');
@@ -722,7 +723,7 @@ FormatMessage32A(
 						f++;
 						if (NULL!=(x=strchr(f,'!'))) {
 							*x='\0';
-							fmtstr=xmalloc(strlen(f)+2);
+							fmtstr=(char*)xmalloc(strlen(f)+2);
 							sprintf(fmtstr,"%%%s",f);
 							f=x+1;
 						}
diff --git a/misc/lzexpand.c b/misc/lzexpand.c
index 717b5868216..1c47990d7c5 100644
--- a/misc/lzexpand.c
+++ b/misc/lzexpand.c
@@ -75,7 +75,7 @@ _lzget(struct lzstate *lzs,BYTE *b) {
 		*b		= lzs->get[lzs->getcur++];
 		return		1;
 	} else {
-		int ret = FILE_Read(lzs->realfd,lzs->get,GETLEN);
+		int ret = _lread32(lzs->realfd,lzs->get,GETLEN);
 		if (ret==HFILE_ERROR)
 			return HFILE_ERROR;
 		if (ret==0)
@@ -102,7 +102,7 @@ read_header(HFILE fd,struct lzfileheader *head) {
 	/* We can't directly read the lzfileheader struct due to 
 	 * structure element alignment
 	 */
-	if (FILE_Read(fd,buf,14)<14)
+	if (_lread32(fd,buf,14)<14)
 		return 0;
 	memcpy(head->magic,buf,8);
 	memcpy(&(head->compressiontype),buf+8,1);
@@ -306,7 +306,7 @@ LZRead32(HFILE fd,LPVOID vbuf,UINT32 toread) {
 		if (lzstates[i].lzfd==fd)
 			break;
 	if (i==nroflzstates)
-		return FILE_Read(fd,buf,toread);
+		return _lread32(fd,buf,toread);
 	lzs=lzstates+i;
 
 /* The decompressor itself is in a define, cause we need it twice
@@ -447,7 +447,7 @@ LZCopy(HFILE src,HFILE dest) {
 
 	/* not compressed? just copy */
 	if (i==nroflzstates)
-		xread=FILE_Read;
+		xread=(INT32(*)(HFILE,LPVOID,UINT32))_lread32;
 	else
 		xread=LZRead32;
 	len=0;
diff --git a/misc/main.c b/misc/main.c
index 3adf5fba7f4..ae853fcbf45 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -9,13 +9,14 @@
 #include <string.h>
 #include <unistd.h>
 #include <ctype.h>
-#include <locale.h>
+/* #include <locale.h> */
 #ifdef MALLOC_DEBUGGING
 #include <malloc.h>
 #endif
 #include <X11/Xlib.h>
 #include <X11/Xresource.h>
 #include <X11/Xutil.h>
+#include <X11/Xlocale.h>
 #include <X11/cursorfont.h>
 #include "message.h"
 #include "module.h"
@@ -75,6 +76,8 @@ WORD WINE_LanguageId = 0;
 
 #define WINE_CLASS    "Wine"    /* Class name for resources */
 
+#define WINE_APP_DEFAULTS "/usr/lib/X11/app-defaults/Wine"
+
 typedef struct tagENVENTRY {
   LPSTR	       	        Name;
   LPSTR	       	        Value;
@@ -371,14 +374,21 @@ static void MAIN_ParseVersion( char *arg )
  */
 static void MAIN_ParseOptions( int *argc, char *argv[] )
 {
-    char *display_name;
+    char *display_name = NULL;
     XrmValue value;
-    XrmDatabase db = XrmGetFileDatabase("/usr/lib/X11/app-defaults/Wine");
+    XrmDatabase db = XrmGetFileDatabase(WINE_APP_DEFAULTS);
+    int i;
+    char *xrm_string;
 
-      /* Parse command line */
     Options.programName = MAIN_GetProgramName( *argc, argv );
-    XrmParseCommand( &db, optionsTable, NB_OPTIONS,
-		     Options.programName, argc, argv );
+
+      /* Get display name from command line */
+    for (i = 1; i < *argc - 1; i++)
+        if (!strcmp( argv[i], "-display" ))
+	{
+	    display_name = argv[i+1];
+	    break;
+        }
 
 #ifdef WINELIB
     /* Need to assemble command line and pass it to WinMain */
@@ -389,8 +399,8 @@ static void MAIN_ParseOptions( int *argc, char *argv[] )
 
       /* Open display */
 
-    if (MAIN_GetResource( db, ".display", &value )) display_name = value.addr;
-    else display_name = NULL;
+    if (display_name == NULL &&
+	MAIN_GetResource( db, ".display", &value )) display_name = value.addr;
 
     if (!(display = XOpenDisplay( display_name )))
     {
@@ -399,6 +409,17 @@ static void MAIN_ParseOptions( int *argc, char *argv[] )
 	exit(1);
     }
 
+      /* Merge file and screen databases */
+    if ((xrm_string = XResourceManagerString( display )) != NULL)
+    {
+        XrmDatabase display_db = XrmGetStringDatabase( xrm_string );
+        XrmMergeDatabases( display_db, &db );
+    }
+
+      /* Parse command line */
+    XrmParseCommand( &db, optionsTable, NB_OPTIONS,
+		     Options.programName, argc, argv );
+
       /* Get all options */
     if (MAIN_GetResource( db, ".iconic", &value ))
 	Options.cmdShow = SW_SHOWMINIMIZED;
@@ -1130,7 +1151,7 @@ BOOL SystemParametersInfo (UINT uAction, UINT uParam, LPVOID lpvParam, UINT fuWi
 			break;
 
 		case SPI_SETDESKWALLPAPER:
-			return (SetDeskWallPaper((LPSTR) lpvParam));
+			return (SetDeskWallPaper32((LPSTR) lpvParam));
 			break;
 
 		case SPI_SETDESKPATTERN:
diff --git a/misc/ole2nls.c b/misc/ole2nls.c
index 5690ec94ec7..66a7a741cff 100644
--- a/misc/ole2nls.c
+++ b/misc/ole2nls.c
@@ -1229,3 +1229,8 @@ BOOL SetLocaleInfoA(DWORD lcid, DWORD lctype, LPCSTR data) {
 	fprintf(stdnimp,"SetLocaleInfoA(%ld,%ld,%s)\n",lcid,lctype,data);
 	return TRUE;
 }
+
+BOOL IsValidLocale(DWORD lcid,DWORD flags) {
+	fprintf(stdnimp,"IsValidLocale(%ld,%ld)\n",lcid,flags);
+	return TRUE;
+}
diff --git a/misc/registry.c b/misc/registry.c
index ac00c2c7fa2..a0606ff5d25 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -1106,19 +1106,19 @@ _w95_loadreg(char* fn,LPKEYSTRUCT lpkey) {
 	if (hfd==HFILE_ERROR)
 		return;
 	magic[4]=0;
-	if (4!=FILE_Read(hfd,magic,4))
+	if (4!=_lread32(hfd,magic,4))
 		return;
 	if (strcmp(magic,"CREG")) {
 		fprintf(stddeb,"%s is not a w95 registry.\n",fn);
 		return;
 	}
-	if (4!=FILE_Read(hfd,&version,4))
+	if (4!=_lread32(hfd,&version,4))
 		return;
-	if (4!=FILE_Read(hfd,&rgdbsection,4))
+	if (4!=_lread32(hfd,&rgdbsection,4))
 		return;
 	if (-1==_llseek(hfd,0x20,SEEK_SET))
 		return;
-	if (4!=FILE_Read(hfd,magic,4))
+	if (4!=_lread32(hfd,magic,4))
 		return;
 	if (strcmp(magic,"RGKN")) {
 		dprintf_reg(stddeb,"second IFF header not RGKN, but %s\n",magic);
@@ -1133,7 +1133,7 @@ _w95_loadreg(char* fn,LPKEYSTRUCT lpkey) {
 
 	nrofdkes = (end-where)/sizeof(struct dke)+100;
 	data = (char*)xmalloc(end-where);
-	if ((end-where)!=FILE_Read(hfd,data,end-where))
+	if ((end-where)!=_lread32(hfd,data,end-where))
 		return;
 	curdata = data;
 
@@ -1215,7 +1215,7 @@ _w95_loadreg(char* fn,LPKEYSTRUCT lpkey) {
 	if (-1==_llseek(hfd,rgdbsection,SEEK_SET))
 		return;
 	data = (char*)xmalloc(end-rgdbsection);
-	if ((end-rgdbsection)!=FILE_Read(hfd,data,end-rgdbsection))
+	if ((end-rgdbsection)!=_lread32(hfd,data,end-rgdbsection))
 		return;
 	_lclose(hfd);
 	curdata = data;
@@ -1554,13 +1554,14 @@ DWORD RegCreateKeyEx32W(
 	if (!lpszSubKey || !*lpszSubKey) {
 		add_handle(++currenthandle,lpNextKey,samDesired);
 		*retkey=currenthandle;
+		lpNextKey->flags|=REG_OPTION_TAINTED;
 		return SHELL_ERROR_SUCCESS;
 	}
 	split_keypath(lpszSubKey,&wps,&wpc);
 	i 	= 0;
 	while ((i<wpc) && (wps[i][0]=='\0')) i++;
 	lpxkey	= lpNextKey;
-	while (i<wpc) {
+	while (wps[i]) {
 		lpxkey=lpNextKey->nextsub;
 		while (lpxkey) {
 			if (!lstrcmp32W(wps[i],lpxkey->keyname))
@@ -1574,13 +1575,15 @@ DWORD RegCreateKeyEx32W(
 	}
 	if (lpxkey) {
 		add_handle(++currenthandle,lpxkey,samDesired);
+		lpxkey->flags  |= REG_OPTION_TAINTED;
 		*retkey		= currenthandle;
-		*lpDispos	= REG_OPENED_EXISTING_KEY;
+		if (lpDispos)
+			*lpDispos	= REG_OPENED_EXISTING_KEY;
 		FREE_KEY_PATH;
 		return	SHELL_ERROR_SUCCESS;
 	}
 	/* good. now the hard part */
-	while (i<wpc) {
+	while (wps[i]) {
 		lplpPrevKey	= &(lpNextKey->nextsub);
 		lpxkey		= *lplpPrevKey;
 		while (lpxkey) {
@@ -1598,6 +1601,7 @@ DWORD RegCreateKeyEx32W(
 		(*lplpPrevKey)->nextsub	= NULL;
 		(*lplpPrevKey)->values	= NULL;
 		(*lplpPrevKey)->nrofvalues = 0;
+		(*lplpPrevKey)->flags 	= REG_OPTION_TAINTED;
 		if (lpszClass)
 			(*lplpPrevKey)->class = strdupW(lpszClass);
 		else
@@ -1608,14 +1612,14 @@ DWORD RegCreateKeyEx32W(
 	add_handle(++currenthandle,lpNextKey,samDesired);
 
 	/*FIXME: flag handling correct? */
-	lpNextKey->flags= fdwOptions;
+	lpNextKey->flags= fdwOptions |REG_OPTION_TAINTED;
 	if (lpszClass)
 		lpNextKey->class = strdupW(lpszClass);
 	else
 		lpNextKey->class = NULL;
-	lpNextKey->flags|=REG_OPTION_TAINTED;
 	*retkey		= currenthandle;
-	*lpDispos	= REG_CREATED_NEW_KEY;
+	if (lpDispos)
+		*lpDispos	= REG_CREATED_NEW_KEY;
 	FREE_KEY_PATH;
 	return SHELL_ERROR_SUCCESS;
 }
diff --git a/misc/shell.c b/misc/shell.c
index dd7aa3bfeeb..4e80173d49f 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -414,11 +414,11 @@ static BYTE* SHELL_GetResourceTable(HFILE hFile)
   int		size;
   
   _llseek( hFile, 0, SEEK_SET );
-  if ((FILE_Read(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
+  if ((_lread32(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
       (mz_header.mz_magic != MZ_SIGNATURE)) return (BYTE*)-1;
 
   _llseek( hFile, mz_header.ne_offset, SEEK_SET );
-  if (FILE_Read( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
+  if (_lread32( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
       return NULL;
 
   if (ne_header.ne_magic == PE_SIGNATURE) 
@@ -436,7 +436,7 @@ static BYTE* SHELL_GetResourceTable(HFILE hFile)
       if( !pTypeInfo ) return NULL;
 
       _llseek(hFile, mz_header.ne_offset+ne_header.resource_tab_offset, SEEK_SET);
-      if( FILE_Read( hFile, (char*)pTypeInfo, size) != size )
+      if( _lread32( hFile, (char*)pTypeInfo, size) != size )
 	{ free(pTypeInfo); return NULL; }
       return pTypeInfo;
     }
@@ -456,7 +456,7 @@ static HANDLE	SHELL_LoadResource(HINSTANCE hInst, HFILE hFile, NE_NAMEINFO* pNIn
  if( (ptr = (BYTE*)GlobalLock16( handle )) )
    {
     _llseek( hFile, (DWORD)pNInfo->offset << sizeShift, SEEK_SET);
-     FILE_Read( hFile, (char*)ptr, pNInfo->length << sizeShift);
+     _lread32( hFile, (char*)ptr, pNInfo->length << sizeShift);
      return handle;
    }
  return (HANDLE)0;
@@ -473,7 +473,7 @@ static HANDLE   ICO_LoadIcon(HINSTANCE hInst, HFILE hFile, LPicoICONDIRENTRY lpi
  if( (ptr = (BYTE*)GlobalLock16( handle )) )
    {
     _llseek( hFile, lpiIDE->dwImageOffset, SEEK_SET);
-     FILE_Read( hFile, (char*)ptr, lpiIDE->dwBytesInRes);
+     _lread32( hFile, (char*)ptr, lpiIDE->dwBytesInRes);
      return handle;
    }
  return (HANDLE)0;
@@ -491,7 +491,7 @@ static HANDLE ICO_GetIconDirectory(HINSTANCE hInst, HFILE hFile, LPicoICONDIR* l
   int		i;
  
   _llseek( hFile, 0, SEEK_SET );
-  if( FILE_Read(hFile,(char*)id,sizeof(id)) != sizeof(id) ) return 0;
+  if( _lread32(hFile,(char*)id,sizeof(id)) != sizeof(id) ) return 0;
 
   /* check .ICO header 
    *
@@ -504,7 +504,7 @@ static HANDLE ICO_GetIconDirectory(HINSTANCE hInst, HFILE hFile, LPicoICONDIR* l
 
   lpiID = (LPicoICONDIR)xmalloc(i);
 
-  if( FILE_Read(hFile,(char*)lpiID->idEntries,i) == i )
+  if( _lread32(hFile,(char*)lpiID->idEntries,i) == i )
   {  
      HANDLE	handle = DirectResAlloc( hInst, 0x10,
 					 id[2]*sizeof(ICONDIRENTRY) + sizeof(id) );
@@ -820,3 +820,16 @@ int ShellHookProc(void)
 	dprintf_reg(stdnimp, "ShellHookProc : Empty Stub !!!\n");
         return 0;
 }
+
+/*************************************************************************
+ *				SHGetFileInfoA		[SHELL32.54]
+ */
+DWORD
+SHGetFileInfo32A(LPCSTR path,DWORD dwFileAttributes,SHFILEINFO32A *psfi,
+	UINT32 sizeofpsfi,UINT32 flags
+) {
+	fprintf(stdnimp,"SHGetFileInfo32A(%s,0x%08lx,%p,%ld,0x%08lx)\n",
+		path,dwFileAttributes,psfi,sizeofpsfi,flags
+	);
+	return TRUE;
+}
diff --git a/misc/spy.c b/misc/spy.c
index 1a1b325a7d0..3cdf52d2050 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -148,8 +148,17 @@ static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] =
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
     /* 0x00E0 - Win32 Scrollbars */
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    "SBM_SETPOS32",             /* 0x00e0 */
+    "SBM_GETPOS32",             /* 0x00e1 */
+    "SBM_SETRANGE32",           /* 0x00e2 */
+    "SBM_GETRANGE32",           /* 0x00e3 */
+    "SBM_ENABLE_ARROWS32",      /* 0x00e4 */
+    NULL,
+    "SBM_SETRANGEREDRAW32",     /* 0x00e6 */
+    NULL, NULL,
+    "SBM_SETSCROLLINFO32",      /* 0x00e9 */
+    "SBM_GETSCROLLINFO32",      /* 0x00ea */
+    NULL, NULL, NULL, NULL, NULL,
 
     /* 0x00F0 - Win32 Buttons */
     "BM_GETCHECK32",            /* 0x00f0 */
diff --git a/misc/user.c b/misc/user.c
index 3885e091bf2..5763a46faee 100644
--- a/misc/user.c
+++ b/misc/user.c
@@ -16,11 +16,13 @@
 #include "hook.h"
 #include "debug.h"
 #include "toolhelp.h"
+#include "message.h"
 
 WORD USER_HeapSel = 0;
 
 
 extern HTASK	TASK_GetNextTask(HTASK);
+extern BOOL32   MENU_SwitchTPWndTo(HTASK);
 
 /***********************************************************************
  *           GetFreeSystemResources   (USER.284)
@@ -117,10 +119,13 @@ void USER_AppExit( HTASK16 hTask, HINSTANCE16 hInstance, HQUEUE16 hQueue )
 
     WND* desktop = WIN_GetDesktop();
 
-    /* Patch desktop window queue */
+    /* Patch desktop window */
     if( desktop->hmemTaskQ == hQueue )
 	desktop->hmemTaskQ = GetTaskQueue(TASK_GetNextTask(hTask));
 
+    /* Patch resident popup menu window */
+    MENU_SwitchTPWndTo(0);
+
     /* Nuke timers */
 
     TIMER_RemoveQueueTimers( hQueue );
diff --git a/misc/winsocket.c b/misc/winsocket.c
index ce3c916acd3..5cdae3d054c 100644
--- a/misc/winsocket.c
+++ b/misc/winsocket.c
@@ -1687,7 +1687,7 @@ INT WSACleanup(void)
 
 VOID
 WsControl(DWORD x1,DWORD x2,LPDWORD x3,LPDWORD x4,LPDWORD x5,LPDWORD x6) {
-	fprintf(stdnimp,"WsControl(%lx,%lx,%lx,%lx,%lx,%lx)\n",
+	fprintf(stdnimp,"WsControl(%lx,%lx,%p,%p,%p,%p)\n",
 		x1,x2,x3,x4,x5,x6
 	);
 	fprintf(stdnimp,"WsControl(x,x,%lx,%lx,%lx,%lx)\n",
diff --git a/miscemu/dpmi.c b/miscemu/dpmi.c
index 453032d6784..77a32854ad3 100644
--- a/miscemu/dpmi.c
+++ b/miscemu/dpmi.c
@@ -181,7 +181,20 @@ void INT_Int31Handler( SIGCONTEXT *context )
         AX_reg(context) = 0x8011; /* descriptor unavailable */
         SET_CFLAG(context);
         break;
-
+    case 0x0200: /* get real mode interrupt vector */
+	fprintf(stdnimp,
+		"int31: get realmode interupt vector(0x%02x) unimplemented.\n",
+		BL_reg(context)
+	);
+    	SET_CFLAG(context);
+        break;
+    case 0x0201: /* set real mode interrupt vector */
+	fprintf(stdnimp,
+		"int31: set realmode interupt vector(0x%02x,0x%04x:0x%04x) unimplemented\n",
+		BL_reg(context),CX_reg(context),DX_reg(context)
+	);
+    	SET_CFLAG(context);
+        break;
     case 0x0204:  /* Get protected mode interrupt vector */
 	dw = (DWORD)INT_GetHandler( BL_reg(context) );
 	CX_reg(context) = HIWORD(dw);
diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c
index 3662fef1c3a..a1fef7788a4 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -553,7 +553,7 @@ BOOL mciDriverNotify(HWND hWndCallBack, UINT wDevID, UINT wStatus)
 
 #define	_MCI_STRDUP_TO_SEG(dest,source) {\
 	HANDLE	x;\
-	x=USER_HEAP_ALLOC(strlen(source));\
+	x=USER_HEAP_ALLOC(strlen(source)+1);\
 	dest=(LPSTR)MAKELONG(x,USER_HeapSel);\
 	strcpy(PTR_SEG_TO_LIN(dest),source);\
 }
@@ -575,8 +575,44 @@ DWORD mciOpen(DWORD dwParam, LPMCI_OPEN_PARMS lp16Parms)
 		}
 	}
 	dprintf_mmsys(stddeb, "mciOpen // wDevID=%d \n", wDevID);
-
 	memcpy(&mciOpenDrv[wDevID],lpParms,sizeof(*lpParms));
+
+	if (dwParam & MCI_OPEN_ELEMENT) {
+		char	*s,*t;
+
+		dprintf_mmsys(stddeb,"mciOpen // lpstrElementName='%s'\n",
+			(char*)PTR_SEG_TO_LIN(lpParms->lpstrElementName)
+		);
+		s=(char*)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
+		t=strrchr(s,'.');
+		if (t) {
+			GetProfileString("mci extensions",t+1,"*",str,sizeof(str));
+			AnsiUpper(str);
+			if (strcmp(str, "CDAUDIO") == 0) {
+				uDevTyp = MCI_DEVTYPE_CD_AUDIO;
+			} else
+			if (strcmp(str, "WAVEAUDIO") == 0) {
+				uDevTyp = MCI_DEVTYPE_WAVEFORM_AUDIO;
+			} else
+			if (strcmp(str, "SEQUENCER") == 0)	{
+				uDevTyp = MCI_DEVTYPE_SEQUENCER;
+			} else
+			if (strcmp(str, "ANIMATION1") == 0) {
+				uDevTyp = MCI_DEVTYPE_ANIMATION;
+			} else
+			if (strcmp(str, "AVIVIDEO") == 0) {
+				uDevTyp = MCI_DEVTYPE_DIGITAL_VIDEO;
+			} else 
+			if (strcmp(str,"*") == 0) {
+				dprintf_mmsys(stddeb,"No [mci extensions] entry for %s found.\n",t);
+				return MCIERR_EXTENSION_NOT_FOUND;
+			} else  {
+				dprintf_mmsys(stddeb,"[mci extensions] entry %s for %s not supported.\n",str,t);
+			}
+		} else
+			return MCIERR_EXTENSION_NOT_FOUND;
+	}
+
 	if (dwParam & MCI_OPEN_ALIAS) {
 		dprintf_mmsys(stddeb, "MCI_OPEN // Alias='%s' !\n",
 			(char*)PTR_SEG_TO_LIN(lpParms->lpstrAlias));
@@ -1911,7 +1947,7 @@ LONG mmioRead(HMMIO16 hmmio, HPSTR pch, LONG cch)
 	dprintf_mmio(stddeb, "mmioRead(%04X, %p, %ld);\n", hmmio, pch, cch);
 	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
-	count = FILE_Read(LOWORD(lpmminfo->dwReserved2), pch, cch);
+	count = _lread32(LOWORD(lpmminfo->dwReserved2), pch, cch);
 	GlobalUnlock16(hmmio);
 	dprintf_mmio(stddeb, "mmioRead // count=%ld\n", count);
 	return count;
@@ -2013,7 +2049,7 @@ UINT mmioAdvance(HMMIO16 hmmio, MMIOINFO * lpmmioinfo, UINT uFlags)
 	lpmminfo = (LPMMIOINFO)GlobalLock16(hmmio);
 	if (lpmminfo == NULL) return 0;
 	if (uFlags == MMIO_READ) {
-		count = FILE_Read(LOWORD(lpmminfo->dwReserved2), 
+		count = _lread32(LOWORD(lpmminfo->dwReserved2), 
 			lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer);
 		}
 	if (uFlags == MMIO_WRITE) {
@@ -2081,7 +2117,7 @@ UINT mmioDescend(HMMIO16 hmmio, MMCKINFO * lpck,
 		(uFlags & MMIO_FINDLIST)) {
 		dprintf_mmio(stddeb, "mmioDescend // MMIO_FINDxxxx dwfcc=%08lX !\n", dwfcc);
 		while (TRUE) {
-			if (FILE_Read(LOWORD(lpmminfo->dwReserved2), (LPSTR)lpck, 
+			if (_lread32(LOWORD(lpmminfo->dwReserved2), (LPSTR)lpck, 
 					sizeof(MMCKINFO)) < sizeof(MMCKINFO)) {
 				_llseek(LOWORD(lpmminfo->dwReserved2), dwOldPos, SEEK_SET);
 				GlobalUnlock16(hmmio);
@@ -2097,7 +2133,7 @@ UINT mmioDescend(HMMIO16 hmmio, MMCKINFO * lpck,
 			}
 		}
 	else {
-		if (FILE_Read(LOWORD(lpmminfo->dwReserved2), (LPSTR)lpck, 
+		if (_lread32(LOWORD(lpmminfo->dwReserved2), (LPSTR)lpck, 
 				sizeof(MMCKINFO)) < sizeof(MMCKINFO)) {
 			_llseek(LOWORD(lpmminfo->dwReserved2), dwOldPos, SEEK_SET);
 			GlobalUnlock16(hmmio);
diff --git a/objects/bitmap.c b/objects/bitmap.c
index 5b060b0a74f..53237a818e3 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -261,13 +261,35 @@ HANDLE32 LoadImage32A(
 	return 0;
 }
 
+/**********************************************************************
+ *	    CopyImage32    (USER32.60)
+ *
+ * FIXME: implementation still lacks nearly all features, see LR_*
+ * defines in windows.h
+ */
+HANDLE32 CopyImage32( HANDLE32 hnd, UINT32 type, INT32 desiredx,
+                      INT32 desiredy, UINT32 flags )
+{
+    switch (type)
+    {
+	case IMAGE_BITMAP:
+		return hnd;	/* FIXME ... need to copy here */
+	case IMAGE_ICON:
+		return CopyIcon32(hnd);
+	case IMAGE_CURSOR:
+		return CopyCursor32(hnd);
+    }
+    return 0;
+}
+
+
 /**********************************************************************
  *	    LoadBitmap16    (USER.175)
  */
 HBITMAP16 LoadBitmap16( HINSTANCE16 instance, SEGPTR name )
 {
     HBITMAP16 hbitmap = 0;
-    HDC hdc;
+    HDC32 hdc;
     HRSRC16 hRsrc;
     HGLOBAL16 handle;
     BITMAPINFO *info;
@@ -292,12 +314,12 @@ HBITMAP16 LoadBitmap16( HINSTANCE16 instance, SEGPTR name )
     if (!(handle = LoadResource16( instance, hRsrc ))) return 0;
 
     info = (BITMAPINFO *)LockResource16( handle );
-    if ((hdc = GetDC(0)) != 0)
+    if ((hdc = GetDC32(0)) != 0)
     {
         char *bits = (char *)info + DIB_BitmapInfoSize( info, DIB_RGB_COLORS );
         hbitmap = CreateDIBitmap( hdc, &info->bmiHeader, CBM_INIT,
                                   bits, info, DIB_RGB_COLORS );
-        ReleaseDC( 0, hdc );
+        ReleaseDC32( 0, hdc );
     }
     FreeResource16( handle );
     return hbitmap;
@@ -309,7 +331,7 @@ HBITMAP16 LoadBitmap16( HINSTANCE16 instance, SEGPTR name )
 HBITMAP32 LoadBitmap32W( HINSTANCE32 instance, LPCWSTR name )
 {
     HBITMAP32 hbitmap = 0;
-    HDC hdc;
+    HDC32 hdc;
     HRSRC32 hRsrc;
     HGLOBAL32 handle;
     BITMAPINFO *info;
@@ -325,12 +347,12 @@ HBITMAP32 LoadBitmap32W( HINSTANCE32 instance, LPCWSTR name )
     if (!(handle = LoadResource32( instance, hRsrc ))) return 0;
 
     info = (BITMAPINFO *)LockResource32( handle );
-    if ((hdc = GetDC(0)) != 0)
+    if ((hdc = GetDC32(0)) != 0)
     {
         char *bits = (char *)info + DIB_BitmapInfoSize( info, DIB_RGB_COLORS );
         hbitmap = CreateDIBitmap( hdc, &info->bmiHeader, CBM_INIT,
                                   bits, info, DIB_RGB_COLORS );
-        ReleaseDC( 0, hdc );
+        ReleaseDC32( 0, hdc );
     }
     return hbitmap;
 }
diff --git a/objects/cursoricon.c b/objects/cursoricon.c
index 2b1c67ff66d..180e1ae28fc 100644
--- a/objects/cursoricon.c
+++ b/objects/cursoricon.c
@@ -236,7 +236,7 @@ HANDLE CURSORICON_LoadHandler( HANDLE handle, HINSTANCE hInstance,
                                       BOOL fCursor )
 {
     HANDLE hAndBits, hXorBits;
-    HDC hdc;
+    HDC32 hdc;
     int size, sizeAnd, sizeXor;
     POINT16 hotspot = { 0 ,0 };
     BITMAPOBJ *bmpXor, *bmpAnd;
@@ -285,7 +285,7 @@ HANDLE CURSORICON_LoadHandler( HANDLE handle, HINSTANCE hInstance,
 
     /* Create the XOR bitmap */
 
-    if (!(hdc = GetDC( 0 )))
+    if (!(hdc = GetDC32( 0 )))
     {
         free( pInfo );
         return 0;
@@ -323,7 +323,7 @@ HANDLE CURSORICON_LoadHandler( HANDLE handle, HINSTANCE hInstance,
 
     hAndBits = CreateDIBitmap( hdc, &pInfo->bmiHeader, CBM_INIT,
                                bits, pInfo, DIB_RGB_COLORS );
-    ReleaseDC( 0, hdc );
+    ReleaseDC32( 0, hdc );
 
     /* Now create the CURSORICONINFO structure */
 
@@ -788,7 +788,7 @@ static BOOL CURSORICON_SetCursor( HCURSOR16 hCursor )
     else
     {
         /* Set the same cursor for all top-level windows */
-        HWND hwnd = GetWindow( GetDesktopWindow(), GW_CHILD );
+        HWND hwnd = GetWindow( GetDesktopWindow32(), GW_CHILD );
         while(hwnd)
         {
             Window win = WIN_GetXWindow( hwnd );
diff --git a/objects/dc.c b/objects/dc.c
index db20ea80113..76d925a7c5c 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -26,6 +26,8 @@ static const WIN_DC_INFO DC_defaultValues =
     0,                      /* flags */
     NULL,                   /* devCaps */
     0,                      /* hMetaFile */
+    0,			    /* hHT */
+    0,			    /* HTLen */
     0,                      /* hClipRgn */
     0,                      /* hVisRgn */
     0,                      /* hGCClipRgn */
@@ -293,7 +295,7 @@ BOOL DC_SetupGCForPen( DC * dc )
     else val.line_style = LineSolid;
     val.line_width = dc->u.x.pen.width;
     val.cap_style  = CapRound;
-    val.join_style = JoinBevel;
+    val.join_style = JoinMiter;
     XChangeGC( display, dc->u.x.gc, 
 	       GCFunction | GCForeground | GCBackground | GCLineWidth |
 	       GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle, &val );
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 76864057f3d..f196635cd59 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -108,7 +108,7 @@ static FONTOBJ AnsiVarFont =
 static FONTOBJ SystemFont =
 {
     { 0, FONT_MAGIC, 1 },   /* header */
-    { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+    { 12, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
       0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
 };
 
@@ -122,7 +122,7 @@ static FONTOBJ DeviceDefaultFont =
 static FONTOBJ SystemFixedFont =
 {
     { 0, FONT_MAGIC, 1 },   /* header */
-    { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+    { 12, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
       0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
 };
 
diff --git a/objects/metafile.c b/objects/metafile.c
index 170a6d95ec4..3d38d3aedd4 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -2,7 +2,7 @@
  * Metafile functions
  *
  * Copyright  David W. Metcalfe, 1994
- *            Niels de Carpentier, Albrecht Kleine 1996
+ *            Niels de Carpentier, Albrecht Kleine, Huw Davies 1996
  *
  */
 
@@ -17,9 +17,6 @@
 
 #define HTINCR  10      /* handle table allocation size increment */
 
-static HANDLE hHT;      /* handle of the handle table */
-static int HTLen;       /* allocated length of handle table */
-
 /******************************************************************
  *         GetMetafile         GDI.124 By Kenny MacDonald 30 Nov 94
  */
@@ -49,7 +46,7 @@ HMETAFILE16 GetMetaFile(LPSTR lpFilename)
     return 0;
   }
   
-  if (FILE_Read(hFile, (char *)mh, MFHEADERSIZE) == HFILE_ERROR) {
+  if (_lread32(hFile, (char *)mh, MFHEADERSIZE) == HFILE_ERROR) {
     GlobalFree16(hmf);
     return 0;
   }
@@ -64,7 +61,7 @@ HMETAFILE16 GetMetaFile(LPSTR lpFilename)
     return 0;
   }
   
-  if (FILE_Read(hFile, (char*)mh + mh->mtHeaderSize * 2, 
+  if (_lread32(hFile, (char*)mh + mh->mtHeaderSize * 2, 
 	        size - mh->mtHeaderSize * 2) == HFILE_ERROR) {
     GlobalFree16(hmf);
     return 0;
@@ -91,7 +88,7 @@ HANDLE CreateMetaFile(LPCSTR lpFilename)
     DC *dc;
     HANDLE handle;
     METAHEADER *mh;
-    int hFile;
+    HFILE hFile;
     
     dprintf_metafile(stddeb,"CreateMetaFile: %s\n", lpFilename);
 
@@ -106,7 +103,14 @@ HANDLE CreateMetaFile(LPCSTR lpFilename)
         GDI_FreeObject(handle);
 	return 0;
     }
-    dc->w.bitsPerPixel    = screenDepth;
+    if (!(dc->w.hHT = GlobalAlloc16(GMEM_MOVEABLE | GMEM_ZEROINIT,
+				    sizeof(HANDLETABLE16) * HTINCR))) {
+	GlobalFree16(dc->w.hMetaFile);
+	GDI_FreeObject(handle);
+	return 0;
+    }
+    dc->w.HTLen = HTINCR;
+    dc->w.bitsPerPixel = screenDepth;
     mh = (METAHEADER *)GlobalLock16(dc->w.hMetaFile);
 
     mh->mtHeaderSize = MFHEADERSIZE / 2;
@@ -122,7 +126,9 @@ HANDLE CreateMetaFile(LPCSTR lpFilename)
 	hFile = _lcreat(lpFilename, 0);
 	if (_lwrite32(hFile, (char *)mh, MFHEADERSIZE) == -1)
 	{
+	    GlobalFree16(dc->w.hHT);
 	    GlobalFree16(dc->w.hMetaFile);
+	    GDI_FreeObject(handle);
 	    return 0;
 	}
 	mh->mtNoParameters = hFile; /* store file descriptor here */
@@ -131,11 +137,6 @@ HANDLE CreateMetaFile(LPCSTR lpFilename)
     else                     /* memory based metafile */
 	mh->mtType = 0;
 
-    /* create the handle table */
-    HTLen = HTINCR;
-    hHT = GlobalAlloc16(GMEM_MOVEABLE | GMEM_ZEROINIT, 
-		      sizeof(HANDLETABLE16) * HTLen);
-    
     GlobalUnlock16(dc->w.hMetaFile);
     dprintf_metafile(stddeb,"CreateMetaFile: returning %04x\n", handle);
     return handle;
@@ -150,7 +151,7 @@ HMETAFILE16 CopyMetaFile(HMETAFILE16 hSrcMetaFile, LPCSTR lpFilename)
     HMETAFILE16 handle = 0;
     METAHEADER *mh;
     METAHEADER *mh2;
-    int hFile;
+    HFILE hFile;
     
     dprintf_metafile(stddeb,"CopyMetaFile: %s\n", lpFilename);
     
@@ -191,12 +192,13 @@ BOOL IsValidMetaFile(HMETAFILE16 hmf)
 {
     BOOL resu=FALSE;
     METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
-    if (mh)
+    if (mh) {
       if (mh->mtType == 1 || mh->mtType == 0) 
         if (mh->mtHeaderSize == MFHEADERSIZE/sizeof(INT16))
           if (mh->mtVersion == MFVERSION)
             resu=TRUE;
-    GlobalUnlock16(hmf);            
+      GlobalUnlock16(hmf);
+    }
     dprintf_metafile(stddeb,"IsValidMetaFile %x => %d\n",hmf,resu);
     return resu;         
 }
@@ -228,7 +230,9 @@ HMETAFILE16 CloseMetaFile(HDC hdc)
 
     if (!MF_MetaParam0(dc, META_EOF))
     {
+	GlobalFree16(dc->w.hHT);
 	GlobalFree16(dc->w.hMetaFile);
+	GDI_FreeObject(hdc);
 	return 0;
     }	
 
@@ -238,20 +242,22 @@ HMETAFILE16 CloseMetaFile(HDC hdc)
 	mh->mtNoParameters = 0;
         if (_llseek(hFile, 0L, 0) == -1)
         {
+	    GlobalFree16(dc->w.hHT);
             GlobalFree16(dc->w.hMetaFile);
+	    GDI_FreeObject(hdc);
             return 0;
         }
         if (_lwrite32(hFile, (char *)mh, MFHEADERSIZE) == -1)
         {
+	    GlobalFree16(dc->w.hHT);
             GlobalFree16(dc->w.hMetaFile);
+	    GDI_FreeObject(hdc);
             return 0;
         }
         _lclose(hFile);
     }
 
-    /* delete the handle table */
-    GlobalFree16(hHT);
-
+    GlobalFree16(dc->w.hHT);
     hmf = dc->w.hMetaFile;
     GlobalUnlock16(hmf);
     GDI_FreeObject(hdc);
@@ -284,6 +290,7 @@ BOOL PlayMetaFile(HDC hdc, HMETAFILE16 hmf)
     METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
     METARECORD *mr;
     HANDLETABLE16 *ht;
+    HGLOBAL16 hHT;
     int offset = 0;
     WORD i;
 
@@ -326,6 +333,7 @@ BOOL EnumMetaFile(HDC hdc, HMETAFILE16 hmf, MFENUMPROC16 lpEnumFunc,LPARAM lpDat
 {
     METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
     METARECORD *mr;
+    HGLOBAL16 hHT;
     SEGPTR ht, spRecord;
     int offset = 0;
   
@@ -848,32 +856,27 @@ int MF_AddHandle(HANDLETABLE16 *ht, WORD htlen, HANDLE hobj)
 
 
 /******************************************************************
- *         MF_AddHandleInternal
+ *         MF_AddHandleDC
  *
- *    Add a handle to the internal handle table and return the index
+ *    Add a handle to the handle table in the DC, growing table if
+ *    necessary. Return the index
  */
 
-int MF_AddHandleInternal(HANDLE hobj)
+int MF_AddHandleDC(DC *dc, HANDLE hobj)
 {
     int i;
-    HANDLETABLE16 *ht = (HANDLETABLE16 *)GlobalLock16(hHT);
-
-    for (i = 0; i < HTLen; i++)
-    {
-	if (*(ht->objectHandle + i) == 0)
-	{
-	    *(ht->objectHandle + i) = hobj;
-	    GlobalUnlock16(hHT);
-	    return i;
-	}
+    HANDLETABLE16 *ht = (HANDLETABLE16 *)GlobalLock16(dc->w.hHT);
+
+    if((i = MF_AddHandle(ht, dc->w.HTLen, hobj)) == -1) {
+	GlobalUnlock16(dc->w.hHT);
+	if(!(dc->w.hHT = GlobalReAlloc16(dc->w.hHT, (dc->w.HTLen + HTINCR) *
+	 sizeof(HANDLETABLE16), GMEM_MOVEABLE | GMEM_ZEROINIT)))
+	    return -1;
+	dc->w.HTLen += HTINCR;
+	ht = (HANDLETABLE16 *)GlobalLock16(dc->w.hHT);
+	i = MF_AddHandle(ht, dc->w.HTLen, hobj);
     }
-    GlobalUnlock16(hHT);
-    if (!(hHT = GlobalReAlloc16(hHT, HTINCR, GMEM_MOVEABLE | GMEM_ZEROINIT)))
-	return -1;
-    HTLen += HTINCR;
-    ht = (HANDLETABLE16 *)GlobalLock16(hHT);
-    *(ht->objectHandle + i) = hobj;
-    GlobalUnlock16(hHT);
+    GlobalUnlock16(dc->w.hHT);
     return i;
 }
 
@@ -1036,7 +1039,7 @@ BOOL MF_CreateBrushIndirect(DC *dc, HBRUSH hBrush, LOGBRUSH16 *logbrush)
     mr->rdSize = sizeof(METARECORD) / 2;
     mr->rdFunction = META_SELECTOBJECT;
 
-    if ((index = MF_AddHandleInternal(hBrush)) == -1)
+    if ((index = MF_AddHandleDC(dc, hBrush)) == -1)
 	return FALSE;
 
     mh = (METAHEADER *)GlobalLock16(dc->w.hMetaFile);
@@ -1128,7 +1131,7 @@ BOOL MF_CreatePatternBrush(DC *dc, HBRUSH hBrush, LOGBRUSH16 *logbrush)
     mr = (METARECORD *)&buffer;
     mr->rdSize = sizeof(METARECORD) / 2;
     mr->rdFunction = META_SELECTOBJECT;
-    if ((index = MF_AddHandleInternal(hBrush)) == -1)
+    if ((index = MF_AddHandleDC(dc, hBrush)) == -1)
 	return FALSE;
 
     mh = (METAHEADER *)GlobalLock16(dc->w.hMetaFile);
@@ -1165,7 +1168,7 @@ BOOL MF_CreatePenIndirect(DC *dc, HPEN16 hPen, LOGPEN16 *logpen)
     mr->rdSize = sizeof(METARECORD) / 2;
     mr->rdFunction = META_SELECTOBJECT;
 
-    if ((index = MF_AddHandleInternal(hPen)) == -1)
+    if ((index = MF_AddHandleDC(dc, hPen)) == -1)
 	return FALSE;
 
     mh = (METAHEADER *)GlobalLock16(dc->w.hMetaFile);
@@ -1202,7 +1205,7 @@ BOOL MF_CreateFontIndirect(DC *dc, HFONT hFont, LOGFONT16 *logfont)
     mr->rdSize = sizeof(METARECORD) / 2;
     mr->rdFunction = META_SELECTOBJECT;
 
-    if ((index = MF_AddHandleInternal(hFont)) == -1)
+    if ((index = MF_AddHandleDC(dc, hFont)) == -1)
 	return FALSE;
 
     mh = (METAHEADER *)GlobalLock16(dc->w.hMetaFile);
diff --git a/objects/palette.c b/objects/palette.c
index a4897baea03..1682d915543 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -387,8 +387,8 @@ HPALETTE16 SelectPalette( HDC hDC, HPALETTE16 hPal, BOOL bForceBackground )
 
     if( hPal != STOCK_DEFAULT_PALETTE )
     {
-	HWND hWnd = WindowFromDC( hDC );
-	HWND hActive = GetActiveWindow();
+	HWND32 hWnd = WindowFromDC32( hDC );
+	HWND32 hActive = GetActiveWindow();
 	
 	/* set primary palette if it's related to current active */
 
@@ -414,8 +414,8 @@ UINT16 RealizePalette( HDC32 hDC )
     {
 	/* Send palette change notification */
 
-	HWND hWnd;
- 	if( (hWnd = WindowFromDC( hDC )) )
+	HWND32 hWnd;
+ 	if( (hWnd = WindowFromDC32( hDC )) )
             SendMessage16( HWND_BROADCAST, WM_PALETTECHANGED, hWnd, 0L);
     }
     return realized;
@@ -428,7 +428,7 @@ UINT16 RealizePalette( HDC32 hDC )
  */
 int UpdateColors( HDC hDC )
 {
-    HWND hWnd = WindowFromDC( hDC );
+    HWND32 hWnd = WindowFromDC32( hDC );
 
     /* Docs say that we have to remap current drawable pixel by pixel
      * but it would take forever given the speed of XGet/PutPixel.
diff --git a/objects/text.c b/objects/text.c
index fbe88bca41d..3d7eb81842f 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -224,6 +224,8 @@ INT16 DrawText16( HDC16 hdc, LPCSTR str, INT16 i_count,
 	tabwidth = size.cx * tabstop;
     }
 
+    if (flags & DT_CALCRECT) flags |= DT_NOCLIP;
+
     do
     {
 	prefix_offset = -1;
@@ -268,7 +270,7 @@ INT16 DrawText16( HDC16 hdc, LPCSTR str, INT16 i_count,
 	y += lh;
 	if (strPtr)
 	{
-	    if (!(flags & DT_NOCLIP) && !(flags & DT_CALCRECT))
+	    if (!(flags & DT_NOCLIP))
 	    {
 		if (y > rect->bottom - lh)
 		    break;
diff --git a/win32/console.c b/win32/console.c
index d933df5e21e..ec866f5619b 100644
--- a/win32/console.c
+++ b/win32/console.c
@@ -11,6 +11,15 @@
 #include "stddebug.h"
 #include "debug.h"
 
+static CONSOLE_SCREEN_BUFFER_INFO dummyinfo =
+{
+    {80, 24},
+    {0, 0},
+    0,
+    {0, 0, 79, 23},
+    {80, 24}
+};
+
 /***********************************************************************
  *           SetConsoleCtrlHandler               (KERNEL32.459)
  */
@@ -19,3 +28,34 @@ BOOL SetConsoleCtrlHandler(HANDLER_ROUTINE * func,  BOOL a)
 	return 0;
 }
 
+/***********************************************************************
+ *           GetConsoleScreenBufferInfo   (KERNEL32.190)
+ */
+BOOL32 GetConsoleScreenBufferInfo( HANDLE32 hConsoleOutput,
+                                   LPCONSOLE_SCREEN_BUFFER_INFO csbi )
+{
+    csbi->dwSize.x = 80;
+    csbi->dwSize.y = 24;
+    csbi->dwCursorPosition.x = 0;
+    csbi->dwCursorPosition.y = 0;
+    csbi->wAttributes = 0;
+    csbi->srWindow.Left	= 0;
+    csbi->srWindow.Right	= 79;
+    csbi->srWindow.Top	= 0;
+    csbi->srWindow.Bottom	= 23;
+    csbi->dwMaximumWindowSize.x = 80;
+    csbi->dwMaximumWindowSize.y = 24;
+    return TRUE;
+}
+
+/***********************************************************************
+ *            GetLargestConsoleWindowSize   (KERNEL32.226)
+ */
+COORD GetLargestConsoleWindowSize( HANDLE32 hConsoleOutput )
+{
+    return dummyinfo.dwMaximumWindowSize;
+}
+
+
+
+
diff --git a/win32/cursoricon32.c b/win32/cursoricon32.c
index 0e256a45b3c..fb8a226a29b 100644
--- a/win32/cursoricon32.c
+++ b/win32/cursoricon32.c
@@ -270,7 +270,7 @@ static HANDLE CURSORICON32_LoadHandler( HANDLE32 handle, HINSTANCE hInstance,
                                       BOOL fCursor )
 {
     HANDLE hAndBits, hXorBits, hRes;
-    HDC hdc;
+    HDC32 hdc;
     int size, sizeAnd, sizeXor;
     POINT16 hotspot = { 0 ,0 };
     BITMAPOBJ *bmpXor, *bmpAnd;
@@ -320,7 +320,7 @@ static HANDLE CURSORICON32_LoadHandler( HANDLE32 handle, HINSTANCE hInstance,
 
     /* Create the XOR bitmap */
 
-    if (!(hdc = GetDC( 0 )))
+    if (!(hdc = GetDC32( 0 )))
     {
         free( pInfo );
         return 0;
@@ -358,7 +358,7 @@ static HANDLE CURSORICON32_LoadHandler( HANDLE32 handle, HINSTANCE hInstance,
 
     hAndBits = CreateDIBitmap( hdc, &pInfo->bmiHeader, CBM_INIT,
                                bits, pInfo, DIB_RGB_COLORS );
-    ReleaseDC( 0, hdc );
+    ReleaseDC32( 0, hdc );
 
     /* Now create the CURSORICONINFO structure */
 
diff --git a/win32/file.c b/win32/file.c
index c8463cbe543..150322bcc57 100644
--- a/win32/file.c
+++ b/win32/file.c
@@ -167,7 +167,7 @@ static void UnixTimeToFileTime(time_t unix_time, FILETIME *filetime)
 time_t FileTimeToUnixTime(FILETIME *filetime)
 {
     /* reverse of UnixTimeToFileTime */
-    return filetime->dwLowDateTime+(filetime->dwHighDateTime<<16);
+    return (filetime->dwLowDateTime>>16)+(filetime->dwHighDateTime<<16);
 }
 
 /***********************************************************************
@@ -339,7 +339,9 @@ UINT32 SetHandleCount32( UINT32 cHandles )
 
 int CloseFileHandle(HFILE hFile)
 {
-    return _lclose(hFile);
+    if (!_lclose(hFile))
+	return TRUE;
+    return FALSE;
 }
 
 static int TranslateAccessFlags(DWORD access_flags)
@@ -451,6 +453,7 @@ BOOL32 SetFileAttributes32A(LPCSTR lpFileName, DWORD attributes)
 		buf.st_mode &= ~0222; /* octal!, clear write permission bits */
 		attributes &= ~FILE_ATTRIBUTE_READONLY;
 	}
+	attributes &= ~(FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
 	if (attributes)
 		fprintf(stdnimp,"SetFileAttributesA(%s):%lx attribute(s) not implemented.\n",lpFileName,attributes);
 	if (-1==chmod(fn,buf.st_mode)) {
diff --git a/win32/findfile.c b/win32/findfile.c
index 4520d2e92b1..8f9bf5230d1 100644
--- a/win32/findfile.c
+++ b/win32/findfile.c
@@ -148,8 +148,6 @@ HANDLE32 FindFirstFile32A(LPCSTR lpfilename,
 	return INVALID_HANDLE_VALUE;
     }
 
-    strcpy(context->mask, slash+1);
-
     /* uppercase mask in place */
     for (p = context->mask ; *p; p++)
 	*p = toupper(*p);
diff --git a/win32/memory.c b/win32/memory.c
index 86bca6e37c2..a08b07f4f40 100644
--- a/win32/memory.c
+++ b/win32/memory.c
@@ -268,6 +268,15 @@ BOOL32 VirtualFree(LPVOID lpvAddress, DWORD cbSize, DWORD fdwFreeType)
     return 1;
 }
 
+/***********************************************************************
+ *           VirtualQuery               (KERNEL32.554)
+ */
+BOOL32 VirtualQuery(LPCVOID address,LPMEMORY_BASIC_INFORMATION buf,DWORD len) 
+{
+	/* FIXME: fill out structure  ... */
+	return TRUE;
+}
+
 int TranslateProtectionFlags(DWORD protection_flags)
 {
     int prot;
@@ -308,7 +317,7 @@ int TranslateProtectionFlags(DWORD protection_flags)
  */
 BOOL WIN32_IsBadReadPtr(void* ptr, unsigned int bytes)
 {
-	dprintf_global(stddeb,"IsBadReadPtr(%x,%x)\n",ptr,bytes);
+	dprintf_global(stddeb,"IsBadReadPtr(%x,%x)\n",(int)ptr,bytes);
 	/* FIXME: Should make check based on actual mappings, here */
 	return FALSE;
 }
@@ -318,7 +327,7 @@ BOOL WIN32_IsBadReadPtr(void* ptr, unsigned int bytes)
  */
 BOOL WIN32_IsBadWritePtr(void* ptr, unsigned int bytes)
 {
-	dprintf_global(stddeb,"IsBadWritePtr(%x,%x)\n",ptr,bytes);
+	dprintf_global(stddeb,"IsBadWritePtr(%x,%x)\n",(int)ptr,bytes);
 	/* FIXME: Should make check based on actual mappings, here */
 	return FALSE;
 }
@@ -327,7 +336,7 @@ BOOL WIN32_IsBadWritePtr(void* ptr, unsigned int bytes)
  */
 BOOL WIN32_IsBadCodePtr(void* ptr, unsigned int bytes)
 {
-	dprintf_global(stddeb,"IsBadCodePtr(%x,%x)\n",ptr,bytes);
+	dprintf_global(stddeb,"IsBadCodePtr(%x,%x)\n",(int)ptr,bytes);
 	/* FIXME: Should make check based on actual mappings, here */
 	return FALSE;
 }
diff --git a/win32/newfns.c b/win32/newfns.c
index 9af9c00757f..b114cdd0a39 100644
--- a/win32/newfns.c
+++ b/win32/newfns.c
@@ -33,6 +33,14 @@ HHOOK SetWindowsHookEx32A(int HookId, HOOKPROC32 hookfn, HINSTANCE hModule,
 	return (HHOOK) NULL;
 }
 
+HHOOK SetWindowsHook32A(int HookId, HOOKPROC32 hookfn)
+{
+	/* Stub for now */
+	fprintf(stdnimp, "SetWindowsHook32A Stub called! (hook Id %d)\n", HookId);
+	SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+	return (HHOOK) NULL;
+}
+
 BOOL UnhookWindowsHookEx32(HHOOK hHook)
 
 {
diff --git a/win32/thread.c b/win32/thread.c
index 6b67874e7cd..accc9f4b30f 100644
--- a/win32/thread.c
+++ b/win32/thread.c
@@ -67,6 +67,11 @@ void DeleteCriticalSection(CRITICAL_SECTION* lpCrit)
 	return;
 }
 
+void
+ReinitializeCriticalSection(CRITICAL_SECTION *lpCrit) {
+	/* hmm */
+}
+
 /***********************************************************************
  *           Tls is available only for the single thread
  * (BTW: TLS means Thread Local Storage)
diff --git a/windows/caret.c b/windows/caret.c
index e7f4b65968d..86acfa3722c 100644
--- a/windows/caret.c
+++ b/windows/caret.c
@@ -49,7 +49,7 @@ HWND32 CARET_GetHwnd()
  */
 static void CARET_DisplayCaret( DISPLAY_CARET status )
 {
-    HDC16 hdc;
+    HDC32 hdc;
     HBRUSH16 hPrevBrush;
 
     if (Caret.on && (status == CARET_ON)) return;
@@ -58,11 +58,11 @@ static void CARET_DisplayCaret( DISPLAY_CARET status )
     /* So now it's always a toggle */
 
     Caret.on = !Caret.on;
-    if (!(hdc = GetDCEx( Caret.hwnd, 0, DCX_USESTYLE | DCX_CACHE ))) return;
+    if (!(hdc = GetDCEx32( Caret.hwnd, 0, DCX_USESTYLE | DCX_CACHE ))) return;
     hPrevBrush = SelectObject( hdc, Caret.hBrush );
     PatBlt( hdc, Caret.x, Caret.y, Caret.width, Caret.height, PATINVERT );
     SelectObject( hdc, hPrevBrush );
-    ReleaseDC( Caret.hwnd, hdc );
+    ReleaseDC32( Caret.hwnd, hdc );
 }
 
   
diff --git a/windows/class.c b/windows/class.c
index e95680118e6..c89e96f90b8 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -44,10 +44,10 @@ void CLASS_DumpClass( CLASS *ptr )
     fprintf( stderr, "Class %p:\n", ptr );
     fprintf( stderr,
              "next=%p  name=%04x '%s'  style=%08x  wndProc=%08x\n"
-             "inst=%04x  hdce=%04x  icon=%04x  cursor=%04x  bkgnd=%04x\n"
+             "inst=%04x  dce=%08x  icon=%04x  cursor=%04x  bkgnd=%04x\n"
              "clsExtra=%d  winExtra=%d  #windows=%d\n",
              ptr->next, ptr->atomName, className, ptr->style,
-             (UINT32)ptr->winproc, ptr->hInstance, ptr->hdce,
+             (UINT32)ptr->winproc, ptr->hInstance, (UINT32)ptr->dce,
              ptr->hIcon, ptr->hCursor, ptr->hbrBackground,
              ptr->cbClsExtra, ptr->cbWndExtra, ptr->cWindows );
     if (ptr->cbClsExtra)
@@ -181,7 +181,7 @@ static BOOL CLASS_FreeClass( CLASS *classPtr )
 
     /* Delete the class */
 
-    if (classPtr->hdce) DCE_FreeDCE( classPtr->hdce );
+    if (classPtr->dce) DCE_FreeDCE( classPtr->dce );
     if (classPtr->hbrBackground) DeleteObject( classPtr->hbrBackground );
     GlobalDeleteAtom( classPtr->atomName );
     CLASS_SetMenuNameA( classPtr, NULL );
@@ -288,7 +288,9 @@ static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE32 hInstance,
     classPtr->atomName    = atom;
     classPtr->menuNameA   = 0;
     classPtr->menuNameW   = 0;
-    classPtr->hdce        = (style&CS_CLASSDC) ? DCE_AllocDCE(0, DCE_CLASS_DC): 0;
+    classPtr->dce         = (style & CS_CLASSDC) ?
+                                 DCE_AllocDCE( 0, DCE_CLASS_DC ) : NULL;
+
     WINPROC_SetProc( &classPtr->winproc, wndProc, wndProcType );
 
     /* Other values must be set by caller */
diff --git a/windows/dce.c b/windows/dce.c
index b52d5479d9d..7afa5f72a67 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -19,7 +19,7 @@
 #include "class.h"
 #include "win.h"
 #include "gdi.h"
-#include "user.h"
+#include "heap.h"
 #include "sysmetrics.h"
 #include "stddebug.h"
 /* #define DEBUG_DC */
@@ -27,7 +27,7 @@
 
 #define NB_DCE    5  /* Number of DCEs created at startup */
 
-static HANDLE firstDCE = 0;
+static DCE *firstDCE = 0;
 static HDC defaultDCstate = 0;
 
 BOOL   DCHook(HDC, WORD, DWORD, DWORD);
@@ -37,26 +37,24 @@ BOOL   DCHook(HDC, WORD, DWORD, DWORD);
 *
  * Allocate a new DCE.
  */
-HANDLE DCE_AllocDCE( HWND hWnd, DCE_TYPE type )
+DCE *DCE_AllocDCE( HWND32 hWnd, DCE_TYPE type )
 {
     DCE * dce;
-    HANDLE handle = USER_HEAP_ALLOC( sizeof(DCE) );
-    if (!handle) return 0;
-    dce = (DCE *) USER_HEAP_LIN_ADDR( handle );
+    if (!(dce = HeapAlloc( SystemHeap, 0, sizeof(DCE) ))) return NULL;
     if (!(dce->hDC = CreateDC( "DISPLAY", NULL, NULL, NULL )))
     {
-	USER_HEAP_FREE( handle );
+        HeapFree( SystemHeap, 0, dce );
 	return 0;
     }
 
     /* store DCE handle in DC hook data field */
 
-    SetDCHook(dce->hDC, GDI_GetDefDCHook(), MAKELONG(handle,DC_MAGIC));
+    SetDCHook(dce->hDC, GDI_GetDefDCHook(), (DWORD)dce);
 
     dce->hwndCurrent = hWnd;
-    dce->hNext = firstDCE;
-    dce->hClipRgn = 0;
-    firstDCE = handle;
+    dce->hClipRgn    = 0;
+    dce->next        = firstDCE;
+    firstDCE = dce;
 
     if( type != DCE_CACHE_DC )
       {
@@ -72,77 +70,60 @@ HANDLE DCE_AllocDCE( HWND hWnd, DCE_TYPE type )
       }
     else dce->DCXflags = DCX_CACHE;
 
-    return handle;
+    return dce;
 }
 
 
 /***********************************************************************
  *           DCE_FreeDCE
  */
-void DCE_FreeDCE( HANDLE hdce )
+void DCE_FreeDCE( DCE *dce )
 {
-    DCE * dce;
-    HANDLE *handle = &firstDCE;
+    DCE **ppDCE = &firstDCE;
 
-    if (!(dce = (DCE *) USER_HEAP_LIN_ADDR( hdce ))) return;
-    while (*handle && (*handle != hdce))
-    {
-	DCE * prev = (DCE *) USER_HEAP_LIN_ADDR( *handle );	
-	handle = &prev->hNext;
-    }
-    if (*handle == hdce) *handle = dce->hNext;
+    if (!dce) return;
+    while (*ppDCE && (*ppDCE != dce)) ppDCE = &(*ppDCE)->next;
+    if (*ppDCE == dce) *ppDCE = dce->next;
 
     SetDCHook(dce->hDC,(SEGPTR)NULL,0L);
 
     DeleteDC( dce->hDC );
     if( dce->hClipRgn && !(dce->DCXflags & DCX_KEEPCLIPRGN) )
 	DeleteObject(dce->hClipRgn);
-    USER_HEAP_FREE( hdce );
+    HeapFree( SystemHeap, 0, dce );
 }
 
-/***********************************************************************
- *           DCE_FindDCE
+
+/**********************************************************************
+ *          WindowFromDC16   (USER32.580)
  */
-HANDLE DCE_FindDCE(HDC hDC)
+HWND16 WindowFromDC16( HDC16 hDC )
 {
- HANDLE hdce = firstDCE;
- DCE*   dce;
-
- while( hdce )
-  {
-    dce = (DCE *) USER_HEAP_LIN_ADDR(hdce);
-    if( dce->hDC == hDC ) break;
-    hdce = dce->hNext;
-  }
- return hdce;
+    return (HWND16)WindowFromDC32( hDC );
 }
 
+
 /**********************************************************************
- *          WindowFromDC   (USER.117) (USER32.580)
+ *          WindowFromDC32   (USER32.580)
  */
-HWND16 WindowFromDC( HDC32 hDC )
+HWND32 WindowFromDC32( HDC32 hDC )
 {
- HANDLE16 hdce = DCE_FindDCE(hDC); 
-
- if( hdce )
-   {
-     DCE* dce = (DCE *) USER_HEAP_LIN_ADDR(hdce);
-     return dce->hwndCurrent;
-   }
-
- return 0;
+    DCE *dce = firstDCE;
+    while (dce && (dce->hDC != hDC)) dce = dce->next;
+    return dce ? dce->hwndCurrent : 0;
 }
 
+
 /***********************************************************************
  *   DCE_InvalidateDCE
  *
  * It is called from SetWindowPos - we have to invalidate all busy
  * DCE's for windows whose client rect intersects with update rectangle 
  */
-BOOL DCE_InvalidateDCE(WND* wndScope, RECT16* pRectUpdate)
+BOOL32 DCE_InvalidateDCE(WND* wndScope, RECT16* pRectUpdate)
 {
- HANDLE hdce;
- DCE*   dce;
+    BOOL32 bRet = FALSE;
+    DCE *dce;
 
  if( !wndScope ) return 0;
 
@@ -151,10 +132,8 @@ BOOL DCE_InvalidateDCE(WND* wndScope, RECT16* pRectUpdate)
 				        pRectUpdate->right,pRectUpdate->bottom);
  /* walk all DCE's */
 
- for( hdce = firstDCE; (hdce); hdce=dce->hNext)
+ for (dce = firstDCE; (dce); dce = dce->next)
   { 
-    dce = (DCE*)USER_HEAP_LIN_ADDR(hdce);
-
     if( dce->DCXflags & DCX_DCEBUSY )
       {
         WND * wndCurrent, * wnd; 
@@ -177,12 +156,15 @@ BOOL DCE_InvalidateDCE(WND* wndScope, RECT16* pRectUpdate)
 	        MapWindowPoints16(wndCurrent->parent->hwndSelf, wndScope->hwndSelf,
 			 				       (LPPOINT16)&wndRect, 2);
 	        if( IntersectRect16(&wndRect,&wndRect,pRectUpdate) )
-	            SetHookFlags(dce->hDC, DCHF_INVALIDATEVISRGN);
+	        {    
+		   SetHookFlags(dce->hDC, DCHF_INVALIDATEVISRGN);
+		   bRet = TRUE;
+		}
 	        break;
 	      }
       }
   }
- return 1;
+ return bRet;
 }
 
 /***********************************************************************
@@ -191,13 +173,11 @@ BOOL DCE_InvalidateDCE(WND* wndScope, RECT16* pRectUpdate)
 void DCE_Init()
 {
     int i;
-    HANDLE handle;
     DCE * dce;
         
     for (i = 0; i < NB_DCE; i++)
     {
-	if (!(handle = DCE_AllocDCE( 0, DCE_CACHE_DC ))) return;
-	dce = (DCE *) USER_HEAP_LIN_ADDR( handle );	
+	if (!(dce = DCE_AllocDCE( 0, DCE_CACHE_DC ))) return;
 	if (!defaultDCstate) defaultDCstate = GetDCState( dce->hDC );
     }
 }
@@ -400,14 +380,23 @@ static void DCE_SetDrawable( WND *wndPtr, DC *dc, WORD flags )
     }
 }
 
+
+/***********************************************************************
+ *           GetDCEx16    (USER.359)
+ */
+HDC16 GetDCEx16( HWND16 hwnd, HRGN16 hrgnClip, DWORD flags )
+{
+    return (HDC16)GetDCEx32( hwnd, hrgnClip, flags );
+}
+
+
 /***********************************************************************
- *           GetDCEx    (USER.359)
+ *           GetDCEx32    (USER32.230)
  *
  * Unimplemented flags: DCX_LOCKWINDOWUPDATE
  */
-HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
+HDC32 GetDCEx32( HWND32 hwnd, HRGN32 hrgnClip, DWORD flags )
 {
-    HANDLE 	hdce;
     HRGN 	hrgnVisible;
     HDC 	hdc = 0;
     DCE * 	dce;
@@ -446,7 +435,8 @@ HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
         flags &= ~(DCX_PARENTCLIP | DCX_CLIPCHILDREN);
       }
 
-    if (hwnd==GetDesktopWindow() || !(wndPtr->dwStyle & WS_CHILD)) flags &= ~DCX_PARENTCLIP;
+    if (hwnd == GetDesktopWindow32() || !(wndPtr->dwStyle & WS_CHILD))
+        flags &= ~DCX_PARENTCLIP;
 
     if (flags & DCX_WINDOW) flags = (flags & ~DCX_CLIPCHILDREN) | DCX_CACHE;
 
@@ -464,17 +454,14 @@ HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
 
     if (flags & DCX_CACHE)
     {
-	for (hdce = firstDCE; (hdce); hdce = dce->hNext)
+	for (dce = firstDCE; (dce); dce = dce->next)
 	{
-	    if (!(dce = (DCE *) USER_HEAP_LIN_ADDR( hdce ))) return 0;
 	    if ((dce->DCXflags & DCX_CACHE) && !(dce->DCXflags & DCX_DCEBUSY)) break;
 	}
     }
     else 
     {
-        hdce = (wndPtr->class->style & CS_OWNDC)?wndPtr->hdce:wndPtr->class->hdce;
-	dce = (DCE *) USER_HEAP_LIN_ADDR( hdce );
-
+        dce = (wndPtr->class->style & CS_OWNDC)?wndPtr->dce:wndPtr->class->dce;
 	if( dce->hwndCurrent == hwnd )
 	  {
 	    dprintf_dc(stddeb,"\tskipping hVisRgn update\n");
@@ -491,8 +478,7 @@ HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
 
     dcx_flags = flags & ( DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_CACHE | DCX_WINDOW | DCX_WINDOWPAINT);
 
-    if (!hdce) return 0;
-    dce = (DCE *) USER_HEAP_LIN_ADDR( hdce );
+    if (!dce) return 0;
     dce->hwndCurrent = hwnd;
     dce->hClipRgn = 0;
     dce->DCXflags = dcx_flags | DCX_DCEBUSY;
@@ -502,7 +488,7 @@ HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
 
     DCE_SetDrawable( wndPtr, dc, flags );
     if( need_update || dc->w.flags & DC_DIRTY )
-     {
+    {
       dprintf_dc(stddeb,"updating hDC anyway\n");
 
       if (flags & DCX_PARENTCLIP)
@@ -521,16 +507,27 @@ HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
         }
            /* optimize away GetVisRgn for desktop if it isn't there */
 
-      else if ((hwnd == GetDesktopWindow()) &&
+      else if ((hwnd == GetDesktopWindow32()) &&
                (rootWindow == DefaultRootWindow(display)))
 	       hrgnVisible = CreateRectRgn( 0, 0, SYSMETRICS_CXSCREEN,
                                                   SYSMETRICS_CYSCREEN);
       else hrgnVisible = DCE_GetVisRgn( hwnd, flags );
 
-      dc->w.flags &= ~DC_DIRTY;
+      if( wndPtr->parent && wndPtr->window )
+      {
+        WND* 	wnd = wndPtr->parent->child;
+	RECT16  rect;
+	
+        for( ; wnd != wndPtr; wnd = wnd->next )
+           if( wnd->class->style & CS_SAVEBITS &&
+               wnd->dwStyle & WS_VISIBLE &&
+	       IntersectRect16(&rect, &wndPtr->rectClient, &wnd->rectClient) )
+               wnd->flags |= WIN_SAVEUNDER_OVERRIDE;
+      }
 
+      dc->w.flags &= ~DC_DIRTY;
       SelectVisRgn( hdc, hrgnVisible );
-     }
+    }
     else hrgnVisible = CreateRectRgn(0,0,0,0);
 
     if ((flags & DCX_INTERSECTRGN) || (flags & DCX_EXCLUDERGN))
@@ -552,49 +549,67 @@ HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
     return hdc;
 }
 
+
 /***********************************************************************
- *           GetDC    (USER.66)
+ *           GetDC16    (USER.66)
  */
-HDC GetDC( HWND hwnd )
+HDC16 GetDC16( HWND16 hwnd )
 {
-    if( !hwnd ) return GetDCEx( GetDesktopWindow(), 0, DCX_CACHE | DCX_WINDOW );
+    return (HDC16)GetDC32( hwnd );
+}
 
-    return GetDCEx( hwnd, 0, DCX_USESTYLE );
+
+/***********************************************************************
+ *           GetDC32    (USER32.229)
+ */
+HDC32 GetDC32( HWND32 hwnd )
+{
+    if (!hwnd)
+        return GetDCEx32( GetDesktopWindow32(), 0, DCX_CACHE | DCX_WINDOW );
+    return GetDCEx32( hwnd, 0, DCX_USESTYLE );
 }
 
 
 /***********************************************************************
- *           GetWindowDC    (USER.67)
+ *           GetWindowDC16    (USER.67)
  */
-HDC GetWindowDC( HWND hwnd )
+HDC16 GetWindowDC16( HWND16 hwnd )
 {
-    if (hwnd)
-    {
-	WND * wndPtr;
-	if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
-    }
-    else hwnd = GetDesktopWindow();
+    if (!hwnd) hwnd = GetDesktopWindow16();
+    return GetDCEx16( hwnd, 0, DCX_USESTYLE | DCX_WINDOW );
+}
+
 
-    return GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW );
+/***********************************************************************
+ *           GetWindowDC32    (USER32.)
+ */
+HDC32 GetWindowDC32( HWND32 hwnd )
+{
+    if (!hwnd) hwnd = GetDesktopWindow32();
+    return GetDCEx32( hwnd, 0, DCX_USESTYLE | DCX_WINDOW );
+}
+
+
+/***********************************************************************
+ *           ReleaseDC16    (USER.68)
+ */
+INT16 ReleaseDC16( HWND16 hwnd, HDC16 hdc )
+{
+    return (INT32)ReleaseDC32( hwnd, hdc );
 }
 
 
 /***********************************************************************
- *           ReleaseDC    (USER.68)
+ *           ReleaseDC32    (USER32.439)
  */
-int ReleaseDC( HWND hwnd, HDC hdc )
+INT32 ReleaseDC32( HWND32 hwnd, HDC32 hdc )
 {
-    HANDLE hdce;
-    DCE * dce = NULL;
+    DCE * dce = firstDCE;
     
     dprintf_dc(stddeb, "ReleaseDC: %04x %04x\n", hwnd, hdc );
         
-    for (hdce = firstDCE; (hdce); hdce = dce->hNext)
-    {
-	if (!(dce = (DCE *) USER_HEAP_LIN_ADDR( hdce ))) return 0;
-	if (dce->hDC == hdc) break;
-    }
-    if (!hdce) return 0;
+    while (dce && (dce->hDC != hdc)) dce = dce->next;
+    if (!dce) return 0;
     if (!(dce->DCXflags & DCX_DCEBUSY) ) return 0;
 
     /* restore previous visible region */
@@ -631,24 +646,18 @@ int ReleaseDC( HWND hwnd, HDC hdc )
  */
 BOOL DCHook(HDC hDC, WORD code, DWORD data, DWORD lParam)
 {
-  HANDLE hdce;
-  HRGN hVisRgn;
-
-  dprintf_dc(stddeb,"DCHook: hDC = %04x, %i\n", hDC, code);
+    HRGN32 hVisRgn;
+    DCE *dce = firstDCE;;
 
-  if( HIWORD(data) == DC_MAGIC )
-      hdce = (HANDLE)LOWORD(data);
-  else
-      hdce = DCE_FindDCE(hDC);
+    dprintf_dc(stddeb,"DCHook: hDC = %04x, %i\n", hDC, code);
 
-  if( !hdce ) return 0;
+    while (dce && (dce->hDC != hDC)) dce = dce->next;
+    if (!dce) return 0;
 
   switch( code )
     {
       case DCHC_INVALIDVISRGN:
          {
-           DCE* dce = (DCE*) USER_HEAP_LIN_ADDR(hdce);
-
            if( dce->DCXflags & DCX_DCEBUSY )
  	     {
 	       SetHookFlags(hDC, DCHF_VALIDATEVISRGN);
diff --git a/windows/defwnd.c b/windows/defwnd.c
index e1767ae75e3..7284cd1a505 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -29,31 +29,6 @@
 static short iF10Key = 0;
 static short iMenuSysKey = 0;
 
-
-/***********************************************************************
- *           DEFWND_InitSysMenuPopup
- *
- * Handle the WM_INITMENUPOPUP message on the system menu.
- */
-static void DEFWND_InitSysMenuPopup( HMENU hmenu, DWORD style, DWORD clsStyle )
-{
-    BOOL gray;
-
-    gray = !(style & WS_THICKFRAME) || (style & (WS_MAXIMIZE | WS_MINIMIZE));
-    EnableMenuItem( hmenu, SC_SIZE, (gray ? MF_GRAYED : MF_ENABLED) );
-    gray = ((style & WS_MAXIMIZE) != 0);
-    EnableMenuItem( hmenu, SC_MOVE, (gray ? MF_GRAYED : MF_ENABLED) );
-    gray = !(style & WS_MINIMIZEBOX) || (style & WS_MINIMIZE);
-    EnableMenuItem( hmenu, SC_MINIMIZE, (gray ? MF_GRAYED : MF_ENABLED) );
-    gray = !(style & WS_MAXIMIZEBOX) || (style & WS_MAXIMIZE);
-    EnableMenuItem( hmenu, SC_MAXIMIZE, (gray ? MF_GRAYED : MF_ENABLED) );
-    gray = !(style & (WS_MAXIMIZE | WS_MINIMIZE));
-    EnableMenuItem( hmenu, SC_RESTORE, (gray ? MF_GRAYED : MF_ENABLED) );
-    gray = (clsStyle & CS_NOCLOSE) != 0;
-    EnableMenuItem( hmenu, SC_CLOSE, (gray ? MF_GRAYED : MF_ENABLED) );
-}
-
-
 /***********************************************************************
  *           DEFWND_HandleWindowPosChanged
  *
@@ -322,17 +297,10 @@ static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT32 msg, WPARAM32 wParam,
         ShowWindow( wndPtr->hwndSelf, wParam ? SW_SHOWNOACTIVATE : SW_HIDE );
 	break; 
 
-    case WM_INITMENUPOPUP:
-        /* Not absolutely sure this belongs here -- AJ */
-        if (HIWORD(lParam))  /* system menu */
-            DEFWND_InitSysMenuPopup( (HMENU)wParam, wndPtr->dwStyle,
-                                     wndPtr->class->style );
-        break;
-
     case WM_CANCELMODE:
 	/* EndMenu() should be called if in menu state but currently it's
 	   impossible to detect - menu code should be updated*/
-	if (GetCapture() == wndPtr->hwndSelf) ReleaseCapture();
+	if (GetCapture32() == wndPtr->hwndSelf) ReleaseCapture();
 	break;
 
     case WM_VKEYTOITEM:
diff --git a/windows/dialog.c b/windows/dialog.c
index 44511b3c6ee..fe31129ad54 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -514,13 +514,12 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCSTR dlgTemplate,
 	{
 	    TEXTMETRIC16 tm;
 	    HFONT oldFont;
-	    HDC hdc;
 
-	    hdc = GetDC(0);
+	    HDC32 hdc = GetDC32(0);
 	    oldFont = SelectObject( hdc, hFont );
 	    GetTextMetrics16( hdc, &tm );
 	    SelectObject( hdc, oldFont );
-	    ReleaseDC( 0, hdc );
+	    ReleaseDC32( 0, hdc );
 	    xUnit = tm.tmAveCharWidth;
 	    yUnit = tm.tmHeight;
             if (tm.tmPitchAndFamily & TMPF_FIXED_PITCH)
@@ -744,8 +743,8 @@ static INT32 DIALOG_DoDialogBox( HWND hwnd, HWND owner )
 	if (dlgInfo->fEnd) break;
     }
     retval = dlgInfo->msgResult;
-    DestroyWindow( hwnd );
     EnableWindow( owner, TRUE );
+    DestroyWindow( hwnd );
     return retval;
 }
 
@@ -897,7 +896,7 @@ BOOL IsDialogMessage( HWND hwndDlg, LPMSG16 msg )
             if (!(dlgCode & DLGC_WANTTAB))
             {
                 SendMessage16( hwndDlg, WM_NEXTDLGCTL,
-                             (GetKeyState(VK_SHIFT) & 0x80), 0 );
+                             (GetKeyState(VK_SHIFT) & 0x8000), 0 );
                 return TRUE;
             }
             break;
diff --git a/windows/event.c b/windows/event.c
index 3759ac0517e..77532ea7805 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -22,17 +22,18 @@
 #include "windows.h"
 #include "gdi.h"
 #include "heap.h"
+#include "queue.h"
 #include "win.h"
 #include "class.h"
 #include "clipboard.h"
 #include "debugger.h"
-#include "hook.h"
 #include "message.h"
 #include "module.h"
 #include "options.h"
 #include "queue.h"
 #include "winpos.h"
 #include "registers.h"
+#include "xmalloc.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "dde_proc.h"
@@ -52,8 +53,8 @@ BYTE AsyncKeyStateTable[256];
        WPARAM   lastEventChar = 0; /* this will have to be changed once
 				    * ToAscii starts working */
 
-static HWND 	captureWnd = 0;
-static BOOL	InputEnabled = TRUE;
+static HWND32 captureWnd = 0;
+static BOOL32 InputEnabled = TRUE;
 
 /* Keyboard translation tables */
 static const int special_key[] =
@@ -174,17 +175,17 @@ void EVENT_ProcessEvent( XEvent *event )
     {
     case KeyPress:
     case KeyRelease:
-        if (!HOOK_GetHook(WH_JOURNALPLAYBACK, 0) )
+        if (InputEnabled)
             EVENT_key( (XKeyEvent*)event );
 	break;
 	
     case ButtonPress:
-        if (!HOOK_GetHook(WH_JOURNALPLAYBACK, 0) )
+        if (InputEnabled)
             EVENT_ButtonPress( (XButtonEvent*)event );
 	break;
 
     case ButtonRelease:
-        if (!HOOK_GetHook(WH_JOURNALPLAYBACK, 0) )
+        if (InputEnabled)
             EVENT_ButtonRelease( (XButtonEvent*)event );
 	break;
 
@@ -197,7 +198,7 @@ void EVENT_ProcessEvent( XEvent *event )
 	   problems if the event order is important. I'm not yet seen
 	   of any problems. Jon 7/6/96.
 	 */
-	if (!HOOK_GetHook(WH_JOURNALPLAYBACK, 0) )
+        if (InputEnabled)
 	{
             while (XCheckTypedWindowEvent(display,((XAnyEvent *)event)->window,
                                           MotionNotify, event));    
@@ -240,6 +241,7 @@ void EVENT_ProcessEvent( XEvent *event )
     case ClientMessage:
 	EVENT_ClientMessage( pWnd, (XClientMessageEvent *) event );
 	break;
+
 /*  case EnterNotify:
  *       EVENT_EnterNotify( pWnd, (XCrossingEvent *) event );
  *       break;
@@ -287,7 +289,7 @@ void EVENT_RegisterWindow( WND *pWnd )
  * Return TRUE if an event is pending, FALSE on timeout or error
  * (for instance lost connection with the server).
  */
-BOOL32 EVENT_WaitXEvent( BOOL32 sleep )
+BOOL32 EVENT_WaitXEvent( BOOL32 sleep, BOOL32 peek )
 {
     fd_set read_set;
     struct timeval timeout;
@@ -335,6 +337,7 @@ BOOL32 EVENT_WaitXEvent( BOOL32 sleep )
     }
 
     /* Process the event (and possibly others that occurred in the meantime) */
+
     do
     {
 
@@ -346,8 +349,39 @@ BOOL32 EVENT_WaitXEvent( BOOL32 sleep )
         }
 #endif  /* CONFIG_IPC */
 
-        XNextEvent( display, &event );
-        EVENT_ProcessEvent( &event );
+	XNextEvent( display, &event );
+
+        if( peek )
+        {
+	  WND*		pWnd;
+	  MESSAGEQUEUE* pQ;
+  
+          if( XFindContext( display, ((XAnyEvent *)&event)->window, winContext, (char **)&pWnd) 
+	      || event.type == NoExpose )  
+              continue;
+
+	  /* check for the "safe" hardware events */
+
+	  if( event.type == MotionNotify ||
+	      event.type == ButtonPress || event.type == ButtonRelease ||
+	      event.type == KeyPress || event.type == KeyRelease ||
+	      event.type == SelectionRequest || event.type == SelectionClear )
+	  {
+	       EVENT_ProcessEvent( &event );
+               continue;
+	  }
+
+	  if( pWnd )
+            if( (pQ = (MESSAGEQUEUE*)GlobalLock16(pWnd->hmemTaskQ)) )
+            {
+              pQ->flags |= QUEUE_FLAG_XEVENT;
+              PostEvent(pQ->hTask);
+	      XPutBackEvent(display, &event);
+              break;
+	    }
+        }
+        else
+          EVENT_ProcessEvent( &event );
     }
     while (XPending( display ));
     return TRUE;
@@ -684,7 +718,7 @@ static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event )
      * window structure is created. WIN_GetDesktop() check is a hack.
      */
 
-    if ( !WIN_GetDesktop() || hwnd == GetDesktopWindow())
+    if ( !WIN_GetDesktop() || hwnd == GetDesktopWindow32())
     {
         desktopX = event->x;
 	desktopY = event->y;
@@ -694,7 +728,7 @@ static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event )
         WND *wndPtr;
 	WINDOWPOS16 *winpos;
 	RECT16 newWindowRect, newClientRect;
-        HRGN hrgnOldPos, hrgnNewPos;
+	HRGN hrgnOldPos, hrgnNewPos;
 
 	if (!(wndPtr = WIN_FindWndPtr( hwnd )) ||
 	    !(wndPtr->flags & WIN_MANAGED) )
@@ -702,6 +736,9 @@ static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event )
 	
         if (!(winpos = SEGPTR_NEW(WINDOWPOS16))) return;
 
+/*	XTranslateCoordinates(display, event->window, rootWindow,
+	    event->x, event->y, &event->x, &event->y, &child);
+            */
 
 	/* Fill WINDOWPOS struct */
 	winpos->flags = SWP_NOACTIVATE | SWP_NOZORDER;
@@ -764,24 +801,45 @@ static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event )
     if(event->target == XA_STRING)
     {
 	HANDLE hText;
-	LPSTR text;
+	LPSTR  text;
+	int    size,i,j;
 
         rprop = event->property;
 
 	if(rprop == None) rprop = event->target;
 
         if(event->selection!=XA_PRIMARY) rprop = None;
-        else if(!CLIPBOARD_IsPresent(CF_TEXT)) rprop = None;
-	else{
-            /* Don't worry if we can't open */
-	    BOOL couldOpen=OpenClipboard( pWnd->hwndSelf );
-	    hText=GetClipboardData(CF_TEXT);
-	    text=GlobalLock16(hText);
-	    XChangeProperty(display,request,rprop,XA_STRING,
-		8,PropModeReplace,text,strlen(text));
-	    GlobalUnlock16(hText);
+        else if(!CLIPBOARD_IsPresent(CF_OEMTEXT)) rprop = None;
+	else
+	{
+            /* open to make sure that clipboard is available */
+
+	    BOOL 	couldOpen = OpenClipboard( pWnd->hwndSelf );
+	    char*	lpstr = 0;
+
+	    hText = GetClipboardData(CF_TEXT);
+	    text = GlobalLock16(hText);
+	    size = GlobalSize16(hText);
+
+	    /* remove carriage returns */
+
+	    lpstr = (char*)xmalloc(size--);
+	    for(i=0,j=0; i < size; i++ )
+	    {
+	       if( text[i] == '\r' && text[i+1] == '\n' ) continue;
+	       lpstr[j++] = text[i];
+	       if( text[i] == '\0' ) break;
+	    }
+	    lpstr[j]='\0';
+
+	    XChangeProperty(display, request, rprop, 
+			    XA_STRING, 8, PropModeReplace, 
+			    lpstr, j);
+	    free(lpstr);
+
 	    /* close only if we opened before */
-	    if(couldOpen)CloseClipboard();
+
+	    if(couldOpen) CloseClipboard();
 	}
     }
 
@@ -805,8 +863,11 @@ static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event )
 static void EVENT_SelectionNotify( XSelectionEvent *event )
 {
     if (event->selection != XA_PRIMARY) return;
+
     if (event->target != XA_STRING) CLIPBOARD_ReadSelection( 0, None );
-    CLIPBOARD_ReadSelection( event->requestor, event->property );
+    else CLIPBOARD_ReadSelection( event->requestor, event->property );
+
+    dprintf_clipboard(stddeb,"\tSelectionNotify done!\n");
 }
 
 
@@ -816,7 +877,7 @@ static void EVENT_SelectionNotify( XSelectionEvent *event )
 static void EVENT_SelectionClear( WND *pWnd, XSelectionClearEvent *event )
 {
     if (event->selection != XA_PRIMARY) return;
-    CLIPBOARD_ReleaseSelection( pWnd->hwndSelf ); 
+    CLIPBOARD_ReleaseSelection( event->window, pWnd->hwndSelf ); 
 }
 
 
@@ -857,6 +918,8 @@ static void EVENT_ClientMessage( WND *pWnd, XClientMessageEvent *event )
   }
  */ 
 
+extern void FOCUS_SetXFocus( HWND32 );
+
 /**********************************************************************
  *		EVENT_MapNotify
  */
@@ -865,18 +928,28 @@ void EVENT_MapNotify( HWND hWnd, XMapEvent *event )
     HWND32 hwndFocus = GetFocus32();
 
     if (hwndFocus && IsChild( hWnd, hwndFocus ))
-      FOCUS_SetXFocus( hwndFocus );
+      FOCUS_SetXFocus( (HWND32)hwndFocus );
 
     return;
 }
 
+
 /**********************************************************************
- *		SetCapture 	(USER.18)
+ *		SetCapture16   (USER.18)
  */
-HWND SetCapture( HWND hwnd )
+HWND16 SetCapture16( HWND16 hwnd )
+{
+    return (HWND16)SetCapture32( hwnd );
+}
+
+
+/**********************************************************************
+ *		SetCapture32   (USER32.463)
+ */
+HWND32 SetCapture32( HWND32 hwnd )
 {
     Window win;
-    HWND old_capture_wnd = captureWnd;
+    HWND32 old_capture_wnd = captureWnd;
 
     if (!hwnd)
     {
@@ -898,9 +971,9 @@ HWND SetCapture( HWND hwnd )
 
 
 /**********************************************************************
- *		ReleaseCapture	(USER.19)
+ *		ReleaseCapture   (USER.19) (USER32.438)
  */
-void ReleaseCapture()
+void ReleaseCapture(void)
 {
     if (captureWnd == 0) return;
     XUngrabPointer( display, CurrentTime );
@@ -908,10 +981,20 @@ void ReleaseCapture()
     dprintf_win(stddeb, "ReleaseCapture\n");
 }
 
+
+/**********************************************************************
+ *		GetCapture16   (USER.236)
+ */
+HWND16 GetCapture16(void)
+{
+    return (HWND16)captureWnd;
+}
+
+
 /**********************************************************************
- *		GetCapture 	(USER.236)
+ *		GetCapture32   (USER32.207)
  */
-HWND GetCapture()
+HWND32 GetCapture32(void)
 {
     return captureWnd;
 }
@@ -971,13 +1054,13 @@ void Mouse_Event( SIGCONTEXT *context )
 
 
 /**********************************************************************
- *			EnableHardwareInput 		[USER.331]
+ *			EnableHardwareInput   (USER.331)
  */
-BOOL EnableHardwareInput(BOOL bEnable)
+BOOL16 EnableHardwareInput(BOOL16 bEnable)
 {
-  BOOL bOldState = InputEnabled;
-  dprintf_event(stdnimp,"EMPTY STUB !!! EnableHardwareInput(%d);\n", bEnable);
+  BOOL16 bOldState = InputEnabled;
+  dprintf_event(stdnimp,"EnableHardwareInput(%d);\n", bEnable);
   InputEnabled = bEnable;
-  return (bOldState && !bEnable);
+  return bOldState;
 }
 
diff --git a/windows/graphics.c b/windows/graphics.c
index e64aa2f359d..aca1f6c9994 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -12,6 +12,7 @@
 #ifndef PI
 #define PI M_PI
 #endif
+#include "graphics.h"
 #include "dc.h"
 #include "bitmap.h"
 #include "callback.h"
@@ -279,6 +280,7 @@ BOOL Ellipse( HDC hdc, INT left, INT top, INT right, INT bottom )
  */
 BOOL Rectangle( HDC hdc, INT left, INT top, INT right, INT bottom )
 {
+    INT32 width;
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) 
     {
@@ -305,21 +307,24 @@ BOOL Rectangle( HDC hdc, INT left, INT top, INT right, INT bottom )
 		  dc->w.DCOrgY + bottom);
 	return TRUE;
     }
-    
+    width = dc->u.x.pen.width;
+    if (!width) width = 1;
+    if(dc->u.x.pen.style == PS_NULL) width = 0;
+
     if ((dc->u.x.pen.style == PS_INSIDEFRAME) &&
-        (dc->u.x.pen.width < right-left) &&
-        (dc->u.x.pen.width < bottom-top))
+        (width < right-left) && (width < bottom-top))
     {
-        left   += dc->u.x.pen.width / 2;
-        right  -= (dc->u.x.pen.width + 1) / 2;
-        top    += dc->u.x.pen.width / 2;
-        bottom -= (dc->u.x.pen.width + 1) / 2;
+        left   += width / 2;
+        right  -= (width + 1) / 2;
+        top    += width / 2;
+        bottom -= (width + 1) / 2;
     }
 
     if (DC_SetupGCForBrush( dc ))
 	XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + left, dc->w.DCOrgY + top,
-		        right-left, bottom-top );
+		        dc->w.DCOrgX + left + (width + 1) / 2,
+		        dc->w.DCOrgY + top + (width + 1) / 2,
+		        right-left-width-1, bottom-top-width-1);
     if (DC_SetupGCForPen( dc ))
 	XDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc,
 		        dc->w.DCOrgX + left, dc->w.DCOrgY + top,
@@ -745,8 +750,8 @@ void DrawFocusRect32( HDC32 hdc, const RECT32* rect )
  * Short-cut function to blit a bitmap into a device.
  * Faster than CreateCompatibleDC() + SelectBitmap() + BitBlt() + DeleteDC().
  */
-BOOL GRAPH_DrawBitmap( HDC hdc, HBITMAP hbitmap, int xdest, int ydest,
-		       int xsrc, int ysrc, int width, int height )
+BOOL32 GRAPH_DrawBitmap( HDC32 hdc, HBITMAP32 hbitmap, int xdest, int ydest,
+                         int xsrc, int ysrc, int width, int height )
 {
     BITMAPOBJ *bmp;
     DC *dc;
@@ -778,8 +783,8 @@ BOOL GRAPH_DrawBitmap( HDC hdc, HBITMAP hbitmap, int xdest, int ydest,
 /**********************************************************************
  *          GRAPH_DrawReliefRect  (Not a MSWin Call)
  */
-void GRAPH_DrawReliefRect( HDC hdc, RECT16 *rect, int highlight_size,
-                           int shadow_size, BOOL pressed )
+void GRAPH_DrawReliefRect( HDC32 hdc, const RECT32 *rect, INT32 highlight_size,
+                           INT32 shadow_size, BOOL32 pressed )
 {
     HBRUSH hbrushOld;
     int i;
diff --git a/windows/hook.c b/windows/hook.c
index 6f9f09a7f27..ce581078bf8 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -37,7 +37,7 @@ static HANDLE16 HOOK_GetNextHook( HANDLE16 hook )
     if (data->next) return data->next;
     if (!data->ownerQueue) return 0;  /* Already system hook */
     /* Now start enumerating the system hooks */
-    return HOOK_systemHooks[data->id - WH_FIRST_HOOK];
+    return HOOK_systemHooks[data->id - WH_MINHOOK];
 }
 
 
@@ -52,8 +52,8 @@ HANDLE16 HOOK_GetHook( INT16 id , HQUEUE16 hQueue )
     HANDLE16 hook = 0;
 
     if ((queue = (MESSAGEQUEUE *)GlobalLock16( hQueue )) != NULL)
-        hook = queue->hooks[id - WH_FIRST_HOOK];
-    if (!hook) hook = HOOK_systemHooks[id - WH_FIRST_HOOK];
+        hook = queue->hooks[id - WH_MINHOOK];
+    if (!hook) hook = HOOK_systemHooks[id - WH_MINHOOK];
     return hook;
 }
 
@@ -70,7 +70,7 @@ static HANDLE16 HOOK_SetHook( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
     HANDLE16 handle;
     HQUEUE16 hQueue = 0;
 
-    if ((id < WH_FIRST_HOOK) || (id > WH_LAST_HOOK)) return 0;
+    if ((id < WH_MINHOOK) || (id > WH_MAXHOOK)) return 0;
     if (!(hInst = GetExePtr( hInst ))) return 0;
 
     dprintf_hook( stddeb, "Setting hook %d: %08x %04x %04x\n",
@@ -83,12 +83,19 @@ static HANDLE16 HOOK_SetHook( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
         if (!(hQueue = GetTaskQueue( hTask ))) return 0;
     }
 
-    if (id == WH_CBT || id == WH_DEBUG || id == WH_SHELL)
+    if (id == WH_DEBUG)
     {
-	fprintf( stdnimp, "Unimplemented hook set: (%d,%08lx,%04x,%04x)!\n",
-                 id, (DWORD)proc, hInst, hTask );
+        fprintf( stdnimp,"WH_DEBUG is broken in 16-bit Windows.\n");
+        return 0;
+    }
+    else if (id == WH_CBT || id == WH_SHELL)
+    {
+	fprintf( stdnimp, "Half-implemented hook set: (%s,%08lx,%04x,%04x)!\n",
+                 (id==WH_CBT)?"WH_CBT":"WH_SHELL", (DWORD)proc, hInst, hTask );
     }
 
+    if (id == WH_JOURNALPLAYBACK) EnableHardwareInput(FALSE);
+     
     /* Create the hook structure */
 
     if (!(handle = USER_HEAP_ALLOC( sizeof(HOOKDATA) ))) return 0;
@@ -105,13 +112,13 @@ static HANDLE16 HOOK_SetHook( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
     if (hQueue)
     {
         MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
-        data->next = queue->hooks[id - WH_FIRST_HOOK];
-        queue->hooks[id - WH_FIRST_HOOK] = handle;
+        data->next = queue->hooks[id - WH_MINHOOK];
+        queue->hooks[id - WH_MINHOOK] = handle;
     }
     else
     {
-        data->next = HOOK_systemHooks[id - WH_FIRST_HOOK];
-        HOOK_systemHooks[id - WH_FIRST_HOOK] = handle;
+        data->next = HOOK_systemHooks[id - WH_MINHOOK];
+        HOOK_systemHooks[id - WH_MINHOOK] = handle;
     }
     return handle;
 }
@@ -138,15 +145,17 @@ static BOOL32 HOOK_RemoveHook( HANDLE16 hook )
         return TRUE;
     }
 
+    if (data->id == WH_JOURNALPLAYBACK) EnableHardwareInput(TRUE);
+     
     /* Remove it from the linked list */
 
     if (data->ownerQueue)
     {
         MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( data->ownerQueue );
         if (!queue) return FALSE;
-        prevHook = &queue->hooks[data->id - WH_FIRST_HOOK];
+        prevHook = &queue->hooks[data->id - WH_MINHOOK];
     }
-    else prevHook = &HOOK_systemHooks[data->id - WH_FIRST_HOOK];
+    else prevHook = &HOOK_systemHooks[data->id - WH_MINHOOK];
 
     while (*prevHook && *prevHook != hook)
         prevHook = &((HOOKDATA *)USER_HEAP_LIN_ADDR(*prevHook))->next;
@@ -224,9 +233,9 @@ void HOOK_FreeModuleHooks( HMODULE16 hModule )
   HHOOK         hook, next;
   int           id;
 
-  for( id = WH_FIRST_HOOK; id <= WH_LAST_HOOK; id++ )
+  for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
     {
-       hook = HOOK_systemHooks[id - WH_FIRST_HOOK];
+       hook = HOOK_systemHooks[id - WH_MINHOOK];
        while( hook )
           if( (hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
 	    {
@@ -253,7 +262,7 @@ void HOOK_FreeQueueHooks( HQUEUE16 hQueue )
   HHOOK 	hook, next;
   int 		id;
 
-  for( id = WH_FIRST_HOOK; id <= WH_LAST_HOOK; id++ )
+  for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
     {
        hook = HOOK_GetHook( id, hQueue );
        while( hook )
@@ -277,15 +286,10 @@ void HOOK_FreeQueueHooks( HQUEUE16 hQueue )
 FARPROC16 SetWindowsHook( INT16 id, HOOKPROC16 proc )
 {
     HINSTANCE16 hInst = __winelib ? 0 : FarGetOwner( HIWORD(proc) );
-    /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
-    HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
+    HTASK16 	hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
+    HANDLE16 	handle = HOOK_SetHook( id, proc, hInst, hTask );
 
-    HANDLE16 handle = HOOK_SetHook( id, proc, hInst, hTask );
-    if (!handle) return (FARPROC16)-1;
-    if (!((HOOKDATA *)USER_HEAP_LIN_ADDR( handle ))->next) return 0;
-    /* Not sure if the return value is correct; should not matter much
-     * since it's never used (see DefHookProc). -- AJ */
-    return (FARPROC16)MAKELONG( handle, HOOK_MAGIC );
+    return (handle) ? (FARPROC16)MAKELONG( handle, HOOK_MAGIC ) : NULL;
 }
 
 
@@ -343,7 +347,7 @@ HHOOK SetWindowsHookEx( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
                         HTASK16 hTask )
 {
     HANDLE16 handle = HOOK_SetHook( id, proc, hInst, hTask );
-    return MAKELONG( handle, HOOK_MAGIC );
+    return (handle) ? MAKELONG( handle, HOOK_MAGIC ) : NULL;
 }
 
 
diff --git a/windows/keyboard.c b/windows/keyboard.c
index ac6cc0f256d..ccc815be87b 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -64,7 +64,7 @@ void SetKeyboardState(BYTE *lpKeyState)
  *            GetAsyncKeyState        (USER.249)
  *
  *	Determine if a key is or was pressed.  retval has high-order 
- * byte set to 1 if currently pressed, low-order byte 1 if key has
+ * bit set to 1 if currently pressed, low-order bit set to 1 if key has
  * been pressed.
  *
  *	This uses the variable AsyncMouseButtonsStates and
@@ -92,7 +92,7 @@ int GetAsyncKeyState(int nKey)
 	break;
      default:
 	retval = AsyncKeyStateTable[nKey] | 
-	(KeyStateTable[nKey] << 8);
+	(KeyStateTable[nKey] ? 0x8000 : 0);
 	break;
     }
 
diff --git a/windows/mdi.c b/windows/mdi.c
index 19b40a63dc8..40b0d4d3508 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -406,7 +406,8 @@ void MDI_ChildGetMinMaxInfo(WND* clientWnd, HWND hwnd, MINMAXINFO16* lpMinMax )
 
  MapWindowPoints16(clientWnd->parent->hwndSelf, 
 	       ((MDICLIENTINFO*)clientWnd->wExtra)->self, (LPPOINT16)&rect, 2);
- AdjustWindowRectEx16( &rect, childWnd->dwStyle, 0, childWnd->dwExStyle );
+ AdjustWindowRectEx16( &rect, childWnd->dwStyle & ~(WS_VSCROLL | WS_HSCROLL),
+		      0, childWnd->dwExStyle );
 
  lpMinMax->ptMaxSize.x = rect.right -= rect.left;
  lpMinMax->ptMaxSize.y = rect.bottom -= rect.top;
@@ -539,6 +540,7 @@ LONG MDI_ChildActivate(WND *clientPtr, HWND hWndChild)
     /* deactivate prev. active child */
     if( wndPrev )
     {
+	wndPrev->dwStyle |= WS_SYSMENU;
 	SendMessage16( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L );
 
 #ifdef WINELIB32
@@ -869,8 +871,6 @@ BOOL MDI_AugmentFrameMenu(MDICLIENTINFO* ci, WND *frame, HWND hChild)
  EnableMenuItem(hSysPopup, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
  EnableMenuItem(hSysPopup, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED);
 
- child->dwStyle &= ~WS_SYSMENU;
-
  /* redraw menu */
  DrawMenuBar(frame->hwndSelf);
 
@@ -882,7 +882,6 @@ BOOL MDI_AugmentFrameMenu(MDICLIENTINFO* ci, WND *frame, HWND hChild)
  */
 BOOL MDI_RestoreFrameMenu( WND *frameWnd, HWND hChild)
 {
- WND*   child    = WIN_FindWndPtr(hChild);
  INT	nItems   = GetMenuItemCount(frameWnd->wIDmenu) - 1;
 
  dprintf_mdi(stddeb,"MDI_RestoreFrameMenu: for child %04x\n",hChild);
@@ -890,7 +889,6 @@ BOOL MDI_RestoreFrameMenu( WND *frameWnd, HWND hChild)
  if( GetMenuItemID(frameWnd->wIDmenu,nItems) != SC_RESTORE )
      return 0; 
 
- child->dwStyle |= WS_SYSMENU;
 
  RemoveMenu(frameWnd->wIDmenu,0,MF_BYPOSITION);
  DeleteMenu(frameWnd->wIDmenu,nItems-1,MF_BYPOSITION);
@@ -1079,7 +1077,7 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 	
       case WM_MDITILE:
 	ci->sbNeedUpdate = TRUE;
-	ShowScrollBar(hwnd,SB_BOTH,FALSE);
+	ShowScrollBar32(hwnd,SB_BOTH,FALSE);
 	MDITile(w, ci,wParam);
         ci->sbNeedUpdate = FALSE;
         return 0;
@@ -1366,10 +1364,15 @@ LRESULT DefMDIChildProc16( HWND16 hwnd, UINT16 message,
 		case SC_MOVE:
 		     if( ci->hwndChildMaximized == hwnd) return 0;
 		     break;
+	        case SC_RESTORE:
+	        case SC_MINIMIZE:
+		     WIN_FindWndPtr(hwnd)->dwStyle |= WS_SYSMENU;
+		     break;
 		case SC_MAXIMIZE:
 		     if( ci->hwndChildMaximized == hwnd) 
 			 return SendMessage16( clientWnd->parent->hwndSelf,
                                              message, wParam, lParam);
+		     WIN_FindWndPtr(hwnd)->dwStyle &= ~WS_SYSMENU;
 		     break;
 		case SC_NEXTWINDOW:
 		     SendMessage16( ci->self, WM_MDINEXT, 0, 0);
@@ -1627,15 +1630,15 @@ void CalcChildScroll( HWND hwnd, WORD scroll )
     vpos = clientRect.top - childRect.top;
 
     if( noscroll )
-	ShowScrollBar(hwnd, SB_BOTH, FALSE);
+	ShowScrollBar32(hwnd, SB_BOTH, FALSE);
     else
     switch( scroll )
       {
 	case SB_HORZ:
 			vpos = hpos; vmin = hmin; vmax = hmax;
 	case SB_VERT:
-			SetScrollPos(hwnd, scroll, vpos, FALSE);
-			SetScrollRange(hwnd, scroll, vmin, vmax, TRUE);
+			SetScrollPos32(hwnd, scroll, vpos, FALSE);
+			SetScrollRange32(hwnd, scroll, vmin, vmax, TRUE);
 			break;
 	case SB_BOTH:
 			SCROLL_SetNCSbState( Wnd, vmin, vmax, vpos,
@@ -1654,23 +1657,23 @@ void ScrollChildren(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  short 	 newPos=-1;
  short 	 curPos;
  short 	 length;
- INT16 	 minPos;
- INT16 	 maxPos;
+ INT32 	 minPos;
+ INT32 	 maxPos;
  short   shift;
 
  if( !wndPtr ) return;
 
  if( uMsg == WM_HSCROLL )
    {
-     GetScrollRange(hWnd,SB_HORZ,&minPos,&maxPos);
-     curPos = GetScrollPos(hWnd,SB_HORZ);
+     GetScrollRange32(hWnd,SB_HORZ,&minPos,&maxPos);
+     curPos = GetScrollPos32(hWnd,SB_HORZ);
      length = (wndPtr->rectClient.right - wndPtr->rectClient.left)/2;
      shift = SYSMETRICS_CYHSCROLL;
    }
  else if( uMsg == WM_VSCROLL )
 	{
-	  GetScrollRange(hWnd,SB_VERT,&minPos,&maxPos);
-	  curPos = GetScrollPos(hWnd,SB_VERT);
+	  GetScrollRange32(hWnd,SB_VERT,&minPos,&maxPos);
+	  curPos = GetScrollPos32(hWnd,SB_VERT);
 	  length = (wndPtr->rectClient.bottom - wndPtr->rectClient.top)/2;
 	  shift = SYSMETRICS_CXVSCROLL;
 	}
@@ -1714,7 +1717,7 @@ void ScrollChildren(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  else if( newPos < minPos )
 	  newPos = minPos;
 
- SetScrollPos(hWnd, (uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ , newPos, TRUE);
+ SetScrollPos32(hWnd, (uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ , newPos, TRUE);
 
  if( uMsg == WM_VSCROLL )
      ScrollWindow(hWnd ,0 ,curPos - newPos, NULL, NULL);
diff --git a/windows/message.c b/windows/message.c
index 5dd9faec121..2f9cae14339 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -34,15 +34,21 @@
 
 #define ASCII_CHAR_HACK 0x0800 
 
+typedef enum { SYSQ_MSG_ABANDON, SYSQ_MSG_SKIP, SYSQ_MSG_ACCEPT } SYSQ_STATUS;
+
 extern WPARAM	lastEventChar;				 /* event.c */
 extern BOOL MouseButtonsStates[3];
 extern BOOL AsyncMouseButtonsStates[3];
 extern BYTE KeyStateTable[256];
 extern BYTE AsyncKeyStateTable[256];
 
+extern MESSAGEQUEUE *pCursorQueue;			 /* queue.c */
+extern MESSAGEQUEUE *pActiveQueue;
+
 DWORD MSG_WineStartTicks; /* Ticks at Wine startup */
 
 static WORD doubleClickSpeed = 452;
+static INT32 debugSMRL = 0;       /* intertask SendMessage() recursion level */
 
 /***********************************************************************
  *           MSG_TranslateMouseMsg
@@ -59,7 +65,7 @@ static WORD doubleClickSpeed = 452;
  *   the coordinates to client coordinates.
  * - Send the WM_SETCURSOR message.
  */
-static BOOL MSG_TranslateMouseMsg( MSG16 *msg, BOOL remove )
+static SYSQ_STATUS MSG_TranslateMouseMsg( MSG16 *msg, BOOL remove )
 {
     WND *pWnd;
     BOOL eatMsg = FALSE;
@@ -70,6 +76,7 @@ static BOOL MSG_TranslateMouseMsg( MSG16 *msg, BOOL remove )
     static WORD  lastClickMsg = 0;
     static POINT16 lastClickPos = { 0, 0 };
     POINT16 pt = msg->pt;
+    MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16(GetTaskQueue(0));
 
     BOOL mouseClick = ((msg->message == WM_LBUTTONDOWN) ||
 		       (msg->message == WM_RBUTTONDOWN) ||
@@ -77,7 +84,7 @@ static BOOL MSG_TranslateMouseMsg( MSG16 *msg, BOOL remove )
 
       /* Find the window */
 
-    if ((msg->hwnd = GetCapture()) != 0)
+    if ((msg->hwnd = GetCapture16()) != 0)
     {
         BOOL32 ret;
 
@@ -87,7 +94,7 @@ static BOOL MSG_TranslateMouseMsg( MSG16 *msg, BOOL remove )
 
         if (!HOOK_GetHook( WH_MOUSE, GetTaskQueue(0)) ||
             !(hook = SEGPTR_NEW(MOUSEHOOKSTRUCT16)))
-            return TRUE;
+            return SYSQ_MSG_ACCEPT;
         hook->pt           = msg->pt;
         hook->hwnd         = msg->hwnd;
         hook->wHitTestCode = HTCLIENT;
@@ -95,21 +102,22 @@ static BOOL MSG_TranslateMouseMsg( MSG16 *msg, BOOL remove )
         ret = !HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
                                msg->message, (LPARAM)SEGPTR_GET(hook));
         SEGPTR_FREE(hook);
-        return ret;
+        return ret ? SYSQ_MSG_ACCEPT : SYSQ_MSG_SKIP ;
     }
    
     hittest = WINPOS_WindowFromPoint( msg->pt, &pWnd );
     if (pWnd->hmemTaskQ != GetTaskQueue(0))
     {
         /* Not for the current task */
-        MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) );
         if (queue) QUEUE_ClearWakeBit( queue, QS_MOUSE );
         /* Wake up the other task */
         queue = (MESSAGEQUEUE *)GlobalLock16( pWnd->hmemTaskQ );
         if (queue) QUEUE_SetWakeBit( queue, QS_MOUSE );
-        return FALSE;
+        return SYSQ_MSG_ABANDON;
     }
-    msg->hwnd = pWnd->hwndSelf;
+    pCursorQueue = queue;
+    msg->hwnd    = pWnd->hwndSelf;
+
     if ((hittest != HTERROR) && mouseClick)
     {
         HWND hwndTop = WIN_GetTopParent( msg->hwnd );
@@ -121,7 +129,8 @@ static BOOL MSG_TranslateMouseMsg( MSG16 *msg, BOOL remove )
 
         /* Activate the window if needed */
 
-        if (msg->hwnd != GetActiveWindow() && msg->hwnd != GetDesktopWindow())
+        if (msg->hwnd != GetActiveWindow() &&
+            msg->hwnd != GetDesktopWindow16())
         {
             LONG ret = SendMessage16( msg->hwnd, WM_MOUSEACTIVATE, hwndTop,
                                     MAKELONG( hittest, msg->message ) );
@@ -139,7 +148,7 @@ static BOOL MSG_TranslateMouseMsg( MSG16 *msg, BOOL remove )
 
     SendMessage16( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd,
                    MAKELONG( hittest, msg->message ));
-    if (eatMsg) return FALSE;
+    if (eatMsg) return SYSQ_MSG_SKIP;
 
       /* Check for double-click */
 
@@ -189,7 +198,7 @@ static BOOL MSG_TranslateMouseMsg( MSG16 *msg, BOOL remove )
 
     if (!HOOK_GetHook( WH_MOUSE, GetTaskQueue(0)) ||
         !(hook = SEGPTR_NEW(MOUSEHOOKSTRUCT16)))
-        return TRUE;
+        return SYSQ_MSG_ACCEPT;
 
     hook->pt           = msg->pt;
     hook->hwnd         = msg->hwnd;
@@ -198,7 +207,7 @@ static BOOL MSG_TranslateMouseMsg( MSG16 *msg, BOOL remove )
     ret = !HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
                            msg->message, (LPARAM)SEGPTR_GET(hook) );
     SEGPTR_FREE(hook);
-    return ret;
+    return ret ? SYSQ_MSG_ACCEPT : SYSQ_MSG_SKIP;
 }
 
 
@@ -209,7 +218,7 @@ static BOOL MSG_TranslateMouseMsg( MSG16 *msg, BOOL remove )
  * Return value indicates whether the translated message must be passed
  * to the user.
  */
-static BOOL MSG_TranslateKeyboardMsg( MSG16 *msg, BOOL remove )
+static SYSQ_STATUS MSG_TranslateKeyboardMsg( MSG16 *msg, BOOL remove )
 {
     WND *pWnd;
 
@@ -235,12 +244,14 @@ static BOOL MSG_TranslateKeyboardMsg( MSG16 *msg, BOOL remove )
         /* Wake up the other task */
         queue = (MESSAGEQUEUE *)GlobalLock16( pWnd->hmemTaskQ );
         if (queue) QUEUE_SetWakeBit( queue, QS_KEY );
-        return FALSE;
+        return SYSQ_MSG_ABANDON;
     }
-    return !HOOK_CallHooks( WH_KEYBOARD, remove ? HC_ACTION : HC_NOREMOVE,
-                            msg->wParam, msg->lParam );
+    return (HOOK_CallHooks( WH_KEYBOARD, remove ? HC_ACTION : HC_NOREMOVE,
+                            msg->wParam, msg->lParam ))
+            ? SYSQ_MSG_SKIP : SYSQ_MSG_ACCEPT;
 }
 
+
 /***********************************************************************
  *           MSG_JournalRecordMsg
  *
@@ -392,26 +403,30 @@ static int MSG_JournalPlayBackMsg(void)
 static BOOL MSG_PeekHardwareMsg( MSG16 *msg, HWND hwnd, WORD first, WORD last,
                                  BOOL remove )
 {
+    SYSQ_STATUS status;
     MESSAGEQUEUE *sysMsgQueue = QUEUE_GetSysQueue();
     int i, pos = sysMsgQueue->nextMessage;
 
     /* If the queue is empty, attempt to fill it */
-    if (!sysMsgQueue->msgCount && XPending(display)) EVENT_WaitXEvent( FALSE );
+    if (!sysMsgQueue->msgCount && XPending(display))
+        EVENT_WaitXEvent( FALSE, FALSE );
 
     for (i = 0; i < sysMsgQueue->msgCount; i++, pos++)
     {
         if (pos >= sysMsgQueue->queueSize) pos = 0;
 	*msg = sysMsgQueue->messages[pos].msg;
 
-          /* Translate message */
+          /* Translate message; return FALSE immediately on SYSQ_MSG_ABANDON */
 
         if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
         {
-            if (!MSG_TranslateMouseMsg( msg, remove )) continue;
+            if ((status = MSG_TranslateMouseMsg(msg,remove)) == SYSQ_MSG_ABANDON)
+                return FALSE;
         }
         else if ((msg->message >= WM_KEYFIRST) && (msg->message <= WM_KEYLAST))
         {
-            if (!MSG_TranslateKeyboardMsg( msg, remove )) continue;
+            if ((status = MSG_TranslateKeyboardMsg(msg,remove)) == SYSQ_MSG_ABANDON)
+                return FALSE;
         }
         else  /* Non-standard hardware event */
         {
@@ -427,21 +442,28 @@ static BOOL MSG_PeekHardwareMsg( MSG16 *msg, HWND hwnd, WORD first, WORD last,
                                       remove ? HC_ACTION : HC_NOREMOVE,
                                       0, (LPARAM)SEGPTR_GET(hook) );
                 SEGPTR_FREE(hook);
-                if (ret) continue;
+                status = ret ? SYSQ_MSG_SKIP : SYSQ_MSG_ACCEPT;
             }
         }
 
+        if (status == SYSQ_MSG_SKIP)
+        {
+            if (remove) QUEUE_RemoveMsg( sysMsgQueue, pos );
+            /* FIXME: call CBT_CLICKSKIPPED from here */
+            continue;
+        }
+
           /* Check message against filters */
 
         if (hwnd && (msg->hwnd != hwnd)) continue;
         if ((first || last) && 
             ((msg->message < first) || (msg->message > last))) continue;
-        if ((msg->hwnd != GetDesktopWindow()) && 
-            (GetWindowTask16(msg->hwnd) != GetCurrentTask()))
-            continue;  /* Not for this task */
-        if (remove && HOOK_GetHook( WH_JOURNALRECORD, GetTaskQueue(0) ))
-            MSG_JournalRecordMsg( msg );
-        if (remove) QUEUE_RemoveMsg( sysMsgQueue, pos );
+        if (remove)
+        {
+            if (HOOK_GetHook( WH_JOURNALRECORD, GetTaskQueue(0) ))
+                MSG_JournalRecordMsg( msg );
+            QUEUE_RemoveMsg( sysMsgQueue, pos );
+        }
         return TRUE;
     }
     return FALSE;
@@ -474,43 +496,71 @@ WORD GetDoubleClickTime()
 static LRESULT MSG_SendMessage( HQUEUE16 hDestQueue, HWND hwnd, UINT msg,
                                 WPARAM wParam, LPARAM lParam )
 {
+    INT32	  prevSMRL = debugSMRL;
+    QSMCTRL 	  qCtrl = { 0, 1};
     MESSAGEQUEUE *queue, *destQ;
 
     if (!(queue = (MESSAGEQUEUE*)GlobalLock16( GetTaskQueue(0) ))) return 0;
     if (!(destQ = (MESSAGEQUEUE*)GlobalLock16( hDestQueue ))) return 0;
 
-    if (IsTaskLocked())
-    {
-        fprintf( stderr, "SendMessage: task is locked\n" );
-        return 0;
-    }
+    if (IsTaskLocked() || !IsWindow(hwnd)) return 0;
+
+    debugSMRL+=4;
+    dprintf_sendmsg(stddeb,"%*sSM: %s [%04x] (%04x -> %04x)\n", 
+		    prevSMRL, "", SPY_GetMsgName(msg), msg, queue->self, hDestQueue );
 
-    if (queue->hWnd)
+    if( !(queue->wakeBits & QS_SMPARAMSFREE) )
     {
-        fprintf( stderr, "Nested SendMessage(), msg %04x skipped\n", msg );
-        return 0;
+      dprintf_sendmsg(stddeb,"\tIntertask SendMessage: sleeping since unreplied SendMessage pending\n");
+      queue->changeBits &= ~QS_SMPARAMSFREE;
+      QUEUE_WaitBits( QS_SMPARAMSFREE );
     }
+
+    /* resume sending */ 
+
     queue->hWnd   = hwnd;
     queue->msg    = msg;
     queue->wParam = wParam;
     queue->lParam = lParam;
     queue->hPrevSendingTask = destQ->hSendingTask;
     destQ->hSendingTask = GetTaskQueue(0);
-    QUEUE_SetWakeBit( destQ, QS_SENDMESSAGE );
 
-    /* Wait for the result */
+    queue->wakeBits &= ~QS_SMPARAMSFREE;
+
+    dprintf_sendmsg(stddeb,"%*ssm: smResultInit = %08x\n", prevSMRL, "", (unsigned)&qCtrl);
+
+    queue->smResultInit = &qCtrl;
+
+    QUEUE_SetWakeBit( destQ, QS_SENDMESSAGE );
 
-    printf( "SendMessage %04x to %04x\n", msg, hDestQueue );
+    /* perform task switch and wait for the result */
 
-    if (!(queue->wakeBits & QS_SMRESULT))
+    while( qCtrl.bPending )
     {
+      if (!(queue->wakeBits & QS_SMRESULT))
+      {
+        queue->changeBits &= ~QS_SMRESULT;
         DirectedYield( destQ->hTask );
         QUEUE_WaitBits( QS_SMRESULT );
+	dprintf_sendmsg(stddeb,"\tsm: have result!\n");
+      }
+      /* got something */
+
+      dprintf_sendmsg(stddeb,"%*ssm: smResult = %08x\n", prevSMRL, "", (unsigned)queue->smResult );
+
+      queue->smResult->lResult = queue->SendMessageReturn;
+      queue->smResult->bPending = FALSE;
+      queue->wakeBits &= ~QS_SMRESULT;
+
+      if( queue->smResult != &qCtrl )
+	  dprintf_msg(stddeb,"%*ssm: weird scenes inside the goldmine!\n", prevSMRL, "");
     }
-    printf( "SendMessage %04x to %04x: got %08lx\n",
-            msg, hDestQueue, queue->SendMessageReturn );
-    queue->wakeBits &= ~QS_SMRESULT;
-    return queue->SendMessageReturn;
+    queue->smResultInit = NULL;
+    
+    dprintf_sendmsg(stddeb,"%*sSM: [%04x] returning %08lx\n", prevSMRL, "", msg, qCtrl.lResult);
+    debugSMRL-=4;
+
+    return qCtrl.lResult;
 }
 
 
@@ -522,19 +572,33 @@ void ReplyMessage( LRESULT result )
     MESSAGEQUEUE *senderQ;
     MESSAGEQUEUE *queue;
 
-    printf( "ReplyMessage\n " );
     if (!(queue = (MESSAGEQUEUE*)GlobalLock16( GetTaskQueue(0) ))) return;
-    if (!(senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->InSendMessageHandle)))
-        return;
-    for (;;)
+
+    dprintf_msg(stddeb,"ReplyMessage, queue %04x\n", queue->self);
+
+    while( (senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->InSendMessageHandle)))
     {
-        if (queue->wakeBits & QS_SENDMESSAGE) QUEUE_ReceiveMessage( queue );
-        else if (senderQ->wakeBits & QS_SMRESULT) Yield();
-        else break;
-    }
-    printf( "ReplyMessage: res = %08lx\n", result );
+      dprintf_msg(stddeb,"\trpm: replying to %04x (%04x -> %04x)\n",
+                          queue->msg, queue->self, senderQ->self);
+
+      if( queue->wakeBits & QS_SENDMESSAGE )
+      {
+	QUEUE_ReceiveMessage( queue );
+	continue; /* ReceiveMessage() already called us */
+      }
+
+      if(!(senderQ->wakeBits & QS_SMRESULT) ) break;
+      OldYield();
+    } 
+    if( !senderQ ) { dprintf_msg(stddeb,"\trpm: done\n"); return; }
+
     senderQ->SendMessageReturn = result;
+    dprintf_msg(stddeb,"\trpm: smResult = %08x, result = %08lx\n", 
+			(unsigned)queue->smResultCurrent, result );
+
+    senderQ->smResult = queue->smResultCurrent;
     queue->InSendMessageHandle = 0;
+
     QUEUE_SetWakeBit( senderQ, QS_SMRESULT );
     DirectedYield( queue->hSendingTask );
 }
@@ -582,6 +646,23 @@ static BOOL MSG_PeekMessage( LPMSG16 msg, HWND hwnd, WORD first, WORD last,
 
 	if (msgQueue->wakeBits & QS_SENDMESSAGE)
             QUEUE_ReceiveMessage( msgQueue );
+
+        /* Now handle a WM_QUIT message 
+	 *
+	 * FIXME: PostQuitMessage() should post WM_QUIT and 
+	 *	  set QS_POSTMESSAGE wakebit instead of this.
+	 */
+
+        if (msgQueue->wPostQMsg &&
+	   (!first || WM_QUIT >= first) && 
+	   (!last || WM_QUIT <= last) )
+        {
+            msg->hwnd    = hwnd;
+            msg->message = WM_QUIT;
+            msg->wParam  = msgQueue->wExitCode;
+            msg->lParam  = 0;
+            break;
+        }
     
         /* Now find a normal message */
 
@@ -612,17 +693,6 @@ static BOOL MSG_PeekMessage( LPMSG16 msg, HWND hwnd, WORD first, WORD last,
             break;
         }
 
-        /* Now handle a WM_QUIT message */
-
-	if (msgQueue->wPostQMsg)
-	{
-	    msg->hwnd    = hwnd;
-	    msg->message = WM_QUIT;
-	    msg->wParam  = msgQueue->wExitCode;
-	    msg->lParam  = 0;
-	    break;
-	}
-
         /* Check again for SendMessage */
 
  	if (msgQueue->wakeBits & QS_SENDMESSAGE)
diff --git a/windows/msgbox.c b/windows/msgbox.c
index f019d41958b..693ccbaf56d 100644
--- a/windows/msgbox.c
+++ b/windows/msgbox.c
@@ -23,7 +23,7 @@ LRESULT SystemMessageBoxProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
   LPMSGBOX lpmb;
   RECT16 rect, textrect;
   HWND hItem;
-  HDC hdc;
+  HDC32 hdc;
   LONG lRet;
   int i, buttons, bwidth, bheight, theight, wwidth, bpos;
   int borheight, iheight, tiheight;
@@ -111,12 +111,12 @@ LRESULT SystemMessageBoxProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
     MapWindowPoints16(0, hwnd, (LPPOINT16)&textrect, 2);
     
     GetClientRect16(hItem, &rect);
-    hdc = GetDC(hItem);
+    hdc = GetDC32(hItem);
     lRet = DrawText16( hdc, lpmb->text, -1, &rect,
                        DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK | DT_CALCRECT);
     theight = rect.bottom  - rect.top;
     tiheight = 16 + MAX(iheight, theight);
-    ReleaseDC(hItem, hdc);
+    ReleaseDC32(hItem, hdc);
     
     /* Position the text */
     SetWindowPos(hItem, 0, textrect.left, (tiheight - theight) / 2, 
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 64de6c06ac6..fe3148d6429 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -15,6 +15,7 @@
 #include "syscolor.h"
 #include "menu.h"
 #include "winpos.h"
+#include "hook.h"
 #include "scroll.h"
 #include "nonclient.h"
 #include "graphics.h"
@@ -63,8 +64,6 @@ static HBITMAP hbitmapRestoreD = 0;
  */
 static void NC_AdjustRect(LPRECT16 rect, DWORD style, BOOL menu, DWORD exStyle)
 {
-    if (style & WS_ICONIC) return;  /* Nothing to change for an icon */
-
     /* Decide if the window will be managed (see CreateWindowEx) */
     if (!(Options.managed && !(style & WS_CHILD) &&
           ((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
@@ -233,6 +232,10 @@ void NC_GetMinMaxInfo( HWND hwnd, POINT16 *maxSize, POINT16 *maxPos,
 LONG NC_HandleNCCalcSize( WND *pWnd, RECT16 *winRect )
 {
     RECT16 tmpRect = { 0, 0, 0, 0 };
+    LONG result = 0;
+
+    if (pWnd->class->style & CS_VREDRAW) result |= WVR_VREDRAW;
+    if (pWnd->class->style & CS_HREDRAW) result |= WVR_HREDRAW;
 
     if( !( pWnd->dwStyle & WS_MINIMIZE ) )
     {
@@ -249,7 +252,7 @@ LONG NC_HandleNCCalcSize( WND *pWnd, RECT16 *winRect )
                                               -tmpRect.left, -tmpRect.top ) + 1;
       }
     }
-    return 0;
+    return result;
 }
 
 
@@ -668,7 +671,7 @@ static void NC_DrawCaption( HDC hdc, RECT16 *rect, HWND hwnd,
  */
 void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint )
 {
-    HDC 	hdc;
+    HDC32 hdc;
     RECT16 rect;
     BOOL	active;
 
@@ -681,7 +684,7 @@ void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint )
 
     dprintf_nonclient(stddeb, "NC_DoNCPaint: %04x %d\n", hwnd, active );
 
-    if (!(hdc = GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return;
+    if (!(hdc = GetDCEx32( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return;
 
     if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
 		        wndPtr->rectClient.top-wndPtr->rectWindow.top,
@@ -689,7 +692,7 @@ void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint )
 		        wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
 	== NULLREGION)
     {
-	ReleaseDC( hwnd, hdc );
+	ReleaseDC32( hwnd, hdc );
 	return;
     }
 
@@ -735,8 +738,10 @@ void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint )
 
       /* Draw the scroll-bars */
 
-    if (wndPtr->dwStyle & WS_VSCROLL) SCROLL_DrawScrollBar(hwnd, hdc, SB_VERT);
-    if (wndPtr->dwStyle & WS_HSCROLL) SCROLL_DrawScrollBar(hwnd, hdc, SB_HORZ);
+    if (wndPtr->dwStyle & WS_VSCROLL)
+        SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE );
+    if (wndPtr->dwStyle & WS_HSCROLL)
+        SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE );
 
       /* Draw the "size-box" */
 
@@ -748,7 +753,7 @@ void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint )
         FillRect16( hdc, &r, sysColorObjects.hbrushScrollbar );
     }    
 
-    ReleaseDC( hwnd, hdc );
+    ReleaseDC32( hwnd, hdc );
 }
 
 
@@ -870,7 +875,8 @@ static void NC_TrackSysMenu( HWND hwnd, HDC hdc, POINT16 pt )
     RECT16 rect;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     int iconic = wndPtr->dwStyle & WS_MINIMIZE;
-
+    HMENU hmenu;
+    
     if (!(wndPtr->dwStyle & WS_SYSMENU)) return;
 
     /* If window has a menu, track the menu bar normally if it not minimized */
@@ -881,7 +887,10 @@ static void NC_TrackSysMenu( HWND hwnd, HDC hdc, POINT16 pt )
 
 	NC_GetSysPopupPos( wndPtr, &rect );
 	if (!iconic) NC_DrawSysButton( hwnd, hdc, TRUE );
-	TrackPopupMenu16( GetSystemMenu(hwnd, 0), TPM_LEFTALIGN | TPM_LEFTBUTTON,
+	hmenu = GetSystemMenu(hwnd, 0);
+	MENU_InitSysMenuPopup(hmenu, wndPtr->dwStyle,
+				    wndPtr->class->style);
+	TrackPopupMenu16( hmenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
                           rect.left, rect.bottom, 0, hwnd, &rect );
 	if (!iconic) NC_DrawSysButton( hwnd, hdc, FALSE );
     }
@@ -920,7 +929,7 @@ static LONG NC_StartSizeMove( HWND hwnd, WPARAM wParam, POINT16 *capturePoint )
     }
     else  /* SC_SIZE */
     {
-	SetCapture(hwnd);
+	SetCapture32(hwnd);
 	while(!hittest)
 	{
             MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
@@ -982,7 +991,7 @@ static void NC_DoSizeMove( HWND hwnd, WORD wParam, POINT16 pt )
     MSG16 msg;
     LONG hittest;
     RECT16 sizingRect, mouseRect;
-    HDC hdc;
+    HDC32 hdc;
     BOOL thickframe;
     POINT16 minTrack, maxTrack, capturePoint = pt;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
@@ -1005,7 +1014,7 @@ static void NC_DoSizeMove( HWND hwnd, WORD wParam, POINT16 pt )
 	if (hittest) hittest += HTLEFT-1;
 	else
 	{
-	    SetCapture(hwnd);
+	    SetCapture32(hwnd);
 	    hittest = NC_StartSizeMove( hwnd, wParam, &capturePoint );
 	    if (!hittest)
 	    {
@@ -1044,16 +1053,16 @@ static void NC_DoSizeMove( HWND hwnd, WORD wParam, POINT16 pt )
     }
     SendMessage16( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
 
-    if (GetCapture() != hwnd) SetCapture( hwnd );    
+    if (GetCapture32() != hwnd) SetCapture32( hwnd );    
 
     if (wndPtr->dwStyle & WS_CHILD)
     {
           /* Retrieve a default cache DC (without using the window style) */
-        hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
+        hdc = GetDCEx32( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
     }
     else
     {  /* Grab the server only when moving top-level windows without desktop */
-	hdc = GetDC( 0 );
+	hdc = GetDC32( 0 );
 	if (rootWindow == DefaultRootWindow(display)) XGrabServer( display );
     }
     NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
@@ -1116,12 +1125,28 @@ static void NC_DoSizeMove( HWND hwnd, WORD wParam, POINT16 pt )
     NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
     ReleaseCapture();
 
-    if (wndPtr->dwStyle & WS_CHILD) ReleaseDC( wndPtr->parent->hwndSelf, hdc );
+    if (wndPtr->dwStyle & WS_CHILD)
+        ReleaseDC32( wndPtr->parent->hwndSelf, hdc );
     else
     {
-	ReleaseDC( 0, hdc );
+	ReleaseDC32( 0, hdc );
 	if (rootWindow == DefaultRootWindow(display)) XUngrabServer( display );
     }
+
+    if (HOOK_GetHook( WH_CBT, GetTaskQueue(0) ))
+    {
+       RECT16* pr = SEGPTR_NEW(RECT16);
+       if( pr )
+       {
+	 *pr = sizingRect;
+	  if( HOOK_CallHooks( WH_CBT, HCBT_MOVESIZE, hwnd,
+			             (LPARAM)SEGPTR_GET(pr)) )
+	      sizingRect = wndPtr->rectWindow;
+	  else
+	      sizingRect = *pr;
+	  SEGPTR_FREE(pr);
+       }
+    }
     SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
     SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L);
 
@@ -1154,10 +1179,10 @@ static void NC_DoSizeMove( HWND hwnd, WORD wParam, POINT16 pt )
 static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
 {
     MSG16 msg;
-    HDC hdc = GetWindowDC( hwnd );
+    HDC32 hdc = GetWindowDC32( hwnd );
     BOOL pressed = TRUE;
 
-    SetCapture( hwnd );
+    SetCapture32( hwnd );
     if (wParam == HTMINBUTTON) NC_DrawMinButton( hwnd, hdc, TRUE );
     else NC_DrawMaxButton( hwnd, hdc, TRUE );
 
@@ -1178,7 +1203,7 @@ static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
     else NC_DrawMaxButton( hwnd, hdc, FALSE );
 
     ReleaseCapture();
-    ReleaseDC( hwnd, hdc );
+    ReleaseDC32( hwnd, hdc );
     if (!pressed) return;
 
     if (wParam == HTMINBUTTON) 
@@ -1194,10 +1219,10 @@ static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
  *
  * Track a mouse button press on the horizontal or vertical scroll-bar.
  */
-static void NC_TrackScrollBar( HWND hwnd, WORD wParam, POINT16 pt )
+static void NC_TrackScrollBar( HWND32 hwnd, WPARAM32 wParam, POINT32 pt )
 {
     MSG16 *msg;
-    WORD scrollbar;
+    INT32 scrollbar;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
     if ((wParam & 0xfff0) == SC_HSCROLL)
@@ -1214,7 +1239,7 @@ static void NC_TrackScrollBar( HWND hwnd, WORD wParam, POINT16 pt )
     if (!(msg = SEGPTR_NEW(MSG16))) return;
     pt.x -= wndPtr->rectWindow.left;
     pt.y -= wndPtr->rectWindow.top;
-    SetCapture( hwnd );
+    SetCapture32( hwnd );
     SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
 
     do
@@ -1252,7 +1277,7 @@ static void NC_TrackScrollBar( HWND hwnd, WORD wParam, POINT16 pt )
  */
 LONG NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam )
 {
-    HDC hdc = GetWindowDC( hwnd );
+    HDC32 hdc;
 
     switch(wParam)  /* Hit test */
     {
@@ -1261,7 +1286,9 @@ LONG NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam )
 	break;
 
     case HTSYSMENU:
+        hdc = GetWindowDC32( hwnd );
 	NC_TrackSysMenu( hwnd, hdc, MAKEPOINT16(lParam) );
+        ReleaseDC32( hwnd, hdc );
 	break;
 
     case HTMENU:
@@ -1295,8 +1322,6 @@ LONG NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam )
     case HTBORDER:
 	break;
     }
-
-    ReleaseDC( hwnd, hdc );
     return 0;
 }
 
@@ -1345,6 +1370,7 @@ LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM wParam, LPARAM lParam )
 LONG NC_HandleSysCommand( HWND hwnd, WPARAM wParam, POINT16 pt )
 {
     WND *wndPtr = WIN_FindWndPtr( hwnd );
+    POINT32 pt32;
 
     dprintf_nonclient(stddeb, "Handling WM_SYSCOMMAND %x %d,%d\n", 
 		      wParam, pt.x, pt.y );
@@ -1380,7 +1406,8 @@ LONG NC_HandleSysCommand( HWND hwnd, WPARAM wParam, POINT16 pt )
 
     case SC_VSCROLL:
     case SC_HSCROLL:
-	NC_TrackScrollBar( hwnd, wParam, pt );
+        CONV_POINT16TO32( &pt, &pt32 );
+	NC_TrackScrollBar( hwnd, wParam, pt32 );
 	break;
 
     case SC_MOUSEMENU:
diff --git a/windows/painting.c b/windows/painting.c
index c1b3d095032..76c5a738615 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -114,8 +114,8 @@ HDC16 BeginPaint16( HWND16 hwnd, LPPAINTSTRUCT16 lps )
      * (because rectClient == rectWindow for WS_MINIMIZE windows).
      */
 
-    lps->hdc = GetDCEx( hwnd, hrgnUpdate, DCX_INTERSECTRGN | DCX_WINDOWPAINT |
-                        DCX_USESTYLE | (bIcon ? DCX_WINDOW : 0) );
+    lps->hdc = GetDCEx16(hwnd, hrgnUpdate, DCX_INTERSECTRGN | DCX_WINDOWPAINT |
+                         DCX_USESTYLE | (bIcon ? DCX_WINDOW : 0) );
 
     dprintf_win(stddeb,"hdc = %04x\n", lps->hdc);
 
@@ -166,7 +166,7 @@ HDC32 BeginPaint32( HWND32 hwnd, PAINTSTRUCT32 *lps )
  */
 BOOL16 EndPaint16( HWND16 hwnd, const PAINTSTRUCT16* lps )
 {
-    ReleaseDC( hwnd, lps->hdc );
+    ReleaseDC16( hwnd, lps->hdc );
     ShowCaret( hwnd );
     return TRUE;
 }
@@ -177,7 +177,7 @@ BOOL16 EndPaint16( HWND16 hwnd, const PAINTSTRUCT16* lps )
  */
 BOOL32 EndPaint32( HWND32 hwnd, const PAINTSTRUCT32 *lps )
 {
-    ReleaseDC( hwnd, (HDC16)lps->hdc );
+    ReleaseDC32( hwnd, lps->hdc );
     ShowCaret( hwnd );
     return TRUE;
 }
@@ -245,7 +245,7 @@ BOOL32 PAINT_RedrawWindow( HWND32 hwnd, const RECT32 *rectUpdate,
     RECT32 rectClient;
     WND* wndPtr;
 
-    if (!hwnd) hwnd = GetDesktopWindow();
+    if (!hwnd) hwnd = GetDesktopWindow32();
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
     if (!IsWindowVisible(hwnd) || (wndPtr->flags & WIN_NO_REDRAW))
         return TRUE;  /* No redraw needed */
@@ -262,7 +262,14 @@ BOOL32 PAINT_RedrawWindow( HWND32 hwnd, const RECT32 *rectUpdate,
         dprintf_win(stddeb, "RedrawWindow: %04x NULL %04x flags=%04x\n",
                      hwnd, hrgnUpdate, flags);
     }
-    GetClientRect32( hwnd, &rectClient );
+
+    if (wndPtr->class->style & CS_PARENTDC)
+    {
+        GetClientRect32( wndPtr->parent->hwndSelf, &rectClient );
+        OffsetRect32( &rectClient, -wndPtr->rectClient.left,
+                      -wndPtr->rectClient.top );
+    }
+    else GetClientRect32( hwnd, &rectClient );
 
     if (flags & RDW_INVALIDATE)  /* Invalidate */
     {
@@ -364,17 +371,17 @@ BOOL32 PAINT_RedrawWindow( HWND32 hwnd, const RECT32 *rectUpdate,
 
         if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
         {
-            HDC hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate,
-                               DCX_INTERSECTRGN | DCX_USESTYLE |
-                               DCX_KEEPCLIPRGN | DCX_WINDOWPAINT |
-                               (bIcon ? DCX_WINDOW : 0) );
+            HDC32 hdc = GetDCEx32( hwnd, wndPtr->hrgnUpdate,
+                                   DCX_INTERSECTRGN | DCX_USESTYLE |
+                                   DCX_KEEPCLIPRGN | DCX_WINDOWPAINT |
+                                   (bIcon ? DCX_WINDOW : 0) );
             if (hdc)
             {
                if (SendMessage16( hwnd, (bIcon) ? WM_ICONERASEBKGND
 						: WM_ERASEBKGND,
                                   (WPARAM)hdc, 0 ))
                   wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
-               ReleaseDC( hwnd, hdc );
+               ReleaseDC32( hwnd, hdc );
             }
         }
     }
@@ -400,18 +407,29 @@ BOOL32 PAINT_RedrawWindow( HWND32 hwnd, const RECT32 *rectUpdate,
            for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
 	     if( wndPtr->dwStyle & WS_VISIBLE )
 	       {
-                 SetRectRgn( hrgn, wndPtr->rectWindow.left, wndPtr->rectWindow.top,
-                                   wndPtr->rectWindow.right, wndPtr->rectWindow.bottom);
-                 if( CombineRgn( hrgn, hrgn, hrgnUpdate, RGN_AND ) != NULLREGION )
-                 {
-		   if( control & RDW_C_USEHRGN &&
-		       wndPtr->dwStyle & WS_CLIPSIBLINGS ) 
-		       CombineRgn( hrgnUpdate, hrgnUpdate, hrgn, RGN_DIFF );
+                   if (wndPtr->class->style & CS_PARENTDC)
+                   {
+                       if (!CombineRgn( hrgn, hrgnUpdate, 0, RGN_COPY ))
+                           continue;
+                   }
+                   else
+                   {
+                       SetRectRgn( hrgn, wndPtr->rectWindow.left,
+                                   wndPtr->rectWindow.top,
+                                   wndPtr->rectWindow.right,
+                                   wndPtr->rectWindow.bottom);
+                       if (!CombineRgn( hrgn, hrgn, hrgnUpdate, RGN_AND ))
+                           continue;
+                   }
+#if 0
+                   if( control & RDW_C_USEHRGN &&
+                       wndPtr->dwStyle & WS_CLIPSIBLINGS ) 
+                       CombineRgn( hrgnUpdate, hrgnUpdate, hrgn, RGN_DIFF );
+#endif
 
                    OffsetRgn( hrgn, -wndPtr->rectClient.left,
                                  -wndPtr->rectClient.top );
                    PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, hrgn, flags, RDW_C_USEHRGN );
-                 }
                }
 	   DeleteObject( hrgn );
 	   if( control & RDW_C_DELETEHRGN ) DeleteObject( hrgnUpdate );
diff --git a/windows/property.c b/windows/property.c
index 089d35baf51..876bd58da75 100644
--- a/windows/property.c
+++ b/windows/property.c
@@ -166,7 +166,12 @@ HANDLE32 RemoveProp32A( HWND32 hwnd, LPCSTR str )
     PROPERTY **pprop, *prop;
     WND *pWnd = WIN_FindWndPtr( hwnd );
 
-    dprintf_prop( stddeb, "RemoveProp: %04x '%s'\n", hwnd, str );
+    if (HIWORD(str))
+      dprintf_prop( stddeb, "RemoveProp: %04x '%s'\n", hwnd, str );
+    else
+      dprintf_prop( stddeb, "RemoveProp: %04x #%04x\n", hwnd, LOWORD(str));
+
+
     if (!pWnd) return NULL;
     if (HIWORD(str))
     {
diff --git a/windows/queue.c b/windows/queue.c
index ca6b4d9652e..aeff35cb3fa 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -15,11 +15,15 @@
 #define MAX_QUEUE_SIZE   120  /* Max. size of a message queue */
 
 static HQUEUE16 hFirstQueue = 0;
+static HQUEUE16 hDoomedQueue = 0;
 static HQUEUE16 hmemSysMsgQueue = 0;
+static MESSAGEQUEUE *sysMsgQueue = NULL;
+
 static MESSAGEQUEUE *pMouseQueue = NULL;  /* Queue for last mouse message */
 static MESSAGEQUEUE *pKbdQueue = NULL;    /* Queue for last kbd message */
-static HQUEUE16 hDoomedQueue = 0;
-static MESSAGEQUEUE *sysMsgQueue = NULL;
+
+MESSAGEQUEUE *pCursorQueue = NULL; 
+MESSAGEQUEUE *pActiveQueue = NULL;
 
 /***********************************************************************
  *	     QUEUE_DumpQueue
@@ -119,9 +123,10 @@ static HQUEUE16 QUEUE_CreateMsgQueue( int size )
     if (!(hQueue = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, queueSize )))
         return 0;
     msgQueue = (MESSAGEQUEUE *) GlobalLock16( hQueue );
-    msgQueue->self = hQueue;
-    msgQueue->msgSize = sizeof(QMSG);
-    msgQueue->queueSize = size;
+    msgQueue->self        = hQueue;
+    msgQueue->msgSize     = sizeof(QMSG);
+    msgQueue->queueSize   = size;
+    msgQueue->wakeBits    = msgQueue->changeBits = QS_SMPARAMSFREE;
     msgQueue->wWinVersion = pTask ? pTask->version : 0;
     GlobalUnlock16( hQueue );
     return hQueue;
@@ -136,6 +141,7 @@ static HQUEUE16 QUEUE_CreateMsgQueue( int size )
 BOOL32 QUEUE_DeleteMsgQueue( HQUEUE16 hQueue )
 {
     MESSAGEQUEUE * msgQueue = (MESSAGEQUEUE*)GlobalLock16(hQueue);
+    HQUEUE16  senderQ;
     HQUEUE16 *pPrev;
 
     dprintf_msg(stddeb,"Deleting message queue %04x\n", hQueue);
@@ -145,6 +151,19 @@ BOOL32 QUEUE_DeleteMsgQueue( HQUEUE16 hQueue )
 	dprintf_msg(stddeb,"DeleteMsgQueue: invalid argument.\n");
 	return 0;
     }
+    if( pCursorQueue == msgQueue ) pCursorQueue = NULL;
+    if( pActiveQueue == msgQueue ) pActiveQueue = NULL;
+
+    /* flush sent messages */
+    senderQ = msgQueue->hSendingTask;
+    while( senderQ )
+    {
+      MESSAGEQUEUE* sq = (MESSAGEQUEUE*)GlobalLock16(senderQ);
+      if( !sq ) break;
+      sq->SendMessageReturn = 0L;
+      QUEUE_SetWakeBit( sq, QS_SMRESULT );
+      senderQ = sq->hPrevSendingTask;
+    }
 
     pPrev = &hFirstQueue;
     while (*pPrev && (*pPrev != hQueue))
@@ -191,6 +210,9 @@ MESSAGEQUEUE *QUEUE_GetSysQueue(void)
  */
 void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit )
 {
+    dprintf_msg(stddeb,"SetWakeBit: queue = %04x (wm=%04x), bit = %04x\n", 
+	                queue->self, queue->wakeMask, bit );
+
     if (bit & QS_MOUSE) pMouseQueue = queue;
     if (bit & QS_KEY) pKbdQueue = queue;
     queue->changeBits |= bit;
@@ -222,9 +244,12 @@ void QUEUE_WaitBits( WORD bits )
 {
     MESSAGEQUEUE *queue;
 
+    dprintf_msg(stddeb,"WaitBits: q %04x waiting for %04x\n", GetTaskQueue(0), bits);
+
     for (;;)
     {
         if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return;
+
         if (queue->changeBits & bits)
         {
             /* One of the bits is set; we can return */
@@ -234,9 +259,17 @@ void QUEUE_WaitBits( WORD bits )
         if (queue->wakeBits & QS_SENDMESSAGE)
         {
             /* Process the sent message immediately */
+
+	    queue->wakeMask = 0;
             QUEUE_ReceiveMessage( queue );
+	    continue;				/* nested sm crux */
         }
+
         queue->wakeMask = bits | QS_SENDMESSAGE;
+	if(queue->changeBits & bits) continue;
+	
+	dprintf_msg(stddeb,"wb: (%04x) wakeMask is %04x, waiting\n", queue->self, queue->wakeMask);
+
         WaitEvent( 0 );
     }
 }
@@ -249,57 +282,55 @@ void QUEUE_WaitBits( WORD bits )
  */
 void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue )
 {
-    MESSAGEQUEUE *senderQ;
-    HWND hwnd;
-    UINT msg;
-    WPARAM wParam;
-    LPARAM lParam;
-    LRESULT result = 0;
-    HQUEUE16 oldSender;
-
-    printf( "ReceiveMessage\n" );
-    if (!(queue->wakeBits & QS_SENDMESSAGE)) return;
-    if (!(senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask))) return;
+    MESSAGEQUEUE *senderQ = NULL;
+    HQUEUE16      prevSender = 0;
+    QSMCTRL*      prevCtrlPtr = NULL;
+    LRESULT       result = 0;
+
+    dprintf_msg(stddeb, "ReceiveMessage, queue %04x\n", queue->self );
+    if (!(queue->wakeBits & QS_SENDMESSAGE) ||
+        !(senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask))) 
+	{ dprintf_msg(stddeb,"\trcm: nothing to do\n"); return; }
 
-    /* Remove sending queue from the list */
-    oldSender                  = queue->InSendMessageHandle;
     queue->InSendMessageHandle = queue->hSendingTask;
-    queue->hSendingTask        = senderQ->hPrevSendingTask;
-    senderQ->hPrevSendingTask  = 0;
-    if (!queue->hSendingTask)
+    if( !(queue->hSendingTask = senderQ->hPrevSendingTask) )
     {
-        queue->wakeBits &= ~QS_SENDMESSAGE;
-        queue->changeBits &= ~QS_SENDMESSAGE;
+      queue->wakeBits &= ~QS_SENDMESSAGE;	/* no more sent messages */
+      queue->changeBits &= ~QS_SENDMESSAGE;
     }
 
-    /* Get the parameters from the sending task */
-    hwnd   = senderQ->hWnd;
-    msg    = senderQ->msg;
-    wParam = senderQ->wParam;
-    lParam = senderQ->lParam;
-    senderQ->hWnd = 0;
+    /* Remove sending queue from the list */
+    prevSender                 = queue->InSendMessageHandle;
+    prevCtrlPtr		       = queue->smResultCurrent;
+    queue->smResultCurrent     = senderQ->smResultInit;
+
+    dprintf_msg(stddeb, "\trcm: smResultCurrent = %08x, prevCtrl = %08x\n", 
+				(unsigned)queue->smResultCurrent, (unsigned)prevCtrlPtr );
     QUEUE_SetWakeBit( senderQ, QS_SMPARAMSFREE );
 
-    printf( "ReceiveMessage: calling wnd proc %04x %04x %04x %08x\n",
-            hwnd, msg, wParam, lParam );
+    dprintf_msg(stddeb, "\trcm: calling wndproc - %04x %04x %04x %08x\n",
+            senderQ->hWnd, senderQ->msg, senderQ->wParam, (unsigned)senderQ->lParam );
 
-    /* Call the window procedure */
-    /* FIXME: should we use CallWindowProc here? */
-    if (IsWindow( hwnd ))
+    if (IsWindow( senderQ->hWnd ))
     {
         DWORD extraInfo = queue->GetMessageExtraInfoVal;
         queue->GetMessageExtraInfoVal = senderQ->GetMessageExtraInfoVal;
-        result = SendMessage16( hwnd, msg, wParam, lParam );
+
+        result = CallWindowProc16( (WNDPROC16)GetWindowLong16(senderQ->hWnd, GWL_WNDPROC),
+				   senderQ->hWnd, senderQ->msg, senderQ->wParam, senderQ->lParam );
+
         queue->GetMessageExtraInfoVal = extraInfo;  /* Restore extra info */
+	dprintf_msg(stddeb,"\trcm: result =  %08x\n", (unsigned)result );
     }
-
-    printf( "ReceiveMessage: wnd proc %04x %04x %04x %08x ret = %08x\n",
-            hwnd, msg, wParam, lParam, result );
+    else dprintf_msg(stddeb,"\trcm: bad hWnd\n");
 
     /* Return the result to the sender task */
     ReplyMessage( result );
 
-    queue->InSendMessageHandle = oldSender;
+    queue->InSendMessageHandle = prevSender;
+    queue->smResultCurrent     = prevCtrlPtr;
+
+    dprintf_msg(stddeb,"ReceiveMessage: done!\n");
 }
 
 
@@ -399,39 +430,44 @@ void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos )
  */
 static void QUEUE_WakeSomeone( UINT message )
 {
-    HWND hwnd;
-    WORD wakeBit;
-    HQUEUE16 hQueue;
-    MESSAGEQUEUE *queue = NULL;
-
-    if ((message >= WM_KEYFIRST) && (message <= WM_KEYLAST)) wakeBit = QS_KEY;
-    else wakeBit = (message == WM_MOUSEMOVE) ? QS_MOUSEMOVE : QS_MOUSEBUTTON;
+    WND*	  wndPtr = NULL;
+    HWND          hwnd;
+    WORD          wakeBit;
+    MESSAGEQUEUE *queue = pCursorQueue;
 
-    if (!(hwnd = GetSysModalWindow16()))
+    if( (message >= WM_KEYFIRST) && (message <= WM_KEYLAST) )
     {
-        if (wakeBit == QS_KEY)
-        {
-            if (!(hwnd = GetFocus32())) hwnd = GetActiveWindow();
-        }
-        else hwnd = GetCapture();
+       wakeBit = QS_KEY;
+       if( pActiveQueue ) queue = pActiveQueue;
     }
-    if (hwnd)
+    else 
     {
-        WND *wndPtr = WIN_FindWndPtr( hwnd );
-        if (wndPtr) queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
+       wakeBit = (message == WM_MOUSEMOVE) ? QS_MOUSEMOVE : QS_MOUSEBUTTON;
+       if( (hwnd = GetCapture32()) )
+	 if( (wndPtr = WIN_FindWndPtr( hwnd )) ) 
+	   queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
     }
-    else if (!(queue = pMouseQueue))
+
+    if( (hwnd = GetSysModalWindow16()) )
+      if( (wndPtr = WIN_FindWndPtr( hwnd )) )
+        queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
+
+    if( !queue ) 
     {
-        hQueue = hFirstQueue;
-        while (hQueue)
-        {
-            queue = GlobalLock16( hQueue );
-            if (queue->wakeBits & wakeBit) break;
-            hQueue = queue->next;
-        }
+      queue = GlobalLock16( hFirstQueue );
+      while( queue )
+      {
+        if (queue->wakeMask & wakeBit) break;
+        queue = GlobalLock16( queue->next );
+      }
+      if( !queue )
+      { 
+        dprintf_msg(stddeb,"WakeSomeone: couldn't find queue\n"); 
+        return; 
+      }
     }
-    if (!queue) printf( "WakeSomeone: no one found\n" );
-    if (queue) QUEUE_SetWakeBit( queue, wakeBit );
+
+    QUEUE_SetWakeBit( queue, wakeBit );
 }
 
 
@@ -595,15 +631,23 @@ BOOL SetMessageQueue( int size )
 	dprintf_msg(stddeb,"SetMessageQueue: failed!\n");
 	return FALSE;
     }
+    queuePtr = (MESSAGEQUEUE *)GlobalLock16( hNewQueue );
 
-    /* Free the old message queue */
-    if ((hQueue = GetTaskQueue(0)) != 0) QUEUE_DeleteMsgQueue( hQueue );
+    /* Copy data and free the old message queue */
+    if ((hQueue = GetTaskQueue(0)) != 0) 
+    {
+       MESSAGEQUEUE *oldQ = (MESSAGEQUEUE *)GlobalLock16( hQueue );
+       memcpy( &queuePtr->reserved2, &oldQ->reserved2, 
+			(int)oldQ->messages - (int)(&oldQ->reserved2) );
+       QUEUE_DeleteMsgQueue( hQueue );
+    }
 
     /* Link new queue into list */
-    queuePtr = (MESSAGEQUEUE *)GlobalLock16( hNewQueue );
     queuePtr->hTask = GetCurrentTask();
     queuePtr->next  = hFirstQueue;
     hFirstQueue = hNewQueue;
+    
+    if( !queuePtr->next ) pCursorQueue = queuePtr;
 
     SetTaskQueue( 0, hNewQueue );
     return TRUE;
diff --git a/windows/scroll.c b/windows/scroll.c
index 9b8d699d50f..f92adf16fd5 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -29,7 +29,7 @@ static int RgnType;
  */
 void ScrollWindow(HWND hwnd, short dx, short dy, LPRECT16 rect, LPRECT16 clipRect)
 {
-    HDC  	hdc;
+    HDC32  	hdc;
     HRGN 	hrgnUpdate,hrgnClip;
     RECT16 	rc, cliprc;
     HWND 	hCaretWnd = CARET_GetHwnd();
@@ -52,7 +52,7 @@ void ScrollWindow(HWND hwnd, short dx, short dy, LPRECT16 rect, LPRECT16 clipRec
               HideCaret(hCaretWnd);
           else hCaretWnd = 0;
  
-	  hdc      = GetDCEx(hwnd, hrgnClip, DCX_CACHE | DCX_CLIPSIBLINGS);
+	  hdc = GetDCEx32(hwnd, hrgnClip, DCX_CACHE | DCX_CLIPSIBLINGS);
           DeleteObject(hrgnClip);
        }
     else	/* clip children */
@@ -63,7 +63,7 @@ void ScrollWindow(HWND hwnd, short dx, short dy, LPRECT16 rect, LPRECT16 clipRec
           if (hCaretWnd == hwnd) HideCaret(hCaretWnd);
           else hCaretWnd = 0;
 
-	  hdc = GetDC(hwnd);
+	  hdc = GetDC32(hwnd);
        }
 
     if (clipRect == NULL)
@@ -73,7 +73,7 @@ void ScrollWindow(HWND hwnd, short dx, short dy, LPRECT16 rect, LPRECT16 clipRec
 
     hrgnUpdate = CreateRectRgn(0, 0, 0, 0);
     ScrollDC(hdc, dx, dy, &rc, &cliprc, hrgnUpdate, NULL);
-    ReleaseDC(hwnd, hdc);
+    ReleaseDC32(hwnd, hdc);
 
     if( !rect )		/* move child windows and update region */
     { 
@@ -230,12 +230,12 @@ BOOL ScrollDC(HDC hdc, short dx, short dy, LPRECT16 rc, LPRECT16 cliprc,
 int ScrollWindowEx(HWND hwnd, short dx, short dy, LPRECT16 rect, LPRECT16 clipRect,
 		   HRGN hrgnUpdate, LPRECT16 rcUpdate, WORD flags)
 {
-    HDC hdc;
+    HDC32 hdc;
     RECT16 rc, cliprc;
 
     dprintf_scroll(stddeb,"ScrollWindowEx: dx=%d, dy=%d, wFlags=%04x\n",dx, dy, flags);
 
-    hdc = GetDC(hwnd);
+    hdc = GetDC32(hwnd);
 
     if (rect == NULL)
 	GetClientRect16(hwnd, &rc);
@@ -254,6 +254,6 @@ int ScrollWindowEx(HWND hwnd, short dx, short dy, LPRECT16 rect, LPRECT16 clipRe
                         ((flags & SW_ERASE) ? RDW_ERASENOW : 0), 0 );
     }
 
-    ReleaseDC(hwnd, hdc);
+    ReleaseDC32(hwnd, hdc);
     return RgnType;
 }
diff --git a/windows/win.c b/windows/win.c
index 80debdfacd8..563c788b769 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -44,6 +44,9 @@ static WORD wDragWidth = 4;
 static WORD wDragHeight= 3;
 
 extern HCURSOR16 CURSORICON_IconToCursor(HICON16);
+extern HWND32 CARET_GetHwnd(void);
+extern BOOL32 WINPOS_ActivateOtherWindow(WND* pWnd);
+extern void   WINPOS_CheckActive(HWND32);
 
 /***********************************************************************
  *           WIN_FindWndPtr
@@ -90,13 +93,13 @@ void WIN_DumpWindow( HWND32 hwnd )
     fprintf( stderr, "Window %04x (%p):\n", hwnd, ptr );
     fprintf( stderr,
              "next=%p  child=%p  parent=%p  owner=%p  class=%p '%s'\n"
-             "inst=%04x  taskQ=%04x  updRgn=%04x  active=%04x hdce=%04x  idmenu=%04x\n"
+             "inst=%04x  taskQ=%04x  updRgn=%04x  active=%04x dce=%p  idmenu=%04x\n"
              "style=%08lx  exstyle=%08lx  wndproc=%08x  text='%s'\n"
              "client=%d,%d-%d,%d  window=%d,%d-%d,%d  iconpos=%d,%d  maxpos=%d,%d\n"
              "sysmenu=%04x  flags=%04x  props=%p  vscroll=%p  hscroll=%p\n",
              ptr->next, ptr->child, ptr->parent, ptr->owner,
              ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
-             ptr->hrgnUpdate, ptr->hwndLastActive, ptr->hdce, ptr->wIDmenu,
+             ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
              ptr->dwStyle, ptr->dwExStyle, (UINT32)ptr->winproc,
              ptr->text ? ptr->text : "",
              ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
@@ -301,37 +304,71 @@ void WIN_SendParentNotify(HWND32 hwnd, WORD event, WORD idChild, LPARAM lValue)
 /***********************************************************************
  *           WIN_DestroyWindow
  *
- * Destroy storage associated to a window
+ * Destroy storage associated to a window. "Internals" p.358
  */
-static void WIN_DestroyWindow( HWND hwnd )
+static void WIN_DestroyWindow( WND* wndPtr )
 {
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    HWND hwnd = wndPtr->hwndSelf;
+    WND* pWnd,*pNext;
 
 #ifdef CONFIG_IPC
     if (main_block)
-	DDE_DestroyWindow(hwnd);
+	DDE_DestroyWindow(wndPtr->hwndSelf);
 #endif  /* CONFIG_IPC */
 	
-    if (!wndPtr) return;
-    WIN_UnlinkWindow( hwnd ); /* Remove the window from the linked list */
-    TIMER_RemoveWindowTimers( hwnd );
+    /* free child windows */
+
+    pNext = wndPtr->child;
+    while( (pWnd = pNext) )
+    {
+        pNext = pWnd->next;
+        WIN_DestroyWindow( pWnd );
+    }
+
+    SendMessage32A( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
+
+    /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
+
+    WINPOS_CheckActive( hwnd );
+    if( hwnd == GetCapture32()) ReleaseCapture();
+
+    /* free resources associated with the window */
+
+    TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
     PROPERTY_RemoveWindowProps( wndPtr );
+
     wndPtr->dwMagic = 0;  /* Mark it as invalid */
     wndPtr->hwndSelf = 0;
+
     if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
     {
         if (wndPtr->hrgnUpdate) DeleteObject( wndPtr->hrgnUpdate );
         QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
     }
-    if (!(wndPtr->dwStyle & WS_CHILD))
+
+    /* toss stale messages from the queue */
+
+    if( wndPtr->hmemTaskQ )
     {
-        if (wndPtr->wIDmenu) DestroyMenu( (HMENU)wndPtr->wIDmenu );
+      int           pos;
+      MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
+
+      while( (pos = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != -1 ) 
+	      QUEUE_RemoveMsg(msgQ, pos);
+      wndPtr->hmemTaskQ = 0;
     }
+
+    if (!(wndPtr->dwStyle & WS_CHILD))
+       if (wndPtr->wIDmenu) DestroyMenu( (HMENU)wndPtr->wIDmenu );
     if (wndPtr->hSysMenu) DestroyMenu( wndPtr->hSysMenu );
     if (wndPtr->window) XDestroyWindow( display, wndPtr->window );
-    if (wndPtr->class->style & CS_OWNDC) DCE_FreeDCE( wndPtr->hdce );
+    if (wndPtr->class->style & CS_OWNDC) DCE_FreeDCE( wndPtr->dce );
+
     WINPROC_FreeProc( wndPtr->winproc );
+
     wndPtr->class->cWindows--;
+    wndPtr->class = NULL;
+
     USER_HEAP_FREE( hwnd );
 }
 
@@ -398,7 +435,7 @@ BOOL32 WIN_CreateDesktopWindow(void)
     pWndDesktop->dwStyle           = WS_VISIBLE | WS_CLIPCHILDREN |
                                      WS_CLIPSIBLINGS;
     pWndDesktop->dwExStyle         = 0;
-    pWndDesktop->hdce              = 0;
+    pWndDesktop->dce               = NULL;
     pWndDesktop->pVScroll          = NULL;
     pWndDesktop->pHScroll          = NULL;
     pWndDesktop->pProp             = NULL;
@@ -426,7 +463,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
 {
     CLASS *classPtr;
     WND *wndPtr;
-    HWND16 hwnd;
+    HWND16 hwnd, hwndLinkAfter;
     POINT16 maxSize, maxPos, minTrack, maxTrack;
     LRESULT wmcreate;
 
@@ -493,12 +530,23 @@ static HWND WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
     /* Fill the window structure */
 
     wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
-    wndPtr->next           = NULL;
-    wndPtr->child          = NULL;
-    wndPtr->parent         = (cs->style & WS_CHILD) ?
-                              WIN_FindWndPtr( cs->hwndParent ) : pWndDesktop;
-    wndPtr->owner          = (cs->style & WS_CHILD) ? NULL :
-                              WIN_FindWndPtr(WIN_GetTopParent(cs->hwndParent));
+    wndPtr->next  = NULL;
+    wndPtr->child = NULL;
+
+    if (cs->style & WS_CHILD)
+    {
+        wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
+        wndPtr->owner  = NULL;
+    }
+    else
+    {
+        wndPtr->parent = pWndDesktop;
+        if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
+            wndPtr->owner = NULL;
+        else
+            wndPtr->owner = WIN_FindWndPtr(WIN_GetTopParent(cs->hwndParent));
+    }
+
     wndPtr->window         = 0;
     wndPtr->class          = classPtr;
     wndPtr->winproc        = NULL;
@@ -524,33 +572,11 @@ static HWND WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
     wndPtr->userdata       = 0;
 
     if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
-    classPtr->cWindows++;
-
-    /* Set the window procedure */
-
-    WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)classPtr->winproc, 0 );
-
-    /* Correct the window style */
-
-    if (!(cs->style & (WS_POPUP | WS_CHILD)))  /* Overlapped window */
-    {
-        wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
-        wndPtr->flags |= WIN_NEED_SIZE;
-    }
-    if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
-
-    /* Get class or window DC if needed */
-
-    if (classPtr->style & CS_OWNDC) wndPtr->hdce = DCE_AllocDCE(hwnd, DCE_WINDOW_DC);
-    else if (classPtr->style & CS_CLASSDC) wndPtr->hdce = classPtr->hdce;
-    else wndPtr->hdce = 0;
-
-    /* Insert the window in the linked list */
-
-    WIN_LinkWindow( hwnd, (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP );
 
     /* Call the WH_CBT hook */
 
+    hwndLinkAfter = (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
+
     if (HOOK_GetHook( WH_CBT, GetTaskQueue(0) ))
     {
         CBT_CREATEWND16* cbtc;
@@ -562,8 +588,6 @@ static HWND WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
             WPARAM16 wparam;
             LPARAM lparam;
 
-            HWND hwndZnew = (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
-
             /* Map the CREATESTRUCT to 16-bit format */
             lparam = (LPARAM)cs;
             if (unicode)
@@ -571,25 +595,44 @@ static HWND WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
             else
                 WINPROC_MapMsg32ATo16( WM_CREATE, 0, &msg, &wparam, &lparam );
             cbtc->lpcs = (CREATESTRUCT16 *)lparam;
-            cbtc->hwndInsertAfter = hwndZnew;
+            cbtc->hwndInsertAfter = hwndLinkAfter;
             wmcreate = !HOOK_CallHooks( WH_CBT, HCBT_CREATEWND, hwnd,
                                         (LPARAM)SEGPTR_GET(cbtc) );
             WINPROC_UnmapMsg32ATo16( WM_CREATE, 0, lparam );
-            if (hwndZnew != cbtc->hwndInsertAfter)
-            {
-                WIN_UnlinkWindow( hwnd );
-                WIN_LinkWindow( hwnd, cbtc->hwndInsertAfter );
-            }
             SEGPTR_FREE(cbtc);
             if (!wmcreate)
             {
                 dprintf_win(stddeb,"CreateWindowEx: CBT-hook returned 0\n" );
-                WIN_DestroyWindow( hwnd );
+                USER_HEAP_FREE( hwnd );
                 return 0;
             }
         }
     }
 
+    /* Set the window procedure */
+
+    classPtr->cWindows++;
+    WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)classPtr->winproc, 0 );
+
+    /* Correct the window style */
+
+    if (!(cs->style & (WS_POPUP | WS_CHILD)))  /* Overlapped window */
+    {
+        wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
+        wndPtr->flags |= WIN_NEED_SIZE;
+    }
+    if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
+
+    /* Get class or window DC if needed */
+
+    if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
+    else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
+    else wndPtr->dce = NULL;
+
+    /* Insert the window in the linked list */
+
+    WIN_LinkWindow( hwnd, hwndLinkAfter );
+
     /* Send the WM_GETMINMAXINFO message and fix the size if needed */
 
     if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
@@ -722,7 +765,8 @@ static HWND WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
     {
 	  /* Abort window creation */
 	dprintf_win(stddeb,"CreateWindowEx: wmcreate==-1, aborting\n");
-        WIN_DestroyWindow( hwnd );
+        WIN_UnlinkWindow( hwnd );
+        WIN_DestroyWindow( wndPtr );
 	return 0;
     }
 
@@ -884,7 +928,14 @@ HWND32 CreateWindowEx32W( DWORD exStyle, LPCWSTR className, LPCWSTR windowName,
 
     if (!(classAtom = GlobalFindAtom32W( className )))
     {
-        fprintf( stderr, "CreateWindowEx32W: bad class name %p\n", className );
+    	if (HIWORD(className))
+        {
+            LPSTR cn = STRING32_DupUniToAnsi(className);
+            fprintf( stderr, "CreateWindowEx32W: bad class name '%s'\n",cn);
+            free(cn);
+	}
+        else
+            fprintf( stderr, "CreateWindowEx32W: bad class name %p\n", className );
         return 0;
     }
 
@@ -908,6 +959,45 @@ HWND32 CreateWindowEx32W( DWORD exStyle, LPCWSTR className, LPCWSTR windowName,
 }
 
 
+/***********************************************************************
+ *           WIN_CheckFocus
+ */
+static void WIN_CheckFocus( WND* pWnd )
+{
+  if( GetFocus16() == pWnd->hwndSelf )
+      SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 ); 
+}
+
+/***********************************************************************
+ *           WIN_SendDestroyMsg
+ */
+static void WIN_SendDestroyMsg( WND* pWnd )
+{
+  WND*	pChild;
+
+  WIN_CheckFocus(pWnd);
+
+  if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret();
+  if( !pWnd->window ) CLIPBOARD_DisOwn( pWnd ); 
+  
+  SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
+
+  if( !IsWindow(pWnd->hwndSelf) )
+  {
+    dprintf_win(stddeb,"\tdestroyed itself while in WM_DESTROY!\n");
+    return;
+  }
+
+  pChild = pWnd->child;
+  while( pChild )
+  { 
+    WIN_SendDestroyMsg( pChild );
+    pChild = pChild->next;
+  }
+  WIN_CheckFocus(pWnd);
+}
+
+
 /***********************************************************************
  *           DestroyWindow   (USER.53)
  */
@@ -922,7 +1012,10 @@ BOOL DestroyWindow( HWND hwnd )
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
     if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
 
-      /* Top-level window */
+      /* Call hooks */
+
+    if( HOOK_CallHooks( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
+        return FALSE;
 
     if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
     {
@@ -930,41 +1023,61 @@ BOOL DestroyWindow( HWND hwnd )
         /* FIXME: clean up palette - see "Internals" p.352 */
     }
 
+    if( !QUEUE_IsDoomedQueue(wndPtr->hmemTaskQ) )
+	 WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LPARAM)hwnd );
+    if( !IsWindow(hwnd) ) return TRUE;
+
+    if( wndPtr->window ) CLIPBOARD_DisOwn( wndPtr ); /* before window is unmapped */
+
       /* Hide the window */
 
     if (wndPtr->dwStyle & WS_VISIBLE)
-	SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOACTIVATE |
-		      SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE );
-    if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
-	ReleaseCapture();
-    WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LPARAM)hwnd );
-
-    CLIPBOARD_DisOwn( hwnd );
+    {
+        SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
+		      SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE |
+		    ((QUEUE_IsDoomedQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
+	if( !IsWindow(hwnd) ) return TRUE;
+    }
 
       /* Recursively destroy owned windows */
 
-    for (;;)
+    if( !(wndPtr->dwStyle & WS_CHILD) )
     {
+      for (;;)
+      {
         WND *siblingPtr = wndPtr->parent->child;  /* First sibling */
         while (siblingPtr)
         {
-            if (siblingPtr->owner == wndPtr) break;
+            if (siblingPtr->owner == wndPtr)
+               if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
+                   break;
+               else 
+                   siblingPtr->owner = NULL;
             siblingPtr = siblingPtr->next;
         }
         if (siblingPtr) DestroyWindow( siblingPtr->hwndSelf );
         else break;
+      }
+
+      WINPOS_ActivateOtherWindow(wndPtr);
+
+      if( wndPtr->owner &&
+	  wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
+	  wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
     }
 
-      /* Send destroy messages and destroy children */
+      /* Send destroy messages */
 
-    SendMessage16( hwnd, WM_DESTROY, 0, 0 );
-    while (wndPtr->child)  /* The child removes itself from the list */
-	DestroyWindow( wndPtr->child->hwndSelf );
-    SendMessage16( hwnd, WM_NCDESTROY, 0, 0 );
+    WIN_SendDestroyMsg( wndPtr );
+    if( !IsWindow(hwnd) ) return TRUE;
 
-      /* Destroy the window */
+      /* Unlink now so we won't bother with the children later on */
 
-    WIN_DestroyWindow( hwnd );
+    if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
+
+      /* Destroy the window storage */
+
+    WIN_DestroyWindow( wndPtr );
     return TRUE;
 }
 
@@ -1145,9 +1258,18 @@ WND *WIN_GetDesktop(void)
 
 
 /**********************************************************************
- *           GetDesktopWindow   (USER.286)
+ *           GetDesktopWindow16   (USER.286)
  */
-HWND GetDesktopWindow(void)
+HWND16 GetDesktopWindow16(void)
+{
+    return (HWND16)pWndDesktop->hwndSelf;
+}
+
+
+/**********************************************************************
+ *           GetDesktopWindow32   (USER32.231)
+ */
+HWND32 GetDesktopWindow32(void)
 {
     return pWndDesktop->hwndSelf;
 }
@@ -1159,9 +1281,9 @@ HWND GetDesktopWindow(void)
  * Exactly the same thing as GetDesktopWindow(), but not documented.
  * Don't ask me why...
  */
-HWND GetDesktopHwnd(void)
+HWND16 GetDesktopHwnd(void)
 {
-    return pWndDesktop->hwndSelf;
+    return (HWND16)pWndDesktop->hwndSelf;
 }
 
 
@@ -1186,7 +1308,7 @@ BOOL EnableWindow( HWND hwnd, BOOL enable )
 	wndPtr->dwStyle |= WS_DISABLED;
 	if ((hwnd == GetFocus32()) || IsChild( hwnd, GetFocus32() ))
 	    SetFocus32( 0 );  /* A disabled window can't have the focus */
-	if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
+	if ((hwnd == GetCapture32()) || IsChild( hwnd, GetCapture32() ))
 	    ReleaseCapture();  /* A disabled window can't capture the mouse */
 	SendMessage16( hwnd, WM_ENABLE, FALSE, 0 );
 	return FALSE;
@@ -1892,12 +2014,12 @@ BOOL FlashWindow(HWND hWnd, BOOL bInvert)
     {
         if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
         {
-            HDC hDC = GetDC(hWnd);
+            HDC32 hDC = GetDC32(hWnd);
             
             if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM)hDC, (LPARAM)0 ))
                 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
             
-            ReleaseDC( hWnd, hDC );
+            ReleaseDC32( hWnd, hDC );
             wndPtr->flags |= WIN_NCACTIVATED;
         }
         else
@@ -2026,7 +2148,7 @@ BOOL16 DragDetect(HWND16 hWnd, POINT16 pt)
   rect.top = pt.y - wDragHeight;
   rect.bottom = pt.y + wDragHeight;
 
-  SetCapture(hWnd);
+  SetCapture32(hWnd);
 
   while(1)
    {
@@ -2105,7 +2227,7 @@ DWORD DragObject(HWND hwndScope, HWND hWnd, WORD wObj, HANDLE hOfStruct,
  lpDragInfo->hOfStruct = hOfStruct;
  lpDragInfo->l = 0L; 
 
- SetCapture(hWnd);
+ SetCapture32(hWnd);
  ShowCursor(1);
 
  while( !dragDone )
diff --git a/windows/winpos.c b/windows/winpos.c
index 48d43ee8288..7efd791ab17 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -48,6 +48,21 @@ extern BOOL     DCE_InvalidateDCE(WND*, RECT16* );
 static HWND hwndActive      = 0;  /* Currently active window */
 static HWND hwndPrevActive  = 0;  /* Previously active window */
 
+extern MESSAGEQUEUE* pActiveQueue;
+
+/***********************************************************************
+ *           WINPOS_CheckActive
+ */
+void WINPOS_CheckActive( HWND32 hwnd )
+{
+  if( hwnd == hwndPrevActive ) hwndPrevActive = 0;
+  if( hwnd == hwndActive )
+  {
+      hwndActive = 0; 
+      dprintf_win(stddeb,"\tattempt to activate destroyed window!\n");
+  }
+}
+
 /***********************************************************************
  *           WINPOS_FindIconPos
  *
@@ -483,12 +498,22 @@ BOOL IsZoomed(HWND hWnd)
 /*******************************************************************
  *         GetActiveWindow    (USER.60)
  */
-HWND GetActiveWindow()
+HWND GetActiveWindow(void)
 {
     return hwndActive;
 }
 
 
+/*******************************************************************
+ *         WINPOS_IsGoodEnough
+ */
+static BOOL32 WINPOS_IsGoodEnough(WND* pWnd)
+{
+ return (pWnd) ? ((!(pWnd->dwStyle & WS_DISABLED) &&
+                     pWnd->dwStyle & WS_VISIBLE ) ? TRUE : FALSE) : FALSE;
+}
+
+
 /*******************************************************************
  *         SetActiveWindow    (USER.59)
  */
@@ -497,8 +522,7 @@ HWND SetActiveWindow( HWND hwnd )
     HWND prev = hwndActive;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
-    if (!wndPtr || (wndPtr->dwStyle & WS_DISABLED) ||
-	!(wndPtr->dwStyle & WS_VISIBLE)) return 0;
+    if ( !WINPOS_IsGoodEnough(wndPtr) ) return 0;
 
     WINPOS_SetActiveWindow( hwnd, 0, 0 );
     return prev;
@@ -562,6 +586,9 @@ BOOL ShowWindow( HWND hwnd, int cmd )
             swpflags |= SWP_FRAMECHANGED;
             if (!(wndPtr->dwStyle & WS_MINIMIZE))
             {
+		if( HOOK_CallHooks( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
+		    return 0;
+
                 if (wndPtr->dwStyle & WS_MAXIMIZE)
                 {
                     wndPtr->flags |= WIN_RESTORE_MAX;
@@ -587,6 +614,9 @@ BOOL ShowWindow( HWND hwnd, int cmd )
             swpflags |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
             if (!(wndPtr->dwStyle & WS_MAXIMIZE))
             {
+		if( HOOK_CallHooks( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
+		    return 0;
+
                   /* Store the current position and find the maximized size */
                 if (!(wndPtr->dwStyle & WS_MINIMIZE))
                     wndPtr->rectNormal = wndPtr->rectWindow; 
@@ -630,6 +660,9 @@ BOOL ShowWindow( HWND hwnd, int cmd )
 
             if (wndPtr->dwStyle & WS_MINIMIZE)
             {
+		if( HOOK_CallHooks( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
+		    return 0;
+
                 if( !SendMessage16( hwnd, WM_QUERYOPEN, 0, 0L) )
                   {
                     swpflags |= SWP_NOSIZE | SWP_NOMOVE;
@@ -660,6 +693,9 @@ BOOL ShowWindow( HWND hwnd, int cmd )
             }
             else if (wndPtr->dwStyle & WS_MAXIMIZE)
             {
+		if( HOOK_CallHooks( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
+		    return 0;
+
                 wndPtr->ptMaxPos.x = wndPtr->rectWindow.left;
                 wndPtr->ptMaxPos.y = wndPtr->rectWindow.top;
                 wndPtr->dwStyle &= ~WS_MAXIMIZE;
@@ -855,6 +891,43 @@ BOOL32 SetWindowPlacement32( HWND32 hwnd, const WINDOWPLACEMENT32 *wndpl )
     return TRUE;
 }
 
+/***********************************************************************
+ *           WINPOS_ForceXWindowRaise
+ */
+void WINPOS_ForceXWindowRaise( WND* pWnd )
+{
+    XWindowChanges winChanges;
+    WND *wndStop, *wndLast;
+
+    if (!pWnd->window) return;
+
+    wndLast = wndStop = pWnd;
+    winChanges.stack_mode = Above;
+    XReconfigureWMWindow( display, pWnd->window, 0, CWStackMode, &winChanges );
+
+    /* Recursively raise owned popups according to their z-order
+     * (it would be easier with sibling-related Below but it doesn't
+     * work very well with SGI mwm for instance)
+     */
+    while (wndLast)
+    {
+        WND *wnd = WIN_GetDesktop()->child;
+        wndLast = NULL;
+        while (wnd != wndStop)
+        {
+            if (wnd->owner == pWnd &&
+                (wnd->dwStyle & WS_POPUP) &&
+                (wnd->dwStyle & WS_VISIBLE))
+                wndLast = wnd;
+            wnd = wnd->next;
+        }
+        if (wndLast)
+        {
+            WINPOS_ForceXWindowRaise( wndLast );
+            wndStop = wndLast;
+        }
+    }
+}
 
 /*******************************************************************
  *	   WINPOS_SetActiveWindow
@@ -867,20 +940,16 @@ BOOL32 WINPOS_SetActiveWindow( HWND32 hWnd, BOOL32 fMouse, BOOL32 fChangeFocus)
     WND                   *wndTemp         = WIN_FindWndPtr(hwndActive);
     CBTACTIVATESTRUCT16   *cbtStruct;
     WORD                   wIconized=0;
-    HANDLE hNewActiveQueue;
-
-    /* FIXME: When proper support for cooperative multitasking is in place 
-     *        hActiveQ will be global 
-     */
-
-    HANDLE                 hActiveQ = 0;   
+    HANDLE		   hOldActiveQueue = (pActiveQueue)?pActiveQueue->self:0;
+    HANDLE 		   hNewActiveQueue;
 
     /* paranoid checks */
-    if( hWnd == GetDesktopWindow() || hWnd == hwndActive )
+    if( hWnd == GetDesktopWindow32() || hWnd == hwndActive )
 	return 0;
 
-    if (wndPtr && (GetTaskQueue(0) != wndPtr->hmemTaskQ))
+/* if (wndPtr && (GetTaskQueue(0) != wndPtr->hmemTaskQ))
 	return 0;
+        */
 
     if( wndTemp )
 	wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
@@ -946,15 +1015,10 @@ BOOL32 WINPOS_SetActiveWindow( HWND32 hWnd, BOOL32 fMouse, BOOL32 fChangeFocus)
         if( !IsWindow(hWnd) ) return 0;
     }
 
-    if (hwndPrevActive)
-    {
-        wndTemp = WIN_FindWndPtr( hwndPrevActive );
-        if (wndTemp) hActiveQ = wndTemp->hmemTaskQ;
-    }
     hNewActiveQueue = wndPtr ? wndPtr->hmemTaskQ : 0;
 
     /* send WM_ACTIVATEAPP if necessary */
-    if (hActiveQ != hNewActiveQueue)
+    if (hOldActiveQueue != hNewActiveQueue)
     {
         WND **list, **ppWnd;
 
@@ -962,24 +1026,27 @@ BOOL32 WINPOS_SetActiveWindow( HWND32 hWnd, BOOL32 fMouse, BOOL32 fChangeFocus)
         {
             for (ppWnd = list; *ppWnd; ppWnd++)
             {
-                /* Make sure that the window still exists */
                 if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
-                if ((*ppWnd)->hmemTaskQ != hActiveQ) continue;
-                SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
-                               0, QUEUE_GetQueueTask(hNewActiveQueue) );
+
+                if ((*ppWnd)->hmemTaskQ == hOldActiveQueue)
+                   SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
+                                   0, QUEUE_GetQueueTask(hNewActiveQueue) );
             }
             HeapFree( SystemHeap, 0, list );
         }
 
+	pActiveQueue = (hNewActiveQueue)
+		       ? (MESSAGEQUEUE*) GlobalLock16(hNewActiveQueue) : NULL;
+
         if ((list = WIN_BuildWinArray( WIN_GetDesktop() )))
         {
             for (ppWnd = list; *ppWnd; ppWnd++)
             {
-                /* Make sure that the window still exists */
                 if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
-                if ((*ppWnd)->hmemTaskQ != hNewActiveQueue) continue;
-                SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
-                               1, QUEUE_GetQueueTask( hActiveQ ) );
+
+                if ((*ppWnd)->hmemTaskQ == hNewActiveQueue)
+                   SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
+                                  1, QUEUE_GetQueueTask( hOldActiveQueue ) );
             }
             HeapFree( SystemHeap, 0, list );
         }
@@ -1009,6 +1076,10 @@ BOOL32 WINPOS_SetActiveWindow( HWND32 hWnd, BOOL32 fMouse, BOOL32 fChangeFocus)
 	    FOCUS_SwitchFocus( GetFocus32(),
 			       (wndPtr->dwStyle & WS_MINIMIZE)? 0: hwndActive);
 
+    if( !hwndPrevActive && wndPtr && 
+	 wndPtr->window && !(wndPtr->flags & WIN_MANAGED) )
+	WINPOS_ForceXWindowRaise(wndPtr);
+
     /* if active wnd is minimized redraw icon title 
   if( hwndActive )
       {
@@ -1020,6 +1091,50 @@ BOOL32 WINPOS_SetActiveWindow( HWND32 hWnd, BOOL32 fMouse, BOOL32 fChangeFocus)
     return (hWnd == hwndActive);
 }
 
+/*******************************************************************
+ *         WINPOS_ActivateOtherWindow
+ *
+ * DestroyWindow() helper. pWnd must be a top-level window.
+ */
+BOOL32 WINPOS_ActivateOtherWindow(WND* pWnd)
+{
+  BOOL32	bRet = 0;
+  WND*  	pWndTo = NULL;
+
+  if( pWnd->hwndSelf == hwndPrevActive )
+      hwndPrevActive = 0;
+
+  if( hwndActive != pWnd->hwndSelf && 
+    ( hwndActive || QUEUE_IsDoomedQueue(pWnd->hmemTaskQ)) )
+      return 0;
+
+  if( pWnd->dwStyle & WS_POPUP &&
+      WINPOS_IsGoodEnough( pWnd->owner ) ) pWndTo = pWnd->owner;
+  else
+  {
+    WND* pWndPtr = pWnd;
+
+    pWndTo = WIN_FindWndPtr(hwndPrevActive);
+
+    while( !WINPOS_IsGoodEnough(pWndTo) ) 
+    {
+      /* by now owned windows should've been taken care of */
+
+      pWndTo = pWndPtr->next;
+      pWndPtr = pWndTo;
+      if( !pWndTo ) return 0;
+    }
+  }
+
+  bRet = WINPOS_SetActiveWindow( pWndTo->hwndSelf, FALSE, TRUE );
+
+  /* switch desktop queue to current active */
+  if( pWndTo->parent == WIN_GetDesktop())
+      WIN_GetDesktop()->hmemTaskQ = pWndTo->hmemTaskQ;
+
+  hwndPrevActive = 0;
+  return bRet;  
+}
 
 /*******************************************************************
  *	   WINPOS_ChangeActiveWindow
@@ -1219,67 +1334,41 @@ static void WINPOS_MoveWindowZOrder( HWND hwnd, HWND hwndAfter )
  */
 HWND WINPOS_ReorderOwnedPopups(HWND hwndInsertAfter, WND* wndPtr, WORD flags)
 {
- WND* 	w = WIN_GetDesktop();
+ WND* 	w = WIN_GetDesktop()->child;
 
- w = w->child;
+  if( wndPtr->dwStyle & WS_POPUP && wndPtr->owner )
+  {
+   /* implement "local z-order" between the top and owner window */
 
- /* if we are dealing with owned popup... 
-  */
- if( wndPtr->dwStyle & WS_POPUP && wndPtr->owner && hwndInsertAfter != HWND_TOP )
-   {
-     BOOL bFound = FALSE;
      HWND hwndLocalPrev = HWND_TOP;
-     HWND hwndNewAfter = 0;
 
-     while( w )
-       {
-         if( !bFound && hwndInsertAfter == hwndLocalPrev )
-             hwndInsertAfter = HWND_TOP;
-
-         if( w->dwStyle & WS_POPUP && w->owner == wndPtr->owner )
-           {
-             bFound = TRUE;
-
-             if( hwndInsertAfter == HWND_TOP )
-               {
-                 hwndInsertAfter = hwndLocalPrev;
-                 break;
-               }
-             hwndNewAfter = hwndLocalPrev;
-           }
-
-         if( w == wndPtr->owner )
-           {
-             /* basically HWND_BOTTOM */
-             hwndInsertAfter = hwndLocalPrev;
-
-             if( bFound )
-                 hwndInsertAfter = hwndNewAfter;
-             break;
-           }
-
-           if( w != wndPtr )
-               hwndLocalPrev = w->hwndSelf;
-
-           w = w->next;
-        }
-   }
- else 
-   /* or overlapped top-level window... 
-    */
-   if( !(wndPtr->dwStyle & WS_CHILD) )
-      while( w )
-        {
-          if( w == wndPtr ) break;
+     if( hwndInsertAfter != HWND_TOP )
+     {
+	while( w != wndPtr->owner )
+	{
+	  hwndLocalPrev = w->hwndSelf;
+	  if( hwndLocalPrev == hwndInsertAfter ) break;
+	  w = w->next;
+	}
+	hwndInsertAfter = hwndLocalPrev;
+     }
 
-          if( w->dwStyle & WS_POPUP && w->owner == wndPtr )
-            {
-              SetWindowPos(w->hwndSelf, hwndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE |
-                                        SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_DEFERERASE);
-              hwndInsertAfter = w->hwndSelf;
-            }
-          w = w->next;
-        }
+  }
+  else if( wndPtr->dwStyle & WS_CHILD ) return hwndInsertAfter;
+
+  w = WIN_GetDesktop()->child;
+  while( w )
+  {
+    if( w == wndPtr ) break;
+
+    if( w->dwStyle & WS_POPUP && w->owner == wndPtr )
+    {
+      SetWindowPos(w->hwndSelf, hwndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE |
+                                SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_DEFERERASE);
+      hwndInsertAfter = w->hwndSelf;
+    }
+    w = w->next;
+  }
 
   return hwndInsertAfter;
 }
@@ -1343,7 +1432,7 @@ static UINT WINPOS_SizeMoveClean(WND* Wnd, HRGN oldVisRgn, LPRECT16 lpOldWndRect
    } 
  else			/* bitblt old client area */
    { 
-     HDC   hDC;
+     HDC32 hDC;
      int   update;
      HRGN  updateRgn;
      int   xfrom,yfrom,xto,yto,width,height;
@@ -1386,11 +1475,13 @@ static UINT WINPOS_SizeMoveClean(WND* Wnd, HRGN oldVisRgn, LPRECT16 lpOldWndRect
 	 OffsetRgn( newVisRgn, Wnd->rectClient.left, Wnd->rectClient.top);
 	 CombineRgn( oldVisRgn, oldVisRgn, newVisRgn, RGN_OR );
 
-         hDC = GetDCEx( Wnd->parent->hwndSelf, oldVisRgn, DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CACHE | DCX_CLIPSIBLINGS);
+         hDC = GetDCEx32( Wnd->parent->hwndSelf, oldVisRgn,
+                          DCX_KEEPCLIPRGN | DCX_INTERSECTRGN |
+                          DCX_CACHE | DCX_CLIPSIBLINGS);
 
          BitBlt( hDC, xto, yto, width, height, hDC, xfrom, yfrom, SRCCOPY );
     
-	 ReleaseDC( Wnd->parent->hwndSelf, hDC); 
+	 ReleaseDC32( Wnd->parent->hwndSelf, hDC); 
        }
 
      if( update != NULLREGION )
@@ -1411,45 +1502,6 @@ static UINT WINPOS_SizeMoveClean(WND* Wnd, HRGN oldVisRgn, LPRECT16 lpOldWndRect
 }
 
 
-/***********************************************************************
- *           WINPOS_ForceXWindowRaise
- */
-void WINPOS_ForceXWindowRaise( WND* pWnd )
-{
-    XWindowChanges winChanges;
-    WND *wndStop, *wndLast;
-
-    if (!pWnd->window) return;
-        
-    wndLast = wndStop = pWnd;
-    winChanges.stack_mode = Above;
-    XReconfigureWMWindow( display, pWnd->window, 0, CWStackMode, &winChanges );
-
-    /* Recursively raise owned popups according to their z-order 
-     * (it would be easier with sibling-related Below but it doesn't
-     * work very well with SGI mwm for instance)
-     */
-    while (wndLast)
-    {
-        WND *wnd = WIN_GetDesktop()->child;
-        wndLast = NULL;
-        while (wnd != wndStop)
-        {
-            if (wnd->owner == pWnd &&
-                (wnd->dwStyle & WS_POPUP) &&
-                (wnd->dwStyle & WS_VISIBLE))
-                wndLast = wnd;
-            wnd = wnd->next;
-        }
-        if (wndLast)
-        {
-            WINPOS_ForceXWindowRaise( wndLast );
-            wndStop = wndLast;
-        }
-    }
-}
-
-
 /***********************************************************************
  *           WINPOS_SetXWindowPos
  *
@@ -1496,22 +1548,27 @@ static void WINPOS_SetXWindowPos( WINDOWPOS16 *winpos )
     }
     if (!(winpos->flags & SWP_NOZORDER))
     {
+	winChanges.stack_mode = Below;
+	changeMask |= CWStackMode;
+
         if (winpos->hwndInsertAfter == HWND_TOP) winChanges.stack_mode = Above;
-        else winChanges.stack_mode = Below;
-        if ((winpos->hwndInsertAfter != HWND_TOP) &&
-            (winpos->hwndInsertAfter != HWND_BOTTOM))
+        else if (winpos->hwndInsertAfter != HWND_BOTTOM)
         {
-            WND * insertPtr = WIN_FindWndPtr( winpos->hwndInsertAfter );
-            winChanges.sibling = insertPtr->window;
-            changeMask |= CWSibling;
-        }
-        changeMask |= CWStackMode;
+            WND*   insertPtr = WIN_FindWndPtr( winpos->hwndInsertAfter );
+	    Window stack[2];
+
+	    stack[0] = insertPtr->window;
+	    stack[1] = wndPtr->window;
+
+	    /* for stupid window managers (i.e. all of them) */
+
+	    XRestackWindows(display, stack, 2); 
+	    changeMask &= ~CWStackMode;
+	}
     }
     if (!changeMask) return;
-    if (wndPtr->flags & WIN_MANAGED)
-        XReconfigureWMWindow( display, wndPtr->window, 0,
-                              changeMask, &winChanges );
-    else XConfigureWindow( display, wndPtr->window, changeMask, &winChanges );
+
+    XReconfigureWMWindow( display, wndPtr->window, 0, changeMask, &winChanges );
 }
 
 
@@ -1533,7 +1590,7 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y,
 						 hwnd, x, y, x+cx, y+cy, flags);  
       /* Check window handle */
 
-    if (hwnd == GetDesktopWindow()) return FALSE;
+    if (hwnd == GetDesktopWindow32()) return FALSE;
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
 
     if (wndPtr->dwStyle & WS_VISIBLE) flags &= ~SWP_SHOWWINDOW;
@@ -1839,7 +1896,7 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y,
 	    HWND newActive = hwndPrevActive;
 	    if (!IsWindow(newActive) || (newActive == winpos->hwnd))
 	    {
-		newActive = GetTopWindow( GetDesktopWindow() );
+		newActive = GetTopWindow( GetDesktopWindow32() );
 		if (newActive == winpos->hwnd)
                     newActive = wndPtr->next ? wndPtr->next->hwndSelf : 0;
 	    }	    
@@ -1859,7 +1916,14 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y,
     EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */
 
     if (!(flags & SWP_DEFERERASE) && !(uFlags & SMC_NOPARENTERASE) )
-        PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_ALLCHILDREN | RDW_ERASENOW, 0 );
+    {
+	RECT32	rect;
+	CONV_RECT16TO32( &oldWindowRect, &rect );
+        PAINT_RedrawWindow( wndPtr->parent->hwndSelf, (wndPtr->flags & WIN_SAVEUNDER_OVERRIDE) 
+			    ? &rect : NULL, 0, RDW_ALLCHILDREN | RDW_ERASENOW |
+			  ((wndPtr->flags & WIN_SAVEUNDER_OVERRIDE) ? RDW_INVALIDATE : 0), 0 );
+        wndPtr->flags &= ~WIN_SAVEUNDER_OVERRIDE;
+    }
     else if( wndPtr->parent == WIN_GetDesktop() && wndPtr->parent->flags & WIN_NEEDS_ERASEBKGND )
 	PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_NOCHILDREN | RDW_ERASENOW, 0 );
 
@@ -1911,7 +1975,7 @@ HDWP16 DeferWindowPos( HDWP16 hdwp, HWND hwnd, HWND hwndAfter, INT x, INT y,
 
     pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
     if (!pDWP) return 0;
-    if (hwnd == GetDesktopWindow()) return 0;
+    if (hwnd == GetDesktopWindow32()) return 0;
 
       /* All the windows of a DeferWindowPos() must have the same parent */
 
-- 
GitLab