Release 960606

Wed Jun  5 20:13:54 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [controls/button.c] [controls/listbox.c]
	Fixed wParam of WM_DRAWITEM message.

	* [if1632/Makefile.in] [loader/builtin.c]
	Remove WPROCS32 DLL, as the relay code can call Wine routines
	directly.

	* [loader/module.c] [loader/ne_image.c]
	Fixed initial stack layout for self-loading modules.

	* [tools/build.c]
	Fixed data segment building for Win16 modules.

	* [windows/defdlg.c]
	Implemented Win32 versions of DefDlgProc().

	* [windows/dialog.c]
	Merged Win16 and Win32 dialog code.
	Added support for control extra data in dialog item template.

	* [windows/win.c]
	Unified Win16 and Win32 versions of CreateWindow().
	Implemented Win32 version of GetWindowLong().

	* [windows/winproc.c]
	Changed the implementation of window procedures, so that 16-bit
	winprocs are valid segmented pointers.

Sun Jun  2 16:39:46 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [misc/registry.c]
	Fixed another bug in the w95 loader. Quietened some debug output.

Sun Jun  2 10:00:22 1996  Ulrich Schmid  <uschmid@mail.hh.provi.de>

	* [windows/winproc.c]
	Bug fix: WM_PARENTNOTIFY: don't fall through to WM_SETTEXT.

Sat Jun  1 12:37:22 1996  Tristan Tarrant <tst@sthinc.demon.co.uk>

	* [resources/TODO] [resources/sysres_It.rc]
	Updated font dialog box.

Thu May 30 21:05:19 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [include/commdlg.h] [misc/commdlg.c]
	ChooseFont() and ChooseColor(): 
	Bugfixes and added more support for some CF_* and CC_* flags: 
	dialog templates and font size control.
	Bugfix in structure definition of CHOOSECOLOR definition.

	* [ipc/dde_proc.c] [windows/event.c]
	Replaced SendMessage with SendMessage16 and added inclusion of
 	dde_proc.h for error-free compilation of ipc module.

Thu May 30 19:00:00 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>

	* [windows/scroll.c]
	Made ScrollDC to save/restore current clipping region.

	* [misc/clipboard.c] [windows/event.c]
	Implemented most of the previously missing features (not tested), 
	improved text pasting from/to X. 

	* [if1632/user.spec] [if1632/gdi.spec] [objects/dc.c]
	  [objects/gdiobj.c] [objects/clipping.c] [windows/dce.c]
	  [windows/winpos.c] [windows/painting.c]
	Updated DCE code, implemented dynamic invalidation of owned DCs.
	This fixes a lot of problems with scrolling in WinWord. Not
	sure about the effect on -desktop.

Wed May 29 23:35:44 1996  Jukka Iivonen <iivonen@cc.helsinki.fi>

	* [win32/time.c] [if1632/kernel32.spec]
	Added SetSystemTime and SetTimeZoneInformation.

	* [if1632/kernel32.spec]
	Added lstrcat, lstrcatA, lstrcmp, lstrcmpA, lstrcpy, lstrlen.

	* [include/windows.h]
	Added SYSTEM_POWER_STATUS structure and prototypes for
	GetSystemPowerStatus, SetSystemPowerState, SetSystemTime.

	* [include/kernel32.h]
	Added a prototype for SetTimeZoneInformation.

	* [win32/environment.c] [if1632/kernel32.spec]
	Added GetSystemPowerStatus and SetSystemPowerState stubs.
diff --git a/ANNOUNCE b/ANNOUNCE
index b2c5356..820759c 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,12 +1,13 @@
-This is release 960528 of Wine the MS Windows emulator.  This is still a
+This is release 960606 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.
+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-960528: (see ChangeLog for details)
-	- First attempt at inter-task SendMessage(); still broken.
+WHAT'S NEW with Wine-960606: (see ChangeLog for details)
+	- More Win32 code.
+	- Window repainting fixes.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -15,10 +16,10 @@
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-    sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960528.tar.gz
-    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960528.tar.gz
-    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960528.tar.gz
-    aris.com:/pub/linux/ALPHA/Wine/development/Wine-960528.tar.gz
+    sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960606.tar.gz
+    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960606.tar.gz
+    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960606.tar.gz
+    aris.com:/pub/linux/ALPHA/Wine/development/Wine-960606.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/ChangeLog b/ChangeLog
index 488637b..34238c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,96 @@
 ----------------------------------------------------------------------
+Wed Jun  5 20:13:54 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [controls/button.c] [controls/listbox.c]
+	Fixed wParam of WM_DRAWITEM message.
+
+	* [if1632/Makefile.in] [loader/builtin.c]
+	Remove WPROCS32 DLL, as the relay code can call Wine routines
+	directly.
+
+	* [loader/module.c] [loader/ne_image.c]
+	Fixed initial stack layout for self-loading modules.
+
+	* [tools/build.c]
+	Fixed data segment building for Win16 modules.
+
+	* [windows/defdlg.c]
+	Implemented Win32 versions of DefDlgProc().
+
+	* [windows/dialog.c]
+	Merged Win16 and Win32 dialog code.
+	Added support for control extra data in dialog item template.
+
+	* [windows/win.c]
+	Unified Win16 and Win32 versions of CreateWindow().
+	Implemented Win32 version of GetWindowLong().
+
+	* [windows/winproc.c]
+	Changed the implementation of window procedures, so that 16-bit
+	winprocs are valid segmented pointers.
+
+Sun Jun  2 16:39:46 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
+
+	* [misc/registry.c]
+	Fixed another bug in the w95 loader. Quietened some debug output.
+
+Sun Jun  2 10:00:22 1996  Ulrich Schmid  <uschmid@mail.hh.provi.de>
+
+	* [windows/winproc.c]
+	Bug fix: WM_PARENTNOTIFY: don't fall through to WM_SETTEXT.
+
+Sat Jun  1 12:37:22 1996  Tristan Tarrant <tst@sthinc.demon.co.uk>
+
+	* [resources/TODO] [resources/sysres_It.rc]
+	Updated font dialog box.
+
+Thu May 30 21:05:19 1996  Albrecht Kleine  <kleine@ak.sax.de>
+
+	* [include/commdlg.h] [misc/commdlg.c]
+	ChooseFont() and ChooseColor(): 
+	Bugfixes and added more support for some CF_* and CC_* flags: 
+	dialog templates and font size control.
+	Bugfix in structure definition of CHOOSECOLOR definition.
+
+	* [ipc/dde_proc.c] [windows/event.c]
+	Replaced SendMessage with SendMessage16 and added inclusion of
+ 	dde_proc.h for error-free compilation of ipc module.
+
+Thu May 30 19:00:00 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>
+
+	* [windows/scroll.c]
+	Made ScrollDC to save/restore current clipping region.
+
+	* [misc/clipboard.c] [windows/event.c]
+	Implemented most of the previously missing features (not tested), 
+	improved text pasting from/to X. 
+
+	* [if1632/user.spec] [if1632/gdi.spec] [objects/dc.c]
+	  [objects/gdiobj.c] [objects/clipping.c] [windows/dce.c]
+	  [windows/winpos.c] [windows/painting.c]
+	Updated DCE code, implemented dynamic invalidation of owned DCs.
+	This fixes a lot of problems with scrolling in WinWord. Not
+	sure about the effect on -desktop.
+
+Wed May 29 23:35:44 1996  Jukka Iivonen <iivonen@cc.helsinki.fi>
+
+	* [win32/time.c] [if1632/kernel32.spec]
+	Added SetSystemTime and SetTimeZoneInformation.
+
+	* [if1632/kernel32.spec]
+	Added lstrcat, lstrcatA, lstrcmp, lstrcmpA, lstrcpy, lstrlen.
+
+	* [include/windows.h]
+	Added SYSTEM_POWER_STATUS structure and prototypes for
+	GetSystemPowerStatus, SetSystemPowerState, SetSystemTime.
+
+	* [include/kernel32.h]
+	Added a prototype for SetTimeZoneInformation.
+
+	* [win32/environment.c] [if1632/kernel32.spec]
+	Added GetSystemPowerStatus and SetSystemPowerState stubs.
+
+----------------------------------------------------------------------
 Tue May 28 19:36:36 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
 
 	* [controls/combo.c]
diff --git a/controls/button.c b/controls/button.c
index 7e24f64..a7870ed 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -519,5 +519,6 @@
     dis.hDC        = hDC;
     dis.itemData   = 0;
     GetClientRect32( wndPtr->hwndSelf, &dis.rcItem );
-    SendMessage32A( GetParent(wndPtr->hwndSelf), WM_DRAWITEM, 1, (LPARAM)&dis);
+    SendMessage32A( GetParent(wndPtr->hwndSelf), WM_DRAWITEM,
+                    wndPtr->wIDmenu, (LPARAM)&dis );
 }
diff --git a/controls/combo.c b/controls/combo.c
index 409f720..44540dd 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -60,12 +60,12 @@
 
 LPHEADCOMBO ComboGetStorageHeader(HWND hwnd)
 {
-  return (LPHEADCOMBO)GetWindowLong(hwnd,4);
+  return (LPHEADCOMBO)GetWindowLong32A(hwnd,4);
 }
 
 LPHEADLIST ComboGetListHeader(HWND hwnd)
 {
-  return (LPHEADLIST)GetWindowLong(hwnd,0);
+  return (LPHEADLIST)GetWindowLong32A(hwnd,0);
 }
 
 int CreateComboStruct(HWND hwnd, LONG style)
@@ -118,7 +118,7 @@
   LPHEADLIST   lphl;
   LPHEADCOMBO  lphc;
   LONG         style = 0;
-  LONG         cstyle = GetWindowLong(hwnd,GWL_STYLE);
+  LONG         cstyle = GetWindowLong32A(hwnd,GWL_STYLE);
   RECT16       rect,lboxrect;
   WND*         wndPtr = WIN_FindWndPtr(hwnd);
   char className[] = "COMBOLBOX";  /* Hack so that class names are > 0x10000 */
@@ -172,21 +172,21 @@
   }
 
   if ((cstyle & 3) != CBS_DROPDOWNLIST)
-      lphc->hWndEdit = CreateWindow16(MAKE_SEGPTR(editName), (SEGPTR)0,
+      lphc->hWndEdit = CreateWindow16( editName, NULL,
 				  WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | ES_LEFT,
 				  0, 0, rect.right-6-CBitWidth,
 				  lphl->StdItemHeight+2*SYSMETRICS_CYBORDER,
-				  hwnd, (HMENU)ID_EDIT, WIN_GetWindowInstance(hwnd), 0L);
+				  hwnd, (HMENU)ID_EDIT, WIN_GetWindowInstance(hwnd), NULL );
 				  
   lboxrect.top+=lphc->LBoxTop;
-  lphc->hWndLBox = CreateWindow16(MAKE_SEGPTR(className), (SEGPTR)0, style |
+  lphc->hWndLBox = CreateWindow16( className, NULL, style |
  				((cstyle & WS_HSCROLL)? WS_HSCROLL : 0) |
  				((cstyle & WS_VSCROLL)? WS_VSCROLL : 0),
 				lboxrect.left, lboxrect.top,
 				lboxrect.right - lboxrect.left, 
 				lboxrect.bottom - lboxrect.top,
 				hwndp,(HMENU)ID_CLB, WIN_GetWindowInstance(hwnd),
-				(SEGPTR)hwnd );
+				(LPVOID)(HWND32)hwnd );
 
    wndPtr->dwStyle &= ~(WS_VSCROLL | WS_HSCROLL);
 
@@ -628,7 +628,7 @@
 {
   LPHEADCOMBO  lphc = ComboGetStorageHeader(hwnd);
   LPHEADLIST   lphl = ComboGetListHeader(hwnd);
-  LONG         cstyle = GetWindowLong(hwnd,GWL_STYLE);
+  LONG         cstyle = GetWindowLong32A(hwnd,GWL_STYLE);
   RECT16       cRect,wRect;
 
   if (lphc->hWndLBox == 0) return FALSE;
@@ -781,11 +781,7 @@
 
 HWND CLBoxGetCombo(HWND hwnd)
 {
-#ifdef WINELIB32
-  return (HWND)GetWindowLong(hwnd,0);
-#else
-  return (HWND)GetWindowWord(hwnd,0);
-#endif
+  return (HWND)GetWindowLong32A(hwnd,0);
 }
 
 LPHEADLIST CLBoxGetListHeader(HWND hwnd)
@@ -799,11 +795,7 @@
 static LRESULT CBLCreate( HWND hwnd, WPARAM wParam, LPARAM lParam )
 {
   CREATESTRUCT16 *createStruct = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
-#ifdef WINELIB32
-  SetWindowLong(hwnd,0,(LONG)createStruct->lpCreateParams);
-#else
-  SetWindowWord(hwnd,0,LOWORD(createStruct->lpCreateParams));
-#endif
+  SetWindowLong32A(hwnd,0,(LONG)createStruct->lpCreateParams);
   return 0;
 }
 
diff --git a/controls/listbox.c b/controls/listbox.c
index 25d4bfb..27a173a 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -95,9 +95,9 @@
   lphl->hSelf          = hwnd;  
   if (CtlType==ODT_COMBOBOX)              /* use the "faked" style for COMBOLBOX */
                                           /* LBS_SORT instead CBS_SORT e.g.      */
-    lphl->dwStyle   = MAKELONG(LOWORD(styles),HIWORD(GetWindowLong(hwnd,GWL_STYLE)));
+    lphl->dwStyle   = MAKELONG(LOWORD(styles),HIWORD(GetWindowLong32A(hwnd,GWL_STYLE)));
   else
-    lphl->dwStyle   = GetWindowLong(hwnd,GWL_STYLE); /* use original style dword */
+    lphl->dwStyle   = GetWindowLong32A(hwnd,GWL_STYLE); /* use original style dword */
   lphl->hParent        = parent;
   lphl->StdItemHeight  = 15; /* FIXME: should get the font height */
   lphl->OwnerDrawn     = styles & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE);
@@ -146,7 +146,7 @@
 
 static LPHEADLIST ListBoxGetStorageHeader(HWND hwnd)
 {
-    return (LPHEADLIST)GetWindowLong(hwnd,0);
+    return (LPHEADLIST)GetWindowLong32A(hwnd,0);
 }
 
 /* Send notification "code" as part of a WM_COMMAND-message if hwnd
@@ -245,7 +245,7 @@
         dis.itemAction = itemAction;
         dis.itemState  = itemState;
         CONV_RECT16TO32( rect, &dis.rcItem );
-        SendMessage32A( lphl->hParent, WM_DRAWITEM, 0, (LPARAM)&dis );
+        SendMessage32A( lphl->hParent, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis );
         return;
     }
     if (itemAction == ODA_DRAWENTIRE || itemAction == ODA_SELECT) {
@@ -315,7 +315,7 @@
  
   *lpmeasure = lpls->mis;
   lpmeasure->itemHeight = lphl->StdItemHeight;
-  SendMessage16(lphl->hParent, WM_MEASUREITEM, 0, (LPARAM)USER_HEAP_SEG_ADDR(hTemp));
+  SendMessage16(lphl->hParent, WM_MEASUREITEM, lphl->CtlID, (LPARAM)USER_HEAP_SEG_ADDR(hTemp));
 
   if (lphl->dwStyle & LBS_OWNERDRAWFIXED) {
     if (lpmeasure->itemHeight > lphl->StdItemHeight)
@@ -765,7 +765,7 @@
 static LONG LBCreate(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST   lphl;
-  LONG	       dwStyle = GetWindowLong(hwnd,GWL_STYLE);
+  LONG	       dwStyle = GetWindowLong32A(hwnd,GWL_STYLE);
   RECT16 rect;
 
   CreateListBoxStruct(hwnd, ODT_LISTBOX, dwStyle, GetParent(hwnd));
@@ -978,7 +978,7 @@
    }
 
 #ifndef WINELIB
-  if (GetWindowLong(lphl->hSelf,GWL_EXSTYLE) & WS_EX_DRAGDETECT)
+  if (GetWindowLong32A(lphl->hSelf,GWL_EXSTYLE) & WS_EX_DRAGDETECT)
      if( DragDetect(lphl->hSelf,MAKEPOINT16(lParam)) )
          SendMessage16(lphl->hParent, WM_BEGINDRAG,0,0L);
 #endif
diff --git a/controls/menu.c b/controls/menu.c
index 3372b74..093627c 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -774,11 +774,12 @@
 
     if (!pTopPWnd)
     {
-	pTopPWnd = WIN_FindWndPtr(CreateWindow16( POPUPMENU_CLASS_ATOM, (SEGPTR)0,
-				   		WS_POPUP | WS_BORDER, x, y, 
-				   		menu->Width + 2*SYSMETRICS_CXBORDER,
-				   		menu->Height + 2*SYSMETRICS_CYBORDER,
-				   		0, 0, wndPtr->hInstance, (SEGPTR)hmenu ));
+	pTopPWnd = WIN_FindWndPtr(CreateWindow16( POPUPMENU_CLASS_ATOM, NULL,
+                                          WS_POPUP | WS_BORDER, x, y,
+                                          menu->Width + 2*SYSMETRICS_CXBORDER,
+                                          menu->Height + 2*SYSMETRICS_CYBORDER,
+                                          0, 0, wndPtr->hInstance,
+                                          (LPVOID)(HMENU32)hmenu ));
 	if (!pTopPWnd) return FALSE;
 	skip_init = TRUE;
     }
@@ -786,11 +787,12 @@
     if( uSubPWndLevel )
     {
 	/* create new window for the submenu */
-	HWND  hWnd = CreateWindow16( POPUPMENU_CLASS_ATOM, (SEGPTR)0,
+	HWND  hWnd = CreateWindow16( POPUPMENU_CLASS_ATOM, NULL,
                                    WS_POPUP | WS_BORDER, x, y,
                                    menu->Width + 2*SYSMETRICS_CXBORDER,
                                    menu->Height + 2*SYSMETRICS_CYBORDER,
-                                   menu->hWnd, 0, wndPtr->hInstance, (SEGPTR)hmenu );
+                                   menu->hWnd, 0, wndPtr->hInstance,
+                                   (LPVOID)(HMENU32)hmenu );
 	if( !hWnd ) return FALSE;
 	menu->hWnd = hWnd;
     }
@@ -1832,13 +1834,7 @@
     case WM_CREATE:
 	{
 	    CREATESTRUCT16 *cs = (CREATESTRUCT16*)PTR_SEG_TO_LIN(lParam);
-#ifdef WINELIB32
-	    HMENU hmenu = (HMENU) (cs->lpCreateParams);
-	    SetWindowLong( hwnd, 0, hmenu );
-#else
-	    HMENU hmenu = (HMENU) ((int)cs->lpCreateParams & 0xffff);
-	    SetWindowWord( hwnd, 0, hmenu );
-#endif
+	    SetWindowLong32A( hwnd, 0, (LONG)cs->lpCreateParams );
 	    return 0;
 	}
 
@@ -1850,12 +1846,7 @@
 	    PAINTSTRUCT16 ps;
 	    BeginPaint16( hwnd, &ps );
 	    MENU_DrawPopupMenu( hwnd, ps.hdc,
-#ifdef WINELIB32
-			        (HMENU)GetWindowLong( hwnd, 0 )
-#else
-			        (HMENU)GetWindowWord( hwnd, 0 )
-#endif
- 			       );
+                                (HMENU)GetWindowLong32A( hwnd, 0 ) );
 	    EndPaint16( hwnd, &ps );
 	    return 0;
 	}
@@ -1872,12 +1863,7 @@
 	    break;
 
     case WM_USER:
-	if( wParam )
-#ifdef WINELIB32
-            SetWindowLong( hwnd, 0, (HMENU)wParam );
-#else
-            SetWindowWord( hwnd, 0, (HMENU)wParam );
-#endif
+	if (wParam) SetWindowLong32A( hwnd, 0, (HMENU)wParam );
         break;
     default:
 	return DefWindowProc16(hwnd, message, wParam, lParam);
diff --git a/if1632/Makefile.in b/if1632/Makefile.in
index ea85539..5cb814c 100644
--- a/if1632/Makefile.in
+++ b/if1632/Makefile.in
@@ -42,7 +42,6 @@
 	winsock.spec \
 	winspool.spec \
 	wprocs.spec \
-	wprocs32.spec \
 	wsock32.spec
 
 SPEC_FILES = $(DLLS:.spec=.S)
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index 3d9119a..ef8e645 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -156,9 +156,9 @@
 180 pascal16 SetDCState(word word) SetDCState
 181 pascal16 RectInRegionOld(word ptr) RectInRegion16
 188 stub GetTextExtentEx
-190 stub SetDCHook
-191 stub GetDCHook
-192 stub SetHookFlags
+190 pascal16 SetDCHook(word segptr long) SetDCHook
+191 pascal   GetDCHook(word ptr) GetDCHook
+192 pascal16 SetHookFlags(word word) SetHookFlags
 193 stub SetBoundsRect
 194 stub GetBoundsRect
 195 stub SelectBitmap
diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec
index 5ff0b8c..82ced33 100644
--- a/if1632/kernel32.spec
+++ b/if1632/kernel32.spec
@@ -510,7 +510,7 @@
 0504 stub SetProcessShutdownParameters
 0505 stub SetProcessWorkingSetSize
 0506 stub SetStdHandle
-0507 stub SetSystemTime
+0507    stdcall SetSystemTime(ptr) SetSystemTime
 0508 stub SetSystemTimeAdjustment
 0509 stub SetTapeParameters
 0510 stub SetTapePosition
@@ -518,7 +518,7 @@
 0512 stub SetThreadContext
 0513 stub SetThreadLocale
 0514 stub SetThreadPriority
-0515 stub SetTimeZoneInformation
+0515    stdcall SetTimeZoneInformation(ptr) SetTimeZoneInformation
 0516    stdcall SetUnhandledExceptionFilter(ptr) SetUnhandledExceptionFilter
 0517 stub SetVDMCurrentDirectories
 0518 stub SetVolumeLabelA
@@ -601,22 +601,22 @@
 0595 stub _lopen
 0596 stub _lread
 0597 stub _lwrite
-0598 stub lstrcat
-0599 stub lstrcatA
+0598    stdcall lstrcat(ptr ptr) strcat
+0599    stdcall lstrcatA(ptr ptr) strcat
 0600 stub lstrcatW
-0601 stub lstrcmp
-0602 stub lstrcmpA
+0601    stdcall lstrcmp(ptr ptr) strcmp
+0602    stdcall lstrcmpA(ptr ptr) strcmp
 0603 stub lstrcmpW
 0604 stub lstrcmpi
 0605 stub lstrcmpiA
 0606 stub lstrcmpiW
-0607 stub lstrcpy
+0607    stdcall lstrcpy(ptr ptr) strcpy
 0608 	stdcall lstrcpyA(ptr ptr) strcpy
 0609 stub lstrcpyW
 0610 stub lstrcpyn
 0611 stub lstrcpynA
 0612 stub lstrcpynW
-0613 stub lstrlen
+0613    stdcall lstrlen(ptr) strlen
 0614 	stdcall lstrlenA(ptr) strlen
 0615 stub lstrlenW
 #late additions
@@ -625,7 +625,7 @@
 0618 stub GetPrivateProfileStructA
 0619 stub GetPrivateProfileStructW
 0620 stub GetProcessVersion
-0621 stub GetSystemPowerStatus
+0621    stdcall GetSystemPowerStatus(ptr) GetSystemPowerStatus
 0622 stub GetSystemTimeAsFileTime
 0623 stub HeapCreateTagsW
 0624 stub HeapExtend
@@ -634,7 +634,7 @@
 0627 stub HeapUsage
 0628 stub IsDebuggerPresent
 0629 stub PostQueuedCompletionStatus
-0630 stub SetSystemPowerState
+0630    stdcall SetSystemPowerState(byte byte) SetSystemPowerState
 0631 stub WritePrivateProfileStructA
 0632 stub WritePrivateProfileStructW
 0633 stub MakeCriticalSectionGlobal
diff --git a/if1632/user.spec b/if1632/user.spec
index 2444720..0a3c3bf 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -40,7 +40,7 @@
 38  pascal16 GetWindowTextLength(word) GetWindowTextLength
 39  pascal16 BeginPaint(word ptr) BeginPaint16
 40  pascal16 EndPaint(word ptr) EndPaint16
-41  pascal16 CreateWindow(segptr segptr long s_word s_word s_word s_word
+41  pascal16 CreateWindow(ptr ptr long s_word s_word s_word s_word
 	                  word word word segptr) CreateWindow16
 42  pascal16 ShowWindow(word word) ShowWindow
 43  pascal16 CloseWindow(word) CloseWindow
@@ -86,9 +86,9 @@
 83  pascal16 FrameRect(word ptr word) FrameRect16
 84  pascal16 DrawIcon(word s_word s_word word) DrawIcon
 85  pascal16 DrawText(word ptr s_word ptr word) DrawText16
-87  pascal16 DialogBox(word segptr word segptr) DialogBox
+87  pascal16 DialogBox(word segptr word segptr) DialogBox16
 88  pascal16 EndDialog(word s_word) EndDialog
-89  pascal16 CreateDialog(word segptr word segptr) CreateDialog
+89  pascal16 CreateDialog(word segptr word segptr) CreateDialog16
 90  pascal16 IsDialogMessage(word ptr) IsDialogMessage
 91  pascal16 GetDlgItem(word word) GetDlgItem
 92  pascal16 SetDlgItemText(word word segptr) SetDlgItemText16
@@ -134,7 +134,7 @@
 132 pascal   SetClassLong(word s_word long) SetClassLong16
 133 pascal16 GetWindowWord(word s_word) GetWindowWord
 134 pascal16 SetWindowWord(word s_word word) SetWindowWord
-135 pascal   GetWindowLong(word s_word) GetWindowLong
+135 pascal   GetWindowLong(word s_word) GetWindowLong16
 136 pascal   SetWindowLong(word s_word long) SetWindowLong16
 137 pascal16 OpenClipboard(word) OpenClipboard
 138 pascal16 CloseClipboard() CloseClipboard
@@ -218,8 +218,8 @@
 215 pascal16 FlushComm(word word) FlushComm
 #216 USERSEEUSERDO
 217 pascal16 LookupMenuHandle(word s_word) LookupMenuHandle
-218 pascal16 DialogBoxIndirect(word word word segptr) DialogBoxIndirect
-219 pascal16 CreateDialogIndirect(word segptr word segptr) CreateDialogIndirect
+218 pascal16 DialogBoxIndirect(word word word segptr) DialogBoxIndirect16
+219 pascal16 CreateDialogIndirect(word ptr word segptr) CreateDialogIndirect16
 220 pascal16 LoadMenuIndirect(ptr) LoadMenuIndirect16
 221 pascal16 ScrollDC(word s_word s_word ptr ptr word ptr) ScrollDC
 222 pascal16 GetKeyboardState(ptr) GetKeyboardState
@@ -239,12 +239,12 @@
 236 pascal16 GetCapture() GetCapture
 237 pascal16 GetUpdateRgn(word word word) GetUpdateRgn
 238 pascal16 ExcludeUpdateRgn(word word) ExcludeUpdateRgn
-239 pascal16 DialogBoxParam(word segptr word segptr long) DialogBoxParam
+239 pascal16 DialogBoxParam(word segptr word segptr long) DialogBoxParam16
 240 pascal16 DialogBoxIndirectParam(word word word segptr long)
-             DialogBoxIndirectParam
-241 pascal16 CreateDialogParam(word segptr word segptr long) CreateDialogParam
-242 pascal16 CreateDialogIndirectParam(word segptr word segptr long)
-             CreateDialogIndirectParam
+             DialogBoxIndirectParam16
+241 pascal16 CreateDialogParam(word segptr word segptr long) CreateDialogParam16
+242 pascal16 CreateDialogIndirectParam(word ptr word segptr long)
+             CreateDialogIndirectParam16
 243 pascal   GetDialogBaseUnits() GetDialogBaseUnits
 244 pascal16 EqualRect(ptr ptr) EqualRect16
 245 stub EnableCommNotification
@@ -302,7 +302,7 @@
 300 stub UnloadInstalledDrivers
 #301 BOZOSLIVEHERE :-))	<- this is actually EditWndProc
 #306 BEAR306
-308 pascal   DefDlgProc(word word word long) DefDlgProc
+308 pascal   DefDlgProc(word word word long) DefDlgProc16
 309 pascal16 GetClipCursor(ptr) GetClipCursor16
 314 stub SignalProc
 319 pascal16 ScrollWindowEx(word s_word s_word ptr ptr word ptr word)
@@ -327,7 +327,7 @@
 357 stub LoadDIBIconHandler
 358 pascal16 IsMenu(word) IsMenu
 359 pascal16 GetDCEx(word word long) GetDCEx
-362 stub DCHook
+362 pascal16 DCHook(word word long long) DCHook
 364 stub LookupIconIDFromDirectoryEx
 368 pascal16 CopyIcon(word word) CopyIcon
 369 pascal16 CopyCursor(word word) CopyCursor
@@ -397,7 +397,7 @@
 449 stub DrawState
 450 stub CreateIconFromResourceEx
 451 pascal16 TranslateMDISysAccel(word ptr) TranslateMDISysAccel
-452 pascal16 CreateWindowEx(long segptr segptr long s_word s_word s_word s_word
+452 pascal16 CreateWindowEx(long ptr ptr long s_word s_word s_word s_word
                             word word word segptr) CreateWindowEx16
 454 pascal16 AdjustWindowRectEx(ptr long word long) AdjustWindowRectEx16
 455 pascal16 GetIconID(word long) GetIconID
diff --git a/if1632/user32.spec b/if1632/user32.spec
index ecbbf4e..f764aca 100644
--- a/if1632/user32.spec
+++ b/if1632/user32.spec
@@ -71,15 +71,11 @@
 0066 stub CreateCursor
 0067 stub CreateDesktopA
 0068 stub CreateDesktopW
-0069 stdcall CreateDialogIndirectParamA(long ptr long ptr long)	
-	USER32_CreateDialogIndirectParamA
+0069 stdcall CreateDialogIndirectParamA(long ptr long ptr long) CreateDialogIndirectParam32A
 0070 stub CreateDialogIndirectParamAorW
-0071 stdcall CreateDialogIndirectParamW(long ptr long ptr long)	
-	USER32_CreateDialogIndirectParamW
-0072 stdcall CreateDialogParamA(long ptr long ptr long)	
-	USER32_CreateDialogParamA
-0073 stdcall CreateDialogParamW(long ptr long ptr long)	
-	USER32_CreateDialogParamW
+0071 stdcall CreateDialogIndirectParamW(long ptr long ptr long) CreateDialogIndirectParam32W
+0072 stdcall CreateDialogParamA(long ptr long ptr long) CreateDialogParam32A
+0073 stdcall CreateDialogParamW(long ptr long ptr long) CreateDialogParam32W
 0074 stub CreateIcon
 0075 stub CreateIconFromResource
 0076 stub CreateIconFromResourceEx
@@ -127,8 +123,8 @@
 0116 stub DdeSetUserHandle
 0117 stub DdeUnaccessData
 0118 stub DdeUninitialize
-0119 stub DefDlgProcA
-0120 stub DefDlgProcW
+0119 stdcall DefDlgProcA(long long long long) DefDlgProc32A
+0120 stdcall DefDlgProcW(long long long long) DefDlgProc32W
 0121 stdcall DefFrameProcA(long long long long long) DefFrameProc32A
 0122 stdcall DefFrameProcW(long long long long long) DefFrameProc32W
 0123 stdcall DefMDIChildProcA(long long long long) DefMDIChildProc32A
@@ -143,13 +139,11 @@
 0132 stub DestroyIcon
 0133 stub DestroyMenu
 0134 stub DestroyWindow
-0135 stdcall DialogBoxIndirectParamA(long ptr long ptr long)	
-			USER32_DialogBoxIndirectParamA
+0135 stdcall DialogBoxIndirectParamA(long ptr long ptr long) DialogBoxIndirectParam32A
 0136 stub DialogBoxIndirectParamAorW
-0137 stdcall DialogBoxIndirectParamW(long ptr long ptr long)	
-			USER32_DialogBoxIndirectParamW
-0138 stdcall DialogBoxParamA(long ptr long ptr long)	USER32_DialogBoxParamA
-0139 stdcall DialogBoxParamW(long ptr long ptr long)	USER32_DialogBoxParamW
+0137 stdcall DialogBoxIndirectParamW(long ptr long ptr long) DialogBoxIndirectParam32W
+0138 stdcall DialogBoxParamA(long ptr long ptr long) DialogBoxParam32A
+0139 stdcall DialogBoxParamW(long ptr long ptr long) DialogBoxParam32W
 0140 stdcall DispatchMessageA(ptr) USER32_DispatchMessageA
 0141 stub DispatchMessageW
 0142 stub DlgDirListA
@@ -314,8 +308,8 @@
 0301 stdcall GetWindow(long long) GetWindow
 0302 stub GetWindowContextHelpId
 0303 stdcall GetWindowDC(long) GetWindowDC
-0304 stub GetWindowLongA
-0305 stub GetWindowLongW
+0304 stdcall GetWindowLongA(long long) GetWindowLong32A
+0305 stdcall GetWindowLongW(long long) GetWindowLong32W
 0306 stdcall GetWindowPlacement(long ptr) GetWindowPlacement32
 0307 stdcall GetWindowRect(long ptr) GetWindowRect32
 0308 stdcall GetWindowTextA(long ptr long) GetWindowText32A
diff --git a/if1632/wprocs.spec b/if1632/wprocs.spec
index 00e6332..531b647 100644
--- a/if1632/wprocs.spec
+++ b/if1632/wprocs.spec
@@ -7,7 +7,7 @@
 5  pascal ComboBoxWndProc(word word word long) ComboBoxWndProc
 6  pascal EditWndProc(word word word long) EditWndProc
 7  pascal PopupMenuWndProc(word word word long) PopupMenuWndProc
-9  pascal DefDlgProc(word word word long) DefDlgProc
+9  pascal DefDlgProc(word word word long) DefDlgProc16
 10 pascal MDIClientWndProc(word word word long) MDIClientWndProc
 13 pascal SystemMessageBoxProc(word word word long) SystemMessageBoxProc
 14 pascal FileOpenDlgProc(word word word long) FileOpenDlgProc
diff --git a/if1632/wprocs32.spec b/if1632/wprocs32.spec
deleted file mode 100644
index e49d04f..0000000
--- a/if1632/wprocs32.spec
+++ /dev/null
@@ -1,23 +0,0 @@
-name	wprocs32
-type	win32
-
-2  stdcall StaticWndProc(long long long long) StaticWndProc32
-3  stdcall ScrollBarWndProc(long long long long) ScrollBarWndProc32
-4  stdcall ListBoxWndProc(long long long long) ListBoxWndProc32
-5  stdcall ComboBoxWndProc(long long long long) ComboBoxWndProc32
-6  stdcall EditWndProc(long long long long) EditWndProc32
-7  stdcall PopupMenuWndProc(long long long long) PopupMenuWndProc32
-9  stdcall DefDlgProc(long long long long) DefDlgProc32
-10 stdcall MDIClientWndProc(long long long long) MDIClientWndProc32
-11 stdcall DefWindowProc(long long long long) DefWindowProc32A
-13 stdcall SystemMessageBoxProc(long long long long) SystemMessageBoxProc32
-14 stdcall FileOpenDlgProc(long long long long) FileOpenDlgProc32
-15 stdcall FileSaveDlgProc(long long long long) FileSaveDlgProc32
-16 stdcall ColorDlgProc(long long long long) ColorDlgProc32
-17 stdcall FindTextDlgProc(long long long long) FindTextDlgProc32
-18 stdcall ReplaceTextDlgProc(long long long long) ReplaceTextDlgProc32
-19 stdcall PrintSetupDlgProc(long long long long) PrintSetupDlgProc32
-20 stdcall PrintDlgProc(long long long long) PrintDlgProc32
-21 stdcall AboutDlgProc(long long long long) AboutDlgProc32
-22 stdcall ComboLBoxWndProc(long long long long) ComboLBoxWndProc32
-23 stdcall CARET_Callback(long long long long) CARET_Callback
diff --git a/include/bitmap.h b/include/bitmap.h
index db8db52..5f0d360 100644
--- a/include/bitmap.h
+++ b/include/bitmap.h
@@ -39,7 +39,7 @@
 extern BOOL BITMAP_Init(void);
 extern int BITMAP_GetObject( BITMAPOBJ * bmp, int count, LPSTR buffer );
 extern BOOL BITMAP_DeleteObject( HBITMAP hbitmap, BITMAPOBJ * bitmap );
-extern HBITMAP BITMAP_SelectObject( HDC hdc, DC * dc, HBITMAP hbitmap,
+extern HBITMAP BITMAP_SelectObject( DC * dc, HBITMAP hbitmap,
                                     BITMAPOBJ * bmp );
 
   /* objects/dib.c */
diff --git a/include/brush.h b/include/brush.h
index c548dbe..daa2eaa 100644
--- a/include/brush.h
+++ b/include/brush.h
@@ -27,7 +27,6 @@
 extern BOOL BRUSH_Init(void);
 extern int BRUSH_GetObject( BRUSHOBJ * brush, int count, LPSTR buffer );
 extern BOOL BRUSH_DeleteObject( HBRUSH hbrush, BRUSHOBJ * brush );
-extern HBRUSH BRUSH_SelectObject( HDC hdc, DC * dc, HBRUSH hbrush,
-                                  BRUSHOBJ * brush );
+extern HBRUSH BRUSH_SelectObject( DC * dc, HBRUSH hbrush, BRUSHOBJ * brush );
 
 #endif  /* __WINE_BRUSH_H */
diff --git a/include/callback.h b/include/callback.h
index c636e60..fb07a71 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -34,6 +34,7 @@
 extern WORD CallTo16_word_llwl ( FARPROC, WORD, LONG, LONG, WORD, LONG );
 extern LONG CallTo16_long_wwwl ( FARPROC, WORD, WORD, WORD, WORD, LONG );
 extern WORD CallTo16_word_lwww ( FARPROC, WORD, LONG, WORD, WORD, WORD );
+extern WORD CallTo16_word_wwll ( FARPROC, WORD, WORD, WORD, LONG, LONG);
 extern WORD CallTo16_word_wllwl( FARPROC, WORD, WORD, LONG, LONG, WORD, LONG );
 extern WORD CallTo16_word_wwlll( FARPROC, WORD, WORD, WORD, LONG, LONG, LONG );
 extern LONG CallTo16_long_lllllllwlwwwl( FARPROC, WORD, LONG, LONG, LONG,
@@ -71,6 +72,8 @@
     CallTo16_long_wwwl( func, ds, hwnd, msg, wParam, lParam )
 #define CallWordBreakProc( func, lpch, ichCurrent, cch, code ) \
     CallTo16_word_lwww( func, CURRENT_DS, lpch, ichCurrent, cch, code )
+#define CallDCHookProc( func, hdc, code, data, lparam) \
+    CallTo16_word_wwll( func, CURRENT_DS, hdc, code, data, lparam )
 #define CallWndProcNCCREATE16( func, ds, exStyle, clsName, winName, style, \
                                x, y, cx, cy, hparent, hmenu, instance, \
                                params, hwnd, msg, wParam, lParam ) \
@@ -124,6 +127,8 @@
     (*func)( hwnd, msg, wParam, lParam )
 #define CallWndProc32( func, hwnd, msg, wParam, lParam ) \
     (*func)( hwnd, msg, wParam, lParam )
+#define CallDCHookProc( func, hdc, code, data, lparam ) \
+    (*func)( hdc, code, data, lparam )
 #define CallWordBreakProc( func, lpch, ichCurrent, cch, code ) \
     (*func)( lpch, ichCurrent, cch, code )
 
diff --git a/include/class.h b/include/class.h
index b958529..8cd8d06 100644
--- a/include/class.h
+++ b/include/class.h
@@ -17,7 +17,7 @@
     UINT32           magic;         /* Magic number */
     UINT32           cWindows;      /* Count of existing windows */
     UINT32           style;         /* Class style */
-    WNDPROC16        lpfnWndProc;   /* Window procedure */ 
+    HANDLE32         winproc;       /* Window procedure */ 
     INT32            cbClsExtra;    /* Class extra bytes */
     INT32            cbWndExtra;    /* Window extra bytes */
     LPSTR            menuNameA;     /* Default menu name (ASCII string) */
diff --git a/include/clipboard.h b/include/clipboard.h
index 502e314..62bdcab 100644
--- a/include/clipboard.h
+++ b/include/clipboard.h
@@ -1,7 +1,9 @@
 #ifndef __WINE_CLIPBOARD_H
 #define __WINE_CLIPBOARD_H
 
-extern void CLIPBOARD_ReadSelection(Window w,Atom prop);
+void CLIPBOARD_ReadSelection(Window w,Atom prop);
 void CLIPBOARD_ReleaseSelection(HWND hwnd);
+void CLIPBOARD_DisOwn(HWND hWnd);
+BOOL CLIPBOARD_IsPresent(WORD wFormat);
 
 #endif /* __WINE_CLIPBOARD_H */
diff --git a/include/commdlg.h b/include/commdlg.h
index 624822b..47efc9d 100644
--- a/include/commdlg.h
+++ b/include/commdlg.h
@@ -2,8 +2,12 @@
  * COMMDLG - Common Wine Dialog ... :-)
  */
 
-#ifndef COMMDLG_H
-#define COMMDLG_H
+#ifndef __WINE_COMMDLG_H
+#define __WINE_COMMDLG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 #include "wintypes.h"		/* needed for CHOOSEFONT structure */
 
@@ -87,7 +91,7 @@
 	DWORD 		Flags;
 	LPARAM		lCustData;
 	UINT		(*lpfnHook)(HWND, UINT, WPARAM, LPARAM);
-	LPCSTR 		lpTemplateName;
+	SEGPTR 		lpTemplateName;
 	} CHOOSECOLOR;
 typedef CHOOSECOLOR *LPCHOOSECOLOR;
 
@@ -306,6 +310,8 @@
 #pragma pack(4)
 #endif
 
-#endif 		/* #ifdef COMMDLG_H */
+#ifdef __cplusplus
+}
+#endif
 
-
+#endif  /* __WINE_COMMDLG_H */
diff --git a/include/dc.h b/include/dc.h
index 7e3874a..6356a6b 100644
--- a/include/dc.h
+++ b/include/dc.h
@@ -10,11 +10,12 @@
 
 #include "gdi.h"
 
-extern void DC_InitDC( HDC hdc );
+extern void DC_InitDC( DC* dc );
 extern BOOL DC_SetupGCForPatBlt( DC * dc, GC gc, BOOL fMapColors );
 extern BOOL DC_SetupGCForBrush( DC * dc );
 extern BOOL DC_SetupGCForPen( DC * dc );
 extern BOOL DC_SetupGCForText( DC * dc );
+extern BOOL DC_CallHookProc( DC * dc, WORD code, LPARAM lParam );
 
 extern const int DC_XROPfunction[];
 
diff --git a/include/dce.h b/include/dce.h
index e38c194..43a7ec5 100644
--- a/include/dce.h
+++ b/include/dce.h
@@ -9,6 +9,21 @@
 
 #include "windows.h"
 
+/* additional DCX flags 
+ */
+
+#define DCX_NORESETATTR		0x00000004
+#define DCX_EXCLUDEUPDATE    	0x00000100
+#define DCX_INTERSECTUPDATE  	0x00000200
+#define DCX_LOCKWINDOWUPDATE 	0x00000400
+#define DCX_NORECOMPUTE      	0x00100000
+#define DCX_VALIDATE         	0x00200000
+
+#define DCX_DCEBUSY		0x00001000
+#define DCX_WINDOWPAINT		0x00020000
+#define DCX_KEEPCLIPRGN		0x00040000
+#define DCX_NOCLIPCHILDREN      0x00080000
+
 typedef enum
 {
     DCE_CACHE_DC,   /* This is a cached DC (allocated by USER) */
@@ -20,17 +35,17 @@
 typedef struct tagDCE
 {
     HANDLE     hNext;
+    HDC	       hDC;
     HWND       hwndCurrent;
-    HDC        hdc;
+    HWND       hwndDC;
+    HRGN       hClipRgn;
     DCE_TYPE   type;
-    BOOL       inUse;
-    WORD       xOrigin;
-    WORD       yOrigin;
+    DWORD      DCXflags;
 } DCE;
 
 
-extern void DCE_Init(void);
-extern HANDLE DCE_AllocDCE( DCE_TYPE type );
-extern void DCE_FreeDCE( HANDLE hdce );
+extern void 	DCE_Init(void);
+extern HANDLE 	DCE_AllocDCE( HWND hWnd, DCE_TYPE type );
+extern void 	DCE_FreeDCE( HANDLE hdce );
 
 #endif  /* DCE_H */
diff --git a/include/dialog.h b/include/dialog.h
index e835b5b..bb4b677 100644
--- a/include/dialog.h
+++ b/include/dialog.h
@@ -9,19 +9,14 @@
 
 #include "windows.h"
 
-extern BOOL DIALOG_Init(void);
-extern HWND DIALOG_GetFirstTabItem( HWND hwndDlg );
-
-#pragma pack(1)
-
   /* Dialog info structure.
    * This structure is stored into the window extra bytes (cbWndExtra).
    * sizeof(DIALOGINFO) must be <= DLGWINDOWEXTRA (=30).
    */
 typedef struct
 {
-    LONG      msgResult;   /* Result of EndDialog() / Default button id */
-    WNDPROC   dlgProc;     /* Dialog procedure */
+    INT32     msgResult;   /* Result of EndDialog() / Default button id */
+    HANDLE32  dlgProc;     /* Dialog procedure */
     LONG      userInfo;    /* User information (for DWL_USER) */
     HWND      hwndFocus;   /* Current control with focus */
     HFONT     hUserFont;   /* Dialog font */
@@ -32,38 +27,7 @@
     HANDLE    hDialogHeap;
 } DIALOGINFO;
 
-
-  /* Dialog control header */
-typedef struct
-{
-    DWORD      style;
-    WORD       x;
-    WORD       y;
-    WORD       cx;
-    WORD       cy;
-    WORD       id;
-} DLGCONTROLHEADER;
-
-
-  /* Dialog template */
-typedef struct
-{
-    DWORD              style;
-    WORD               nbItems;
-    WORD               x;
-    WORD               y;
-    WORD               cx;
-    WORD               cy;
-    SEGPTR             menuName;
-    SEGPTR             className;
-    SEGPTR             caption;
-    WORD               pointSize;
-    SEGPTR             faceName;
-} DLGTEMPLATE;
-
-#pragma pack(4)
-
-extern WORD xBaseUnit,yBaseUnit;
-int DIALOG_DoDialogBox( HWND hwnd, HWND owner );
+extern BOOL DIALOG_Init(void);
+extern HWND DIALOG_GetFirstTabItem( HWND hwndDlg );
 
 #endif  /* DIALOG_H */
diff --git a/include/gdi.h b/include/gdi.h
index 96847b9..ac9b3a6 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -185,6 +185,9 @@
 {
     GDIOBJHDR     header;
     WORD          saveLevel;
+    DWORD         dwHookData;
+    FARPROC16     hookProc;
+    HDC           hSelf;
     WIN_DC_INFO   w;
     union
     {
@@ -193,9 +196,18 @@
     } u;
 } DC;
 
+  /* DC hook codes */
+#define DCHC_INVALIDVISRGN      0x0001
+#define DCHC_DELETEDC           0x0002
+
+#define DCHF_INVALIDATEVISRGN   0x0001
+#define DCHF_VALIDATEVISRGN     0x0002
+
   /* DC flags */
-#define DC_MEMORY     1   /* It is a memory DC */
-#define DC_SAVED      2   /* It is a saved DC */
+#define DC_MEMORY     0x0001   /* It is a memory DC */
+#define DC_SAVED      0x0002   /* It is a saved DC */
+#define DC_DIRTY      0x0004   /* hVisRgn has to be updated */
+#define DC_THUNKHOOK  0x0008   /* DC hook is in the 16-bit code */ 
 
   /* Last 32 bytes are reserved for stock object handles */
 #define GDI_HEAP_SIZE               0xffe0
@@ -267,6 +279,10 @@
 extern HANDLE GDI_AllocObject( WORD, WORD );
 extern BOOL GDI_FreeObject( HANDLE );
 extern GDIOBJHDR * GDI_GetObjPtr( HANDLE, WORD );
+extern FARPROC16 GDI_GetDefDCHook(void);
+
+#define UpdateDirtyDC(dc) \
+	    DC_CallHookProc(dc, DCHC_INVALIDVISRGN, 0)
 
 extern Display * display;
 extern Screen * screen;
diff --git a/include/kernel32.h b/include/kernel32.h
index 9b5b014..834cc2f 100644
--- a/include/kernel32.h
+++ b/include/kernel32.h
@@ -119,4 +119,6 @@
 #define FILE_ATTRIBUTE_ATOMIC_WRITE     0x0200
 #define FILE_ATTRIBUTE_XACTION_WRITE    0x0400
 
+BOOL       SetTimeZoneInformation(const TIME_ZONE_INFORMATION*);
+
 #endif  /* __WINE_KERNEL32_H */
diff --git a/include/module.h b/include/module.h
index c867f43..6ded804 100644
--- a/include/module.h
+++ b/include/module.h
@@ -127,7 +127,6 @@
 extern SEGPTR MODULE_GetEntryPoint( HMODULE hModule, WORD ordinal );
 extern BOOL MODULE_SetEntryPoint( HMODULE hModule, WORD ordinal, WORD offset );
 extern FARPROC16 MODULE_GetWndProcEntry16( const char *name );
-extern FARPROC32 MODULE_GetWndProcEntry32( const char *name );
 
 /* builtin.c */
 extern BOOL BUILTIN_Init(void);
diff --git a/include/struct32.h b/include/struct32.h
index a1c1e36..702b918 100644
--- a/include/struct32.h
+++ b/include/struct32.h
@@ -35,16 +35,6 @@
 	WORD cy WINE_PACKED;
 } DLGTEMPLATE32;
 
-typedef struct {
-	DWORD style;
-	DWORD dwExtendedStyle;
-	short x WINE_PACKED;
-	short y WINE_PACKED;
-	short cx WINE_PACKED;
-	short cy WINE_PACKED;
-	WORD id WINE_PACKED;
-} DLGITEMTEMPLATE32;
-
 typedef struct tagMSG32
 {
 	DWORD hwnd;
diff --git a/include/win.h b/include/win.h
index b451832..81e0c08 100644
--- a/include/win.h
+++ b/include/win.h
@@ -34,10 +34,10 @@
     struct tagWND *parent;        /* Window parent (from CreateWindow) */
     struct tagWND *owner;         /* Window owner */
     CLASS         *class;         /* Window class */
+    HANDLE32       winproc;       /* Window procedure */
     DWORD          dwMagic;       /* Magic number (must be WND_MAGIC) */
     HWND16         hwndSelf;      /* Handle of this window */
     HINSTANCE16    hInstance;     /* Window hInstance (from CreateWindow) */
-    WNDPROC16      lpfnWndProc;   /* Window procedure */
     RECT16         rectClient;    /* Client area rel. to parent client area */
     RECT16         rectWindow;    /* Whole window rel. to parent client area */
     RECT16         rectNormal;    /* Window rect. when in normal state */
@@ -57,6 +57,7 @@
     Window         window;        /* X window (only for top-level windows) */
     HMENU          hSysMenu;      /* window's copy of System Menu */
     HANDLE         hProp;         /* Handle of Properties List */
+    DWORD          userdata;      /* User private data */
     DWORD          wExtra[1];     /* Window extra bytes */
 } WND;
 
diff --git a/include/windows.h b/include/windows.h
index 03cf15b..3a1dcec 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1,7 +1,11 @@
 /* Initial draft attempt of windows.h, by Peter MacDonald, pmacdona@sanjuan.uvic.ca */
 
-#ifndef WINDOWS_H
-#define WINDOWS_H
+#ifndef __WINE_WINDOWS_H
+#define __WINE_WINDOWS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 #include "wintypes.h"
 #include "winuser.h"
@@ -544,8 +548,6 @@
   POINT16   pt WINE_PACKED;
 } MSG, *LPMSG;
 	
-#define MAKEINTATOM(i)   ((SEGPTR)MAKELONG((i),0))
-
   /* Raster operations */
 
 #define R2_BLACK         1
@@ -2795,6 +2797,17 @@
         DWORD  dmDisplayFrequency;
 } DEVMODE;
 
+typedef struct _SYSTEM_POWER_STATUS
+{
+  BOOL    ACLineStatus;
+  BYTE    BatteryFlag;
+  BYTE    BatteryLifePercent;
+  BYTE    reserved;
+  DWORD   BatteryLifeTime;
+  DWORD   BatteryFullLifeTime;
+} SYSTEM_POWER_STATUS, *LPSYSTEM_POWER_STATUS;
+
+
 #ifndef WINELIB
 #pragma pack(4)
 #endif
@@ -2863,10 +2876,6 @@
 HDC        CreateDC(LPCSTR,LPCSTR,LPCSTR,const DEVMODE*);
 HBRUSH     CreateDIBPatternBrush(HGLOBAL,UINT);
 HBITMAP    CreateDIBitmap(HDC,BITMAPINFOHEADER*,DWORD,LPVOID,BITMAPINFO*,UINT);
-HWND       CreateDialog(HINSTANCE,SEGPTR,HWND,DLGPROC);
-HWND       CreateDialogIndirect(HINSTANCE,SEGPTR,HWND,DLGPROC);
-HWND       CreateDialogIndirectParam(HINSTANCE,SEGPTR,HWND,DLGPROC,LPARAM);
-HWND       CreateDialogParam(HINSTANCE,SEGPTR,HWND,DLGPROC,LPARAM);
 HBITMAP    CreateDiscardableBitmap(HDC,INT,INT);
 HRGN       CreateEllipticRgn(INT32,INT32,INT32,INT32);
 HFONT      CreateFont(INT,INT,INT,INT,INT,BYTE,BYTE,BYTE,BYTE,BYTE,BYTE,BYTE,BYTE,LPCSTR);
@@ -2885,7 +2894,6 @@
 HRGN       CreateRoundRectRgn(INT32,INT32,INT32,INT32,INT32,INT32);
 HBRUSH     CreateSolidBrush(COLORREF);
 void       DebugBreak(void);
-LRESULT    DefDlgProc(HWND,UINT,WPARAM,LPARAM);
 DWORD      DefHookProc(short,WORD,DWORD,HHOOK*);
 HDWP16     DeferWindowPos(HDWP16,HWND,HWND,INT,INT,INT,INT,UINT);
 ATOM       DeleteAtom(ATOM);
@@ -2898,10 +2906,6 @@
 BOOL       DestroyIcon(HICON);
 BOOL       DestroyMenu(HMENU);
 BOOL       DestroyWindow(HWND);
-INT        DialogBox(HINSTANCE,SEGPTR,HWND,DLGPROC);
-INT        DialogBoxIndirect(HINSTANCE,HANDLE,HWND,DLGPROC);
-INT        DialogBoxIndirectParam(HINSTANCE,HANDLE,HWND,DLGPROC,LONG);
-INT        DialogBoxParam(HINSTANCE,SEGPTR,HWND,DLGPROC,LONG);
 HANDLE     DirectResAlloc(HANDLE,WORD,WORD);
 void       DirectedYield(HTASK);
 LONG       DispatchMessage(const MSG*);
@@ -2920,7 +2924,6 @@
 BOOL       EnableScrollBar(HWND,UINT,UINT);
 BOOL       EnableWindow(HWND,BOOL);
 BOOL       EndDeferWindowPos(HDWP16);
-BOOL       EndDialog(HWND,INT);
 BOOL       EnumChildWindows(HWND,WNDENUMPROC,LPARAM);
 UINT       EnumClipboardFormats(UINT);
 INT        EnumFontFamilies(HDC,LPCSTR,FONTENUMPROC,LPARAM);
@@ -2989,6 +2992,7 @@
 HCURSOR    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);
@@ -3071,6 +3075,7 @@
 int        GetSystemMetrics(WORD);
 WORD       GetSystemPaletteEntries(HDC,WORD,WORD,LPPALETTEENTRY);
 WORD       GetSystemPaletteUse(HDC);
+BOOL       GetSystemPowerStatus(LPSYSTEM_POWER_STATUS);
 VOID       GetSystemTime(LPSYSTEMTIME); /* Win32 */
 DWORD      GetTabbedTextExtent(HDC,LPSTR,int,int,LPINT16);
 HINSTANCE  GetTaskDS(void);
@@ -3247,6 +3252,7 @@
 BOOL32     SetCurrentDirectory(LPCSTR);
 HCURSOR    SetCursor(HCURSOR);
 void       SetCursorPos(short,short);
+BOOL       SetDCHook(HDC,FARPROC16,DWORD);
 void       SetDCState(HDC,HDC);
 int        SetDIBits(HDC,HANDLE,WORD,WORD,LPSTR,LPBITMAPINFO,WORD);
 int        SetDIBitsToDevice(HDC,short,short,WORD,WORD,WORD,WORD,WORD,WORD,LPSTR,LPBITMAPINFO,WORD);
@@ -3257,6 +3263,7 @@
 UINT       SetErrorMode(UINT);
 HWND       SetFocus(HWND);
 WORD       SetHandleCount(WORD);
+WORD       SetHookFlags(HDC,WORD);
 void       SetKeyboardState(BYTE*);
 WORD       SetMapMode(HDC,WORD);
 DWORD      SetMapperFlags(HDC,DWORD);
@@ -3283,6 +3290,8 @@
 void       SetSysColors(int,LPINT16,COLORREF*);
 HWND       SetSysModalWindow(HWND);
 WORD       SetSystemPaletteUse(HDC,WORD);
+BOOL       SetSystemPowerState(BOOL, BOOL);
+BOOL       SetSystemTime(const SYSTEMTIME*);
 WORD       SetSystemTimer(HWND,WORD,WORD,FARPROC);
 HQUEUE     SetTaskQueue(HTASK,HQUEUE);
 WORD       SetTextAlign(HDC,WORD);
@@ -3332,6 +3341,7 @@
 BOOL       UnrealizeObject(HBRUSH);
 int        UpdateColors(HDC);
 void       UpdateWindow(HWND32);
+void       UserYield(void);
 void       ValidateCodeSegments(void);
 LPSTR      ValidateFreeSpaces(void);
 void       ValidateRgn(HWND32,HRGN32);
@@ -3370,13 +3380,13 @@
 
 /* Declarations for functions that are the same in Win16 and Win32 */
 
+BOOL16     EndDialog(HWND32,INT32);
 INT16      ExcludeUpdateRgn(HDC32,HWND32);
 void       FillWindow(HWND16,HWND16,HDC16,HBRUSH16);
 DWORD      GetBitmapDimension(HBITMAP16);
 WORD       GetClassWord(HWND32,INT32);
 DWORD      GetLogicalDrives(void);
 INT16      GetUpdateRgn(HWND32,HRGN32,BOOL32);
-LONG       GetWindowLong(HWND32,INT32);
 WORD       GetWindowWord(HWND32,INT32);
 INT16      OffsetRgn(HRGN32,INT32,INT32);
 DWORD      OffsetViewportOrg(HDC16,INT16,INT16);
@@ -3429,6 +3439,26 @@
 BOOL16     CopyRect16(RECT16*,const RECT16*);
 BOOL32     CopyRect32(RECT32*,const RECT32*);
 #define    CopyRect WINELIB_NAME(CopyRect)
+HWND16     CreateDialog16(HINSTANCE16,SEGPTR,HWND16,DLGPROC);
+#define    CreateDialog32A(inst,ptr,hwnd,dlg) \
+           CreateDialogParam32A(inst,ptr,hwnd,dlg,0)
+#define    CreateDialog32W(inst,ptr,hwnd,dlg) \
+           CreateDialogParam32W(inst,ptr,hwnd,dlg,0)
+#define    CreateDialog WINELIB_NAME_AW(CreateDialog)
+HWND16     CreateDialogIndirect16(HINSTANCE16,LPCVOID,HWND16,DLGPROC);
+#define    CreateDialogIndirect32A(inst,ptr,hwnd,dlg) \
+           CreateDialogIndirectParam32A(inst,ptr,hwnd,dlg,0)
+#define    CreateDialogIndirect32W(inst,ptr,hwnd,dlg) \
+           CreateDialogIndirectParam32W(inst,ptr,hwnd,dlg,0)
+#define    CreateDialogIndirect WINELIB_NAME_AW(CreateDialogIndirect)
+HWND16     CreateDialogIndirectParam16(HINSTANCE16,LPCVOID,HWND16,DLGPROC,LPARAM);
+HWND32     CreateDialogIndirectParam32A(HINSTANCE32,LPCVOID,HWND32,DLGPROC,LPARAM);
+HWND32     CreateDialogIndirectParam32W(HINSTANCE32,LPCVOID,HWND32,DLGPROC,LPARAM);
+#define    CreateDialogIndirectParam WINELIB_NAME_AW(CreateDialogIndirectParam)
+HWND16     CreateDialogParam16(HINSTANCE16,SEGPTR,HWND16,DLGPROC,LPARAM);
+HWND32     CreateDialogParam32A(HINSTANCE32,LPCSTR,HWND32,DLGPROC,LPARAM);
+HWND32     CreateDialogParam32W(HINSTANCE32,LPCWSTR,HWND32,DLGPROC,LPARAM);
+#define    CreateDialogParam WINELIB_NAME_AW(CreateDialogParam)
 HRGN16     CreateEllipticRgnIndirect16(const RECT16 *);
 HRGN32     CreateEllipticRgnIndirect32(const RECT32 *);
 #define    CreateEllipticRgnIndirect WINELIB_NAME(CreateEllipticRgnIndirect)
@@ -3441,7 +3471,7 @@
 HRGN16     CreateRectRgnIndirect16(const RECT16*);
 HRGN32     CreateRectRgnIndirect32(const RECT32*);
 #define    CreateRectRgnIndirect WINELIB_NAME(CreateRectRgnIndirect)
-HWND16     CreateWindow16(SEGPTR,SEGPTR,DWORD,INT16,INT16,INT16,INT16,HWND16,HMENU16,HINSTANCE16,SEGPTR);
+HWND16     CreateWindow16(LPCSTR,LPCSTR,DWORD,INT16,INT16,INT16,INT16,HWND16,HMENU16,HINSTANCE16,LPVOID);
 #define    CreateWindow32A(className,titleName,style,x,y,width,height,\
                            parent,menu,instance,param) \
            CreateWindowEx32A(0,className,titleName,style,x,y,width,height,\
@@ -3451,10 +3481,14 @@
            CreateWindowEx32W(0,className,titleName,style,x,y,width,height,\
                            parent,menu,instance,param)
 #define    CreateWindow WINELIB_NAME_AW(CreateWindow)
-HWND16     CreateWindowEx16(DWORD,SEGPTR,SEGPTR,DWORD,INT16,INT16,INT16,INT16,HWND16,HMENU16,HINSTANCE16,SEGPTR);
+HWND16     CreateWindowEx16(DWORD,LPCSTR,LPCSTR,DWORD,INT16,INT16,INT16,INT16,HWND16,HMENU16,HINSTANCE16,LPVOID);
 HWND32     CreateWindowEx32A(DWORD,LPCSTR,LPCSTR,DWORD,INT32,INT32,INT32,INT32,HWND32,HMENU32,HINSTANCE32,LPVOID);
 HWND32     CreateWindowEx32W(DWORD,LPCWSTR,LPCWSTR,DWORD,INT32,INT32,INT32,INT32,HWND32,HMENU32,HINSTANCE32,LPVOID);
 #define    CreateWindowEx WINELIB_NAME_AW(CreateWindowEx)
+LRESULT    DefDlgProc16(HWND16,UINT16,WPARAM16,LPARAM);
+LRESULT    DefDlgProc32A(HWND32,UINT32,WPARAM32,LPARAM);
+LRESULT    DefDlgProc32W(HWND32,UINT32,WPARAM32,LPARAM);
+#define    DefDlgProc WINELIB_NAME_AW(DefDlgProc)
 LRESULT    DefFrameProc16(HWND16,HWND16,UINT16,WPARAM16,LPARAM);
 LRESULT    DefFrameProc32A(HWND32,HWND32,UINT32,WPARAM32,LPARAM);
 LRESULT    DefFrameProc32W(HWND32,HWND32,UINT32,WPARAM32,LPARAM);
@@ -3467,6 +3501,26 @@
 LRESULT    DefWindowProc32A(HWND32,UINT32,WPARAM32,LPARAM);
 LRESULT    DefWindowProc32W(HWND32,UINT32,WPARAM32,LPARAM);
 #define    DefWindowProc WINELIB_NAME_AW(DefWindowProc)
+INT16      DialogBox16(HINSTANCE16,SEGPTR,HWND16,DLGPROC);
+#define    DialogBox32A(inst,template,owner,func) \
+           DialogBoxParam32A(inst,template,owner,func,0)
+#define    DialogBox32W(inst,template,owner,func) \
+           DialogBoxParam32W(inst,template,owner,func,0)
+#define    DialogBox WINELIB_NAME_AW(DialogBox)
+INT16      DialogBoxIndirect16(HINSTANCE16,HANDLE16,HWND16,DLGPROC);
+#define    DialogBoxIndirect32A(inst,template,owner,func) \
+           DialogBoxIndirectParam32A(inst,template,owner,func,0)
+#define    DialogBoxIndirect32W(inst,template,owner,func) \
+           DialogBoxIndirectParam32W(inst,template,owner,func,0)
+#define    DialogBoxIndirect WINELIB_NAME_AW(DialogBoxIndirect)
+INT16      DialogBoxIndirectParam16(HINSTANCE16,HANDLE16,HWND16,DLGPROC,LPARAM);
+INT32      DialogBoxIndirectParam32A(HINSTANCE32,LPCVOID,HWND32,DLGPROC,LPARAM);
+INT32      DialogBoxIndirectParam32W(HINSTANCE32,LPCVOID,HWND32,DLGPROC,LPARAM);
+#define    DialogBoxIndirectParam WINELIB_NAME_AW(DialogBoxIndirectParam)
+INT16      DialogBoxParam16(HINSTANCE16,SEGPTR,HWND16,DLGPROC,LPARAM);
+INT32      DialogBoxParam32A(HINSTANCE32,LPCSTR,HWND32,DLGPROC,LPARAM);
+INT32      DialogBoxParam32W(HINSTANCE32,LPCWSTR,HWND32,DLGPROC,LPARAM);
+#define    DialogBoxParam WINELIB_NAME_AW(DialogBoxParam)
 INT16      DlgDirListComboBox16(HWND16,LPCSTR,INT16,INT16,UINT16);
 INT32      DlgDirListComboBox32A(HWND32,LPCSTR,INT32,INT32,UINT32);
 INT32      DlgDirListComboBox32W(HWND32,LPCWSTR,INT32,INT32,UINT32);
@@ -3574,6 +3628,10 @@
 BOOL16     GetWindowExtEx16(HDC16,LPPOINT16);
 BOOL32     GetWindowExtEx32(HDC32,LPPOINT32);
 #define    GetWindowExtEx WINELIB_NAME(GetWindowExtEx)
+LONG       GetWindowLong16(HWND16,INT16);
+LONG       GetWindowLong32A(HWND32,INT32);
+LONG       GetWindowLong32W(HWND32,INT32);
+#define    GetWindowLong WINELIB_NAME_AW(GetWindowLong)
 BOOL16     GetWindowOrgEx16(HDC16,LPPOINT16);
 BOOL32     GetWindowOrgEx32(HDC32,LPPOINT32);
 #define    GetWindowOrgEx WINELIB_NAME(GetWindowOrgEx)
@@ -3890,4 +3948,9 @@
 #ifdef WINELIB
 #define WINELIB_UNIMP(x) fprintf (stderr, "WineLib: Unimplemented %s\n", x)
 #endif
-#endif  /* WINDOWS_H */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* __WINE_WINDOWS_H */
diff --git a/include/winproc.h b/include/winproc.h
index c26546c..7f799e1 100644
--- a/include/winproc.h
+++ b/include/winproc.h
@@ -17,9 +17,11 @@
     WIN_PROC_32W
 } WINDOWPROCTYPE;
 
-extern WNDPROC16 WINPROC_AllocWinProc( WNDPROC32 func, WINDOWPROCTYPE type );
-extern WINDOWPROCTYPE WINPROC_GetWinProcType( WNDPROC16 func );
-extern WNDPROC32 WINPROC_GetWinProcFunc( WNDPROC16 func );
-extern void WINPROC_FreeWinProc( WNDPROC16 func );
+extern HANDLE32 WINPROC_AllocWinProc( UINT32 func, WINDOWPROCTYPE type );
+extern HANDLE32 WINPROC_CopyWinProc( HANDLE32 handle );
+extern void WINPROC_FreeWinProc( HANDLE32 handle );
+extern WINDOWPROCTYPE WINPROC_GetWinProcType( HANDLE32 handle );
+extern WNDPROC16 WINPROC_GetFunc16( HANDLE32 handle );
+extern WNDPROC32 WINPROC_GetFunc32( HANDLE32 handle );
 
 #endif  /* __WINE_WINPROC_H */
diff --git a/include/wintypes.h b/include/wintypes.h
index 0ed35af..97718cc 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -345,6 +345,7 @@
                                        (((DWORD)((WORD)(high))) << 16)))
 #define MAKELPARAM(low,high)   ((LPARAM)MAKELONG(low,high))
 #define MAKEWPARAM(low,high)   ((WPARAM32)MAKELONG(low,high))
+#define MAKEINTATOM(atom)      ((LPCSTR)MAKELONG((atom),0))
 
 #define SELECTOROF(ptr)     (HIWORD(ptr))
 #define OFFSETOF(ptr)       (LOWORD(ptr))
diff --git a/ipc/dde_proc.c b/ipc/dde_proc.c
index 660dfd6..b65b5fa 100644
--- a/ipc/dde_proc.c
+++ b/ipc/dde_proc.c
@@ -452,7 +452,7 @@
 		    remote_message->wParam, (int)remote_message->lParam);
 
 	/* execute the recieved message */
-	passed= SendMessage(dde_window, remote_message->message,
+	passed= SendMessage16(dde_window, remote_message->message,
 			    remote_message->wParam, remote_message->lParam);
 
 	/* Tell the sended, that the message is here */
@@ -481,7 +481,7 @@
   {
      if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION) {
 	if (was_sent)
-	   SendMessage( wndPtr->hwndSelf, remote_message->message,
+	   SendMessage16( wndPtr->hwndSelf, remote_message->message,
 			remote_message->wParam, remote_message->lParam );
 	else
 	   PostMessage( wndPtr->hwndSelf, remote_message->message,
@@ -528,7 +528,7 @@
   if (hwnd==0)
       hwnd=-1;
   /* just send a message to see how things are going */
-  SendMessage( hwnd, WM_DDE_INITIATE, 0, 0);
+  SendMessage16( hwnd, WM_DDE_INITIATE, 0, 0);
 }
 
 void dde_proc_delete(int proc_idx)
@@ -553,7 +553,7 @@
 
 static void print_dde_message(char *desc, MSG *msg)
 {
-    extern const char *MessageTypeNames[];
+/*    extern const char *MessageTypeNames[];*/
     extern int debug_last_handle_size;
     WORD wStatus,hWord;
     void *ptr;
@@ -571,7 +571,7 @@
 
     fprintf(stddeb,"%s", desc);
     fprintf(stddeb,"%04x %04x==%s %04x %08lx ",
-	    msg->hwnd, msg->message,MessageTypeNames[msg->message],
+	    msg->hwnd, msg->message,"",/*MessageTypeNames[msg->message],*/
 	    msg->wParam, msg->lParam);
     switch(msg->message) {
       case WM_DDE_INITIATE:
diff --git a/library/miscstubs.c b/library/miscstubs.c
index 0999340..ed8aaa7 100644
--- a/library/miscstubs.c
+++ b/library/miscstubs.c
@@ -103,16 +103,6 @@
   return ErrorProc;
 }
 
-/***********************************************************************
- *           MODULE_GetWndProcEntry32 (not a Windows API function)
- *
- * Return an entry point from the WPROCS32 dll.
- */
-WNDPROC MODULE_GetWndProcEntry32( char *name )
-{
-    return MODULE_GetWndProcEntry16( name );
-}
-
 void DEBUG_EnterDebugger(void)
 {
 }
diff --git a/loader/builtin.c b/loader/builtin.c
index e261ab0..76c0d29 100644
--- a/loader/builtin.c
+++ b/loader/builtin.c
@@ -103,7 +103,6 @@
 extern const DLL_DESCRIPTOR NTDLL_Descriptor;
 extern const DLL_DESCRIPTOR SHELL32_Descriptor;
 extern const DLL_DESCRIPTOR USER32_Descriptor;
-extern const DLL_DESCRIPTOR WPROCS32_Descriptor;
 extern const DLL_DESCRIPTOR WINSPOOL_Descriptor;
 extern const DLL_DESCRIPTOR WSOCK32_Descriptor;
 
@@ -151,7 +150,6 @@
     { &NTDLL_Descriptor,    0 },
     { &SHELL32_Descriptor,  0 },
     { &USER32_Descriptor,   0 },
-    { &WPROCS32_Descriptor, DLL_FLAG_ALWAYS_USED },
     { &WINSPOOL_Descriptor, 0 },
     { &WSOCK32_Descriptor,  0 },
     /* Last entry */
diff --git a/loader/module.c b/loader/module.c
index f6638fd..9257c75 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -775,25 +775,6 @@
 
 
 /***********************************************************************
- *           MODULE_GetWndProcEntry32  (not a Windows API function)
- *
- * Return an entry point from the WPROCS32 dll.
- */
-#ifndef WINELIB
-FARPROC32 MODULE_GetWndProcEntry32( const char *name )
-{
-    FARPROC32 ret;
-    static HMODULE hModule = 0;
-
-    if (!hModule) hModule = GetModuleHandle( "WPROCS32" );
-    if (!(ret = PE_GetProcAddress( hModule, name )))
-        fprintf( stderr, "GetWndProc32: %s not found, please report\n", name );
-    return ret;
-}
-#endif
-
-
-/***********************************************************************
  *           MODULE_GetModuleName
  */
 LPSTR MODULE_GetModuleName( HMODULE hModule )
@@ -1003,7 +984,7 @@
                     char *p;
 
                     /* Try with prepending the path of the current module */
-                    GetModuleFileName( hModule, buffer, 256 );
+                    GetModuleFileName( hModule, buffer, sizeof(buffer) );
                     if (!(p = strrchr( buffer, '\\' ))) p = buffer;
                     memcpy( p + 1, pstr + 1, *pstr );
                     strcpy( p + 1 + *pstr, ".dll" );
@@ -1033,6 +1014,7 @@
 		/* Handle self loading modules */
 		SEGTABLEENTRY * pSegTable = (SEGTABLEENTRY *) NE_SEG_TABLE(pModule);
 		SELFLOADHEADER *selfloadheader;
+                STACK16FRAME *stack16Top;
 		HMODULE hselfload = GetModuleHandle("WPROCS");
 		WORD oldss, oldsp, saved_dgroup = pSegTable[pModule->dgroup - 1].selector;
 		fprintf (stderr, "Warning:  %*.*s is a self-loading module\n"
@@ -1054,7 +1036,18 @@
 		oldss = IF1632_Saved16_ss;
 		oldsp = IF1632_Saved16_sp;
 		IF1632_Saved16_ss = pModule->self_loading_sel;
-		IF1632_Saved16_sp = 0xFF00;
+		IF1632_Saved16_sp = 0xFF00 - sizeof(*stack16Top);
+                stack16Top = CURRENT_STACK16;
+                stack16Top->saved_ss = 0;
+                stack16Top->saved_sp = 0;
+                stack16Top->ds = stack16Top->es = pModule->self_loading_sel;
+                stack16Top->entry_point = 0;
+                stack16Top->entry_ip = 0;
+                stack16Top->entry_cs = 0;
+                stack16Top->bp = 0;
+                stack16Top->ip = 0;
+                stack16Top->cs = 0;
+
 		if (!IF1632_Stack32_base) {
 		  STACK32FRAME* frame32;
 		  char *stack32Top;
diff --git a/loader/ne_image.c b/loader/ne_image.c
index 8fb2030..9ef9966 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -65,6 +65,7 @@
 #ifndef WINELIB
  	/* Implement self loading segments */
  	SELFLOADHEADER *selfloadheader;
+        STACK16FRAME *stack16Top;
  	WORD oldss, oldsp, oldselector, newselector;
  	selfloadheader = (SELFLOADHEADER *)
  		PTR_SEG_OFF_TO_LIN(pSegTable->selector,0);
@@ -72,7 +73,17 @@
  	oldsp = IF1632_Saved16_sp;
  	oldselector = pSeg->selector;
  	IF1632_Saved16_ss = pModule->self_loading_sel;
- 	IF1632_Saved16_sp = 0xFF00;
+ 	IF1632_Saved16_sp = 0xFF00 - sizeof(*stack16Top);
+        stack16Top = CURRENT_STACK16;
+        stack16Top->saved_ss = 0;
+        stack16Top->saved_sp = 0;
+        stack16Top->ds = stack16Top->es = pModule->self_loading_sel;
+        stack16Top->entry_point = 0;
+        stack16Top->entry_ip = 0;
+        stack16Top->entry_cs = 0;
+        stack16Top->bp = 0;
+        stack16Top->ip = 0;
+        stack16Top->cs = 0;
         /* FIXME: we probably need to pass a DOS file handle here */
  	newselector =  CallTo16_word_www(selfloadheader->LoadAppSeg,
  		pModule->self_loading_sel, hModule, fd, segnum);
diff --git a/loader/pe_image.c b/loader/pe_image.c
index fffff8a..e97df39 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -170,6 +170,16 @@
   	char *name = (char*)load_addr+pe_imp->ModuleName;
 	mod_ptr[i] = LoadModule(name,(LPVOID)-1);
 	if(mod_ptr[i]<=(HMODULE)32)
+        {
+            char *p, buffer[256];
+
+            /* Try with prepending the path of the current module */
+            GetModuleFileName( hModule, buffer, sizeof(buffer) );
+            if (!(p = strrchr( buffer, '\\' ))) p = buffer;
+            strcpy( p + 1, name );
+            mod_ptr[i] = LoadModule( buffer, (LPVOID)-1 );
+        }
+	if(mod_ptr[i]<=(HMODULE)32)
 	{
 		fprintf(stderr,"Module %s not found\n",name);
 		exit(0);
diff --git a/misc/clipboard.c b/misc/clipboard.c
index 0cc5848..a9c01d9 100644
--- a/misc/clipboard.c
+++ b/misc/clipboard.c
@@ -2,27 +2,33 @@
  * 'Wine' Clipboard function handling
  *
  * Copyright 1994 Martin Ayotte
-static char Copyright[] = "Copyright Martin Ayotte, 1994";
-*/
+ *	     1996 Alex Korobka
+ *
+ */
 
 #include <stdlib.h>
 #include <stdio.h>
-#include <windows.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <string.h>
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
+#include "windows.h"
 #include "win.h"
 #include "message.h"
 #include "clipboard.h"
+#include "xmalloc.h"
 #include "stddebug.h"
 #include "debug.h"
 
+#define  CF_REGFORMATBASE 	0xC000
+
 typedef struct tagCLIPFORMAT {
     WORD	wFormatID;
     WORD	wRefCount;
+    WORD	wDataPresent;
     LPSTR	Name;
     HANDLE	hData;
     DWORD	BufSize;
@@ -30,36 +36,132 @@
     void	*NextFormat;
 } CLIPFORMAT, *LPCLIPFORMAT;
 
-static HWND hWndClipboardOwner = 0;
-static HWND hWndViewer = 0;
-static WORD LastRegFormat = 0xC000;
+/* *************************************************************************
+ *			internal variables
+ */
+
+static HWND hWndClipOwner  = 0;		/* current clipboard owner */
+static HWND hWndClipWindow = 0;		/* window that opened clipboard */
+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;
 
-CLIPFORMAT ClipFormats[12]  = {
-    { CF_TEXT, 1, "Text", (HANDLE)NULL, 0, NULL, &ClipFormats[1] },
-    { CF_BITMAP, 1, "Bitmap", (HANDLE)NULL, 0, &ClipFormats[0], &ClipFormats[2] },
-    { CF_METAFILEPICT, 1, "MetaFile Picture", (HANDLE)NULL, 0, &ClipFormats[1], &ClipFormats[3] },
-    { CF_SYLK, 1, "Sylk", (HANDLE)NULL, 0, &ClipFormats[2], &ClipFormats[4] },
-    { CF_DIF, 1, "DIF", (HANDLE)NULL, 0, &ClipFormats[3], &ClipFormats[5] },
-    { CF_TIFF, 1, "TIFF", (HANDLE)NULL, 0, &ClipFormats[4], &ClipFormats[6] },
-    { CF_OEMTEXT, 1, "OEM Text", (HANDLE)NULL, 0, &ClipFormats[5], &ClipFormats[7] },
-    { CF_DIB, 1, "DIB", (HANDLE)NULL, 0, &ClipFormats[6], &ClipFormats[8] },
-    { CF_PALETTE, 1, "Palette", (HANDLE)NULL, 0, &ClipFormats[7], &ClipFormats[9] },
-    { CF_PENDATA, 1, "PenData", (HANDLE)NULL, 0, &ClipFormats[8], &ClipFormats[10] },
-    { CF_RIFF, 1, "RIFF", (HANDLE)NULL, 0, &ClipFormats[9], &ClipFormats[11] },
-    { CF_WAVE, 1, "Wave", (HANDLE)NULL, 0, &ClipFormats[10], NULL }
+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 }
     };
 
 /**************************************************************************
+ *			CLIPBOARD_DisOwn
+ */
+void CLIPBOARD_DisOwn(HWND hWnd)
+{
+  LPCLIPFORMAT lpFormat = ClipFormats;
+
+  if( hWnd != hWndClipOwner || !hWndClipOwner ) return;
+
+  SendMessage16(hWndClipOwner,WM_RENDERALLFORMATS,0,0L);
+
+  /* check if all formats were rendered */
+
+  while(lpFormat)
+    { 
+       if( lpFormat->wDataPresent && !lpFormat->hData )
+	 {
+	   dprintf_clipboard(stddeb,"\tdata missing for clipboard format %i\n", lpFormat->wFormatID); 
+	   lpFormat->wDataPresent = 0;
+	 }
+       lpFormat = lpFormat->NextFormat;
+    }
+
+  hWndClipOwner = 0;
+}
+
+/**************************************************************************
+ *			CLIPBOARD_DeleteRecord
+ */
+void CLIPBOARD_DeleteRecord(LPCLIPFORMAT lpFormat)
+{
+  if( lpFormat->wFormatID >= CF_GDIOBJFIRST &&
+      lpFormat->wFormatID <= CF_GDIOBJLAST )
+      DeleteObject(lpFormat->hData);
+  else if( lpFormat->hData )
+           GlobalFree16(lpFormat->hData);
+
+  lpFormat->wDataPresent = 0; 
+  lpFormat->hData = 0;
+
+  bClipChanged = TRUE;
+}
+
+/**************************************************************************
+ *			CLIPBOARD_RequestXSelection
+ */
+BOOL CLIPBOARD_RequestXSelection()
+{
+  wait_for_selection=True;
+  dprintf_clipboard(stddeb,"Requesting selection\n");
+
+  XConvertSelection(display,XA_PRIMARY,XA_STRING,
+                    XInternAtom(display,"PRIMARY_TEXT",False),
+                    WIN_GetXWindow(hWndClipWindow),CurrentTime);
+
+  /* TODO: need time-out for broken clients */
+  while(wait_for_selection) EVENT_WaitXEvent(-1);
+
+  return (BOOL)ClipFormats[0].wDataPresent;
+}
+
+/**************************************************************************
+ *			CLIPBOARD_IsPresent
+ */
+BOOL CLIPBOARD_IsPresent(WORD wFormat)
+{
+    LPCLIPFORMAT lpFormat = ClipFormats; 
+
+    while(TRUE) {
+        if (lpFormat == NULL) return FALSE;
+        if (lpFormat->wFormatID == wFormat) break;
+        lpFormat = lpFormat->NextFormat;
+        }
+    return (lpFormat->wDataPresent);
+}
+
+/**************************************************************************
  *			OpenClipboard		[USER.137]
  */
 BOOL OpenClipboard(HWND hWnd)
 {
-    if (hWndClipboardOwner != 0) return FALSE;
-    hWndClipboardOwner = hWnd;
-    dprintf_clipboard(stddeb,"OpenClipboard(%04x); !\n", hWnd);
-    return TRUE;
+    BOOL bRet = FALSE;
+    dprintf_clipboard(stddeb,"OpenClipboard(%04x) = ", hWnd);
+
+    if (!hWndClipWindow)
+       {
+    	 hWndClipWindow = hWnd;
+	 bRet = TRUE;
+       }
+    bClipChanged = FALSE;
+
+    dprintf_clipboard(stddeb,"%i\n", bRet);
+    return bRet;
 }
 
 
@@ -68,9 +170,13 @@
  */
 BOOL CloseClipboard()
 {
-    if (hWndClipboardOwner == 0) return FALSE;
-    hWndClipboardOwner = 0;
     dprintf_clipboard(stddeb,"CloseClipboard(); !\n");
+
+    if (hWndClipWindow == 0) return FALSE;
+    hWndClipWindow = 0;
+
+    if (bClipChanged && hWndViewer) SendMessage16(hWndViewer,WM_DRAWCLIPBOARD,0,0L);
+
     return TRUE;
 }
 
@@ -81,16 +187,26 @@
 BOOL EmptyClipboard()
 {
     LPCLIPFORMAT lpFormat = ClipFormats; 
-    if (hWndClipboardOwner == 0) return FALSE;
-    dprintf_clipboard(stddeb,"EmptyClipboard(); !\n");
-    while(TRUE) {
-	if (lpFormat == NULL) break;
-	if (lpFormat->hData != 0) {
-	    GlobalFree16(lpFormat->hData);
-	    lpFormat->hData = 0;
-	    }
+
+    dprintf_clipboard(stddeb,"EmptyClipboard()\n");
+
+    if (hWndClipWindow == 0) return FALSE;
+
+    /* destroy private objects */
+
+    if (hWndClipOwner)
+	SendMessage16(hWndClipOwner,WM_DESTROYCLIPBOARD,0,0L);
+  
+    while(lpFormat) 
+      {
+	if ( lpFormat->wDataPresent )
+	     CLIPBOARD_DeleteRecord( lpFormat );
+
 	lpFormat = lpFormat->NextFormat;
-	}
+      }
+
+    hWndClipOwner = hWndClipWindow;
+
     if(wineOwnsSelection){
         dprintf_clipboard(stddeb,"Losing selection\n");
 	wineOwnsSelection=False;
@@ -106,8 +222,8 @@
 HWND GetClipboardOwner()
 {
     dprintf_clipboard(stddeb,
-		"GetClipboardOwner() = %04x !\n", hWndClipboardOwner);
-    return hWndClipboardOwner;
+		"GetClipboardOwner() = %04x !\n", hWndClipOwner);
+    return hWndClipOwner;
 }
 
 
@@ -117,20 +233,40 @@
 HANDLE SetClipboardData(WORD wFormat, HANDLE hData)
 {
     LPCLIPFORMAT lpFormat = ClipFormats; 
+    Window       owner;
+
     dprintf_clipboard(stddeb,
 		"SetClipboardDate(%04X, %04x) !\n", wFormat, hData);
-    while(TRUE) {
+
+    while(TRUE) 
+      {
 	if (lpFormat == NULL) return 0;
 	if (lpFormat->wFormatID == wFormat) break;
 	lpFormat = lpFormat->NextFormat;
-	}
-    /* doc says we shouldn't use CurrentTime */
-    /* should we become owner of CLIPBOARD as well? */
-    XSetSelectionOwner(display,XA_PRIMARY,WIN_GetXWindow(hWndClipboardOwner),CurrentTime);
-    wineOwnsSelection = True;
-    dprintf_clipboard(stddeb,"Getting selection\n");
-    if (lpFormat->hData != 0) GlobalFree16(lpFormat->hData);
+      }
+
+    /* Acquire X selection:
+     *
+     * doc says we shouldn't use CurrentTime 
+     * should we become owner of CLIPBOARD as well? 
+     */
+
+    owner = WIN_GetXWindow(hWndClipWindow);
+
+    XSetSelectionOwner(display,XA_PRIMARY,owner,CurrentTime);
+    if( XGetSelectionOwner(display,XA_PRIMARY) == owner )
+      {
+        wineOwnsSelection = True;
+        dprintf_clipboard(stddeb,"Getting selection\n");
+      }
+
+    if ( lpFormat->wDataPresent ) 
+         CLIPBOARD_DeleteRecord(lpFormat);
+
+    bClipChanged = TRUE;
+    lpFormat->wDataPresent = TRUE;
     lpFormat->hData = hData;
+
     return lpFormat->hData;
 }
 
@@ -141,22 +277,26 @@
 HANDLE GetClipboardData(WORD wFormat)
 {
     LPCLIPFORMAT lpFormat = ClipFormats; 
-    dprintf_clipboard(stddeb,"GetClipboardData(%04X) !\n", wFormat);
-    if (!hWndClipboardOwner) return 0;
-    if(wFormat == CF_TEXT && !wineOwnsSelection)
-    {	wait_for_selection=True;
-        dprintf_clipboard(stddeb,"Requesting selection\n");
-	XConvertSelection(display,XA_PRIMARY,XA_STRING,
-		XInternAtom(display,"PRIMARY_TEXT",False),
-		WIN_GetXWindow(hWndClipboardOwner),CurrentTime);
-	/* TODO: need time-out for broken clients */
-	while(wait_for_selection) EVENT_WaitXEvent(-1);
-    }
+    dprintf_clipboard(stddeb,"GetClipboardData(%04X)\n", wFormat);
+
+    if (!hWndClipWindow) return 0;
+
+    /*  if(wFormat == CF_TEXT && !wineOwnsSelection)
+        CLIPBOARD_RequestXSelection(); 
+     */
+
     while(TRUE) {
 	if (lpFormat == NULL) return 0;
 	if (lpFormat->wFormatID == wFormat) break;
 	lpFormat = lpFormat->NextFormat;
 	}
+
+    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;
 }
 
@@ -166,19 +306,23 @@
  */
 INT CountClipboardFormats()
 {
-    int FormatCount = 0;
+    int 	 FormatCount = 0;
     LPCLIPFORMAT lpFormat = ClipFormats; 
+
+    dprintf_clipboard(stddeb,"CountClipboardFormats()\n");
+
     while(TRUE) {
 	if (lpFormat == NULL) break;
-	if (lpFormat->hData != 0) {
-        dprintf_clipboard(stddeb,
-		"CountClipboardFormats // Find Not Empty (%04x) !\n",
-					lpFormat->hData);
-	    FormatCount++;
+	if (lpFormat->wDataPresent) 
+	    {
+               dprintf_clipboard(stddeb, "\tdata found for format %i\n", lpFormat->wFormatID);
+
+	       FormatCount++;
 	    }
 	lpFormat = lpFormat->NextFormat;
 	}
-    dprintf_clipboard(stddeb,"CountClipboardFormats() = %d !\n", FormatCount);
+
+    dprintf_clipboard(stddeb,"\ttotal %d\n", FormatCount);
     return FormatCount;
 }
 
@@ -189,28 +333,37 @@
 UINT EnumClipboardFormats(UINT wFormat)
 {
     LPCLIPFORMAT lpFormat = ClipFormats; 
-    dprintf_clipboard(stddeb,"EnumClipboardFormats(%04X) !\n", wFormat);
+
+    dprintf_clipboard(stddeb,"EnumClipboardFormats(%04X)\n", wFormat);
+
+    if( (!wFormat || wFormat == CF_TEXT) && !wineOwnsSelection)
+        CLIPBOARD_RequestXSelection();
+
     if (wFormat == 0) {
-	if (lpFormat->hData != 0) 
+	if (lpFormat->wDataPresent) 
 	    return lpFormat->wFormatID;
 	else 
 	    wFormat = lpFormat->wFormatID;
 	}
+
+    /* walk up to the specified format record */
+
     while(TRUE) {
 	if (lpFormat == NULL) return 0;
 	if (lpFormat->wFormatID == wFormat) break;
 	lpFormat = lpFormat->NextFormat;
 	}
-    dprintf_clipboard(stddeb,"EnumClipboardFormats // Find Last (%04X) !\n",
-				lpFormat->wFormatID);
+
+    /* find next format with available data */
+
     lpFormat = lpFormat->NextFormat;
     while(TRUE) {
 	if (lpFormat == NULL) return 0;
-	if (lpFormat->hData != 0) break;
+	if (lpFormat->wDataPresent ) break;
 	lpFormat = lpFormat->NextFormat;
 	}
-    dprintf_clipboard(stddeb,
-		"EnumClipboardFormats // Find Not Empty Id=%04X hData=%04x !\n",
+
+    dprintf_clipboard(stddeb, "\t got not empty - Id=%04X hData=%04x !\n",
 				lpFormat->wFormatID, lpFormat->hData);
     return lpFormat->wFormatID;
 }
@@ -223,27 +376,41 @@
 {
     LPCLIPFORMAT lpNewFormat; 
     LPCLIPFORMAT lpFormat = ClipFormats; 
+
     if (FormatName == NULL) return 0;
+
+    dprintf_clipboard(stddeb,"RegisterClipboardFormat('%s') !\n", FormatName);
+
+    /* walk format chain to see if it's already registered */
+
     while(TRUE) {
-	if (lpFormat->NextFormat == NULL) break;
+	if ( !strcmp(lpFormat->Name,FormatName) )
+	   {
+	     lpFormat->wRefCount++;
+	     return lpFormat->wFormatID;
+	   }
+ 
+	if ( lpFormat->NextFormat == NULL ) break;
+
 	lpFormat = lpFormat->NextFormat;
 	}
-    lpNewFormat = (LPCLIPFORMAT)malloc(sizeof(CLIPFORMAT));
-    if (lpNewFormat == NULL) return 0;
+
+    /* allocate storage for new format entry */
+
+    lpNewFormat = (LPCLIPFORMAT)xmalloc(sizeof(CLIPFORMAT));
     lpFormat->NextFormat = lpNewFormat;
-    dprintf_clipboard(stddeb,"RegisterClipboardFormat('%s') !\n", FormatName);
     lpNewFormat->wFormatID = LastRegFormat;
     lpNewFormat->wRefCount = 1;
-    lpNewFormat->Name = (LPSTR)malloc(strlen(FormatName) + 1);
-    if (lpNewFormat->Name == NULL) {
-	free(lpNewFormat);
-    	return 0;
-    	}
+
+    lpNewFormat->Name = (LPSTR)xmalloc(strlen(FormatName) + 1);
     strcpy(lpNewFormat->Name, FormatName);
+
+    lpNewFormat->wDataPresent = 0;
     lpNewFormat->hData = 0;
     lpNewFormat->BufSize = 0;
     lpNewFormat->PrevFormat = lpFormat;
     lpNewFormat->NextFormat = NULL;
+
     return LastRegFormat++;
 }
 
@@ -254,21 +421,26 @@
 int GetClipboardFormatName(WORD wFormat, LPSTR retStr, short maxlen)
 {
     LPCLIPFORMAT lpFormat = ClipFormats; 
+
     dprintf_clipboard(stddeb,
 	"GetClipboardFormat(%04X, %p, %d) !\n", wFormat, retStr, maxlen);
+
     while(TRUE) {
 	if (lpFormat == NULL) return 0;
 	if (lpFormat->wFormatID == wFormat) break;
 	lpFormat = lpFormat->NextFormat;
 	}
-    if (lpFormat->Name == NULL) return 0;
+
+    if (lpFormat->Name == NULL || 
+	lpFormat->wFormatID < CF_REGFORMATBASE) return 0;
+
     dprintf_clipboard(stddeb,
 		"GetClipboardFormat // Name='%s' !\n", lpFormat->Name);
-    maxlen = MIN(maxlen - 1, strlen(lpFormat->Name));
-    dprintf_clipboard(stddeb,"GetClipboardFormat // maxlen=%d !\n", maxlen);
-    memcpy(retStr, lpFormat->Name, maxlen);
+
+    strncpy(retStr, lpFormat->Name, maxlen - 1);
     retStr[maxlen] = 0;
-    return maxlen;
+
+    return strlen(retStr);
 }
 
 
@@ -278,7 +450,9 @@
 HWND SetClipboardViewer(HWND hWnd)
 {
     HWND hwndPrev = hWndViewer;
-    dprintf_clipboard(stddeb,"SetClipboardViewer(%04x) !\n", hWnd);
+
+    dprintf_clipboard(stddeb,"SetClipboardViewer(%04x)\n", hWnd);
+
     hWndViewer = hWnd;
     return hwndPrev;
 }
@@ -289,7 +463,8 @@
  */
 HWND GetClipboardViewer()
 {
-    dprintf_clipboard(stddeb,"GetClipboardFormat() = %04x !\n", hWndViewer);
+    dprintf_clipboard(stddeb,"GetClipboardFormat() = %04x\n", hWndViewer);
+
     return hWndViewer;
 }
 
@@ -299,10 +474,18 @@
  */
 BOOL ChangeClipboardChain(HWND hWnd, HWND hWndNext)
 {
-    dprintf_clipboard(stdnimp,
-		"ChangeClipboardChain(%04x, %04x) !\n", hWnd, hWndNext);
+    BOOL bRet = 0;
 
-     return 0;
+    dprintf_clipboard(stdnimp, "ChangeClipboardChain(%04x, %04x)\n", hWnd, hWndNext);
+
+    if( hWndViewer )
+      bRet = !SendMessage16( hWndViewer, WM_CHANGECBCHAIN, (WPARAM)hWnd, (LPARAM)hWndNext);   
+    else
+      dprintf_clipboard(stddeb,"ChangeClipboardChain: hWndViewer is lost\n");
+
+    if( hWnd == hWndViewer ) hWndViewer = hWndNext;
+
+    return 0;
 }
 
 
@@ -311,16 +494,12 @@
  */
 BOOL IsClipboardFormatAvailable(WORD wFormat)
 {
-    LPCLIPFORMAT lpFormat = ClipFormats; 
     dprintf_clipboard(stddeb,"IsClipboardFormatAvailable(%04X) !\n", wFormat);
-    if(wFormat == CF_TEXT && !wineOwnsSelection) /* obtain selection as text if possible */
-	return GetClipboardData(CF_TEXT)!=0;
-    while(TRUE) {
-	if (lpFormat == NULL) return FALSE;
-	if (lpFormat->wFormatID == wFormat) break;
-	lpFormat = lpFormat->NextFormat;
-	}
-    return (lpFormat->hData != 0);
+
+    if(wFormat == CF_TEXT && !wineOwnsSelection)
+	CLIPBOARD_RequestXSelection();
+
+    return CLIPBOARD_IsPresent(wFormat);
 }
 
 
@@ -330,8 +509,8 @@
 HWND GetOpenClipboardWindow()
 {
     dprintf_clipboard(stddeb,
-		"GetOpenClipboardWindow() = %04x !\n", hWndClipboardOwner);
-    return hWndClipboardOwner;
+		"GetOpenClipboardWindow() = %04x\n", hWndClipWindow);
+    return hWndClipWindow;
 }
 
 
@@ -359,18 +538,24 @@
     LPCLIPFORMAT lpFormat = ClipFormats; 
     if(prop==None)
         hText=0;
-    else{
+    else
+      {
 	Atom atype=None;
 	int aformat;
 	unsigned long nitems,remain;
 	unsigned char *val=NULL;
+
         dprintf_clipboard(stddeb,"Received prop %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)
-		printf("couldn't read property\n");
+		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;
@@ -381,14 +566,20 @@
 	    GlobalUnlock16(hText);
 	}
 	XFree(val);
-    }
+      }
+
     while(TRUE) {
 	if (lpFormat == NULL) return;
 	if (lpFormat->wFormatID == CF_TEXT) break;
 	lpFormat = lpFormat->NextFormat;
 	}
-    if (lpFormat->hData != 0) GlobalFree16(lpFormat->hData);
+
+    if (lpFormat->wDataPresent) 
+       CLIPBOARD_DeleteRecord(lpFormat);
+
     wait_for_selection=False;
+
+    lpFormat->wDataPresent = TRUE;
     lpFormat->hData = hText;
     dprintf_clipboard(stddeb,"Received selection\n");
 }
diff --git a/misc/commdlg.c b/misc/commdlg.c
index 9dae2c0..95b18f9 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -84,7 +84,7 @@
     }
 
     hInst = WIN_GetWindowInstance( lpofn->hwndOwner );
-    bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpofn->hwndOwner,
+    bRet = DialogBoxIndirectParam16( hInst, hDlgTmpl, lpofn->hwndOwner,
                                    MODULE_GetWndProcEntry16("FileOpenDlgProc"),
                                    (DWORD)lpofn );
 
@@ -126,7 +126,7 @@
     else hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_SAVE_FILE );
 
     hInst = WIN_GetWindowInstance( lpofn->hwndOwner );
-    bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpofn->hwndOwner,
+    bRet = DialogBoxIndirectParam16( hInst, hDlgTmpl, lpofn->hwndOwner,
                                    MODULE_GetWndProcEntry16("FileSaveDlgProc"),
                                    (DWORD)lpofn); 
     if (!(lpofn->Flags & OFN_ENABLETEMPLATEHANDLE))
@@ -416,7 +416,7 @@
   notification = HIWORD(lParam);
 #endif
     
-  lpofn = (LPOPENFILENAME)GetWindowLong(hWnd, DWL_USER);
+  lpofn = (LPOPENFILENAME)GetWindowLong32A(hWnd, DWL_USER);
   switch (control)
     {
     case lst1: /* file list */
@@ -591,7 +591,7 @@
  */
 LRESULT FileOpenDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
 {  
- LPOPENFILENAME lpofn = (LPOPENFILENAME)GetWindowLong(hWnd, DWL_USER);
+ LPOPENFILENAME lpofn = (LPOPENFILENAME)GetWindowLong32A(hWnd, DWL_USER);
  
  if (wMsg!=WM_INITDIALOG)
   if (FILEDLG_HookCallChk(lpofn))
@@ -634,7 +634,7 @@
  */
 LRESULT FileSaveDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
 {
- LPOPENFILENAME lpofn = (LPOPENFILENAME)GetWindowLong(hWnd, DWL_USER);
+ LPOPENFILENAME lpofn = (LPOPENFILENAME)GetWindowLong32A(hWnd, DWL_USER);
  
  if (wMsg!=WM_INITDIALOG)
   if (FILEDLG_HookCallChk(lpofn))
@@ -677,31 +677,13 @@
 
 
 /***********************************************************************
- *           ChooseColor   (COMMDLG.5)
- */
-BOOL ChooseColor(LPCHOOSECOLOR lpChCol)
-{
-    HANDLE hInst, hDlgTmpl;
-    BOOL bRet;
-
-    hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_CHOOSE_COLOR );
-    hInst = WIN_GetWindowInstance( lpChCol->hwndOwner );
-    bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpChCol->hwndOwner,
-                                   MODULE_GetWndProcEntry16("ColorDlgProc"), 
-                                   (DWORD)lpChCol );
-    SYSRES_FreeResource( hDlgTmpl );
-    return bRet;
-}
-
-
-/***********************************************************************
  *           FindTextDlg   (COMMDLG.11)
  */
 BOOL FindText(LPFINDREPLACE lpFind)
 {
     HANDLE hInst, hDlgTmpl;
     BOOL bRet;
-    SEGPTR ptr;
+    LPCVOID ptr;
 
     /*
      * FIXME : Should respond to FR_ENABLETEMPLATE and FR_ENABLEHOOK here
@@ -713,10 +695,10 @@
      */
     hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_FIND_TEXT );
     hInst = WIN_GetWindowInstance( lpFind->hwndOwner );
-    if (!(ptr = (SEGPTR)WIN16_GlobalLock16( hDlgTmpl ))) return -1;
-    bRet = CreateDialogIndirectParam( hInst, ptr, lpFind->hwndOwner,
-                                      MODULE_GetWndProcEntry16("FindTextDlgProc"),
-                                      (DWORD)lpFind );
+    if (!(ptr = GlobalLock16( hDlgTmpl ))) return -1;
+    bRet = CreateDialogIndirectParam16( hInst, ptr, lpFind->hwndOwner,
+                                        MODULE_GetWndProcEntry16("FindTextDlgProc"),
+                                        (DWORD)lpFind );
     GlobalUnlock16( hDlgTmpl );
     SYSRES_FreeResource( hDlgTmpl );
     return bRet;
@@ -730,7 +712,7 @@
 {
     HANDLE hInst, hDlgTmpl;
     BOOL bRet;
-    SEGPTR ptr;
+    LPCVOID ptr;
 
     /*
      * FIXME : Should respond to FR_ENABLETEMPLATE and FR_ENABLEHOOK here
@@ -742,10 +724,10 @@
      */
     hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_REPLACE_TEXT );
     hInst = WIN_GetWindowInstance( lpFind->hwndOwner );
-    if (!(ptr = (SEGPTR)WIN16_GlobalLock16( hDlgTmpl ))) return -1;
-    bRet = CreateDialogIndirectParam( hInst, ptr, lpFind->hwndOwner,
-                                      MODULE_GetWndProcEntry16("ReplaceTextDlgProc"),
-                                      (DWORD)lpFind );
+    if (!(ptr = GlobalLock16( hDlgTmpl ))) return -1;
+    bRet = CreateDialogIndirectParam16( hInst, ptr, lpFind->hwndOwner,
+                                        MODULE_GetWndProcEntry16("ReplaceTextDlgProc"),
+                                        (DWORD)lpFind );
     GlobalUnlock16( hDlgTmpl );
     SYSRES_FreeResource( hDlgTmpl );
     return bRet;
@@ -806,7 +788,7 @@
     int uFindReplaceMessage = RegisterWindowMessage32A( FINDMSGSTRING );
     int uHelpMessage = RegisterWindowMessage32A( HELPMSGSTRING );
 
-    lpfr = (LPFINDREPLACE)GetWindowLong(hWnd, DWL_USER);
+    lpfr = (LPFINDREPLACE)GetWindowLong32A(hWnd, DWL_USER);
     switch (wParam) {
 	case IDOK:
 	    GetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
@@ -898,7 +880,7 @@
     int uFindReplaceMessage = RegisterWindowMessage32A( FINDMSGSTRING );
     int uHelpMessage = RegisterWindowMessage32A( HELPMSGSTRING );
 
-    lpfr = (LPFINDREPLACE)GetWindowLong(hWnd, DWL_USER);
+    lpfr = (LPFINDREPLACE)GetWindowLong32A(hWnd, DWL_USER);
     switch (wParam) {
 	case IDOK:
 	    GetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
@@ -989,7 +971,7 @@
 	hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_PRINT );
 
     hInst = WIN_GetWindowInstance( lpPrint->hwndOwner );
-    bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpPrint->hwndOwner,
+    bRet = DialogBoxIndirectParam16( hInst, hDlgTmpl, lpPrint->hwndOwner,
                                    (lpPrint->Flags & PD_PRINTSETUP) ?
                                      MODULE_GetWndProcEntry16("PrintSetupDlgProc") :
                                      MODULE_GetWndProcEntry16("PrintDlgProc"),
@@ -1095,7 +1077,48 @@
 }
 
 
-/* --------------------------- Choose Color Dialog ------------------------------ */
+/* ------------------------ Choose Color Dialog --------------------------- */
+
+/***********************************************************************
+ *           ChooseColor   (COMMDLG.5)
+ */
+BOOL ChooseColor(LPCHOOSECOLOR lpChCol)
+{
+    HINSTANCE hInst;
+    HANDLE hDlgTmpl, hResInfo;
+    BOOL bRet;
+
+    dprintf_commdlg(stddeb,"ChooseColor\n");
+    if (!lpChCol) return FALSE;    
+    if (lpChCol->Flags & CC_ENABLETEMPLATEHANDLE) hDlgTmpl = lpChCol->hInstance;
+    else if (lpChCol->Flags & CC_ENABLETEMPLATE)
+    {
+        if (!(hResInfo = FindResource( lpChCol->hInstance,
+                                       lpChCol->lpTemplateName, RT_DIALOG)))
+        {
+            CommDlgLastError = CDERR_FINDRESFAILURE;
+            return FALSE;
+        }
+        hDlgTmpl = LoadResource( lpChCol->hInstance, hResInfo );
+    }
+    else hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_CHOOSE_COLOR );
+    if (!hDlgTmpl)
+    {
+        CommDlgLastError = CDERR_LOADRESFAILURE;
+        return FALSE;
+    }
+    hInst = WIN_GetWindowInstance( lpChCol->hwndOwner );
+    bRet = DialogBoxIndirectParam16( hInst, hDlgTmpl, lpChCol->hwndOwner,
+                                     MODULE_GetWndProcEntry16("ColorDlgProc"), 
+                                     (DWORD)lpChCol );
+    if (!(lpChCol->Flags & CC_ENABLETEMPLATEHANDLE))
+    {
+        if (lpChCol->Flags & CC_ENABLETEMPLATE) FreeResource( hDlgTmpl );
+        else SYSRES_FreeResource( hDlgTmpl );
+    }
+    return bRet;
+}
+
 
 static const COLORREF predefcolors[6][8]=
 {
@@ -1456,7 +1479,7 @@
  int oben;
  RECT16 rect;
  HWND hwnd=GetDlgItem(hDlg,0x2be);
- struct CCPRIVATE *lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER); 
+ struct CCPRIVATE *lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
 
  if (IsWindowVisible(GetDlgItem(hDlg,0x2c6)))   /* if full size */
  {
@@ -1496,7 +1519,7 @@
  HDC hDC;
  int w=GetDialogBaseUnits();
  HWND hwnd=GetDlgItem(hDlg,0x2c6);
- struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER); 
+ struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
  RECT16 rect;
  POINT16 point;
  HPEN16 hPen;
@@ -1541,7 +1564,7 @@
 {
  int sdif,hdif,xdif,ydif,r,g,b,hue,sat;
  HWND hwnd=GetDlgItem(hDlg,0x2c6);
- struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER);  
+ struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER);  
  HBRUSH hbrush;
  HDC hdc ;
  RECT16 rect,client;
@@ -1584,7 +1607,7 @@
 static void CC_PaintColorGraph(HWND hDlg)
 {
  HWND hwnd=GetDlgItem(hDlg,0x2c6);
- struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER); 
+ struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
  HDC  hDC;
  RECT16 rect;
  if (IsWindowVisible(hwnd))   /* if full size */
@@ -1643,7 +1666,7 @@
 static void CC_EditSetRGB(HWND hDlg,COLORREF cr)
 {
  char buffer[10];
- struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER); 
+ struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
  int r=GetRValue(cr);
  int g=GetGValue(cr);
  int b=GetBValue(cr);
@@ -1666,7 +1689,7 @@
 static void CC_EditSetHSL(HWND hDlg,int h,int s,int l)
 {
  char buffer[10];
- struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER); 
+ struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
  lpp->updating=TRUE;
  if (IsWindowVisible(GetDlgItem(hDlg,0x2c6)))   /* if full size */
  {
@@ -1688,7 +1711,7 @@
 static void CC_SwitchToFullSize(HWND hDlg,COLORREF result,LPRECT16 lprect)
 {
  int i;
- struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER); 
+ struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
  
  EnableWindow(GetDlgItem(hDlg,0x2cf),FALSE);
  CC_PrepareColorGraph(hDlg);
@@ -1885,7 +1908,7 @@
     UINT cokmsg;
     HDC hdc;
     COLORREF *cr;
-    struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER); 
+    struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
     dprintf_commdlg(stddeb,"CC_WMCommand wParam=%x lParam=%lx\n",wParam,lParam);
     switch (wParam)
     {
@@ -2008,7 +2031,7 @@
  */
 static LRESULT CC_WMPaint(HWND hDlg, WPARAM wParam, LPARAM lParam) 
 {
-    struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER); 
+    struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
     /* we have to paint dialog children except text and buttons */
  
     CC_PaintPredefColorArray(hDlg,6,8);
@@ -2035,7 +2058,7 @@
  */
 static LRESULT CC_WMLButtonDown(HWND hDlg, WPARAM wParam, LPARAM lParam) 
 {
-   struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER); 
+   struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
    int r,g,b,i;
    i=0;
    if (CC_MouseCheckPredefColorArray(hDlg,0x2d0,6,8,lParam,&lpp->lpcc->rgbResult))
@@ -2085,7 +2108,7 @@
 			 UINT wParam, LONG lParam)
 {
  int res;
- struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER); 
+ struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong32A(hDlg, DWL_USER); 
  if (message!=WM_INITDIALOG)
  {
   if (!lpp)
@@ -2142,15 +2165,38 @@
  */
 BOOL ChooseFont(LPCHOOSEFONT lpChFont)
 {
-    HANDLE hInst, hDlgTmpl;
+    HINSTANCE hInst;
+    HANDLE hDlgTmpl, hResInfo;
     BOOL bRet;
+
     dprintf_commdlg(stddeb,"ChooseFont\n");
-    hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_CHOOSE_FONT );
+    if (!lpChFont) return FALSE;    
+    if (lpChFont->Flags & CF_ENABLETEMPLATEHANDLE) hDlgTmpl = lpChFont->hInstance;
+    else if (lpChFont->Flags & CF_ENABLETEMPLATE)
+    {
+        if (!(hResInfo = FindResource( lpChFont->hInstance,
+                                       lpChFont->lpTemplateName, RT_DIALOG)))
+        {
+            CommDlgLastError = CDERR_FINDRESFAILURE;
+            return FALSE;
+        }
+        hDlgTmpl = LoadResource( lpChFont->hInstance, hResInfo );
+    }
+    else hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_CHOOSE_FONT );
+    if (!hDlgTmpl)
+    {
+        CommDlgLastError = CDERR_LOADRESFAILURE;
+        return FALSE;
+    }
     hInst = WIN_GetWindowInstance( lpChFont->hwndOwner );
-    bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpChFont->hwndOwner,
+    bRet = DialogBoxIndirectParam16( hInst, hDlgTmpl, lpChFont->hwndOwner,
                                    MODULE_GetWndProcEntry16("FormatCharDlgProc"), 
                                    (DWORD)lpChFont );
-    SYSRES_FreeResource( hDlgTmpl );
+    if (!(lpChFont->Flags & CF_ENABLETEMPLATEHANDLE))
+    {
+        if (lpChFont->Flags & CF_ENABLETEMPLATE) FreeResource( hDlgTmpl );
+        else SYSRES_FreeResource( hDlgTmpl );
+    }
     return bRet;
 }
 
@@ -2188,7 +2234,7 @@
   WORD w;
   HWND hwnd=LOWORD(lParam);
   HWND hDlg=GetParent(hwnd);
-  LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong(hDlg, DWL_USER); 
+  LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong32A(hDlg, DWL_USER); 
 
   dprintf_commdlg(stddeb,"FontFamilyEnumProc: font=%s (nFontType=%d)\n",
      			lplf->lfFaceName,nFontType);
@@ -2294,7 +2340,7 @@
   HWND hcmb2=LOWORD(lParam);
   HWND hcmb3=HIWORD(lParam);
   HWND hDlg=GetParent(hcmb3);
-  LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong(hDlg, DWL_USER); 
+  LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong32A(hDlg, DWL_USER); 
   int i;
   
   dprintf_commdlg(stddeb,"FontStyleEnumProc: (nFontType=%d)\n",nFontType);
@@ -2544,7 +2590,7 @@
  */
 LRESULT CFn_WMCtlColor(HWND hDlg, WPARAM wParam, LPARAM lParam)
 {
-  LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong(hDlg, DWL_USER); 
+  LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong32A(hDlg, DWL_USER); 
 
   if (lpcf->Flags & CF_EFFECTS)
    if (HIWORD(lParam)==CTLCOLOR_STATIC && GetDlgCtrlID(LOWORD(lParam))==stc6)
@@ -2566,7 +2612,7 @@
   int i,j;
   long l;
   HDC hdc;
-  LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong(hDlg, DWL_USER); 
+  LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong32A(hDlg, DWL_USER); 
   LPLOGFONT lpxx=PTR_SEG_TO_LIN(lpcf->lpLogFont);
   
   dprintf_commdlg(stddeb,"FormatCharDlgProc // WM_COMMAND lParam=%08lX\n", lParam);
@@ -2642,6 +2688,7 @@
 		    lpxx->lfOutPrecision=OUT_DEFAULT_PRECIS;
 		    lpxx->lfClipPrecision=CLIP_DEFAULT_PRECIS;
 		    lpxx->lfQuality=DEFAULT_QUALITY;
+                    lpcf->iPointSize= -10*lpxx->lfHeight;
 
 		    hFont=CreateFontIndirect(lpxx);
 		    if (hFont)
@@ -2665,7 +2712,16 @@
 		    CallWindowProc16(lpcf->lpfnHook,hDlg,WM_COMMAND,psh15,(LPARAM)lpcf);
 		  break;
 
-	case IDOK:EndDialog(hDlg, TRUE);
+	case IDOK:if (  (!(lpcf->Flags & CF_LIMITSIZE))  ||
+                     ( (lpcf->Flags & CF_LIMITSIZE) && 
+                      (-lpxx->lfHeight >= lpcf->nSizeMin) && 
+                      (-lpxx->lfHeight <= lpcf->nSizeMax)))
+	             EndDialog(hDlg, TRUE);
+	          else
+	          {
+	           sprintf(buffer,"Select a font size among %d and %d points.",lpcf->nSizeMin,lpcf->nSizeMax);
+	           MessageBox(hDlg,buffer,NULL,MB_OK);
+	          } 
 		  return(TRUE);
 	case IDCANCEL:EndDialog(hDlg, FALSE);
 		  return(TRUE);
@@ -2682,7 +2738,7 @@
  */
 LRESULT FormatCharDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 {
-  LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong(hDlg, DWL_USER);  
+  LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong32A(hDlg, DWL_USER);  
   if (message!=WM_INITDIALOG)
   {
    int res=0;
diff --git a/misc/escape.c b/misc/escape.c
index f86def0..9336c84 100644
--- a/misc/escape.c
+++ b/misc/escape.c
@@ -13,6 +13,6 @@
 INT Escape(HDC hdc, INT nEscape, INT cbInput, 
 	   LPCSTR lpszInData, LPVOID lpvOutData)
 {
-    fprintf(stderr, "Escape(nEscape = %04x)\n", nEscape);
+/*     fprintf(stderr, "Escape(nEscape = %04x)\n", nEscape); */
     return 0;
 }
diff --git a/misc/registry.c b/misc/registry.c
index faaf190..9a71264 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -880,11 +880,10 @@
 
 	while (key) {
 		if (key->name == NULL) {
-			fprintf(stderr,"key with dkeaddr %lx not loaded, skipping hierarchy\n",
+			fprintf(stderr,"_w95_walk_tree:Please report: key with dkeaddr %lx not loaded, skipping hierarchy\n",
 				key->dkeaddr
 			);
-			key = key->next;
-			continue;
+			return;
 		}
 		lpxkey=_find_or_add_key(lpkey,strdupA2W(key->name));
 
@@ -963,7 +962,9 @@
 	for (i=0;i<n;i++)
 		if (nr2da[(i+off)%n].dkeaddr == dkeaddr)
 			return keys+nr2da[(i+off)%n].nr;
-	fprintf(stderr,"search didn't found dkeaddr %lx?\n",dkeaddr);
+	/* 0x3C happens often, just report unusual values */
+	if (dkeaddr!=0x3c)
+		dprintf_reg(stddeb,"search hasn't found dkeaddr %lx?\n",dkeaddr);
 	return NULL;
 }
 
@@ -1043,7 +1044,7 @@
 	where	= 0x40;
 	end	= rgdbsection;
 
-	nrofdkes = (end-where)/sizeof(struct dke);
+	nrofdkes = (end-where)/sizeof(struct dke)+100;
 	data = (char*)xmalloc(end-where);
 	if ((end-where)!=read(fd,data,end-where))
 		return;
@@ -1052,6 +1053,7 @@
 	keys = (struct _w95key*)xmalloc(nrofdkes * sizeof(struct _w95key));
 	memset(keys,'\0',nrofdkes*sizeof(struct _w95key));
 	nr2da= (struct _w95nr2da*)xmalloc(nrofdkes * sizeof(struct _w95nr2da));
+	memset(nr2da,'\0',nrofdkes*sizeof(struct _w95nr2da));
 
 	for (i=0;i<nrofdkes;i++) {
 		struct	dke	dke;
@@ -1080,7 +1082,9 @@
 				dkeaddr = dkeaddr & ~0xFFF;
 		}
 		if (nr>nrofdkes) {
-			dprintf_reg(stddeb,"nr %ld exceeds nrofdkes %d, skipping.\n",nr,nrofdkes);
+			/* 0xFFFFFFFF happens often, just report unusual values */
+			if (nr!=0xFFFFFFFF)
+				dprintf_reg(stddeb,"nr %ld exceeds nrofdkes %d, skipping.\n",nr,nrofdkes);
 			continue;
 		}
 		if (keys[nr].dkeaddr) {
@@ -1091,8 +1095,13 @@
 					break;
 			if (x==-1)
 				break; /* finished reading if we got only 0 */
-			if (nr)
-				dprintf_reg(stddeb,"key doubled? nr=%ld,key->dkeaddr=%lx,dkeaddr=%lx\n",nr,keys[nr].dkeaddr,dkeaddr);
+			if (nr) {
+				if (	(dke.next!=(long)keys[nr].next)	||
+					(dke.nextsub!=(long)keys[nr].nextsub)	||
+					(dke.prevlvl!=(long)keys[nr].prevlvl) 
+				)
+					dprintf_reg(stddeb,"key doubled? nr=%ld,key->dkeaddr=%lx,dkeaddr=%lx\n",nr,keys[nr].dkeaddr,dkeaddr);
+			}
 			continue;
 		}
 		nr2da[i].nr	 = nr;
@@ -1144,7 +1153,7 @@
 				nextrgdb = curdata+off_next_rgdb;
 				curdata+=0x20;
 			} else {
-				dprintf_reg(stddeb,"at end of RGDB section, but no next header. Breaking.\n");
+				dprintf_reg(stddeb,"at end of RGDB section, but no next header (%x of %lx). Breaking.\n",curdata-data,end-rgdbsection);
 				break;
 			}
 		}
@@ -1157,22 +1166,12 @@
 
 		XREAD(&dkh,sizeof(dkh));
 		nr = dkh.nrLS + (dkh.nrMS<<8);
-		if (nr>nrofdkes) {
+		if ((nr>nrofdkes) || (dkh.nrLS == 0xFFFF)) {
 			if (dkh.nrLS == 0xFFFF) {
-				curdata+= dkh.nextkeyoff - bytesread;
-				XREAD(magic,4);
-				if (strcmp(magic,"RGDB")) {
-					if ((curdata-data)<end)
-						dprintf_reg(stddeb,"while skipping to next RGDB block found magic %s\n",magic);
-					break;
-				}
-				curdata+=0x1c;
+				/* skip over key using nextkeyoff */
+ 				curdata+=dkh.nextkeyoff-sizeof(struct dkh);
 				continue;
 			}
-			if (dkh.nrLS == 0xFFFE) {
-				dprintf_reg(stddeb,"0xFFFE at %x\n",curdata-data);
-				break;
-			}
 			dprintf_reg(stddeb,"haven't found nr %ld.\n",nr);
 			key = &xkey;
 			memset(key,'\0',sizeof(xkey));
diff --git a/misc/shell.c b/misc/shell.c
index 4ee423e..6228161 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -361,7 +361,7 @@
     if (!hIcon) hIcon = LoadIcon(0,MAKEINTRESOURCE(OIC_WINEICON));
     handle = SYSRES_LoadResource( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX );
     if (!handle) return FALSE;
-    bRet = DialogBoxIndirectParam( WIN_GetWindowInstance( hWnd ),
+    bRet = DialogBoxIndirectParam16( WIN_GetWindowInstance( hWnd ),
                                    handle, hWnd,
                                    MODULE_GetWndProcEntry16("AboutDlgProc"), 
 				   (LONG)hIcon );
diff --git a/misc/spy.c b/misc/spy.c
index 072f62e..f1cbabe 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -191,9 +191,16 @@
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
     /* 0x0130 */
-    NULL, "wm_lbtrackpoint", 
-    NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL,
+    "wm_lbtrackpoint",          /* 0x0131 */
+    "WM_CTLCOLORMSGBOX",        /* 0x0132 */
+    "WM_CTLCOLOREDIT",          /* 0x0133 */
+    "WM_CTLCOLORLISTBOX",       /* 0x0134 */
+    "WM_CTLCOLORBTN",           /* 0x0135 */
+    "WM_CTLCOLORDLG",           /* 0x0136 */
+    "WM_CTLCOLORSCROLLBAR",     /* 0x0137 */
+    "WM_CTLCOLORSTATIC",        /* 0x0138 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
     /* 0x0140 - Win32 Comboboxes */
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
diff --git a/objects/bitblt.c b/objects/bitblt.c
index 2805a10..9db1ceb 100644
--- a/objects/bitblt.c
+++ b/objects/bitblt.c
@@ -35,6 +35,8 @@
 
 #define MAX_OP_LEN  6  /* Longest opcode + 1 for the terminating 0 */
 
+extern void CLIPPING_UpdateGCRegion(DC* );
+
 static const unsigned char BITBLT_Opcodes[256][MAX_OP_LEN] =
 {
     { OP(PAT,DST,GXclear) },                         /* 0x00  0              */
@@ -1031,6 +1033,9 @@
     useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
     if (!dcSrc && useSrc) return FALSE;
 
+    if (dcDst->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion( dcDst );
+    if (dcSrc && (dcSrc->w.flags & DC_DIRTY)) CLIPPING_UpdateGCRegion( dcSrc );
+
       /* Map the coordinates to device coords */
 
     xDst      = dcDst->w.DCOrgX + XLPTODP( dcDst, xDst );
@@ -1270,7 +1275,7 @@
     dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC );
 
     dprintf_bitblt(stddeb,
-                "BitBlt: %04x %d,%d %d bpp -> %04x %d,%d %dx%dx%d rop=%06lx\n",
+                "BitBlt: hdcSrc=%04x %d,%d %d bpp -> hdcDest=%04x %d,%d %dx%dx%d rop=%06lx\n",
                 hdcSrc, xSrc, ySrc, dcSrc ? dcSrc->w.bitsPerPixel : 0,
                 hdcDst, xDst, yDst, width, height, dcDst->w.bitsPerPixel, rop);
 
diff --git a/objects/bitmap.c b/objects/bitmap.c
index a028713..870667e 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -122,11 +122,17 @@
  */
 HBITMAP CreateCompatibleBitmap( HDC hdc, INT width, INT height )
 {
-    DC * dc;
-    dprintf_gdi(stddeb, "CreateCompatibleBitmap: %04x %dx%d\n", 
+    HBITMAP	hbmpRet = 0;
+    DC * 	dc;
+    dprintf_gdi(stddeb, "CreateCompatibleBitmap(%04x,%d,%d) = \n", 
 		hdc, width, height );
     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
-    return CreateBitmap( width, height, 1, dc->w.bitsPerPixel, NULL );
+    
+    hbmpRet = CreateBitmap( width, height, 1, dc->w.bitsPerPixel, NULL );
+
+    dprintf_gdi(stddeb,"\t\t%04x\n", hbmpRet);
+
+    return hbmpRet;
 }
 
 
@@ -278,7 +284,7 @@
 /***********************************************************************
  *           BITMAP_SelectObject
  */
-HBITMAP BITMAP_SelectObject( HDC hdc, DC * dc, HBITMAP hbitmap,
+HBITMAP BITMAP_SelectObject( DC * dc, HBITMAP hbitmap,
 			     BITMAPOBJ * bmp )
 {
     HRGN hrgn;
@@ -300,7 +306,7 @@
 	XFreeGC( display, dc->u.x.gc );
 	dc->u.x.gc = XCreateGC( display, dc->u.x.drawable, 0, NULL );
 	dc->w.bitsPerPixel = bmp->bitmap.bmBitsPixel;
-        DC_InitDC( hdc );
+        DC_InitDC( dc );
     }
     else CLIPPING_UpdateGCRegion( dc );  /* Just update GC clip region */
     return prevHandle;
diff --git a/objects/brush.c b/objects/brush.c
index e5ee9b0..a1780ba 100644
--- a/objects/brush.c
+++ b/objects/brush.c
@@ -334,14 +334,14 @@
 /***********************************************************************
  *           BRUSH_SelectObject
  */
-HBRUSH BRUSH_SelectObject( HDC hdc, DC * dc, HBRUSH hbrush, BRUSHOBJ * brush )
+HBRUSH BRUSH_SelectObject( DC * dc, HBRUSH hbrush, BRUSHOBJ * brush )
 {
     HBITMAP hBitmap;
     BITMAPINFO * bmpInfo;
     HBRUSH prevHandle = dc->w.hBrush;
 
     dprintf_gdi(stddeb, "Brush_SelectObject: hdc=%04x hbrush=%04x\n",
-                hdc,hbrush);
+                dc->hSelf,hbrush);
     if (dc->header.wMagic == METAFILE_DC_MAGIC)
     {
 	switch (brush->logbrush.lbStyle)
@@ -400,7 +400,7 @@
 	if ((bmpInfo = (BITMAPINFO *) GlobalLock16( (HANDLE)brush->logbrush.lbHatch )))
 	{
 	    int size = DIB_BitmapInfoSize( bmpInfo, brush->logbrush.lbColor );
-	    hBitmap = CreateDIBitmap( hdc, &bmpInfo->bmiHeader, CBM_INIT,
+	    hBitmap = CreateDIBitmap( dc->hSelf, &bmpInfo->bmiHeader, CBM_INIT,
 				      ((char *)bmpInfo) + size, bmpInfo,
 				      (WORD) brush->logbrush.lbColor );
 	    BRUSH_SelectPatternBrush( dc, hBitmap );
diff --git a/objects/clipping.c b/objects/clipping.c
index 7064d03..3683d58 100644
--- a/objects/clipping.c
+++ b/objects/clipping.c
@@ -50,6 +50,13 @@
         fprintf( stderr, "UpdateGCRegion: hVisRgn is zero. Please report this.\n" );
         exit(1);
     }
+
+    if (dc->w.flags & DC_DIRTY)
+    {
+        UpdateDirtyDC(dc);
+        dc->w.flags &= ~DC_DIRTY;
+    }
+
     if (!dc->w.hClipRgn)
         CombineRgn( dc->w.hGCClipRgn, dc->w.hVisRgn, 0, RGN_COPY );
     else
@@ -80,6 +87,7 @@
 	dc->w.hClipRgn = 0;
 	retval = SIMPLEREGION; /* Clip region == whole DC */
     }
+
     CLIPPING_UpdateGCRegion( dc );
     return retval;
 }
@@ -96,6 +104,8 @@
 
     dprintf_clipping(stddeb, "SelectVisRgn: %04x %04x\n", hdc, hrgn );
 
+    dc->w.flags &= ~DC_DIRTY;
+
     retval = CombineRgn( dc->w.hVisRgn, hrgn, 0, RGN_COPY );
     CLIPPING_UpdateGCRegion( dc );
     return retval;
@@ -271,6 +281,7 @@
     if (!dc) return ERROR;    
     dprintf_clipping(stddeb, "ExcludeVisRect: %04x %dx%d,%dx%d\n",
 	    hdc, left, top, right, bottom );
+
     return CLIPPING_IntersectVisRect( dc, left, top, right, bottom, TRUE );
 }
 
@@ -285,6 +296,7 @@
     if (!dc) return ERROR;    
     dprintf_clipping(stddeb, "IntersectVisRect: %04x %dx%d,%dx%d\n",
 	    hdc, left, top, right, bottom );
+
     return CLIPPING_IntersectVisRect( dc, left, top, right, bottom, FALSE );
 }
 
@@ -299,6 +311,10 @@
 
     dprintf_clipping(stddeb, "PtVisible: %04x %d,%d\n", hdc, x, y );
     if (!dc->w.hGCClipRgn) return FALSE;
+
+    if( dc->w.flags & DC_DIRTY ) UpdateDirtyDC(dc);
+    dc->w.flags &= ~DC_DIRTY;
+
     return PtInRegion( dc->w.hGCClipRgn, XLPTODP(dc,x), YLPTODP(dc,y) );
 }
 
@@ -375,6 +391,9 @@
         fprintf( stderr, "SaveVisRgn: hVisRgn is zero. Please report this.\n" );
         exit(1);
     }
+    if( dc->w.flags & DC_DIRTY ) UpdateDirtyDC(dc);
+    dc->w.flags &= ~DC_DIRTY;
+
     if (!(obj = (RGNOBJ *) GDI_GetObjPtr( dc->w.hVisRgn, REGION_MAGIC )))
 	return 0;
     if (!(copy = CreateRectRgn( 0, 0, 0, 0 ))) return 0;
diff --git a/objects/dc.c b/objects/dc.c
index 8094756..6349560 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -14,11 +14,13 @@
 #include "color.h"
 #include "debug.h"
 #include "font.h"
+#include "callback.h"
 #include "xmalloc.h"
 
 static DeviceCaps * displayDevCaps = NULL;
 
 extern void CLIPPING_UpdateGCRegion( DC * dc );     /* objects/clipping.c */
+extern BOOL DCHook( HDC, WORD, DWORD, DWORD );      /* windows/dce.c */
 
   /* Default DC values */
 static const WIN_DC_INFO DC_defaultValues =
@@ -142,15 +144,14 @@
  *
  * Setup device-specific DC values for a newly created DC.
  */
-void DC_InitDC( HDC hdc )
+void DC_InitDC( DC* dc )
 {
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    RealizeDefaultPalette( hdc );
-    SetTextColor( hdc, dc->w.textColor );
-    SetBkColor( hdc, dc->w.backgroundColor );
-    SelectObject( hdc, dc->w.hPen );
-    SelectObject( hdc, dc->w.hBrush );
-    SelectObject( hdc, dc->w.hFont );
+    RealizeDefaultPalette( dc->hSelf );
+    SetTextColor( dc->hSelf, dc->w.textColor );
+    SetBkColor( dc->hSelf, dc->w.backgroundColor );
+    SelectObject( dc->hSelf, dc->w.hPen );
+    SelectObject( dc->hSelf, dc->w.hBrush );
+    SelectObject( dc->hSelf, dc->w.hFont );
     XSetGraphicsExposures( display, dc->u.x.gc, False );
     XSetSubwindowMode( display, dc->u.x.gc, IncludeInferiors );
     CLIPPING_UpdateGCRegion( dc );
@@ -191,6 +192,8 @@
         val.background = COLOR_PixelToPalette[val.background];
     }
 
+    if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc);
+
     val.function = DC_XROPfunction[dc->w.ROPmode-1];
     val.fill_style = dc->u.x.brush.fillStyle;
     switch(val.fill_style)
@@ -262,6 +265,8 @@
 
     if (dc->u.x.pen.style == PS_NULL) return FALSE;
 
+    if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc); 
+
     if ((screenDepth <= 8) &&  /* FIXME: Should check for palette instead */
         ((dc->w.ROPmode == R2_BLACK) || (dc->w.ROPmode == R2_WHITE)))
     {
@@ -309,6 +314,9 @@
         fprintf( stderr, "DC_SetupGCForText: fstruct is NULL. Please report this\n" );
         return FALSE;
     }
+   
+    if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc);
+
     val.function   = GXcopy;  /* Text is always GXcopy */
     val.foreground = dc->w.textPixel;
     val.background = dc->w.backgroundPixel;
@@ -322,6 +330,26 @@
 
 
 /***********************************************************************
+ *           DC_CallHookProc
+ */
+BOOL DC_CallHookProc(DC* dc, WORD code, LPARAM lParam)
+{
+  BOOL   bRet = 0;
+  FARPROC ptr = GDI_GetDefDCHook();
+
+  dprintf_dc(stddeb,"CallDCHook: code %04x\n", code);
+
+  /* if 16-bit callback is, in fact, a thunk to DCHook simply call DCHook */
+
+  if( dc->hookProc && !(dc->w.flags & (DC_SAVED | DC_MEMORY)) )
+    bRet = (dc->hookProc == ptr) ?
+          DCHook(dc->hSelf, code, dc->dwHookData, lParam):
+          CallDCHookProc(dc->hookProc, dc->hSelf, code, dc->dwHookData, lParam);
+
+  return bRet;
+}
+
+/***********************************************************************
  *           GetDCState    (GDI.179)
  */
 HDC GetDCState( HDC hdc )
@@ -338,6 +366,8 @@
     memset( &newdc->u.x, 0, sizeof(newdc->u.x) );
     memcpy( &newdc->w, &dc->w, sizeof(dc->w) );
     memcpy( &newdc->u.x.pen, &dc->u.x.pen, sizeof(dc->u.x.pen) );
+
+    newdc->hSelf = (HDC)handle;
     newdc->saveLevel = 0;
     newdc->w.flags |= DC_SAVED;
 
@@ -474,7 +504,11 @@
 	DC_FillDevCaps( displayDevCaps );
     }
 
+    dc->hSelf = (HDC)handle;
     dc->saveLevel = 0;
+    dc->dwHookData = 0L;
+    dc->hookProc = (SEGPTR)NULL;
+
     memcpy( &dc->w, &DC_defaultValues, sizeof(DC_defaultValues) );
     memset( &dc->u.x, 0, sizeof(dc->u.x) );
 
@@ -491,7 +525,7 @@
         return 0;
     }
 
-    DC_InitDC( handle );
+    DC_InitDC( dc );
 
     return handle;
 }
@@ -530,8 +564,12 @@
 	return 0;
     }
     bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
-    
+
+    dc->hSelf = (HDC)handle;    
     dc->saveLevel = 0;
+    dc->dwHookData = 0L; 
+    dc->hookProc = (SEGPTR)NULL;
+
     memcpy( &dc->w, &DC_defaultValues, sizeof(DC_defaultValues) );
     memset( &dc->u.x, 0, sizeof(dc->u.x) );
 
@@ -551,7 +589,7 @@
         return 0;
     }
 
-    DC_InitDC( handle );
+    DC_InitDC( dc );
 
     return handle;
 }
@@ -713,3 +751,60 @@
     dc->w.DCOrgY = y;
     return prevOrg;
 }
+
+
+/***********************************************************************
+ *           SetDCHook   (GDI.190)
+ */
+BOOL SetDCHook( HDC hDC, FARPROC16 hookProc, DWORD dwHookData )
+{
+    DC *dc = (DC *)GDI_GetObjPtr( hDC, DC_MAGIC );
+
+    dprintf_dc( stddeb, "SetDCHook: hookProc %08x, default is %08x\n",
+                (unsigned)hookProc,(unsigned)GDI_GetDefDCHook() );
+
+    if (!dc) return FALSE;
+    dc->hookProc = hookProc;
+    dc->dwHookData = dwHookData;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           GetDCHook   (GDI.191)
+ */
+DWORD GetDCHook( HDC hDC, FARPROC16 *phookProc )
+{
+    DC *dc = (DC *)GDI_GetObjPtr( hDC, DC_MAGIC );
+    if (!dc) return 0;
+    *phookProc = dc->hookProc;
+    return dc->dwHookData;
+}
+
+
+/***********************************************************************
+ *           SetHookFlags       (GDI.192)
+ */
+WORD SetHookFlags(HDC hDC, WORD flags)
+{
+  DC* dc = (DC*)GDI_GetObjPtr( hDC, DC_MAGIC );
+
+  if( dc )
+    {
+        WORD wRet = dc->w.flags & DC_DIRTY;
+
+        /* "Undocumented Windows" info is slightly
+         *  confusing
+         */
+
+        dprintf_dc(stddeb,"SetHookFlags: hDC %04x, flags %04x\n",hDC,flags);
+
+        if( flags & DCHF_INVALIDATEVISRGN )
+            dc->w.flags |= DC_DIRTY;
+        else if( flags & DCHF_VALIDATEVISRGN || !flags )
+            dc->w.flags &= ~DC_DIRTY;
+        return wRet;
+    }
+  return 0;
+}
+
diff --git a/objects/dib.c b/objects/dib.c
index 26ef98e..becf185 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -18,6 +18,7 @@
 #include "debug.h"
 #include "xmalloc.h"
 
+extern void CLIPPING_UpdateGCRegion(DC* );
 
 /***********************************************************************
  *           DIB_GetImageWidthBytes
@@ -575,6 +576,8 @@
         if (!(colorMapping = DIB_BuildColorMap( dc, coloruse, depth, info )))
             return 0;
 
+    if( dc->w.flags & DC_DIRTY ) CLIPPING_UpdateGCRegion(dc);
+
       /* Transfer the pixels */
     XCREATEIMAGE(bmpImage, infoWidth, lines, depth );
 
diff --git a/objects/font.c b/objects/font.c
index ff7c0c6..8f3b4a1 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -785,7 +785,12 @@
  */
 BOOL GetCharABCWidths(HDC hdc, UINT wFirstChar, UINT wLastChar, LPABC lpABC)
 {
-    /* No TrueType fonts in Wine */
+
+    /* No TrueType fonts in Wine so far */
+
+    fprintf(stdnimp,"STUB: GetCharABCWidths(%04x,%04x,%04x,%08x)\n",
+			   hdc,wFirstChar,wLastChar,(unsigned)lpABC);
+  
     return FALSE;
 }
 
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 6af4d94..81c1c16 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -12,6 +12,7 @@
 #include "brush.h"
 #include "font.h"
 #include "heap.h"
+#include "module.h"
 #include "palette.h"
 #include "pen.h"
 #include "region.h"
@@ -152,16 +153,23 @@
     (GDIOBJHDR *) &SystemFixedFont
 };
 
+static FARPROC16 defDCHookCallback;
+
 
 /***********************************************************************
  *           GDI_Init
  *
- * GDI initialisation.
+ * GDI initialization.
  */
 BOOL GDI_Init(void)
 {
     HPALETTE16 hpalette;
 
+    defDCHookCallback = (FARPROC16)MODULE_GetEntryPoint(GetModuleHandle("USER"),
+                                                        362  /* DCHook */ );
+    dprintf_gdi( stddeb, "DCHook: 16-bit callback is %08x\n",
+                 (unsigned)defDCHookCallback );
+
       /* Create default palette */
 
     if (!(hpalette = COLOR_Init())) return FALSE;
@@ -171,11 +179,11 @@
 
     if (!BITMAP_Init()) return FALSE;
 
-      /* Initialise brush dithering */
+      /* Initialize brush dithering */
 
     if (!BRUSH_Init()) return FALSE;
 
-      /* Initialise fonts */
+      /* Initialize fonts */
 
     if (!FONT_Init()) return FALSE;
 
@@ -184,6 +192,15 @@
 
 
 /***********************************************************************
+ *           GDI_GetDefDCHook
+ */
+FARPROC16 GDI_GetDefDCHook(void)
+{
+    return defDCHookCallback;
+}
+
+
+/***********************************************************************
  *           GDI_AllocObject
  */
 HANDLE GDI_AllocObject( WORD size, WORD magic )
@@ -321,7 +338,7 @@
     GDIOBJHDR * ptr = NULL;
     DC * dc;
     
-    dprintf_gdi(stddeb, "SelectObject: %04x %04x\n", hdc, handle );
+    dprintf_gdi(stddeb, "SelectObject: hdc=%04x %04x\n", hdc, handle );
     if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
       ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
     else 
@@ -340,9 +357,9 @@
       case PEN_MAGIC:
 	  return PEN_SelectObject( dc, handle, (PENOBJ *)ptr );
       case BRUSH_MAGIC:
-	  return BRUSH_SelectObject( hdc, dc, handle, (BRUSHOBJ *)ptr );
+	  return BRUSH_SelectObject( dc, handle, (BRUSHOBJ *)ptr );
       case BITMAP_MAGIC:
-	  return BITMAP_SelectObject( hdc, dc, handle, (BITMAPOBJ *)ptr );
+	  return BITMAP_SelectObject( dc, handle, (BITMAPOBJ *)ptr );
       case FONT_MAGIC:
 	  return FONT_SelectObject( dc, handle, (FONTOBJ *)ptr );	  
       case REGION_MAGIC:
diff --git a/objects/text.c b/objects/text.c
index 10ef8b4..1d5a5e1 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -338,9 +338,9 @@
     if (!DC_SetupGCForText( dc )) return TRUE;
     font = dc->u.x.font.fstruct;
 
-    dprintf_text(stddeb,"ExtTextOut: %d,%d '%*.*s', %d  flags=%d\n",
-            x, y, count, count, str, count, flags);
-    if (lprect != NULL) dprintf_text(stddeb, "rect %d %d %d %d\n",
+    dprintf_text(stddeb,"ExtTextOut: hdc=%04x %d,%d '%*.*s', %d  flags=%d\n",
+            hdc, x, y, count, count, str, count, flags);
+    if (lprect != NULL) dprintf_text(stddeb, "\trect=(%d,%d- %d,%d)\n",
                                      lprect->left, lprect->top,
                                      lprect->right, lprect->bottom );
 
@@ -363,6 +363,9 @@
         if (rect.bottom < rect.top) SWAP_INT( rect.top, rect.bottom );
     }
 
+    dprintf_text(stddeb,"\treal coord: x=%i, y=%i, rect=(%d,%d-%d,%d)\n",
+			  x, y, rect.left, rect.top, rect.right, rect.bottom);
+
       /* Draw the rectangle */
 
     if (flags & ETO_OPAQUE)
@@ -394,6 +397,7 @@
 	  x -= info.width / 2;
 	  break;
     }
+
     switch( dc->w.textAlign & (TA_TOP | TA_BOTTOM | TA_BASELINE) )
     {
       case TA_TOP:
diff --git a/programs/progman/ChangeLog b/programs/progman/ChangeLog
index 12efc7a..9345fd7 100644
--- a/programs/progman/ChangeLog
+++ b/programs/progman/ChangeLog
@@ -1,3 +1,7 @@
+Sun Jun  2 13:14:55 1996  Ulrich Schmid  <uschmid@mail.hh.provi.de>
+
+	* Program icons: repaint on WM_NCPAINT or WM_PAINTICON
+
 Sun Apr 14 20:09:19 1996  Pablo Saratxaga <srtxg@linux.chanae.stben.be>
 
 	* [Fr.rc] (new)
diff --git a/programs/progman/program.c b/programs/progman/program.c
index b2ecdfb..84d4fff 100644
--- a/programs/progman/program.c
+++ b/programs/progman/program.c
@@ -32,7 +32,8 @@
 	return(0);
       }
 
-    case WM_PAINT:
+    case WM_PAINTICON:
+    case WM_NCPAINT:
       {
 	PROGRAM *program;
 	PAINTSTRUCT      ps;
@@ -205,6 +206,7 @@
   SetWindowLong(program->hWnd, 0, (LONG) hProgram);
 
   ShowWindow (program->hWnd, SW_SHOWMINIMIZED);
+  SetWindowPos (program->hWnd, 0, x, y, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE);
   UpdateWindow (program->hWnd);
 
   return hProgram;
diff --git a/resources/TODO b/resources/TODO
index 1263235..b46b36f 100644
--- a/resources/TODO
+++ b/resources/TODO
@@ -63,6 +63,7 @@
 * English
 * German
 * Finnish
+* Italian
 .....
 
 Thank you.
diff --git a/resources/sysres_It.rc b/resources/sysres_It.rc
index 35a5626..82a9bb9 100644
--- a/resources/sysres_It.rc
+++ b/resources/sysres_It.rc
@@ -38,7 +38,6 @@
  ICON "", 1088, 195, 10, 18, 20
 }
 
-
 OPEN_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Apri"
@@ -131,16 +130,32 @@
  COMBOBOX 1138, 168, 110, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
 }
 
-
-CHOOSE_FONT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134
+CHOOSE_FONT DIALOG DISCARDABLE  13, 54, 264, 147
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Font"
 FONT 8, "Helv"
 {
- LTEXT "Font:", 1088, 6, 6, 40, 9
- LTEXT "", 1089, 60, 6, 150, 9
- DEFPUSHBUTTON "Ok", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
- PUSHBUTTON "Annulla", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
+    LTEXT           "&Font:",1088 ,6,3,40,9
+    COMBOBOX        1136 ,6,13,94,54,  CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
+                    CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE
+    LTEXT           "St&ile:",1089 ,108,3,44,9
+    COMBOBOX        1137,108,13,64,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
+                    WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE
+    LTEXT           "&Dimensione:",1090,179,3,30,9
+    COMBOBOX        1138,179,13,32,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
+                    WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE | CBS_SORT
+    DEFPUSHBUTTON   "OK",IDOK,218,6,40,14,WS_GROUP
+    PUSHBUTTON      "Annulla",IDCANCEL,218,23,40,14,WS_GROUP
+    PUSHBUTTON      "A&pplica", 1026,218,40,40,14,WS_GROUP
+    PUSHBUTTON      "&Aiuto" , 1038,218,57,40,14,WS_GROUP
+    GROUPBOX        "Effetti",1072,6,72,84,34,WS_GROUP
+    CHECKBOX	    "&Barrato", 1040, 10,82,50,10, BS_AUTOCHECKBOX | WS_TABSTOP
+    CHECKBOX 	    "&Sottolineato", 1041, 10,94,50,10, BS_AUTOCHECKBOX 
+    LTEXT           "&Colore:", 1091 ,6,110,30,9
+    COMBOBOX        1139,6,120,84,100,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS |
+		    CBS_AUTOHSCROLL |  WS_BORDER | WS_VSCROLL | WS_TABSTOP
+    GROUPBOX        "Esempio",1073,98,72,160,49,WS_GROUP
+    CTEXT           "AaBbYyZz",1093,104,81,149,37,SS_NOPREFIX | WS_VISIBLE
 }
 
 CHOOSE_COLOR DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 300, 200
diff --git a/tools/build.c b/tools/build.c
index 62944d5..b64c9af 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -1016,21 +1016,18 @@
             break;
 
           case TYPE_BYTE:
-            printf( "/* %s.%d */\n", DLLName, i);
             odp->offset = data_offset;
-            data_offset += StoreVariableCode( data, 1, odp);
+            data_offset += StoreVariableCode( data + data_offset, 1, odp);
             break;
 
           case TYPE_WORD:
-            printf( "/* %s.%d */\n", DLLName, i);
             odp->offset = data_offset;
-            data_offset += StoreVariableCode( data, 2, odp);
+            data_offset += StoreVariableCode( data + data_offset, 2, odp);
             break;
 
           case TYPE_LONG:
-            printf( "/* %s.%d */\n", DLLName, i);
             odp->offset = data_offset;
-            data_offset += StoreVariableCode( data, 4, odp);
+            data_offset += StoreVariableCode( data + data_offset, 4, odp);
             break;
 
           case TYPE_RETURN:
diff --git a/win32/Makefile.in b/win32/Makefile.in
index 72d1277..1b36259 100644
--- a/win32/Makefile.in
+++ b/win32/Makefile.in
@@ -21,8 +21,7 @@
 	struct32.c \
 	thread.c \
 	time.c \
-	user32.c \
-	winprocs.c
+	user32.c
 
 all: $(MODULE).o
 
diff --git a/win32/environment.c b/win32/environment.c
index 57e6b00..54267c1 100644
--- a/win32/environment.c
+++ b/win32/environment.c
@@ -37,3 +37,33 @@
     return buffer;
 }
 
+
+/***********************************************************************
+ *           GetSystemPowerStatus      (KERNEL32.621)
+ */
+BOOL GetSystemPowerStatus(LPSYSTEM_POWER_STATUS sps_ptr)
+{
+    return FALSE;   /* no power management support */
+}
+
+
+/***********************************************************************
+ *           SetSystemPowerState      (KERNEL32.630)
+ */
+BOOL SetSystemPowerState(BOOL suspend_or_hibernate, BOOL force_flag)
+{
+    /* suspend_or_hibernate flag: w95 does not support
+       this feature anyway */
+
+    for ( ;0; )
+    {
+        if ( force_flag )
+        {
+        }
+        else
+        {
+        }
+    }
+    return TRUE;
+}
+
diff --git a/win32/time.c b/win32/time.c
index 610d4a6..5d649a0 100644
--- a/win32/time.c
+++ b/win32/time.c
@@ -60,6 +60,43 @@
     systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
 }
 
+
+/***********************************************************************
+ *              SetSystemTime            (KERNEL32.507)
+ */
+BOOL SetSystemTime(const SYSTEMTIME *systime)
+{
+    struct timeval tv;
+    struct timezone tz;
+    struct tm t;
+    time_t sec;
+
+    /* call gettimeofday to get the current timezone */
+    gettimeofday(&tv, &tz);
+
+    /* get the number of seconds */
+    t.tm_sec = systime->wSecond;
+    t.tm_min = systime->wMinute;
+    t.tm_hour = systime->wHour;
+    t.tm_mday = systime->wDay;
+    t.tm_mon = systime->wMonth;
+    t.tm_year = systime->wYear;
+    sec = mktime (&t);
+
+    /* set the new time */
+    tv.tv_sec = sec;
+    tv.tv_usec = systime->wMilliseconds * 1000;
+    if (settimeofday(&tv, &tz))
+    {
+        return FALSE;
+    }
+    else
+    {
+        return TRUE;
+    }
+}
+
+
 /***********************************************************************
  *              GetTimeZoneInformation  (KERNEL32.302)
  */
@@ -78,6 +115,27 @@
     return TIME_ZONE_ID_UNKNOWN;
 }
 
+
+/***********************************************************************
+ *              SetTimeZoneInformation  (KERNEL32.515)
+ */
+BOOL SetTimeZoneInformation(const TIME_ZONE_INFORMATION *tzinfo)
+{
+    struct timezone tz;
+
+    tz.tz_minuteswest = tzinfo->Bias;
+    tz.tz_dsttime = DST_NONE;
+    if (settimeofday(NULL, &tz))
+    {
+        return FALSE;
+    }
+    else
+    {
+        return TRUE;
+    }
+}
+
+
 /***********************************************************************
  *              Sleep  (KERNEL32.523)
  */
diff --git a/win32/user32.c b/win32/user32.c
index 7572b7e..290e1cc 100644
--- a/win32/user32.c
+++ b/win32/user32.c
@@ -18,7 +18,6 @@
 #include "struct32.h"
 #include "resource32.h"
 #include "string32.h"
-#include "dialog.h"
 #include "win.h"
 #include "winproc.h"
 #include "debug.h"
@@ -68,275 +67,6 @@
     return SetTimer( hwnd, id, timeout, MAKE_SEGPTR(proc));
 }   
 
-/* WARNING: It has not been verified that the signature or semantics
-   of the corresponding NT function is the same */
-
-HWND USER32_CreateDialogIndirectParamAorW(HINSTANCE hInst,LPVOID templ,
-	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam,int A)
-{
-	DLGTEMPLATE32 *dlgTempl=templ;
-	DLGITEMTEMPLATE32 *dlgitem;
-	WORD *ptr;
-	DWORD MenuName=0;
-	DWORD ClassName=0;
-	DWORD szFontName=0;
-	WORD wPointSize;
-	HFONT hFont=0;
-	HMENU hMenu=0;
-	DWORD exStyle;
-	DWORD szCaption;
-	RECT16 rect;
-	DIALOGINFO *dlgInfo;
-	WND *wndPtr;
-	WORD xUnit = xBaseUnit;
-	WORD yUnit = yBaseUnit;
-	int i;
-	DWORD ClassId;
-	DWORD Text;
-	HWND hwnd,hwndCtrl;
-	HWND hwndDefButton=0;
-	WCHAR buffer[200];
-
-	/* parse the dialog template header*/
-	exStyle = dlgTempl->dwExtendedStyle;
-	ptr = (WORD*)(dlgTempl+1);
-	switch(*ptr){
-		case 0: MenuName=0;ptr++;break;
-		case 0xFFFF: MenuName=*(ptr+1);ptr+=2;break;
-		default: MenuName = (DWORD)ptr;
-			ptr += STRING32_lstrlenW(ptr)+1;
-	}
-	switch(*ptr){ 
-		case 0: ClassName = DIALOG_CLASS_ATOM;ptr++;break;
-		case 0xFFFF: ClassName = *(ptr+1);ptr+=2;break;
-		default: ClassName = (DWORD)ptr;
-				ptr += STRING32_lstrlenW(ptr)+1;
-	}
-	szCaption=(DWORD)ptr;
-	ptr+=STRING32_lstrlenW(ptr)+1;
-	if(dlgTempl->style & DS_SETFONT)
-	{
-		wPointSize = *ptr;
-		ptr++;
-		szFontName = (DWORD)ptr;
-		ptr+=STRING32_lstrlenW(ptr)+1;
-	}
-	
-	if(MenuName) hMenu=WIN32_LoadMenuW(hInst,(LPWSTR)MenuName);
-	if(dlgTempl->style & DS_SETFONT)
-	{
-		fprintf(stderr,"Win32: dialog fonts not supported yet\n");
-	}
-	
-	/* Create dialog main window */
-	rect.left = rect.top = 0;
-	rect.right = dlgTempl->cx * xUnit / 4;
-	rect.bottom = dlgTempl->cy * yUnit / 8;
-
-	/* FIXME: proper modalframe handling ??*/
-	if (dlgTempl->style & DS_MODALFRAME) exStyle |= WS_EX_DLGMODALFRAME;
-
-        AdjustWindowRectEx16( &rect, dlgTempl->style,
-                              hMenu ? TRUE : FALSE , exStyle );
-	rect.right -= rect.left;
-	rect.bottom -= rect.top;
-
-	if(dlgTempl->x == CW_USEDEFAULT16)
-		rect.left = rect.top = CW_USEDEFAULT16;
-	else{
-		rect.left += dlgTempl->x * xUnit / 4;
-		rect.top += dlgTempl->y * yUnit / 8;
-		if (!(dlgTempl->style & DS_ABSALIGN))
-			ClientToScreen16(hWndParent, (POINT16 *)&rect );
-	}
-
-	/* FIXME: Here is the place to consider A */
-	hwnd = CreateWindowEx32W(exStyle, (LPWSTR)ClassName, (LPWSTR)szCaption,
-		dlgTempl->style & ~WS_VISIBLE, 
-		rect.left, rect.top, rect.right, rect.bottom,
-		hWndParent, hMenu, hInst, 0);
-
-	if(!hwnd)
-	{
-		if(hFont)DeleteObject(hFont);
-		if(hMenu)DeleteObject(hMenu);
-		return 0;
-	}
-
-	wndPtr = WIN_FindWndPtr(hwnd);
-
-	/* FIXME: should purge junk from system menu, but windows/dialog.c
-	   says this does not belong here */
-
-	/* Create control windows */
-	dprintf_dialog(stddeb, " BEGIN\n" );
-	dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
-	dlgInfo->msgResult = 0;	/* This is used to store the default button id */
-	dlgInfo->hDialogHeap = 0;
-
-	for (i = 0; i < dlgTempl->noOfItems; i++)
-	{
-		if((int)ptr&3)
-			ptr++;
-		dlgitem = (DLGITEMTEMPLATE32*)ptr;
-		ptr = (WORD*)(dlgitem+1);
-		if(*ptr == 0xFFFF) {
-			/* FIXME: ignore HIBYTE? */
-			ClassId = *(ptr+1);
-			ptr+=2;
-		}else{
-			ClassId = (DWORD)ptr;
-			ptr += STRING32_lstrlenW(ptr)+1;
-		}
-		if(*ptr == 0xFFFF) {
-			Text = *(ptr+1);
-			ptr+=2;
-		}else{
-			Text = (DWORD)ptr;
-			ptr += STRING32_lstrlenW(ptr)+1;
-		}
-		if(!HIWORD(ClassId))
-		{
-			switch(LOWORD(ClassId))
-			{
-				case 0x80: STRING32_AnsiToUni(buffer,"BUTTON" ); break;
-				case 0x81: STRING32_AnsiToUni( buffer, "EDIT" ); break;
-				case 0x82: STRING32_AnsiToUni( buffer, "STATIC" ); break;
-				case 0x83: STRING32_AnsiToUni( buffer, "LISTBOX" ); break;
-				case 0x84: STRING32_AnsiToUni( buffer, "SCROLLBAR" ); break;
-				case 0x85: STRING32_AnsiToUni( buffer, "COMBOBOX" ); break;
-				default:   buffer[0] = '\0'; break;
-			}
-			ClassId = (DWORD)buffer;
-		}
-		/*FIXME: debugging output*/
-		/*FIXME: local edit ?*/
-		exStyle = dlgitem->dwExtendedStyle|WS_EX_NOPARENTNOTIFY;
-		if(*ptr)
-		{
-			fprintf(stderr,"having data\n");
-		}
-		ptr++;
-		hwndCtrl = CreateWindowEx32W(WS_EX_NOPARENTNOTIFY,
-			(LPWSTR)ClassId, (LPWSTR)Text,
-			dlgitem->style | WS_CHILD,
-			dlgitem->x * xUnit / 4,
-			dlgitem->y * yUnit / 8,
-			dlgitem->cx * xUnit / 4,
-			dlgitem->cy * yUnit / 8,
-			hwnd, (HMENU)((DWORD)dlgitem->id),
-			hInst, (SEGPTR)0 );
-		SetWindowPos( hwndCtrl, HWND_BOTTOM, 0, 0, 0, 0,
-			SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
-		/* Send initialisation messages to the control */
-		if (hFont) SendMessage32A( hwndCtrl, WM_SETFONT, (WPARAM)hFont, 0 );
-		if (SendMessage32A( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
-		{
-			/* If there's already a default push-button, set it back */
-			/* to normal and use this one instead. */
-			if (hwndDefButton)
-				SendMessage32A( hwndDefButton, BM_SETSTYLE32, BS_PUSHBUTTON, FALSE);
-			hwndDefButton = hwndCtrl;
-			dlgInfo->msgResult = GetWindowWord( hwndCtrl, GWW_ID );
-		}
-	}
-	dprintf_dialog(stddeb, " END\n" );
-
-	 /* Initialise dialog extra data */
-	dlgInfo->dlgProc   = WINPROC_AllocWinProc(lpDialogFunc,WIN_PROC_32A);
-	dlgInfo->hUserFont = hFont;
-	dlgInfo->hMenu     = hMenu;
-	dlgInfo->xBaseUnit = xUnit;
-	dlgInfo->yBaseUnit = yUnit;
-	dlgInfo->hwndFocus = DIALOG_GetFirstTabItem( hwnd );
-
-	/* Send initialisation messages and set focus */
-	if (dlgInfo->hUserFont)
-		SendMessage32A( hwnd, WM_SETFONT, (WPARAM)dlgInfo->hUserFont, 0 );
-	if (SendMessage32A( hwnd, WM_INITDIALOG, (WPARAM)dlgInfo->hwndFocus, dwInitParam ))
-		SetFocus( dlgInfo->hwndFocus );
-	if (dlgTempl->style & WS_VISIBLE) ShowWindow(hwnd, SW_SHOW);
-		return hwnd;
-}
-
-HWND USER32_CreateDialogIndirectParamW(HINSTANCE hInst,LPVOID dlgTempl,
-	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
-{
-	return USER32_CreateDialogIndirectParamAorW(hInst,dlgTempl,hWndParent,
-		lpDialogFunc,dwInitParam,0);
-}
-
-HWND USER32_CreateDialogIndirectParamA(HINSTANCE hInst,LPVOID dlgTempl,
-	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
-{
-	return USER32_CreateDialogIndirectParamAorW(hInst,dlgTempl,hWndParent,
-		lpDialogFunc,dwInitParam,1);
-}
-
-HWND USER32_CreateDialogParamW(HINSTANCE hInst,LPCWSTR lpszName,
-	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
-{
-	HANDLE32 hrsrc;
-	hrsrc=FindResource32(hInst,lpszName,(LPWSTR)RT_DIALOG);
-	if(!hrsrc)return 0;
-	return USER32_CreateDialogIndirectParamW(hInst,
-		LoadResource32(hInst, hrsrc),hWndParent,lpDialogFunc,dwInitParam);
-}
-
-HWND USER32_CreateDialogParamA(HINSTANCE hInst,LPCSTR lpszName,
-	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
-{
-	HWND res;
-	if(!HIWORD(lpszName))
-		res = USER32_CreateDialogParamW(hInst,(LPCWSTR)lpszName,hWndParent,
-				lpDialogFunc,dwInitParam);
-	else{
-		LPWSTR uni=STRING32_DupAnsiToUni(lpszName);
-		res=USER32_CreateDialogParamW(hInst,uni,hWndParent,
-			lpDialogFunc,dwInitParam);
-	}
-	return res;
-}
-
-int USER32_DialogBoxIndirectParamW(HINSTANCE hInstance,LPVOID dlgTempl,
-	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
-{
-	HWND hwnd;
-	hwnd = USER32_CreateDialogIndirectParamW(hInstance,dlgTempl,
-		hWndParent,lpDialogFunc,dwInitParam);
-	if(hwnd)return DIALOG_DoDialogBox(hwnd,hWndParent);
-	return -1;
-}
-
-int USER32_DialogBoxIndirectParamA(HINSTANCE hInstance,LPVOID dlgTempl,
-	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
-{
-	HWND hwnd;
-	hwnd = USER32_CreateDialogIndirectParamA(hInstance,dlgTempl,
-		hWndParent,lpDialogFunc,dwInitParam);
-	if(hwnd)return DIALOG_DoDialogBox(hwnd,hWndParent);
-	return -1;
-}
-
-int USER32_DialogBoxParamW(HINSTANCE hInstance,LPCWSTR lpszName,
-	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
-{
-	HWND hwnd;
-	hwnd = USER32_CreateDialogParamW(hInstance,lpszName,
-		hWndParent,lpDialogFunc,dwInitParam);
-	if(hwnd)return DIALOG_DoDialogBox(hwnd,hWndParent);
-	 return -1;
-}
-
-int USER32_DialogBoxParamA(HINSTANCE hInstance,LPCSTR lpszName,
-	HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
-{
-	HWND hwnd;
-	hwnd = USER32_CreateDialogParamA(hInstance,lpszName,
-		hWndParent,lpDialogFunc,dwInitParam);
-	if(hwnd)return DIALOG_DoDialogBox(hwnd,hWndParent);
-	return -1;
-}
 
 int USER32_wsprintfA( int *args )
 {
diff --git a/win32/winprocs.c b/win32/winprocs.c
deleted file mode 100644
index 428b5ab..0000000
--- a/win32/winprocs.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Win32 WndProc function stubs
- *
- * Copyright 1995 Thomas Sandford (tdgsandf@prds-grn.demon.co.uk)
- *
- * These functions are simply lParam fixers for the Win16 routines
- */
-
-#include <stdio.h>
-#include "windows.h"
-
-#ifndef WINELIB32
-
-#include "winerror.h"
-#include "kernel32.h"
-#include "wintypes.h"
-#include "struct32.h"
-#include "wincon.h"
-#include "stackframe.h"
-#include "stddebug.h"
-#include "debug.h"
-
-BOOL UsesLParamPtr(DWORD message)
-
-{
-    switch (message) {
-	case WM_NCCREATE:
-	case WM_NCCALCSIZE:
-	case WM_WINDOWPOSCHANGING:
-	case WM_WINDOWPOSCHANGED:
-	case WM_GETTEXT:
-	case WM_SETTEXT:
-	case WM_GETMINMAXINFO:
-	    return TRUE;
-	default:
-	    return FALSE;
-    }
-}
-
-BOOL WIN32_CallWindowProcTo16(LRESULT(*func)(HWND,UINT,WPARAM,LPARAM),
-	HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
-{
-	WINDOWPOS16 wp;
-	union{
-		MINMAXINFO16 mmi;
-		NCCALCSIZE_PARAMS16 nccs;
-		CREATESTRUCT16 cs;
-	} st;
-	WINDOWPOS32 *pwp;
-	CREATESTRUCT32A *pcs;
-	LONG result;
-	if(!lParam || !UsesLParamPtr(msg))
-		return func(hwnd,msg,wParam,lParam);
-	switch(msg)
-	{
-		case WM_GETMINMAXINFO:
-			STRUCT32_MINMAXINFO32to16((void*)lParam,&st.mmi);
-			result=func(hwnd,msg,wParam,MAKE_SEGPTR(&st.mmi));
-			STRUCT32_MINMAXINFO16to32(&st.mmi,(void*)lParam);
-			return result;
-		case WM_WINDOWPOSCHANGING:
-		case WM_WINDOWPOSCHANGED:
-			STRUCT32_WINDOWPOS32to16((void*)lParam,&wp);
-			result=func(hwnd,msg,wParam,MAKE_SEGPTR(&wp));
-			STRUCT32_WINDOWPOS16to32(&wp,(void*)lParam);
-			return result;
-		 case WM_NCCALCSIZE:
-		 	pwp=((NCCALCSIZE_PARAMS32*)lParam)->lppos;
-		 	STRUCT32_NCCALCSIZE32to16Flat((void*)lParam,&st.nccs,wParam);
-			if (wParam && pwp) {
-				STRUCT32_WINDOWPOS32to16(pwp,&wp);
-				st.nccs.lppos = &wp;
-			}else
-				st.nccs.lppos = 0;
-			result=func(hwnd,msg,wParam,MAKE_SEGPTR(&st.nccs));
-			STRUCT32_NCCALCSIZE16to32Flat(&st.nccs,(void*)lParam,wParam);
-			if (wParam && pwp)
-				STRUCT32_WINDOWPOS16to32(&wp,pwp);
-			return result;
-		case WM_NCCREATE:
-			pcs = (CREATESTRUCT32A*)lParam;
-			STRUCT32_CREATESTRUCT32Ato16((void*)lParam,&st.cs);
-			st.cs.lpszName = HIWORD(pcs->lpszName) ? 
-				MAKE_SEGPTR(pcs->lpszName) : pcs->lpszName;
-			st.cs.lpszClass = HIWORD(pcs->lpszClass) ? 
-				MAKE_SEGPTR(pcs->lpszClass) : pcs->lpszClass;
-			result=func(hwnd,msg,wParam,MAKE_SEGPTR(&st.cs));
-			STRUCT32_CREATESTRUCT16to32A(&st.cs,(void*)lParam);
-			pcs->lpszName = HIWORD(pcs->lpszName) ? 
-				PTR_SEG_TO_LIN(st.cs.lpszName) : pcs->lpszName;
-			pcs->lpszClass = HIWORD(pcs-> lpszClass) ? 
-				PTR_SEG_TO_LIN(st.cs.lpszClass) : pcs-> lpszClass;
-			return result;
-		case WM_GETTEXT:
-		case WM_SETTEXT:
-			return func(hwnd,msg,wParam,MAKE_SEGPTR((void*)lParam));
-		default:
-			fprintf(stderr,"No support for 32-16 msg 0x%x\n",msg);
-	}
-	return func(hwnd,msg,wParam,MAKE_SEGPTR((void*)lParam));
-}
-
-
-extern LRESULT AboutDlgProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT ColorDlgProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT ComboBoxWndProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT EditWndProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT FileOpenDlgProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT FileSaveDlgProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT FindTextDlgProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT ListBoxWndProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT MDIClientWndProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT PopupMenuWndProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT PrintDlgProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT PrintSetupDlgProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT ReplaceTextDlgProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT ScrollBarWndProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT StaticWndProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT SystemMessageBoxProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT ComboLBoxWndProc(HWND,UINT,WPARAM,LPARAM);
-
-LRESULT StaticWndProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(StaticWndProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT ScrollBarWndProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(ScrollBarWndProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT ListBoxWndProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(ListBoxWndProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT ComboBoxWndProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(ComboBoxWndProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT EditWndProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(EditWndProc,(HWND)hwnd, msg, wParam,lParam);
-}
-
-LRESULT PopupMenuWndProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(PopupMenuWndProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT DefDlgProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(DefDlgProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT MDIClientWndProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(MDIClientWndProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT SystemMessageBoxProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(SystemMessageBoxProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT FileOpenDlgProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(FileOpenDlgProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT FileSaveDlgProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(FileSaveDlgProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT ColorDlgProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(ColorDlgProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT FindTextDlgProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(FindTextDlgProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT ReplaceTextDlgProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(ReplaceTextDlgProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT PrintSetupDlgProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(PrintSetupDlgProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT PrintDlgProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(PrintDlgProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT AboutDlgProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(AboutDlgProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT ComboLBoxWndProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(ComboLBoxWndProc,(HWND)hwnd, msg, wParam, lParam);
-}
-#endif
diff --git a/windows/class.c b/windows/class.c
index 4a3f6eb..4cf9e11 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -43,11 +43,11 @@
 
     fprintf( stderr, "Class %p:\n", ptr );
     fprintf( stderr,
-             "next=%p  name=%04x '%s'  style=%08x  wndProc=%08lx\n"
+             "next=%p  name=%04x '%s'  style=%08x  wndProc=%08x\n"
              "inst=%04x  hdce=%04x  icon=%04x  cursor=%04x  bkgnd=%04x\n"
              "clsExtra=%d  winExtra=%d  #windows=%d\n",
              ptr->next, ptr->atomName, className, ptr->style,
-             (DWORD)ptr->lpfnWndProc, ptr->hInstance, ptr->hdce,
+             ptr->winproc, ptr->hInstance, ptr->hdce,
              ptr->hIcon, ptr->hCursor, ptr->hbrBackground,
              ptr->cbClsExtra, ptr->cbWndExtra, ptr->cWindows );
     if (ptr->cbClsExtra)
@@ -76,7 +76,7 @@
     {
         GlobalGetAtomName32A( ptr->atomName, className, sizeof(className) );
         fprintf( stderr, "%08x %-20.20s %08x %08x\n", (UINT32)ptr, className,
-                 ptr->style, (UINT32)ptr->lpfnWndProc );
+                 ptr->style, ptr->winproc );
     }
     fprintf( stderr, "\n" );
 }
@@ -160,13 +160,12 @@
  *
  * Set the window procedure and return the old one.
  */
-static WNDPROC16 CLASS_SetWndProc( CLASS *classPtr, WNDPROC16 proc,
-                                   WINDOWPROCTYPE type )
+static HANDLE32 CLASS_SetWndProc( CLASS *classPtr, HANDLE32 proc,
+                                  WINDOWPROCTYPE type )
 {
-    WNDPROC16 oldProc = classPtr->lpfnWndProc;
-    if (type == WIN_PROC_16) classPtr->lpfnWndProc = proc;
-    else classPtr->lpfnWndProc = WINPROC_AllocWinProc( (WNDPROC32)proc, type );
-    WINPROC_FreeWinProc( oldProc );
+    HANDLE32 oldProc = classPtr->winproc;
+    classPtr->winproc = WINPROC_AllocWinProc( proc, type );
+    if (oldProc) WINPROC_FreeWinProc( oldProc );
     return oldProc;
 }
 
@@ -274,7 +273,7 @@
  */
 static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE32 hInstance,
                                    DWORD style, INT32 classExtra,
-                                   INT32 winExtra, WNDPROC16 wndProc,
+                                   INT32 winExtra, HANDLE32 wndProc,
                                    WINDOWPROCTYPE wndProcType )
 {
     CLASS *classPtr;
@@ -309,14 +308,14 @@
     classPtr->magic       = CLASS_MAGIC;
     classPtr->cWindows    = 0;  
     classPtr->style       = style;
-    classPtr->lpfnWndProc = 0;
+    classPtr->winproc     = 0;
     classPtr->cbWndExtra  = winExtra;
     classPtr->cbClsExtra  = classExtra;
     classPtr->hInstance   = hInstance;
     classPtr->atomName    = atom;
     classPtr->menuNameA   = 0;
     classPtr->menuNameW   = 0;
-    classPtr->hdce        = (style&CS_CLASSDC) ? DCE_AllocDCE(DCE_CLASS_DC): 0;
+    classPtr->hdce        = (style&CS_CLASSDC) ? DCE_AllocDCE(0, DCE_CLASS_DC): 0;
     CLASS_SetWndProc( classPtr, wndProc, wndProcType );
     /* Other values must be set by caller */
 
@@ -339,7 +338,8 @@
     if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
                                           wc->cbClsExtra, wc->cbWndExtra,
-                                          wc->lpfnWndProc, WIN_PROC_16 )))
+                                          (HANDLE32)wc->lpfnWndProc,
+                                          WIN_PROC_16 )))
     {
         GlobalDeleteAtom( atom );
         return 0;
@@ -375,7 +375,7 @@
     if (!(atom = GlobalAddAtom32A( wc->lpszClassName ))) return 0;
     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
                                           wc->cbClsExtra, wc->cbWndExtra,
-                                          (WNDPROC16)wc->lpfnWndProc,
+                                          (HANDLE32)wc->lpfnWndProc,
                                           WIN_PROC_32A )))
     {
         GlobalDeleteAtom( atom );
@@ -410,7 +410,7 @@
     if (!(atom = GlobalAddAtom32W( wc->lpszClassName ))) return 0;
     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
                                           wc->cbClsExtra, wc->cbWndExtra,
-                                          (WNDPROC16)wc->lpfnWndProc,
+                                          (HANDLE32)wc->lpfnWndProc,
                                           WIN_PROC_32W )))
     {
         GlobalDeleteAtom( atom );
@@ -444,7 +444,8 @@
     if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
                                           wc->cbClsExtra, wc->cbWndExtra,
-                                          wc->lpfnWndProc, WIN_PROC_16 )))
+                                          (HANDLE32)wc->lpfnWndProc,
+                                          WIN_PROC_16 )))
     {
         GlobalDeleteAtom( atom );
         return 0;
@@ -480,7 +481,7 @@
     if (!(atom = GlobalAddAtom32A( wc->lpszClassName ))) return 0;
     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
                                           wc->cbClsExtra, wc->cbWndExtra,
-                                          (WNDPROC16)wc->lpfnWndProc,
+                                          (HANDLE32)wc->lpfnWndProc,
                                           WIN_PROC_32A )))
     {
         GlobalDeleteAtom( atom );
@@ -515,7 +516,7 @@
     if (!(atom = GlobalAddAtom32W( wc->lpszClassName ))) return 0;
     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
                                           wc->cbClsExtra, wc->cbWndExtra,
-                                          (WNDPROC16)wc->lpfnWndProc,
+                                          (HANDLE32)wc->lpfnWndProc,
                                           WIN_PROC_32W )))
     {
         GlobalDeleteAtom( atom );
@@ -620,9 +621,19 @@
  */
 LONG GetClassLong16( HWND hwnd, INT16 offset )
 {
-    DWORD ret = GetClassLong32A( hwnd, offset );
-    if ((offset == GCL_MENUNAME) && HIWORD(ret))
-        return (LONG)SEGPTR_GET((void *)ret);  /* Name needs to be a SEGPTR */
+    LONG ret;
+
+    switch( offset )
+    {
+    case GCL_MENUNAME:
+        ret = GetClassLong32A( hwnd, offset );
+        return (LONG)SEGPTR_GET( (void *)ret );
+    case GCL_WNDPROC:
+        ret = GetClassLong32A( hwnd, offset );
+        return (LONG)WINPROC_GetFunc16( (HANDLE32)ret );
+    default:
+        return GetClassLong32A( hwnd, offset );
+    }
     return (LONG)ret;
 }
 
@@ -645,8 +656,9 @@
         case GCL_STYLE:      return (LONG)wndPtr->class->style;
         case GCL_CBWNDEXTRA: return (LONG)wndPtr->class->cbWndExtra;
         case GCL_CBCLSEXTRA: return (LONG)wndPtr->class->cbClsExtra;
-        case GCL_WNDPROC:    return (LONG)wndPtr->class->lpfnWndProc;
         case GCL_HMODULE:    return (LONG)wndPtr->class->hInstance;
+        case GCL_WNDPROC:
+            return (LONG)WINPROC_GetFunc32( wndPtr->class->winproc );
         case GCL_MENUNAME:
             return (LONG)CLASS_GetMenuNameA( wndPtr->class );
         case GCL_HBRBACKGROUND:
@@ -727,7 +739,7 @@
     {
     case GCL_WNDPROC:
         if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
-        return (LONG)CLASS_SetWndProc( wndPtr->class, (WNDPROC16)newval,
+        return (LONG)CLASS_SetWndProc( wndPtr->class, (HANDLE32)newval,
                                        WIN_PROC_16 );
     case GCL_MENUNAME:
         return SetClassLong32A( hwnd, offset, (LONG)PTR_SEG_TO_LIN(newval) );
@@ -764,7 +776,7 @@
             CLASS_SetMenuNameA( wndPtr->class, (LPCSTR)newval );
             return 0;  /* Old value is now meaningless anyway */
         case GCL_WNDPROC:
-            return (LONG)CLASS_SetWndProc( wndPtr->class, (WNDPROC16)newval,
+            return (LONG)CLASS_SetWndProc( wndPtr->class, (HANDLE32)newval,
                                            WIN_PROC_32A );
         case GCL_HBRBACKGROUND:
         case GCL_HCURSOR:
@@ -797,7 +809,7 @@
     switch(offset)
     {
     case GCL_WNDPROC:
-        return (LONG)CLASS_SetWndProc( wndPtr->class, (WNDPROC16)newval,
+        return (LONG)CLASS_SetWndProc( wndPtr->class, (HANDLE32)newval,
                                        WIN_PROC_32W );
     case GCL_MENUNAME:
         CLASS_SetMenuNameW( wndPtr->class, (LPCWSTR)newval );
@@ -854,7 +866,7 @@
         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
         (hInstance != classPtr->hInstance)) return FALSE;
     wc->style         = (UINT16)classPtr->style;
-    wc->lpfnWndProc   = classPtr->lpfnWndProc;
+    wc->lpfnWndProc   = WINPROC_GetFunc16( classPtr->winproc );
     wc->cbClsExtra    = (INT16)classPtr->cbClsExtra;
     wc->cbWndExtra    = (INT16)classPtr->cbWndExtra;
     wc->hInstance     = (HINSTANCE16)classPtr->hInstance;
@@ -882,7 +894,7 @@
         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
         (hInstance != classPtr->hInstance)) return FALSE;
     wc->style         = classPtr->style;
-    wc->lpfnWndProc   = (WNDPROC32)classPtr->lpfnWndProc;
+    wc->lpfnWndProc   = WINPROC_GetFunc32( classPtr->winproc );
     wc->cbClsExtra    = classPtr->cbClsExtra;
     wc->cbWndExtra    = classPtr->cbWndExtra;
     wc->hInstance     = classPtr->hInstance;
@@ -908,7 +920,7 @@
         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
         (hInstance != classPtr->hInstance)) return FALSE;
     wc->style         = classPtr->style;
-    wc->lpfnWndProc   = (WNDPROC32)classPtr->lpfnWndProc;
+    wc->lpfnWndProc   = WINPROC_GetFunc32( classPtr->winproc );
     wc->cbClsExtra    = classPtr->cbClsExtra;
     wc->cbWndExtra    = classPtr->cbWndExtra;
     wc->hInstance     = classPtr->hInstance;
@@ -937,7 +949,7 @@
         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
         (hInstance != classPtr->hInstance)) return FALSE;
     wc->style         = classPtr->style;
-    wc->lpfnWndProc   = classPtr->lpfnWndProc;
+    wc->lpfnWndProc   = WINPROC_GetFunc16( classPtr->winproc );
     wc->cbClsExtra    = (INT16)classPtr->cbClsExtra;
     wc->cbWndExtra    = (INT16)classPtr->cbWndExtra;
     wc->hInstance     = (HINSTANCE16)classPtr->hInstance;
@@ -966,7 +978,7 @@
         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
         (hInstance != classPtr->hInstance)) return FALSE;
     wc->style         = classPtr->style;
-    wc->lpfnWndProc   = (WNDPROC32)classPtr->lpfnWndProc;
+    wc->lpfnWndProc   = WINPROC_GetFunc32( classPtr->winproc );
     wc->cbClsExtra    = classPtr->cbClsExtra;
     wc->cbWndExtra    = classPtr->cbWndExtra;
     wc->hInstance     = classPtr->hInstance;
@@ -993,7 +1005,7 @@
         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
         (hInstance != classPtr->hInstance)) return FALSE;
     wc->style         = classPtr->style;
-    wc->lpfnWndProc   = (WNDPROC32)classPtr->lpfnWndProc;
+    wc->lpfnWndProc   = WINPROC_GetFunc32( classPtr->winproc );
     wc->cbClsExtra    = classPtr->cbClsExtra;
     wc->cbWndExtra    = classPtr->cbWndExtra;
     wc->hInstance     = classPtr->hInstance;
diff --git a/windows/dce.c b/windows/dce.c
index 5728434..4ec7624 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -2,9 +2,18 @@
  * USER DCE functions
  *
  * Copyright 1993 Alexandre Julliard
+ *	     1996 Alex Korobka
  *
-static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
-*/
+ *
+ * Note: Visible regions of CS_OWNDC/CS_CLASSDC window DCs 
+ * have to be updated dynamically. 
+ * 
+ * Internal DCX flags:
+ *
+ * DCX_DCEBUSY     - dce structure is in use
+ * DCX_KEEPCLIPRGN - do not delete clipping region in ReleaseDC
+ * DCX_WINDOWPAINT - BeginPaint specific flag
+ */
 
 #include "dce.h"
 #include "class.h"
@@ -21,30 +30,48 @@
 static HANDLE firstDCE = 0;
 static HDC defaultDCstate = 0;
 
+BOOL   DCHook(HDC, WORD, DWORD, DWORD);
 
 /***********************************************************************
  *           DCE_AllocDCE
- *
+*
  * Allocate a new DCE.
  */
-HANDLE DCE_AllocDCE( DCE_TYPE type )
+HANDLE DCE_AllocDCE( HWND 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->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL )))
+    if (!(dce->hDC = CreateDC( "DISPLAY", NULL, NULL, NULL )))
     {
 	USER_HEAP_FREE( handle );
 	return 0;
     }
-    dce->hwndCurrent = 0;
-    dce->type  = type;
-    dce->inUse = (type != DCE_CACHE_DC);
-    dce->xOrigin = 0;
-    dce->yOrigin = 0;
+
+    /* store DCE handle in DC hook data field */
+
+    SetDCHook(dce->hDC, GDI_GetDefDCHook(), MAKELONG(handle,DC_MAGIC));
+
+    dce->hwndCurrent = hWnd;
     dce->hNext = firstDCE;
+    dce->hClipRgn = 0;
     firstDCE = handle;
+
+    if( type != DCE_CACHE_DC )
+      {
+	dce->DCXflags = DCX_DCEBUSY;
+	if( hWnd )
+	  {
+	    WND* wnd = WIN_FindWndPtr(hWnd);
+	
+	    if( wnd->dwStyle & WS_CLIPCHILDREN ) dce->DCXflags |= DCX_CLIPCHILDREN;
+	    if( wnd->dwStyle & WS_CLIPSIBLINGS ) dce->DCXflags |= DCX_CLIPSIBLINGS;
+	  }
+	SetHookFlags(dce->hDC,DCHF_INVALIDATEVISRGN);
+      }
+    else dce->DCXflags = DCX_CACHE;
+
     return handle;
 }
 
@@ -64,10 +91,77 @@
 	handle = &prev->hNext;
     }
     if (*handle == hdce) *handle = dce->hNext;
-    DeleteDC( dce->hdc );
+
+    SetDCHook(dce->hDC,(SEGPTR)NULL,0L);
+
+    DeleteDC( dce->hDC );
+    if( dce->hClipRgn && !(dce->DCXflags & DCX_KEEPCLIPRGN) )
+	DeleteObject(dce->hClipRgn);
     USER_HEAP_FREE( hdce );
 }
 
+/***********************************************************************
+ *           DCE_FindDCE
+ */
+HANDLE DCE_FindDCE(HDC 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;
+}
+
+/***********************************************************************
+ *   DCE_InvalidateDCE
+ */
+BOOL DCE_InvalidateDCE(WND* wndScope, RECT16* pRectUpdate)
+{
+ HANDLE hdce;
+ DCE*   dce;
+
+ if( !wndScope ) return 0;
+
+ dprintf_dc(stddeb,"InvalidateDCE: scope hwnd = %04x, (%i,%i - %i,%i)\n",
+                    wndScope->hwndSelf, pRectUpdate->left,pRectUpdate->top,
+				        pRectUpdate->right,pRectUpdate->bottom);
+
+ for( hdce = firstDCE; (hdce); hdce=dce->hNext)
+  { 
+    dce = (DCE*)USER_HEAP_LIN_ADDR(hdce);
+
+    if( dce->DCXflags & DCX_DCEBUSY )
+      {
+        WND * wndCurrent, * wnd; 
+
+	wnd = wndCurrent = WIN_FindWndPtr(dce->hwndCurrent);
+
+	/* desktop is not critical */
+
+	if( wnd == WIN_GetDesktop() ) continue;
+
+	for( ; wnd ; wnd = wnd->parent )
+	    if( wnd == wndScope )
+	      { 
+	        RECT16 wndRect = wndCurrent->rectWindow;
+
+	        dprintf_dc(stddeb,"\tgot hwnd %04x\n", wndCurrent->hwndSelf);
+  
+	        MapWindowPoints16(wndCurrent->parent->hwndSelf, wndScope->hwndSelf,
+			 				(LPPOINT16)&wndRect, 2);
+	        if( IntersectRect16(&wndRect,&wndRect,pRectUpdate) )
+	            SetHookFlags(dce->hDC, DCHF_INVALIDATEVISRGN);
+	        break;
+	      }
+      }
+  }
+ return 1;
+}
 
 /***********************************************************************
  *           DCE_Init
@@ -80,9 +174,9 @@
         
     for (i = 0; i < NB_DCE; i++)
     {
-	if (!(handle = DCE_AllocDCE( DCE_CACHE_DC ))) return;
+	if (!(handle = DCE_AllocDCE( 0, DCE_CACHE_DC ))) return;
 	dce = (DCE *) USER_HEAP_LIN_ADDR( handle );	
-	if (!defaultDCstate) defaultDCstate = GetDCState( dce->hdc );
+	if (!defaultDCstate) defaultDCstate = GetDCState( dce->hDC );
     }
 }
 
@@ -186,9 +280,11 @@
     int xoffset, yoffset;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
-      /* Get visible rectangle and create a region with it */
+      /* Get visible rectangle and create a region with it 
+       * FIXME: do we really need to calculate vis rgns for X windows? 
+       */
 
-    if (!DCE_GetVisRect( wndPtr, !(flags & DCX_WINDOW), &rect ))
+    if (!wndPtr || !DCE_GetVisRect( wndPtr, !(flags & DCX_WINDOW), &rect ))
     {
         return CreateRectRgn( 0, 0, 0, 0 );  /* Visible region is empty */
     }
@@ -281,103 +377,147 @@
     }
 }
 
-
 /***********************************************************************
  *           GetDCEx    (USER.359)
- */
-/* Unimplemented flags: DCX_LOCKWINDOWUPDATE
+ *
+ * Unimplemented flags: DCX_LOCKWINDOWUPDATE
  */
 HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
 {
-    HANDLE hdce;
-    HRGN hrgnVisible;
-    HDC hdc = 0;
-    DCE * dce;
-    DC * dc;
-    WND * wndPtr;
+    HANDLE 	hdce;
+    HRGN 	hrgnVisible;
+    HDC 	hdc = 0;
+    DCE * 	dce;
+    DC * 	dc;
+    WND * 	wndPtr;
+    DWORD 	dcx_flags = 0;
+    BOOL	need_update = TRUE;
+
+    dprintf_dc(stddeb,"GetDCEx: hwnd %04x, hrgnClip %04x, flags %08x\n", hwnd, hrgnClip, (unsigned)flags);
     
-    if (hwnd)
-    {
-	if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
-    }
-    else wndPtr = NULL;
+    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
 
     if (flags & DCX_USESTYLE)
     {
-        /* Set the flags according to the window style. */
-	/* Not sure if this is the real meaning of the DCX_USESTYLE flag... */
-	flags &= ~(DCX_CACHE | DCX_CLIPCHILDREN |
-                   DCX_CLIPSIBLINGS | DCX_PARENTCLIP);
-	if (wndPtr)
+	flags &= ~( DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS | DCX_PARENTCLIP);
+
+        if( wndPtr->dwStyle & WS_CLIPSIBLINGS )
+            flags |= DCX_CLIPSIBLINGS;
+
+	if ( !(flags & DCX_WINDOW) )
 	{
             if (!(wndPtr->class->style & (CS_OWNDC | CS_CLASSDC)))
 		flags |= DCX_CACHE;
+
             if (wndPtr->class->style & CS_PARENTDC) flags |= DCX_PARENTCLIP;
-	    if (wndPtr->dwStyle & WS_CLIPCHILDREN) flags |= DCX_CLIPCHILDREN;
-	    if (wndPtr->dwStyle & WS_CLIPSIBLINGS) flags |= DCX_CLIPSIBLINGS;
+
+	    if (wndPtr->dwStyle & WS_CLIPCHILDREN &&
+                     !(wndPtr->dwStyle & WS_MINIMIZE) ) flags |= DCX_CLIPCHILDREN;
 	}
 	else flags |= DCX_CACHE;
     }
 
-      /* Can only use PARENTCLIP on child windows */
-    if (!wndPtr || !(wndPtr->dwStyle & WS_CHILD)) flags &= ~DCX_PARENTCLIP;
+    if( flags & DCX_NOCLIPCHILDREN )
+      {
+        flags |= DCX_CACHE;
+        flags &= ~(DCX_PARENTCLIP | DCX_CLIPCHILDREN);
+      }
 
-      /* Whole window DC implies using cache DC and not clipping children */
+    if (hwnd==GetDesktopWindow() || !(wndPtr->dwStyle & WS_CHILD)) flags &= ~DCX_PARENTCLIP;
+
     if (flags & DCX_WINDOW) flags = (flags & ~DCX_CLIPCHILDREN) | DCX_CACHE;
 
+    if( flags & DCX_PARENTCLIP )
+      {
+        flags |= DCX_CACHE;
+        if( !(flags & (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN)) )
+          if( (wndPtr->dwStyle & WS_VISIBLE) && (wndPtr->parent->dwStyle & WS_VISIBLE) )
+            {
+              flags &= ~DCX_CLIPCHILDREN;
+              if( wndPtr->parent->dwStyle & WS_CLIPSIBLINGS )
+                flags |= DCX_CLIPSIBLINGS;
+            }
+      }
+
     if (flags & DCX_CACHE)
     {
 	for (hdce = firstDCE; (hdce); hdce = dce->hNext)
 	{
 	    if (!(dce = (DCE *) USER_HEAP_LIN_ADDR( hdce ))) return 0;
-	    if ((dce->type == DCE_CACHE_DC) && (!dce->inUse)) break;
+	    if ((dce->DCXflags & DCX_CACHE) && !(dce->DCXflags & DCX_DCEBUSY)) break;
 	}
     }
-    else hdce = wndPtr->hdce;
+    else 
+    {
+        hdce = (wndPtr->class->style & CS_OWNDC)?wndPtr->hdce:wndPtr->class->hdce;
+	dce = (DCE *) USER_HEAP_LIN_ADDR( hdce );
+
+	if( dce->hwndCurrent == hwnd )
+	  {
+	    dprintf_dc(stddeb,"\tskipping hVisRgn update\n");
+	    need_update = FALSE;
+	  }
+
+	if( hrgnClip && dce->hClipRgn && !(dce->DCXflags & DCX_KEEPCLIPRGN))
+	  {
+	    fprintf(stdnimp,"GetDCEx: hClipRgn collision!\n");
+            DeleteObject(dce->hClipRgn); 
+	    need_update = TRUE;
+	  }
+    }
+
+    dcx_flags = flags & ( DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_CACHE | DCX_WINDOW | DCX_WINDOWPAINT);
 
     if (!hdce) return 0;
     dce = (DCE *) USER_HEAP_LIN_ADDR( hdce );
     dce->hwndCurrent = hwnd;
-    dce->inUse       = TRUE;
-    hdc = dce->hdc;
-    
-      /* Initialize DC */
+    dce->hClipRgn = 0;
+    dce->DCXflags = dcx_flags | DCX_DCEBUSY;
+    hdc = dce->hDC;
     
     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
 
     DCE_SetDrawable( wndPtr, dc, flags );
-    if (hwnd)
-    {
-        if (flags & DCX_PARENTCLIP)  /* Get a VisRgn for the parent */
+    if( need_update || dc->w.flags & DC_DIRTY )
+     {
+      dprintf_dc(stddeb,"updating hDC anyway\n");
+
+      if (flags & DCX_PARENTCLIP)
         {
             WND *parentPtr = wndPtr->parent;
-            DWORD newflags = flags & ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN |
+            dcx_flags = flags & ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN |
                                        DCX_WINDOW);
             if (parentPtr->dwStyle & WS_CLIPSIBLINGS)
-                newflags |= DCX_CLIPSIBLINGS;
-            hrgnVisible = DCE_GetVisRgn( parentPtr->hwndSelf, newflags );
+                dcx_flags |= DCX_CLIPSIBLINGS;
+            hrgnVisible = DCE_GetVisRgn( parentPtr->hwndSelf, dcx_flags );
             if (flags & DCX_WINDOW)
                 OffsetRgn( hrgnVisible, -wndPtr->rectWindow.left,
                                         -wndPtr->rectWindow.top );
             else OffsetRgn( hrgnVisible, -wndPtr->rectClient.left,
                                          -wndPtr->rectClient.top );
         }
-        else hrgnVisible = DCE_GetVisRgn( hwnd, flags );
-    }
-    else  /* Get a VisRgn for the whole screen */
-    {
-        hrgnVisible = CreateRectRgn( 0, 0, SYSMETRICS_CXSCREEN,
+      else if( hwnd==GetDesktopWindow() ) hrgnVisible = CreateRectRgn( 0, 0, SYSMETRICS_CXSCREEN,
                                      SYSMETRICS_CYSCREEN);
-    }
+      else hrgnVisible = DCE_GetVisRgn( hwnd, flags );
 
-      /* Intersect VisRgn with the given region */
+      dc->w.flags &= ~DC_DIRTY;
+
+      SelectVisRgn( hdc, hrgnVisible );
+     }
+    else hrgnVisible = CreateRectRgn(0,0,0,0);
 
     if ((flags & DCX_INTERSECTRGN) || (flags & DCX_EXCLUDERGN))
     {
-        CombineRgn( hrgnVisible, hrgnVisible, hrgnClip,
+	dce->DCXflags |= flags & (DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_EXCLUDERGN);
+	dce->hClipRgn = hrgnClip;
+
+	dprintf_dc(stddeb, "\tsaved VisRgn, clipRgn = %04x\n", hrgnClip);
+
+	SaveVisRgn( hdc );
+        CombineRgn( hrgnVisible, InquireVisRgn( hdc ), hrgnClip,
                     (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
+	SelectVisRgn( hdc, hrgnVisible );
     }
-    SelectVisRgn( hdc, hrgnVisible );
     DeleteObject( hrgnVisible );
 
     dprintf_dc(stddeb, "GetDCEx(%04x,%04x,0x%lx): returning %04x\n", 
@@ -385,12 +525,13 @@
     return hdc;
 }
 
-
 /***********************************************************************
  *           GetDC    (USER.66)
  */
 HDC GetDC( HWND hwnd )
 {
+    if( !hwnd ) return GetDCEx( GetDesktopWindow(), 0, DCX_CACHE | DCX_WINDOW );
+
     return GetDCEx( hwnd, 0, DCX_USESTYLE );
 }
 
@@ -400,15 +541,14 @@
  */
 HDC GetWindowDC( HWND hwnd )
 {
-    int flags = DCX_CACHE | DCX_WINDOW;
     if (hwnd)
     {
 	WND * wndPtr;
 	if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
-/*	if (wndPtr->dwStyle & WS_CLIPCHILDREN) flags |= DCX_CLIPCHILDREN; */
-	if (wndPtr->dwStyle & WS_CLIPSIBLINGS) flags |= DCX_CLIPSIBLINGS;
     }
-    return GetDCEx( hwnd, 0, flags );
+    else hwnd = GetDesktopWindow();
+
+    return GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW );
 }
 
 
@@ -425,14 +565,98 @@
     for (hdce = firstDCE; (hdce); hdce = dce->hNext)
     {
 	if (!(dce = (DCE *) USER_HEAP_LIN_ADDR( hdce ))) return 0;
-	if (dce->inUse && (dce->hdc == hdc)) break;
+	if (dce->hDC == hdc) break;
     }
     if (!hdce) return 0;
+    if (!(dce->DCXflags & DCX_DCEBUSY) ) return 0;
 
-    if (dce->type == DCE_CACHE_DC)
+    /* restore previous visible region */
+
+    if ( dce->DCXflags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN) &&
+	(dce->DCXflags & DCX_CACHE || dce->DCXflags & DCX_WINDOWPAINT) )
     {
-	SetDCState( dce->hdc, defaultDCstate );
-	dce->inUse = FALSE;
+	dprintf_dc(stddeb,"\tcleaning up visrgn...\n");
+	dce->DCXflags &= ~(DCX_EXCLUDERGN | DCX_INTERSECTRGN | DCX_WINDOWPAINT);
+
+	if( dce->DCXflags & DCX_KEEPCLIPRGN )
+	    dce->DCXflags &= ~DCX_KEEPCLIPRGN;
+	else
+	  {
+	    if( dce->hClipRgn > 1 )
+	        DeleteObject( dce->hClipRgn );
+	    dce->hClipRgn = 0;
+	  } 
+        dce->hClipRgn = 0;
+	RestoreVisRgn(dce->hDC);
+    }
+
+    if (dce->DCXflags & DCX_CACHE)
+    {
+	SetDCState( dce->hDC, defaultDCstate );
+	dce->DCXflags &= ~DCX_DCEBUSY;
     }
     return 1;
 }
+
+/***********************************************************************
+ *           DCHook    (USER.362)
+ *
+ * See "Undoc. Windows" for hints (DC, SetDCHook, SetHookFlags)..  
+ */
+BOOL DCHook(HDC hDC, WORD code, DWORD data, DWORD lParam)
+{
+  HANDLE hdce;
+  HRGN hVisRgn;
+
+  dprintf_dc(stddeb,"DCHook: hDC = %04x, %i\n", hDC, code);
+
+  if( HIWORD(data) == DC_MAGIC )
+      hdce = (HANDLE)LOWORD(data);
+  else
+      hdce = DCE_FindDCE(hDC);
+
+  if( !hdce ) return 0;
+
+  switch( code )
+    {
+      case DCHC_INVALIDVISRGN:
+         {
+           DCE* dce = (DCE*) USER_HEAP_LIN_ADDR(hdce);
+
+           if( dce->DCXflags & DCX_DCEBUSY )
+ 	     {
+	       SetHookFlags(hDC, DCHF_VALIDATEVISRGN);
+	       hVisRgn = DCE_GetVisRgn(dce->hwndCurrent, dce->DCXflags);
+
+	       dprintf_dc(stddeb,"\tapplying saved clipRgn\n");
+  
+	       /* clip this region with saved clipping region */
+
+               if ( (dce->DCXflags & DCX_INTERSECTRGN && dce->hClipRgn != 1) ||
+                  (  dce->DCXflags & DCX_EXCLUDERGN && dce->hClipRgn) )
+                  {
+
+                    if( (!dce->hClipRgn && dce->DCXflags & DCX_INTERSECTRGN) ||
+                         (dce->hClipRgn == 1 && dce->DCXflags & DCX_EXCLUDERGN) )            
+                         SetRectRgn(hVisRgn,0,0,0,0);
+                    else
+                         CombineRgn(hVisRgn, hVisRgn, dce->hClipRgn, 
+                                      (dce->DCXflags & DCX_EXCLUDERGN)? RGN_DIFF:RGN_AND);
+	          }  
+	       SelectVisRgn(hDC, hVisRgn);
+	       DeleteObject(hVisRgn);
+	     }
+           else
+	     dprintf_dc(stddeb,"DCHook: DC is not in use!\n");
+         }
+	 break;
+
+      case DCHC_DELETEDC: /* FIXME: ?? */
+	 break;
+
+      default:
+	 fprintf(stdnimp,"DCHook: unknown code\n");
+    }
+  return 0;
+}
+
diff --git a/windows/defdlg.c b/windows/defdlg.c
index 39e77e0..9379e07 100644
--- a/windows/defdlg.c
+++ b/windows/defdlg.c
@@ -1,16 +1,15 @@
 /*
  * Default dialog procedure
  *
- * Copyright 1993 Alexandre Julliard
+ * Copyright 1993, 1996 Alexandre Julliard
  *
  */
 
 #include "windows.h"
 #include "dialog.h"
 #include "win.h"
-#include "stddebug.h"
-/* #define DEBUG_DIALOG */
-#include "debug.h"
+#include "winproc.h"
+
 
 /***********************************************************************
  *           DEFDLG_SetFocus
@@ -110,37 +109,22 @@
 
 
 /***********************************************************************
- *           DefDlgProc   (USER.308)
+ *           DEFDLG_Proc
+ *
+ * Implementation of DefDlgProc(). Only handle messages that need special
+ * handling for dialogs.
  */
-LRESULT DefDlgProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
+static LRESULT DEFDLG_Proc( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
+                            LPARAM lParam, DIALOGINFO *dlgInfo )
 {
-    DIALOGINFO * dlgInfo;
-    BOOL result = FALSE;
-    WND * wndPtr = WIN_FindWndPtr( hwnd );
-    
-    if (!wndPtr) return 0;
-    dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
-
-    dlgInfo->msgResult = 0;
-    if (dlgInfo->dlgProc)
-    {
-	  /* Call dialog procedure */
-	result = (BOOL)CallWindowProc16( dlgInfo->dlgProc, hwnd, 
-                                         msg, wParam, lParam );
-
-	  /* Check if window destroyed by dialog procedure */
-	wndPtr = WIN_FindWndPtr( hwnd );
-	if (!wndPtr) return result;
-    }
-    
-    if (!result) switch(msg)
+    switch(msg)
     {
 	case WM_INITDIALOG:
-	    break;
+	    return 0;
 
         case WM_ERASEBKGND:
 	    FillWindow( hwnd, hwnd, (HDC)wParam, (HBRUSH)CTLCOLOR_DLG );
-	    return TRUE;
+	    return 1;
 
 	case WM_NCDESTROY:
 
@@ -166,28 +150,34 @@
 		dlgInfo->hMenu = 0;
 	    }
 
+            /* Delete window procedure */
+            if (dlgInfo->dlgProc)
+            {
+                WINPROC_FreeWinProc( dlgInfo->dlgProc );
+                dlgInfo->dlgProc = 0;
+            }
+
 	      /* Window clean-up */
-	    DefWindowProc16( hwnd, msg, wParam, lParam );
-	    break;
+	    return DefWindowProc32A( hwnd, msg, wParam, lParam );
 
 	case WM_SHOWWINDOW:
 	    if (!wParam) DEFDLG_SaveFocus( hwnd, dlgInfo );
-	    return DefWindowProc16( hwnd, msg, wParam, lParam );
+	    return DefWindowProc32A( hwnd, msg, wParam, lParam );
 
 	case WM_ACTIVATE:
 	    if (wParam) DEFDLG_RestoreFocus( hwnd, dlgInfo );
 	    else DEFDLG_SaveFocus( hwnd, dlgInfo );
-	    break;
+	    return 0;
 
 	case WM_SETFOCUS:
 	    DEFDLG_RestoreFocus( hwnd, dlgInfo );
-	    break;
+	    return 0;
 
         case DM_SETDEFID:
-            if (dlgInfo->fEnd) return TRUE;
+            if (dlgInfo->fEnd) return 1;
             DEFDLG_SetDefButton( hwnd, dlgInfo,
                                  wParam ? GetDlgItem( hwnd, wParam ) : 0 );
-            return TRUE;
+            return 1;
 
         case DM_GETDEFID:
             if (dlgInfo->fEnd || !dlgInfo->msgResult) return 0;
@@ -207,16 +197,142 @@
                 if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
                 DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest );
             }
-            break;
+            return 0;
 
         case WM_CLOSE:
             EndDialog( hwnd, TRUE );
             DestroyWindow( hwnd );
             return 0;
+    }
+    return 0;
+}
+
+
+/***********************************************************************
+ *           DefDlgProc16   (USER.308)
+ */
+LRESULT DefDlgProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam )
+{
+    DIALOGINFO * dlgInfo;
+    BOOL16 result = FALSE;
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    
+    if (!wndPtr) return 0;
+    dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
+
+    dlgInfo->msgResult = 0;
+    if (dlgInfo->dlgProc)
+    {
+	  /* Call dialog procedure */
+	result = (BOOL16)CallWindowProc16( (WNDPROC16)dlgInfo->dlgProc, hwnd, 
+                                           msg, wParam, lParam );
+
+        /* Check if window was destroyed by dialog procedure */
+        if (result || !IsWindow( hwnd )) return result;
+    }
+    
+    switch(msg)
+    {
+	case WM_INITDIALOG:
+        case WM_ERASEBKGND:
+	case WM_NCDESTROY:
+	case WM_SHOWWINDOW:
+	case WM_ACTIVATE:
+	case WM_SETFOCUS:
+        case DM_SETDEFID:
+        case DM_GETDEFID:
+	case WM_NEXTDLGCTL:
+        case WM_CLOSE:
+            return DEFDLG_Proc( (HWND32)hwnd, msg, (WPARAM32)wParam,
+                                lParam, dlgInfo );
 
 	default:
 	    return DefWindowProc16( hwnd, msg, wParam, lParam );
     }
-        
-    return result;
+}
+
+
+/***********************************************************************
+ *           DefDlgProc32A   (USER32.119)
+ */
+LRESULT DefDlgProc32A( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
+{
+    DIALOGINFO * dlgInfo;
+    BOOL16 result = FALSE;
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    
+    if (!wndPtr) return 0;
+    dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
+
+    dlgInfo->msgResult = 0;
+    if (dlgInfo->dlgProc)
+    {
+	  /* Call dialog procedure */
+	result = (BOOL16)CallWindowProc32A( (WNDPROC32)dlgInfo->dlgProc, hwnd, 
+                                            msg, wParam, lParam );
+
+        /* Check if window was destroyed by dialog procedure */
+        if (result || !IsWindow( hwnd )) return result;
+    }
+    
+    switch(msg)
+    {
+	case WM_INITDIALOG:
+        case WM_ERASEBKGND:
+	case WM_NCDESTROY:
+	case WM_SHOWWINDOW:
+	case WM_ACTIVATE:
+	case WM_SETFOCUS:
+        case DM_SETDEFID:
+        case DM_GETDEFID:
+	case WM_NEXTDLGCTL:
+        case WM_CLOSE:
+            return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
+
+	default:
+	    return DefWindowProc32A( hwnd, msg, wParam, lParam );
+    }
+}
+
+
+/***********************************************************************
+ *           DefDlgProc32W   (USER32.120)
+ */
+LRESULT DefDlgProc32W( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
+{
+    DIALOGINFO * dlgInfo;
+    BOOL16 result = FALSE;
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    
+    if (!wndPtr) return 0;
+    dlgInfo = (DIALOGINFO *)&wndPtr->wExtra;
+
+    dlgInfo->msgResult = 0;
+    if (dlgInfo->dlgProc)
+    {
+	  /* Call dialog procedure */
+	result = (BOOL16)CallWindowProc32W( (WNDPROC32)dlgInfo->dlgProc, hwnd, 
+                                            msg, wParam, lParam );
+
+        /* Check if window was destroyed by dialog procedure */
+        if (result || !IsWindow( hwnd )) return result;
+    }
+    
+    switch(msg)
+    {
+	case WM_INITDIALOG:
+        case WM_ERASEBKGND:
+	case WM_NCDESTROY:
+	case WM_SHOWWINDOW:
+	case WM_ACTIVATE:
+	case WM_SETFOCUS:
+        case DM_SETDEFID:
+        case DM_GETDEFID:
+	case WM_NEXTDLGCTL:
+        case WM_CLOSE:
+            return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
+
+	default:
+	    return DefWindowProc32W( hwnd, msg, wParam, lParam );
+    }
 }
diff --git a/windows/defwnd.c b/windows/defwnd.c
index d3eb72a..bed9009 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -377,7 +377,7 @@
         if (wParam && wndPtr->text)
         {
             lstrcpyn( (LPSTR)PTR_SEG_TO_LIN(lParam), wndPtr->text, wParam );
-            return (LRESULT)strlen( (LPSTR)PTR_SEG_TO_LIN(lParam) ) + 1;
+            result = (LRESULT)strlen( (LPSTR)PTR_SEG_TO_LIN(lParam) ) + 1;
         }
         break;
 
@@ -442,7 +442,7 @@
         if (wParam && wndPtr->text)
         {
             lstrcpyn( (LPSTR)lParam, wndPtr->text, wParam );
-            return (LRESULT)strlen( (LPSTR)lParam ) + 1;
+            result = (LRESULT)strlen( (LPSTR)lParam ) + 1;
         }
         break;
 
diff --git a/windows/dialog.c b/windows/dialog.c
index edf4623..4e010bc 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -1,8 +1,7 @@
 /*
  * Dialog functions
  *
- * Copyright 1993, 1994 Alexandre Julliard
- *
+ * Copyright 1993, 1994, 1996 Alexandre Julliard
  */
 
 #include <stdlib.h>
@@ -13,15 +12,50 @@
 #include "heap.h"
 #include "win.h"
 #include "ldt.h"
+#include "resource32.h"
 #include "stackframe.h"
+#include "string32.h"
 #include "user.h"
+#include "winproc.h"
 #include "message.h"
 #include "stddebug.h"
-/* #define DEBUG_DIALOG */
 #include "debug.h"
 
+
+  /* Dialog control information */
+typedef struct
+{
+    DWORD      style;
+    DWORD      exStyle;
+    INT16      x;
+    INT16      y;
+    INT16      cx;
+    INT16      cy;
+    UINT16     id;
+    LPCSTR     className;
+    LPCSTR     windowName;
+    LPVOID     data;
+} DLG_CONTROL_INFO;
+
+  /* Dialog template */
+typedef struct
+{
+    DWORD      style;
+    DWORD      exStyle;
+    UINT16     nbItems;
+    INT16      x;
+    INT16      y;
+    INT16      cx;
+    INT16      cy;
+    LPCSTR     menuName;
+    LPCSTR     className;
+    LPCSTR     caption;
+    WORD       pointSize;
+    LPCSTR     faceName;
+} DLG_TEMPLATE;
+
   /* Dialog base units */
-WORD xBaseUnit = 0, yBaseUnit = 0;
+static WORD xBaseUnit = 0, yBaseUnit = 0;
 
 
 /***********************************************************************
@@ -36,9 +70,9 @@
     
       /* Calculate the dialog base units */
 
-    if (!(hdc = GetDC( 0 ))) return FALSE;
+    if (!(hdc = CreateDC( "DISPLAY", NULL, NULL, NULL ))) return FALSE;
     GetTextMetrics( hdc, &tm );
-    ReleaseDC( 0, hdc );
+    DeleteDC( hdc );
     xBaseUnit = tm.tmAveCharWidth;
     yBaseUnit = tm.tmHeight;
 
@@ -67,96 +101,278 @@
 
 
 /***********************************************************************
- *           DIALOG_GetControl
+ *           DIALOG_GetControl16
  *
  * Return the class and text of the control pointed to by ptr,
  * fill the header structure and return a pointer to the next control.
  */
-static SEGPTR DIALOG_GetControl( SEGPTR ptr, DLGCONTROLHEADER *header,
-                                 SEGPTR *class, SEGPTR *text )
+static LPCSTR DIALOG_GetControl16( LPCSTR p, DLG_CONTROL_INFO *info )
 {
-    unsigned char *base = (unsigned char *)PTR_SEG_TO_LIN( ptr );
-    unsigned char *p = base;
+    static char buffer[10];
 
-    header->x  = GET_WORD(p); p += sizeof(WORD);
-    header->y  = GET_WORD(p); p += sizeof(WORD);
-    header->cx = GET_WORD(p); p += sizeof(WORD);
-    header->cy = GET_WORD(p); p += sizeof(WORD);
-    header->id = GET_WORD(p); p += sizeof(WORD);
-    header->style = GET_DWORD(p); p += sizeof(DWORD);
+    info->x       = GET_WORD(p);  p += sizeof(WORD);
+    info->y       = GET_WORD(p);  p += sizeof(WORD);
+    info->cx      = GET_WORD(p);  p += sizeof(WORD);
+    info->cy      = GET_WORD(p);  p += sizeof(WORD);
+    info->id      = GET_WORD(p);  p += sizeof(WORD);
+    info->style   = GET_DWORD(p); p += sizeof(DWORD);
+    info->exStyle = 0;
 
     if (*p & 0x80)
     {
-        *class = MAKEINTRESOURCE( *p );
+        switch((BYTE)*p)
+        {
+            case 0x80: strcpy( buffer, "BUTTON" ); break;
+            case 0x81: strcpy( buffer, "EDIT" ); break;
+            case 0x82: strcpy( buffer, "STATIC" ); break;
+            case 0x83: strcpy( buffer, "LISTBOX" ); break;
+            case 0x84: strcpy( buffer, "SCROLLBAR" ); break;
+            case 0x85: strcpy( buffer, "COMBOBOX" ); break;
+            default:   buffer[0] = '\0'; break;
+        }
+        info->className = buffer;
         p++;
     }
     else 
     {
-	*class = ptr + (WORD)(p - base);
+	info->className = p;
 	p += strlen(p) + 1;
     }
+    dprintf_dialog(stddeb, "   %s ", info->className );
 
-    if (*p == 0xff)
+    if ((BYTE)*p == 0xff)
     {
 	  /* Integer id, not documented (?). Only works for SS_ICON controls */
-	*text = MAKEINTRESOURCE( GET_WORD(p+1) );
-	p += 4;
+	info->windowName = (LPCSTR)(UINT32)GET_WORD(p+1);
+	p += 3;
+        dprintf_dialog( stddeb,"%04x", LOWORD(info->windowName) );
     }
     else
     {
-	*text = ptr + (WORD)(p - base);
-	p += strlen(p) + 2;
+	info->windowName = p;
+	p += strlen(p) + 1;
+        dprintf_dialog(stddeb,"'%s'", info->windowName );
     }
-    return ptr + (WORD)(p - base);
+
+    info->data = (LPVOID)(*p ? p + 1 : NULL);  /* FIXME: is this right? */
+    p += *p + 1;
+
+    dprintf_dialog( stddeb," %d, %d, %d, %d, %d, %08lx, %08lx\n", 
+                    info->id, info->x, info->y, info->cx, info->cy,
+                    info->style, (DWORD)info->data);
+    return p;
 }
 
 
 /***********************************************************************
- *           DIALOG_ParseTemplate
+ *           DIALOG_GetControl32
  *
- * Fill a DLGTEMPLATE structure from the dialog template, and return
- * a pointer to the first control.
+ * Return the class and text of the control pointed to by ptr,
+ * fill the header structure and return a pointer to the next control.
  */
-static SEGPTR DIALOG_ParseTemplate( SEGPTR template, DLGTEMPLATE * result )
+static const WORD *DIALOG_GetControl32( const WORD *p, DLG_CONTROL_INFO *info )
 {
-    unsigned char *base = (unsigned char *)PTR_SEG_TO_LIN(template);
-    unsigned char * p = base;
- 
-    result->style = GET_DWORD(p); p += sizeof(DWORD);
-    result->nbItems = *p++;
-    result->x  = GET_WORD(p); p += sizeof(WORD);
-    result->y  = GET_WORD(p); p += sizeof(WORD);
-    result->cx = GET_WORD(p); p += sizeof(WORD);
-    result->cy = GET_WORD(p); p += sizeof(WORD);
+    static WCHAR buffer[10];
 
-    /* Get the menu name */
+    info->style   = GET_DWORD(p); p += 2;
+    info->exStyle = GET_DWORD(p); p += 2;
+    info->x       = GET_WORD(p); p++;
+    info->y       = GET_WORD(p); p++;
+    info->cx      = GET_WORD(p); p++;
+    info->cy      = GET_WORD(p); p++;
+    info->id      = GET_WORD(p); p++;
 
-    if (*p == 0xff)
+    if (GET_WORD(p) == 0xffff)
     {
-        result->menuName = MAKEINTRESOURCE( GET_WORD(p+1) );
-        p += 3;
-    }
-    else if (*p)
-    {
-        result->menuName = template + (WORD)(p - base);
-        p += strlen(p) + 1;
+        switch(GET_WORD(p+1))
+        {
+            case 0x80: STRING32_AnsiToUni( buffer, "BUTTON" ); break;
+            case 0x81: STRING32_AnsiToUni( buffer, "EDIT" ); break;
+            case 0x82: STRING32_AnsiToUni( buffer, "STATIC" ); break;
+            case 0x83: STRING32_AnsiToUni( buffer, "LISTBOX" ); break;
+            case 0x84: STRING32_AnsiToUni( buffer, "SCROLLBAR" ); break;
+            case 0x85: STRING32_AnsiToUni( buffer, "COMBOBOX" ); break;
+            default:   buffer[0] = '\0'; break;
+        }
+        info->className = (LPCSTR)buffer;
+        p += 2;
     }
     else
     {
+        info->className = (LPCSTR)p;
+        p += STRING32_lstrlenW( (LPCWSTR)p ) + 1;
+    }
+    dprintf_dialog(stddeb, "   %p ", info->className );
+
+    if (GET_WORD(p) == 0xffff)
+    {
+	info->windowName = (LPCSTR)(p + 1);
+	p += 2;
+        dprintf_dialog( stddeb,"%04x", LOWORD(info->windowName) );
+    }
+    else
+    {
+	info->windowName = (LPCSTR)p;
+        p += STRING32_lstrlenW( (LPCWSTR)p ) + 1;
+        dprintf_dialog(stddeb,"'%p'", info->windowName );
+    }
+
+    if (GET_WORD(p))
+    {
+        info->data = (LPVOID)(p + 1);
+        p += GET_WORD(p) / sizeof(WORD);
+    }
+    else info->data = NULL;
+    p++;
+
+    dprintf_dialog( stddeb," %d, %d, %d, %d, %d, %08lx, %08lx, %08lx\n", 
+                    info->id, info->x, info->y, info->cx, info->cy,
+                    info->style, info->exStyle, (DWORD)info->data);
+    /* Next control is on dword boundary */
+    return (const WORD *)((((int)p) + 3) & ~3);
+}
+
+
+/***********************************************************************
+ *           DIALOG_CreateControls
+ *
+ * Create the control windows for a dialog.
+ */
+static BOOL32 DIALOG_CreateControls( WND *pWnd, LPCSTR template, INT32 items,
+                                     HINSTANCE32 hInst, BOOL win32 )
+{
+    DIALOGINFO *dlgInfo = (DIALOGINFO *)pWnd->wExtra;
+    DLG_CONTROL_INFO info;
+    HWND32 hwndCtrl, hwndDefButton = 0;
+
+    dprintf_dialog(stddeb, " BEGIN\n" );
+    while (items--)
+    {
+        if (!win32)
+        {
+            HINSTANCE16 instance;
+            template = DIALOG_GetControl16( template, &info );
+            if (HIWORD(info.className) && !strcmp( info.className, "EDIT") &&
+                ((info.style & DS_LOCALEDIT) != DS_LOCALEDIT))
+            {
+                if (!dlgInfo->hDialogHeap)
+                {
+                    dlgInfo->hDialogHeap = GlobalAlloc16(GMEM_FIXED, 0x10000);
+                    if (!dlgInfo->hDialogHeap)
+                    {
+                        fprintf( stderr, "CreateDialogIndirectParam: Insufficient memory to create heap for edit control\n" );
+                        continue;
+                    }
+                    LocalInit(dlgInfo->hDialogHeap, 0, 0xffff);
+                }
+                instance = dlgInfo->hDialogHeap;
+            }
+            else instance = (HINSTANCE16)hInst;
+
+            hwndCtrl = CreateWindowEx16( info.exStyle | WS_EX_NOPARENTNOTIFY,
+                                         info.className, info.windowName,
+                                         info.style | WS_CHILD,
+                                         info.x * dlgInfo->xBaseUnit / 4,
+                                         info.y * dlgInfo->yBaseUnit / 8,
+                                         info.cx * dlgInfo->xBaseUnit / 4,
+                                         info.cy * dlgInfo->yBaseUnit / 8,
+                                         pWnd->hwndSelf, (HMENU)info.id,
+                                         instance, info.data );
+        }
+        else
+        {
+            template = (LPCSTR)DIALOG_GetControl32( (WORD *)template, &info );
+            hwndCtrl = CreateWindowEx32W( info.exStyle | WS_EX_NOPARENTNOTIFY,
+                                          (LPCWSTR)info.className,
+                                          (LPCWSTR)info.windowName,
+                                          info.style | WS_CHILD,
+                                          info.x * dlgInfo->xBaseUnit / 4,
+                                          info.y * dlgInfo->yBaseUnit / 8,
+                                          info.cx * dlgInfo->xBaseUnit / 4,
+                                          info.cy * dlgInfo->yBaseUnit / 8,
+                                          pWnd->hwndSelf, (HMENU)info.id,
+                                          hInst, info.data );
+        }
+        if (!hwndCtrl) return FALSE;
+
+        /* Make the control last one in Z-order, so that controls remain
+           in the order in which they were created */
+	SetWindowPos( hwndCtrl, HWND_BOTTOM, 0, 0, 0, 0,
+                      SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
+
+            /* Send initialisation messages to the control */
+        if (dlgInfo->hUserFont) SendMessage32A( hwndCtrl, WM_SETFONT,
+                                               (WPARAM)dlgInfo->hUserFont, 0 );
+        if (SendMessage32A(hwndCtrl, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
+        {
+              /* If there's already a default push-button, set it back */
+              /* to normal and use this one instead. */
+            if (hwndDefButton)
+                SendMessage32A( hwndDefButton, BM_SETSTYLE32,
+                                BS_PUSHBUTTON,FALSE );
+            hwndDefButton = hwndCtrl;
+            dlgInfo->msgResult = GetWindowWord( hwndCtrl, GWW_ID );
+        }
+    }    
+    dprintf_dialog(stddeb, " END\n" );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           DIALOG_ParseTemplate16
+ *
+ * Fill a DLG_TEMPLATE structure from the dialog template, and return
+ * a pointer to the first control.
+ */
+static LPCSTR DIALOG_ParseTemplate16( LPCSTR p, DLG_TEMPLATE * result )
+{
+    result->style   = GET_DWORD(p); p += sizeof(DWORD);
+    result->exStyle = 0;
+    result->nbItems = *p++;
+    result->x       = GET_WORD(p);  p += sizeof(WORD);
+    result->y       = GET_WORD(p);  p += sizeof(WORD);
+    result->cx      = GET_WORD(p);  p += sizeof(WORD);
+    result->cy      = GET_WORD(p);  p += sizeof(WORD);
+    dprintf_dialog( stddeb, "DIALOG %d, %d, %d, %d\n",
+                    result->x, result->y, result->cx, result->cy );
+    dprintf_dialog( stddeb, " STYLE %08lx\n", result->style );
+
+    /* Get the menu name */
+
+    switch( (BYTE)*p )
+    {
+    case 0:
         result->menuName = 0;
         p++;
+        break;
+    case 0xff:
+        result->menuName = (LPCSTR)(UINT32)GET_WORD( p + 1 );
+        p += 3;
+	dprintf_dialog(stddeb, " MENU %04x\n", LOWORD(result->menuName) );
+        break;
+    default:
+        result->menuName = p;
+        dprintf_dialog( stddeb, " MENU '%s'\n", p );
+        p += strlen(p) + 1;
+        break;
     }
 
     /* Get the class name */
 
-    if (*p) result->className = template + (WORD)(p - base);
+    if (*p)
+    {
+        result->className = p;
+        dprintf_dialog( stddeb, " CLASS '%s'\n", result->className );
+    }
     else result->className = DIALOG_CLASS_ATOM;
     p += strlen(p) + 1;
 
     /* Get the window caption */
 
-    result->caption = template + (WORD)(p - base);
+    result->caption = p;
     p += strlen(p) + 1;
+    dprintf_dialog( stddeb, " CAPTION '%s'\n", result->caption );
 
     /* Get the font name */
 
@@ -164,114 +380,130 @@
     {
 	result->pointSize = GET_WORD(p);
         p += sizeof(WORD);
-	result->faceName = template + (WORD)(p - base);
+	result->faceName = p;
         p += strlen(p) + 1;
+	dprintf_dialog( stddeb, " FONT %d,'%s'\n",
+                        result->pointSize, result->faceName );
+    }
+    return p;
+}
+
+
+/***********************************************************************
+ *           DIALOG_ParseTemplate32
+ *
+ * Fill a DLG_TEMPLATE structure from the dialog template, and return
+ * a pointer to the first control.
+ */
+static LPCSTR DIALOG_ParseTemplate32( LPCSTR template, DLG_TEMPLATE * result )
+{
+    const WORD *p = (const WORD *)template;
+
+    result->style   = GET_DWORD(p); p += 2;
+    result->exStyle = GET_DWORD(p); p += 2;
+    result->nbItems = GET_WORD(p); p++;
+    result->x       = GET_WORD(p); p++;
+    result->y       = GET_WORD(p); p++;
+    result->cx      = GET_WORD(p); p++;
+    result->cy      = GET_WORD(p); p++;
+    dprintf_dialog( stddeb, "DIALOG %d, %d, %d, %d\n",
+                    result->x, result->y, result->cx, result->cy );
+    dprintf_dialog( stddeb, " STYLE %08lx\n", result->style );
+    dprintf_dialog( stddeb, " EXSTYLE %08lx\n", result->exStyle );
+
+    /* Get the menu name */
+
+    switch(GET_WORD(p))
+    {
+    case 0x0000:
+        result->menuName = NULL;
+        p++;
+        break;
+    case 0xffff:
+        result->menuName = (LPCSTR)(UINT32)GET_WORD( p + 1 );
+        p += 2;
+	dprintf_dialog(stddeb, " MENU %04x\n", LOWORD(result->menuName) );
+        break;
+    default:
+        result->menuName = (LPCSTR)p;
+        dprintf_dialog( stddeb, " MENU '%p'\n", p );
+        p += STRING32_lstrlenW( (LPCWSTR)p ) + 1;
+        break;
     }
 
-    return template + (WORD)(p - base);
-}
+    /* Get the class name */
 
+    switch(GET_WORD(p))
+    {
+    case 0x0000:
+        result->className = DIALOG_CLASS_ATOM;
+        p++;
+        break;
+    case 0xffff:
+        result->className = (LPCSTR)(UINT32)GET_WORD( p + 1 );
+        p += 2;
+	dprintf_dialog(stddeb, " CLASS %04x\n", LOWORD(result->className) );
+        break;
+    default:
+        result->className = (LPCSTR)p;
+        dprintf_dialog( stddeb, " CLASS '%p'\n", p );
+        p += STRING32_lstrlenW( (LPCWSTR)p ) + 1;
+        break;
+    }
 
-/***********************************************************************
- *           DIALOG_DisplayTemplate
- */
-static void DIALOG_DisplayTemplate( DLGTEMPLATE * result )
-{
-    dprintf_dialog(stddeb, "DIALOG %d, %d, %d, %d\n", result->x, result->y,
-                   result->cx, result->cy );
-    dprintf_dialog(stddeb, " STYLE %08lx\n", result->style );
-    dprintf_dialog( stddeb, " CAPTION '%s'\n",
-                    (char *)PTR_SEG_TO_LIN(result->caption) );
+    /* Get the window caption */
 
-    if (HIWORD(result->className))
-        dprintf_dialog( stddeb, " CLASS '%s'\n",
-                        (char *)PTR_SEG_TO_LIN(result->className) );
-    else
-        dprintf_dialog( stddeb, " CLASS #%d\n", LOWORD(result->className) );
+    result->caption = (LPCSTR)p;
+    p += STRING32_lstrlenW( (LPCWSTR)p ) + 1;
+    dprintf_dialog( stddeb, " CAPTION '%p'\n", result->caption );
 
-    if (HIWORD(result->menuName))
-        dprintf_dialog( stddeb, " MENU '%s'\n",
-                        (char *)PTR_SEG_TO_LIN(result->menuName) );
-    else if (LOWORD(result->menuName))
-	dprintf_dialog(stddeb, " MENU %04x\n", LOWORD(result->menuName) );
+    /* Get the font name */
 
     if (result->style & DS_SETFONT)
-	dprintf_dialog( stddeb, " FONT %d,'%s'\n", result->pointSize,
-                        (char *)PTR_SEG_TO_LIN(result->faceName) );
+    {
+	result->pointSize = GET_WORD(p);
+        p++;
+	result->faceName = (LPCSTR)p;
+        p += STRING32_lstrlenW( (LPCWSTR)p ) + 1;
+	dprintf_dialog( stddeb, " FONT %d,'%p'\n",
+                        result->pointSize, result->faceName );
+    }
+    /* First control is on dword boundary */
+    return (LPCSTR)((((int)p) + 3) & ~3);
 }
 
 
 /***********************************************************************
- *           CreateDialog   (USER.89)
+ *           DIALOG_CreateIndirect
  */
-HWND CreateDialog( HINSTANCE hInst, SEGPTR dlgTemplate,
-		   HWND owner, DLGPROC dlgProc )
-{
-    return CreateDialogParam( hInst, dlgTemplate, owner, dlgProc, 0 );
-}
-
-
-/***********************************************************************
- *           CreateDialogParam   (USER.241)
- */
-HWND CreateDialogParam( HINSTANCE hInst, SEGPTR dlgTemplate,
-		        HWND owner, DLGPROC dlgProc, LPARAM param )
-{
-    HWND hwnd = 0;
-    HRSRC hRsrc;
-    HGLOBAL hmem;
-    SEGPTR data;
-
-    dprintf_dialog(stddeb, "CreateDialogParam: %04x,%08lx,%04x,%08lx,%ld\n",
-                   hInst, (DWORD)dlgTemplate, owner, (DWORD)dlgProc, param );
-     
-    if (!(hRsrc = FindResource( hInst, dlgTemplate, RT_DIALOG ))) return 0;
-    if (!(hmem = LoadResource( hInst, hRsrc ))) return 0;
-    if (!(data = WIN16_LockResource( hmem ))) hwnd = 0;
-    else hwnd = CreateDialogIndirectParam(hInst, data, owner, dlgProc, param);
-    FreeResource( hmem );
-    return hwnd;
-}
-
-
-/***********************************************************************
- *           CreateDialogIndirect   (USER.219)
- */
-HWND CreateDialogIndirect( HINSTANCE hInst, SEGPTR dlgTemplate,
-			   HWND owner, DLGPROC dlgProc )
-{
-    return CreateDialogIndirectParam( hInst, dlgTemplate, owner, dlgProc, 0 );
-}
-
-
-/***********************************************************************
- *           CreateDialogIndirectParam   (USER.242)
- */
-HWND CreateDialogIndirectParam( HINSTANCE hInst, SEGPTR dlgTemplate,
-			        HWND owner, DLGPROC dlgProc, LPARAM param )
+static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCSTR dlgTemplate,
+                                   HWND owner, HANDLE32 dlgProc,
+                                   LPARAM param, BOOL win32 )
 {
     HMENU hMenu = 0;
     HFONT hFont = 0;
-    HWND hwnd, hwndCtrl;
+    HWND hwnd;
     RECT16 rect;
     WND * wndPtr;
-    int i;
-    DLGTEMPLATE template;
-    SEGPTR headerPtr;
+    DLG_TEMPLATE template;
     DIALOGINFO * dlgInfo;
-    DWORD exStyle = 0;
     WORD xUnit = xBaseUnit;
     WORD yUnit = yBaseUnit;
 
       /* Parse dialog template */
 
     if (!dlgTemplate) return 0;
-    headerPtr = DIALOG_ParseTemplate( dlgTemplate, &template );
-    if (debugging_dialog) DIALOG_DisplayTemplate( &template );
+    if (win32) dlgTemplate = DIALOG_ParseTemplate32( dlgTemplate, &template );
+    else dlgTemplate = DIALOG_ParseTemplate16( dlgTemplate, &template );
 
       /* Load menu */
 
-    if (template.menuName) hMenu = LoadMenu( hInst, template.menuName );
+    if (template.menuName)
+    {
+        LPSTR str = SEGPTR_STRDUP( template.menuName );  /* FIXME: win32 */
+        hMenu = LoadMenu( hInst, SEGPTR_GET(str) );
+        SEGPTR_FREE( str );
+    }
 
       /* Create custom font if needed */
 
@@ -282,7 +514,7 @@
 	hFont = CreateFont( -template.pointSize, 0, 0, 0, FW_DONTCARE,
 			    FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
 			    DEFAULT_QUALITY, FF_DONTCARE,
-                            (LPSTR)PTR_SEG_TO_LIN(template.faceName) );
+                            template.faceName );  /* FIXME: win32 */
 	if (hFont)
 	{
 	    TEXTMETRIC tm;
@@ -301,14 +533,15 @@
 	}
     }
     
-      /* Create dialog main window */
+    /* Create dialog main window */
 
     rect.left = rect.top = 0;
     rect.right = template.cx * xUnit / 4;
     rect.bottom = template.cy * yUnit / 8;
-    if (template.style & DS_MODALFRAME) exStyle |= WS_EX_DLGMODALFRAME;
+    if (template.style & DS_MODALFRAME)
+        template.exStyle |= WS_EX_DLGMODALFRAME;
     AdjustWindowRectEx16( &rect, template.style, 
-                          hMenu ? TRUE : FALSE , exStyle );
+                          hMenu ? TRUE : FALSE , template.exStyle );
     rect.right -= rect.left;
     rect.bottom -= rect.top;
 
@@ -322,10 +555,17 @@
             ClientToScreen16( owner, (POINT16 *)&rect );
     }
 
-    hwnd = CreateWindowEx16( exStyle, template.className, template.caption, 
-			   template.style & ~WS_VISIBLE,
-			   rect.left, rect.top, rect.right, rect.bottom,
-			   owner, hMenu, hInst, (SEGPTR)0 );
+    if (win32)
+        hwnd = CreateWindowEx32W(template.exStyle, (LPCWSTR)template.className,
+                                 (LPCWSTR)template.caption,
+                                 template.style & ~WS_VISIBLE,
+                                 rect.left, rect.top, rect.right, rect.bottom,
+                                 owner, hMenu, hInst, NULL );
+    else
+        hwnd = CreateWindowEx16(template.exStyle, template.className,
+                                template.caption, template.style & ~WS_VISIBLE,
+                                rect.left, rect.top, rect.right, rect.bottom,
+                                owner, hMenu, hInst, NULL );
     if (!hwnd)
     {
 	if (hFont) DeleteObject( hFont );
@@ -334,137 +574,161 @@
     }
     wndPtr = WIN_FindWndPtr( hwnd );
 
-      /* Create control windows */
-
-    dprintf_dialog(stddeb, " BEGIN\n" );
-
-    dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
-    dlgInfo->msgResult = 0;  /* This is used to store the default button id */
-    dlgInfo->hDialogHeap = 0;
-
-    for (i = 0; i < template.nbItems; i++)
-    {
-	DLGCONTROLHEADER header;
-	SEGPTR className, winName;
-        HWND hwndDefButton = 0;
-        char buffer[10];
-
-	headerPtr = DIALOG_GetControl( headerPtr, &header,
-                                       &className, &winName );
-
-        if (!HIWORD(className))
-        {
-            switch(LOWORD(className))
-            {
-            case 0x80: strcpy( buffer, "BUTTON" ); break;
-            case 0x81: strcpy( buffer, "EDIT" ); break;
-            case 0x82: strcpy( buffer, "STATIC" ); break;
-            case 0x83: strcpy( buffer, "LISTBOX" ); break;
-            case 0x84: strcpy( buffer, "SCROLLBAR" ); break;
-            case 0x85: strcpy( buffer, "COMBOBOX" ); break;
-            default:   buffer[0] = '\0'; break;
-            }
-            className = MAKE_SEGPTR(buffer);
-        }
-
-        if (HIWORD(className))
-            dprintf_dialog(stddeb, "   %s ", (char*)PTR_SEG_TO_LIN(className));
-        else dprintf_dialog(stddeb, "   %04x ", LOWORD(className) );
-	if (HIWORD(winName))
-            dprintf_dialog(stddeb,"'%s'", (char *)PTR_SEG_TO_LIN(winName) );
-	else dprintf_dialog(stddeb,"%04x", LOWORD(winName) );
-
-	dprintf_dialog(stddeb," %d, %d, %d, %d, %d, %08lx\n", 
-                       header.id, header.x, header.y, 
-                       header.cx, header.cy, header.style );
-
-	if (HIWORD(className) &&
-            !strcmp( (char *)PTR_SEG_TO_LIN(className), "EDIT") &&
-            ((header.style & DS_LOCALEDIT) != DS_LOCALEDIT))
-        {
-	    if (!dlgInfo->hDialogHeap)
-            {
-		dlgInfo->hDialogHeap = GlobalAlloc16(GMEM_FIXED, 0x10000);
-		if (!dlgInfo->hDialogHeap)
-                {
-		    fprintf(stderr,"CreateDialogIndirectParam: Insufficient memory to create heap for edit control\n");
-		    continue;
-		}
-		LocalInit(dlgInfo->hDialogHeap, 0, 0xffff);
-	    }
-	    hwndCtrl = CreateWindowEx16(WS_EX_NOPARENTNOTIFY, className, winName,
-                                      header.style | WS_CHILD,
-                                      header.x * xUnit / 4,
-                                      header.y * yUnit / 8,
-                                      header.cx * xUnit / 4,
-                                      header.cy * yUnit / 8,
-                                      hwnd, (HMENU)header.id,
-                                      dlgInfo->hDialogHeap, (SEGPTR)0 );
-	}
-	else
-        {
-	    hwndCtrl = CreateWindowEx16( WS_EX_NOPARENTNOTIFY, className,
-                                         winName,
-                                         header.style | WS_CHILD,
-                                         header.x * xUnit / 4,
-                                         header.y * yUnit / 8,
-                                         header.cx * xUnit / 4,
-                                         header.cy * yUnit / 8,
-                                         hwnd, (HMENU)header.id,
-                                         hInst, (SEGPTR)0 );
-	}
-
-        /* Make the control last one in Z-order, so that controls remain
-           in the order in which they were created */
-	SetWindowPos( hwndCtrl, HWND_BOTTOM, 0, 0, 0, 0,
-                      SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
-
-            /* Send initialisation messages to the control */
-        if (hFont) SendMessage16( hwndCtrl, WM_SETFONT, (WPARAM)hFont, 0 );
-        if (SendMessage16( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
-        {
-              /* If there's already a default push-button, set it back */
-              /* to normal and use this one instead. */
-            if (hwndDefButton)
-                SendMessage32A( hwndDefButton, BM_SETSTYLE32,
-                                BS_PUSHBUTTON,FALSE );
-            hwndDefButton = hwndCtrl;
-            dlgInfo->msgResult = GetWindowWord( hwndCtrl, GWW_ID );
-        }
-    }    
-
-    dprintf_dialog(stddeb, " END\n" );
-    
       /* Initialise dialog extra data */
 
+    dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
     dlgInfo->dlgProc   = dlgProc;
     dlgInfo->hUserFont = hFont;
     dlgInfo->hMenu     = hMenu;
     dlgInfo->xBaseUnit = xUnit;
     dlgInfo->yBaseUnit = yUnit;
+    dlgInfo->msgResult = 0;  /* This is used to store the default button id */
+    dlgInfo->hDialogHeap = 0;
+
+    /* Create controls */
+
+    if (!DIALOG_CreateControls( wndPtr, dlgTemplate, template.nbItems,
+                                hInst, win32 ))
+    {
+        DestroyWindow( hwnd );
+        return 0;
+    }
+
+    /* Send initialisation messages and set focus */
+
     dlgInfo->hwndFocus = DIALOG_GetFirstTabItem( hwnd );
-
-      /* Send initialisation messages and set focus */
-
     if (dlgInfo->hUserFont)
-	SendMessage16( hwnd, WM_SETFONT, (WPARAM)dlgInfo->hUserFont, 0 );
-    if (SendMessage16( hwnd, WM_INITDIALOG, (WPARAM)dlgInfo->hwndFocus, param ))
+	SendMessage32A( hwnd, WM_SETFONT, (WPARAM)dlgInfo->hUserFont, 0 );
+    if (SendMessage32A(hwnd, WM_INITDIALOG, (WPARAM)dlgInfo->hwndFocus, param))
 	SetFocus( dlgInfo->hwndFocus );
-    if (template.style & WS_VISIBLE) ShowWindow(hwnd, SW_SHOW);
+    if (template.style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
     return hwnd;
 }
 
 
 /***********************************************************************
+ *           CreateDialog16   (USER.89)
+ */
+HWND16 CreateDialog16( HINSTANCE16 hInst, SEGPTR dlgTemplate,
+                       HWND16 owner, DLGPROC dlgProc )
+{
+    return CreateDialogParam16( hInst, dlgTemplate, owner, dlgProc, 0 );
+}
+
+
+/***********************************************************************
+ *           CreateDialogParam16   (USER.241)
+ */
+HWND16 CreateDialogParam16( HINSTANCE16 hInst, SEGPTR dlgTemplate,
+                            HWND16 owner, DLGPROC dlgProc, LPARAM param )
+{
+    HWND16 hwnd = 0;
+    HRSRC hRsrc;
+    HGLOBAL16 hmem;
+    LPCVOID data;
+
+    dprintf_dialog(stddeb, "CreateDialogParam16: %04x,%08lx,%04x,%08lx,%ld\n",
+                   hInst, (DWORD)dlgTemplate, owner, (DWORD)dlgProc, param );
+
+    if (!(hRsrc = FindResource( hInst, dlgTemplate, RT_DIALOG ))) return 0;
+    if (!(hmem = LoadResource( hInst, hRsrc ))) return 0;
+    if (!(data = LockResource( hmem ))) hwnd = 0;
+    else hwnd = CreateDialogIndirectParam16( hInst, data, owner,
+                                             dlgProc, param );
+    FreeResource( hmem );
+    return hwnd;
+}
+
+
+/***********************************************************************
+ *           CreateDialogParam32A   (USER32.72)
+ */
+HWND32 CreateDialogParam32A( HINSTANCE32 hInst, LPCSTR name,
+                             HWND32 owner, DLGPROC dlgProc, LPARAM param )
+{
+    if (HIWORD(name))
+    {
+        LPWSTR str = STRING32_DupAnsiToUni( name );
+        HWND32 hwnd = CreateDialogParam32W( hInst, str, owner, dlgProc, param);
+        free( str );
+        return hwnd;
+    }
+    return CreateDialogParam32W( hInst, (LPCWSTR)name, owner, dlgProc, param );
+}
+
+
+/***********************************************************************
+ *           CreateDialogParam32W   (USER32.73)
+ */
+HWND32 CreateDialogParam32W( HINSTANCE32 hInst, LPCWSTR name,
+                             HWND32 owner, DLGPROC dlgProc, LPARAM param )
+{
+    HANDLE32 hrsrc = FindResource32( hInst, name, (LPWSTR)RT_DIALOG );
+    if (!hrsrc) return 0;
+    return CreateDialogIndirectParam32W( hInst, LoadResource32( hInst, hrsrc ),
+                                         owner, dlgProc, param );
+}
+
+
+/***********************************************************************
+ *           CreateDialogIndirect16   (USER.219)
+ */
+HWND16 CreateDialogIndirect16( HINSTANCE16 hInst, LPCVOID dlgTemplate,
+                               HWND16 owner, DLGPROC dlgProc )
+{
+    return CreateDialogIndirectParam16( hInst, dlgTemplate, owner, dlgProc, 0);
+}
+
+
+/***********************************************************************
+ *           CreateDialogIndirectParam16   (USER.242)
+ */
+HWND16 CreateDialogIndirectParam16( HINSTANCE16 hInst, LPCVOID dlgTemplate,
+                                    HWND16 owner, DLGPROC dlgProc,
+                                    LPARAM param )
+{
+    HANDLE32 proc = WINPROC_AllocWinProc( (UINT32)dlgProc, WIN_PROC_16 );
+    return DIALOG_CreateIndirect( hInst, dlgTemplate,
+                                  owner, proc, param, FALSE );
+}
+
+
+/***********************************************************************
+ *           CreateDialogIndirectParam32A   (USER32.69)
+ */
+HWND32 CreateDialogIndirectParam32A( HINSTANCE32 hInst, LPCVOID dlgTemplate,
+                                     HWND32 owner, DLGPROC dlgProc,
+                                     LPARAM param )
+{
+    HANDLE32 proc = WINPROC_AllocWinProc( (UINT32)dlgProc, WIN_PROC_32A );
+    return DIALOG_CreateIndirect( hInst, dlgTemplate,
+                                  owner, proc, param, TRUE );
+}
+
+
+/***********************************************************************
+ *           CreateDialogIndirectParam32W   (USER32.71)
+ */
+HWND32 CreateDialogIndirectParam32W( HINSTANCE32 hInst, LPCVOID dlgTemplate,
+                                     HWND32 owner, DLGPROC dlgProc,
+                                     LPARAM param )
+{
+    HANDLE32 proc = WINPROC_AllocWinProc( (UINT32)dlgProc, WIN_PROC_32W );
+    return DIALOG_CreateIndirect( hInst, dlgTemplate,
+                                  owner, proc, param, TRUE );
+}
+
+
+/***********************************************************************
  *           DIALOG_DoDialogBox
  */
-int DIALOG_DoDialogBox( HWND hwnd, HWND owner )
+static INT32 DIALOG_DoDialogBox( HWND hwnd, HWND owner )
 {
     WND * wndPtr;
     DIALOGINFO * dlgInfo;
     HANDLE msgHandle;
     MSG* lpmsg;
-    int retval;
+    INT32 retval;
 
       /* Owner must be a top-level window */
     owner = WIN_GetTopParent( owner );
@@ -495,62 +759,108 @@
 
 
 /***********************************************************************
- *           DialogBox   (USER.87)
+ *           DialogBox16   (USER.87)
  */
-INT DialogBox( HINSTANCE hInst, SEGPTR dlgTemplate,
-	       HWND owner, DLGPROC dlgProc )
+INT16 DialogBox16( HINSTANCE16 hInst, SEGPTR dlgTemplate,
+                   HWND16 owner, DLGPROC dlgProc )
 {
-    return DialogBoxParam( hInst, dlgTemplate, owner, dlgProc, 0 );
+    return DialogBoxParam16( hInst, dlgTemplate, owner, dlgProc, 0 );
 }
 
 
 /***********************************************************************
- *           DialogBoxParam   (USER.239)
+ *           DialogBoxParam16   (USER.239)
  */
-INT DialogBoxParam( HINSTANCE hInst, SEGPTR dlgTemplate,
-		    HWND owner, DLGPROC dlgProc, LPARAM param )
+INT16 DialogBoxParam16( HINSTANCE16 hInst, SEGPTR template,
+                        HWND16 owner, DLGPROC dlgProc, LPARAM param )
 {
-    HWND hwnd;
-    
-    dprintf_dialog(stddeb, "DialogBoxParam: %04x,%08lx,%04x,%08lx,%ld\n",
-                   hInst, (DWORD)dlgTemplate, owner, (DWORD)dlgProc, param );
-    hwnd = CreateDialogParam( hInst, dlgTemplate, owner, dlgProc, param );
+    HWND16 hwnd = CreateDialogParam16( hInst, template, owner, dlgProc, param);
+    if (hwnd) return (INT16)DIALOG_DoDialogBox( hwnd, owner );
+    return -1;
+}
+
+
+/***********************************************************************
+ *           DialogBoxParam32A   (USER32.138)
+ */
+INT32 DialogBoxParam32A( HINSTANCE32 hInst, LPCSTR name,
+                         HWND32 owner, DLGPROC dlgProc, LPARAM param )
+{
+    HWND32 hwnd = CreateDialogParam32A( hInst, name, owner, dlgProc, param );
     if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
     return -1;
 }
 
 
 /***********************************************************************
- *           DialogBoxIndirect   (USER.218)
+ *           DialogBoxParam32W   (USER32.139)
  */
-INT DialogBoxIndirect( HINSTANCE hInst, HANDLE dlgTemplate,
-		       HWND owner, DLGPROC dlgProc )
+INT32 DialogBoxParam32W( HINSTANCE32 hInst, LPCWSTR name,
+                         HWND32 owner, DLGPROC dlgProc, LPARAM param )
 {
-    return DialogBoxIndirectParam( hInst, dlgTemplate, owner, dlgProc, 0 );
+    HWND32 hwnd = CreateDialogParam32W( hInst, name, owner, dlgProc, param );
+    if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
+    return -1;
 }
 
 
 /***********************************************************************
- *           DialogBoxIndirectParam   (USER.240)
+ *           DialogBoxIndirect16   (USER.218)
  */
-INT DialogBoxIndirectParam( HINSTANCE hInst, HANDLE dlgTemplate,
-			    HWND owner, DLGPROC dlgProc, LPARAM param )
+INT16 DialogBoxIndirect16( HINSTANCE16 hInst, HANDLE16 dlgTemplate,
+                           HWND16 owner, DLGPROC dlgProc )
 {
-    HWND hwnd;
-    SEGPTR ptr;
+    return DialogBoxIndirectParam16( hInst, dlgTemplate, owner, dlgProc, 0 );
+}
 
-    if (!(ptr = (SEGPTR)WIN16_GlobalLock16( dlgTemplate ))) return -1;
-    hwnd = CreateDialogIndirectParam( hInst, ptr, owner, dlgProc, param );
+
+/***********************************************************************
+ *           DialogBoxIndirectParam16   (USER.240)
+ */
+INT16 DialogBoxIndirectParam16( HINSTANCE16 hInst, HANDLE16 dlgTemplate,
+                                HWND16 owner, DLGPROC dlgProc, LPARAM param )
+{
+    HWND16 hwnd;
+    LPCVOID ptr;
+
+    if (!(ptr = GlobalLock16( dlgTemplate ))) return -1;
+    hwnd = CreateDialogIndirectParam16( hInst, ptr, owner, dlgProc, param );
     GlobalUnlock16( dlgTemplate );
+    if (hwnd) return (INT16)DIALOG_DoDialogBox( hwnd, owner );
+    return -1;
+}
+
+
+/***********************************************************************
+ *           DialogBoxIndirectParam32A   (USER32.135)
+ */
+INT32 DialogBoxIndirectParam32A( HINSTANCE32 hInstance, LPCVOID template,
+                                 HWND32 owner, DLGPROC dlgProc ,LPARAM param )
+{
+    HWND32 hwnd = CreateDialogIndirectParam32A( hInstance, template,
+                                                owner, dlgProc, param );
     if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
     return -1;
 }
 
 
 /***********************************************************************
- *           EndDialog   (USER.88)
+ *           DialogBoxIndirectParam32W   (USER32.137)
  */
-BOOL EndDialog( HWND hwnd, INT retval )
+INT32 DialogBoxIndirectParam32W( HINSTANCE32 hInstance, LPCVOID template,
+                                 HWND32 owner, DLGPROC dlgProc ,LPARAM param )
+{
+    HWND32 hwnd = CreateDialogIndirectParam32W( hInstance, template,
+                                                owner, dlgProc, param );
+    if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
+    return -1;
+}
+
+
+/***********************************************************************
+ *           EndDialog   (USER.88) (USER32.173)
+ */
+BOOL16 EndDialog( HWND32 hwnd, INT32 retval )
 {
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     DIALOGINFO * dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
diff --git a/windows/event.c b/windows/event.c
index 53beabe..ce75d90 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -32,6 +32,7 @@
 #include "registers.h"
 #include "stddebug.h"
 #include "debug.h"
+#include "dde_proc.h"
 
 
 #ifdef ndef
@@ -628,14 +629,18 @@
  */
 static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event )
 {
-    if (hwnd == GetDesktopWindow())
+    /* FIXME: with -desktop xxx we get this event _before_ desktop 
+     * window structure is created. WIN_GetDesktop() check is a hack.
+     */
+
+    if ( !WIN_GetDesktop() || hwnd == GetDesktopWindow())
     {
         desktopX = event->x;
 	desktopY = event->y;
     }
     else
     {
-      /* A managed window; most of this code is shamelessly
+      /* Managed window; most of this code is shamelessly
        * stolen from SetWindowPos - FIXME: outdated
        */
       
@@ -710,17 +715,20 @@
 static void EVENT_SelectionRequest( HWND hwnd, XSelectionRequestEvent *event )
 {
     XSelectionEvent result;
-    Atom rprop;
-    Window request=event->requestor;
-    rprop=None;
+    Atom 	    rprop = None;
+    Window 	    request = event->requestor;
+
     if(event->target == XA_STRING)
     {
 	HANDLE hText;
 	LPSTR text;
-        rprop=event->property;
-	if(rprop == None)rprop=event->target;
-        if(event->selection!=XA_PRIMARY)rprop=None;
-        else if(!IsClipboardFormatAvailable(CF_TEXT))rprop=None;
+
+        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(hwnd);
@@ -733,8 +741,10 @@
 	    if(couldOpen)CloseClipboard();
 	}
     }
-    if(rprop==None) dprintf_event(stddeb,"Request for %s ignored\n",
-	XGetAtomName(display,event->target));
+
+    if(rprop==None) 
+       dprintf_event(stddeb,"Request for %s ignored\n", XGetAtomName(display,event->target));
+
     result.type=SelectionNotify;
     result.display=display;
     result.requestor=request;
diff --git a/windows/mdi.c b/windows/mdi.c
index b515e58..a48aea3 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -356,10 +356,11 @@
         style |= (WS_VISIBLE | WS_OVERLAPPEDWINDOW);
       }
  
-    hwnd = CreateWindow16( cs->szClass, cs->szTitle, style, 
+    hwnd = CreateWindow16( (LPCSTR)PTR_SEG_TO_LIN(cs->szClass),
+                           (LPCSTR)PTR_SEG_TO_LIN(cs->szTitle), style, 
 			  cs->x, cs->y, cs->cx, cs->cy, parent, 
                          (HMENU)(DWORD)(WORD)wIDmenu, w->hInstance, 
-			 (SEGPTR)lParam);
+			 (LPVOID)lParam);
 
     if (hwnd)
     {
diff --git a/windows/message.c b/windows/message.c
index aef426c..e12db33 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -699,7 +699,8 @@
     }
 
     SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wParam, lParam );
-    ret = CallWindowProc16( wndPtr->lpfnWndProc, hwnd, msg, wParam, lParam );
+    ret = CallWindowProc16( (WNDPROC16)wndPtr->winproc,
+                            hwnd, msg, wParam, lParam );
     SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, ret );
     return ret;
 }
@@ -738,7 +739,7 @@
     }
 
     SPY_EnterMessage( SPY_SENDMESSAGE32, hwnd, msg, wParam, lParam );
-    ret = CallWindowProc32A( (WNDPROC32)wndPtr->lpfnWndProc,
+    ret = CallWindowProc32A( (WNDPROC32)wndPtr->winproc,
                              hwnd, msg, wParam, lParam );
     SPY_ExitMessage( SPY_RESULT_OK32, hwnd, msg, ret );
     return ret;
@@ -778,7 +779,7 @@
     }
 
     SPY_EnterMessage( SPY_SENDMESSAGE32, hwnd, msg, wParam, lParam );
-    ret = CallWindowProc32W( (WNDPROC32)wndPtr->lpfnWndProc,
+    ret = CallWindowProc32W( (WNDPROC32)wndPtr->winproc,
                              hwnd, msg, wParam, lParam );
     SPY_ExitMessage( SPY_RESULT_OK32, hwnd, msg, ret );
     return ret;
@@ -869,14 +870,14 @@
 
     if (!msg->hwnd) return 0;
     if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
-    if (!wndPtr->lpfnWndProc) return 0;
+    if (!wndPtr->winproc) return 0;
     painting = (msg->message == WM_PAINT);
     if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
 /*    HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
 
     SPY_EnterMessage( SPY_DISPATCHMESSAGE16, msg->hwnd, msg->message,
                       msg->wParam, msg->lParam );
-    retval = CallWindowProc16( wndPtr->lpfnWndProc, msg->hwnd, msg->message,
+    retval = CallWindowProc16( wndPtr->winproc, msg->hwnd, msg->message,
                                msg->wParam, msg->lParam );
     SPY_ExitMessage( SPY_RESULT_OK16, msg->hwnd, msg->message, retval );
 
diff --git a/windows/msgbox.c b/windows/msgbox.c
index dc33193..ca18764 100644
--- a/windows/msgbox.c
+++ b/windows/msgbox.c
@@ -99,11 +99,10 @@
     bwidth = rect.left;
     GetWindowRect16(GetDlgItem(hwnd, 1), &rect);
     bwidth -= rect.left;
-    for (buttons = 0, i = 1; i < 8; i++) {
+    for (buttons = 0, i = 1; i < 8; i++)
+    {
       hItem = GetDlgItem(hwnd, i);
-      if (GetWindowLong(hItem, GWL_STYLE) & WS_VISIBLE) {
-	buttons++;
-      }
+      if (GetWindowLong32A(hItem, GWL_STYLE) & WS_VISIBLE) buttons++;
     }
     
     /* Get the text size */
@@ -141,7 +140,7 @@
     for (buttons = i = 0; i < 7; i++) {
       /* some arithmetic to get the right order for YesNoCancel windows */
       hItem = GetDlgItem(hwnd, (i + 5) % 7 + 1);
-      if (GetWindowLong(hItem, GWL_STYLE) & WS_VISIBLE) {
+      if (GetWindowLong32A(hItem, GWL_STYLE) & WS_VISIBLE) {
 	if (buttons++ == ((lpmb->type & MB_DEFMASK) >> 8)) {
 	  SetFocus(hItem);
 	  SendMessage32A( hItem, BM_SETSTYLE32, BS_DEFPUSHBUTTON, TRUE );
@@ -187,7 +186,7 @@
 
     handle = SYSRES_LoadResource( SYSRES_DIALOG_MSGBOX );
     if (!handle) return 0;
-    ret = DialogBoxIndirectParam( WIN_GetWindowInstance(hWnd),
+    ret = DialogBoxIndirectParam16( WIN_GetWindowInstance(hWnd),
                                   handle, hWnd,
                                   MODULE_GetWndProcEntry16("SystemMessageBoxProc"),
                                   (LONG)&mbox );
diff --git a/windows/painting.c b/windows/painting.c
index 10bdb97..e9c8283 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -10,6 +10,7 @@
 #include "win.h"
 #include "queue.h"
 #include "gdi.h"
+#include "dce.h"
 #include "stddebug.h"
 /* #define DEBUG_WIN */
 #include "debug.h"
@@ -104,8 +105,14 @@
 
     HideCaret( hwnd );
 
-    lps->hdc = GetDCEx( hwnd, hrgnUpdate, DCX_INTERSECTRGN | DCX_USESTYLE );
-    if(hrgnUpdate > 1) DeleteObject( hrgnUpdate );
+    dprintf_win(stddeb,"hrgnUpdate = %04x, ", hrgnUpdate);
+
+    lps->hdc = GetDCEx( hwnd, hrgnUpdate, DCX_INTERSECTRGN | DCX_WINDOWPAINT | DCX_USESTYLE );
+
+    dprintf_win(stddeb,"hdc = %04x\n", lps->hdc);
+
+    /* pseudocode from "Internals" doesn't delete hrgnUpdate - yet another clue
+       that ReleaseDC should take care of it (hence DCX_KEEPCLIPRGN) */
 
     if (!lps->hdc)
     {
@@ -348,7 +355,7 @@
         if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
         {
             HDC hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate,
-                               DCX_INTERSECTRGN | DCX_USESTYLE );
+                               DCX_INTERSECTRGN | DCX_USESTYLE | DCX_KEEPCLIPRGN | DCX_WINDOWPAINT);
             if (hdc)
             {
               /* Don't send WM_ERASEBKGND to icons */
diff --git a/windows/scroll.c b/windows/scroll.c
index 5569093..d25450d 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -17,10 +17,9 @@
 /* #define DEBUG_SCROLL */
 #include "debug.h"
 
-
-
-extern HRGN DCE_GetVisRgn(HWND, WORD);
-extern HWND CARET_GetHwnd();
+extern HRGN DCE_GetVisRgn(HWND, WORD);		/* windows/dce.c */
+extern HWND CARET_GetHwnd();			/* windows/caret.c */
+extern void CLIPPING_UpdateGCRegion(DC* );	/* objects/clipping.c */
 
 static int RgnType;
 
@@ -112,9 +111,7 @@
 /*************************************************************************
  *             ScrollWindow         (USER.61)
  *
- * FIXME: a bit broken
  */
-
 void ScrollWindow(HWND hwnd, short dx, short dy, LPRECT16 rect, LPRECT16 clipRect)
 {
     HDC  hdc;
@@ -131,7 +128,7 @@
     /* if rect is NULL children have to be moved */
     if ( !rect )
        {
-	GetClientRect16(hwnd, &rc);
+	  GetClientRect16(hwnd, &rc);
 	  hrgnClip = CreateRectRgnIndirect16( &rc );
 
           if ((hCaretWnd == hwnd) || IsChild(hwnd,hCaretWnd))
@@ -192,14 +189,14 @@
 /*************************************************************************
  *             ScrollDC         (USER.221)
  *
- * FIXME: half-broken
  */
-
 BOOL ScrollDC(HDC hdc, short dx, short dy, LPRECT16 rc, LPRECT16 cliprc,
 	      HRGN hrgnUpdate, LPRECT16 rcUpdate)
 {
-    HRGN hrgnClip;
-    POINT16 src, dest;
+    HRGN        hrgnClip 	= 0;
+    HRGN 	hrgnScrollClip  = 0;
+    RECT16	rectClip;
+    POINT16 	src, dest;
     short width, height;
     DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
 
@@ -207,20 +204,37 @@
                    dx, dy, hrgnUpdate, rcUpdate, cliprc, rc ? rc->left : 0,
                    rc ? rc->top : 0, rc ? rc->right : 0, rc ? rc->bottom : 0 );
 
-    if (rc == NULL)
+    if (rc == NULL || !hdc || !dc)
 	return FALSE;
 
-    if (!dc) 
-    { 
-        fprintf(stdnimp,"ScrollDC: Invalid HDC\n");
-        return FALSE;
-    }
+    /* set clipping region */
 
     if (cliprc)
-    {
-	hrgnClip = CreateRectRgnIndirect16(cliprc);
-	SelectClipRgn(hdc, hrgnClip);
-    }
+	IntersectRect16(&rectClip,rc,cliprc);
+    else
+	rectClip = *rc;
+
+    if( rectClip.left >= rectClip.right || rectClip.top >= rectClip.bottom )
+	return FALSE;
+    
+    hrgnClip = GetClipRgn(hdc);
+    hrgnScrollClip = CreateRectRgnIndirect16(&rectClip);
+
+    if( hrgnClip )
+      {
+        /* call UpdateGCRegion directly to avoid
+         * one more temporary region
+	 */ 
+
+        CombineRgn( hrgnScrollClip, hrgnClip, 0, RGN_COPY );
+        SetRectRgn( hrgnClip, rectClip.left, rectClip.top, rectClip.right, rectClip.bottom );
+
+	CLIPPING_UpdateGCRegion( dc );
+      }
+    else
+        SelectClipRgn( hdc, hrgnScrollClip ); 
+
+    /* translate coordinates */
 
     if (dx > 0)
     {
@@ -246,10 +260,14 @@
     width = rc->right - rc->left - abs(dx);
     height = rc->bottom - rc->top - abs(dy);
 
+    /* copy bits */
+
     if (!BitBlt(hdc, dest.x, dest.y, width, height, hdc, src.x, src.y, 
 		SRCCOPY))
 	return FALSE;
 
+    /* compute update areas */
+
     if (hrgnUpdate)
     {
 	HRGN hrgn1,hrgn2;
@@ -291,6 +309,11 @@
 	UnionRect16( rcUpdate, &rx, &ry );
     }
 
+    /* restore clipping region */
+
+    SelectClipRgn( hdc, (hrgnClip)?hrgnScrollClip:0 );
+    DeleteObject( hrgnScrollClip );     
+
     return TRUE;
 }
 
diff --git a/windows/win.c b/windows/win.c
index c89ef23..a59225c 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -3,6 +3,7 @@
  *
  * Copyright 1993, 1994 Alexandre Julliard
  */
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -27,6 +28,7 @@
 #include "shm_main_blk.h"
 #include "dde_proc.h"
 #include "callback.h"
+#include "clipboard.h"
 #include "winproc.h"
 #include "stddebug.h"
 /* #define DEBUG_WIN  */ 
@@ -90,13 +92,13 @@
     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"
-             "style=%08lx  exstyle=%08lx  wndproc=%08lx  text='%s'\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=%04x  vscroll=%04x  hscroll=%04x\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->dwStyle, ptr->dwExStyle, (DWORD)ptr->lpfnWndProc,
+             ptr->dwStyle, ptr->dwExStyle, ptr->winproc,
              ptr->text ? ptr->text : "",
              ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
              ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
@@ -142,11 +144,9 @@
 
         GlobalGetAtomName16(ptr->class->atomName,className,sizeof(className));
         
-        fprintf( stderr, "%08lx %-6.4x %-17.17s %08x %04x:%04x\n",
+        fprintf( stderr, "%08lx %-6.4x %-17.17s %08x %08x\n",
                  (DWORD)ptr, ptr->hmemTaskQ, className,
-                 (unsigned) ptr->dwStyle,
-                 HIWORD(ptr->lpfnWndProc),
-                 LOWORD(ptr->lpfnWndProc));
+                 (unsigned) ptr->dwStyle, ptr->winproc );
         
         if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
         ptr = ptr->next;
@@ -307,12 +307,11 @@
  *
  * Set the window procedure and return the old one.
  */
-static WNDPROC16 WIN_SetWndProc(WND *pWnd, WNDPROC16 proc, WINDOWPROCTYPE type)
+static HANDLE32 WIN_SetWndProc( WND *pWnd, HANDLE32 proc, WINDOWPROCTYPE type)
 {
-    WNDPROC16 oldProc = pWnd->lpfnWndProc;
-    if (type == WIN_PROC_16) pWnd->lpfnWndProc = proc;
-    else pWnd->lpfnWndProc = WINPROC_AllocWinProc( (WNDPROC32)proc, type );
-    WINPROC_FreeWinProc( oldProc );
+    HANDLE32 oldProc = pWnd->winproc;
+    pWnd->winproc = WINPROC_AllocWinProc( proc, type );
+    if (oldProc) WINPROC_FreeWinProc( oldProc );
     return oldProc;
 }
 
@@ -382,6 +381,8 @@
     HDC hdc;
     HWND hwndDesktop;
 
+    dprintf_win(stddeb,"Creating desktop window\n");
+
     if (!(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
 	return FALSE;
 
@@ -394,6 +395,7 @@
     pWndDesktop->parent            = NULL;
     pWndDesktop->owner             = NULL;
     pWndDesktop->class             = class;
+    pWndDesktop->winproc           = WINPROC_CopyWinProc( class->winproc );
     pWndDesktop->dwMagic           = WND_MAGIC;
     pWndDesktop->hwndSelf          = hwndDesktop;
     pWndDesktop->hInstance         = 0;
@@ -411,7 +413,6 @@
     pWndDesktop->hmemTaskQ         = 0; /* Desktop does not belong to a task */
     pWndDesktop->hrgnUpdate        = 0;
     pWndDesktop->hwndLastActive    = hwndDesktop;
-    pWndDesktop->lpfnWndProc       = (WNDPROC16)0;
     pWndDesktop->dwStyle           = WS_VISIBLE | WS_CLIPCHILDREN |
                                      WS_CLIPSIBLINGS;
     pWndDesktop->dwExStyle         = 0;
@@ -423,8 +424,8 @@
     pWndDesktop->window            = rootWindow;
     pWndDesktop->hSysMenu          = 0;
     pWndDesktop->hProp             = 0;
-    WIN_SetWndProc( pWndDesktop, class->lpfnWndProc,
-                    WINPROC_GetWinProcType(class->lpfnWndProc) );
+    pWndDesktop->userdata          = 0;
+
     EVENT_RegisterWindow( pWndDesktop->window, hwndDesktop );
     SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
     if ((hdc = GetDC( hwndDesktop )) != 0)
@@ -441,27 +442,37 @@
  *
  * Implementation of CreateWindowEx().
  */
-static HWND WIN_CreateWindowEx( DWORD exStyle, ATOM classAtom, DWORD style,
-                                INT16 x, INT16 y, INT16 width, INT16 height,
-                                HWND parent, HMENU menu, HINSTANCE16 instance )
+static HWND WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
+                                BOOL unicode )
 {
     CLASS *classPtr;
     WND *wndPtr;
     HWND16 hwnd;
     POINT16 maxSize, maxPos, minTrack, maxTrack;
+    LRESULT wmcreate;
+
+    dprintf_win( stddeb, "CreateWindowEx: " );
+    if (HIWORD(cs->lpszName)) dprintf_win( stddeb, "'%s' ", cs->lpszName );
+    else dprintf_win( stddeb, "#%04x ", LOWORD(cs->lpszName) );
+    if (HIWORD(cs->lpszClass)) dprintf_win( stddeb, "'%s' ", cs->lpszClass );
+    else dprintf_win( stddeb, "#%04x ", LOWORD(cs->lpszClass) );
+
+    dprintf_win( stddeb, "%08lx %08lx %d,%d %dx%d %04x %04x %04x %p\n",
+		 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
+		 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams);
 
     /* Find the parent window */
 
-    if (parent)
+    if (cs->hwndParent)
     {
 	/* Make sure parent is valid */
-        if (!IsWindow( parent ))
+        if (!IsWindow( cs->hwndParent ))
         {
-            fprintf( stderr, "CreateWindowEx: bad parent %04x\n", parent );
+            fprintf( stderr, "CreateWindowEx: bad parent %04x\n", cs->hwndParent );
 	    return 0;
 	}
     }
-    else if (style & WS_CHILD)
+    else if (cs->style & WS_CHILD)
     {
         fprintf( stderr, "CreateWindowEx: no parent for child window\n" );
         return 0;  /* WS_CHILD needs a parent */
@@ -469,7 +480,8 @@
 
     /* Find the window class */
 
-    if (!(classPtr = CLASS_FindClassByAtom( classAtom, GetExePtr(instance) )))
+    if (!(classPtr = CLASS_FindClassByAtom( classAtom,
+                                            GetExePtr(cs->hInstance) )))
     {
         char buffer[256];
         GlobalGetAtomName32A( classAtom, buffer, sizeof(buffer) );
@@ -479,14 +491,14 @@
 
     /* Fix the coordinates */
 
-    if (x == CW_USEDEFAULT16) x = y = 0;
-    if (width == CW_USEDEFAULT16)
+    if (cs->x == CW_USEDEFAULT32) cs->x = cs->y = 0;
+    if (cs->cx == CW_USEDEFAULT32)
     {
-/*        if (!(style & (WS_CHILD | WS_POPUP))) width = height = 0;
+/*        if (!(cs->style & (WS_CHILD | WS_POPUP))) cs->cx = cs->cy = 0;
         else */
         {
-            width = 600;
-            height = 400;
+            cs->cx = 600;
+            cs->cy = 400;
         }
     }
 
@@ -504,13 +516,16 @@
     wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
     wndPtr->next           = NULL;
     wndPtr->child          = NULL;
-    wndPtr->parent         = (style & WS_CHILD) ? WIN_FindWndPtr( parent ) : pWndDesktop;
-    wndPtr->owner          = (style & WS_CHILD) ? NULL : WIN_FindWndPtr(WIN_GetTopParent(parent));
+    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->window         = 0;
     wndPtr->class          = classPtr;
+    wndPtr->winproc        = WINPROC_CopyWinProc( classPtr->winproc );
     wndPtr->dwMagic        = WND_MAGIC;
     wndPtr->hwndSelf       = hwnd;
-    wndPtr->hInstance      = instance;
+    wndPtr->hInstance      = cs->hInstance;
     wndPtr->ptIconPos.x    = -1;
     wndPtr->ptIconPos.y    = -1;
     wndPtr->ptMaxPos.x     = -1;
@@ -519,71 +534,66 @@
     wndPtr->hmemTaskQ      = GetTaskQueue(0);
     wndPtr->hrgnUpdate     = 0;
     wndPtr->hwndLastActive = hwnd;
-    wndPtr->lpfnWndProc    = (WNDPROC16)0;
-    wndPtr->dwStyle        = style & ~WS_VISIBLE;
-    wndPtr->dwExStyle      = exStyle;
+    wndPtr->dwStyle        = cs->style & ~WS_VISIBLE;
+    wndPtr->dwExStyle      = cs->dwExStyle;
     wndPtr->wIDmenu        = 0;
     wndPtr->flags          = 0;
     wndPtr->hVScroll       = 0;
     wndPtr->hHScroll       = 0;
     wndPtr->hSysMenu       = MENU_GetDefSysMenu();
     wndPtr->hProp          = 0;
+    wndPtr->userdata       = 0;
 
     if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
     classPtr->cWindows++;
 
     /* Correct the window style */
 
-    if (!(style & (WS_POPUP | WS_CHILD)))  /* Overlapped window */
+    if (!(cs->style & (WS_POPUP | WS_CHILD)))  /* Overlapped window */
     {
         wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
         wndPtr->flags |= WIN_NEED_SIZE;
     }
-    if (exStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
+    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(DCE_WINDOW_DC);
+    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;
 
-    /* Set the window procedure */
-
-    WIN_SetWndProc( wndPtr, classPtr->lpfnWndProc,
-                    WINPROC_GetWinProcType(classPtr->lpfnWndProc) );
-
     /* Insert the window in the linked list */
 
     WIN_LinkWindow( hwnd, HWND_TOP );
 
     /* Send the WM_GETMINMAXINFO message and fix the size if needed */
 
-    if ((style & WS_THICKFRAME) || !(style & (WS_POPUP | WS_CHILD)))
+    if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
     {
         NC_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
-        if (maxSize.x < width) width = maxSize.x;
-        if (maxSize.y < height) height = maxSize.y;
+        if (maxSize.x < cs->cx) cs->cx = maxSize.x;
+        if (maxSize.y < cs->cy) cs->cy = maxSize.y;
     }
-    if (width <= 0) width = 1;
-    if (height <= 0) height = 1;
+    if (cs->cx <= 0) cs->cx = 1;
+    if (cs->cy <= 0) cs->cy = 1;
 
-    wndPtr->rectWindow.left   = x;
-    wndPtr->rectWindow.top    = y;
-    wndPtr->rectWindow.right  = x + width;
-    wndPtr->rectWindow.bottom = y + height;
+    wndPtr->rectWindow.left   = cs->x;
+    wndPtr->rectWindow.top    = cs->y;
+    wndPtr->rectWindow.right  = cs->x + cs->cx;
+    wndPtr->rectWindow.bottom = cs->y + cs->cy;
     wndPtr->rectClient        = wndPtr->rectWindow;
     wndPtr->rectNormal        = wndPtr->rectWindow;
 
     /* Create the X window (only for top-level windows, and then only */
     /* when there's no desktop window) */
 
-    if (!(style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
+    if (!(cs->style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
     {
         XSetWindowAttributes win_attr;
         Atom XA_WM_DELETE_WINDOW;
 
-	if (Options.managed && ((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
-            (exStyle & WS_EX_DLGMODALFRAME)))
+	if (Options.managed && ((cs->style & (WS_DLGFRAME | WS_THICKFRAME)) ||
+            (cs->dwExStyle & WS_EX_DLGMODALFRAME)))
         {
 	    win_attr.event_mask = ExposureMask | KeyPressMask |
 	                          KeyReleaseMask | PointerMotionMask |
@@ -604,8 +614,8 @@
         win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
         win_attr.save_under    = ((classPtr->style & CS_SAVEBITS) != 0);
         win_attr.cursor        = CURSORICON_XCursor;
-        wndPtr->window = XCreateWindow( display, rootWindow, x, y,
-                                        width, height, 0, CopyFromParent,
+        wndPtr->window = XCreateWindow( display, rootWindow, cs->x, cs->y,
+                                        cs->cx, cs->cy, 0, CopyFromParent,
                                         InputOutput, CopyFromParent,
                                         CWEventMask | CWOverrideRedirect |
                                         CWColormap | CWCursor | CWSaveUnder |
@@ -613,9 +623,9 @@
 	XA_WM_DELETE_WINDOW = XInternAtom( display, "WM_DELETE_WINDOW",
 					   False );
 	XSetWMProtocols( display, wndPtr->window, &XA_WM_DELETE_WINDOW, 1 );
-	if (parent)  /* Get window owner */
+	if (cs->hwndParent)  /* Get window owner */
 	{
-            Window win = WIN_GetXWindow( parent );
+            Window win = WIN_GetXWindow( cs->hwndParent );
             if (win) XSetTransientForHint( display, wndPtr->window, win );
 	}
         EVENT_RegisterWindow( wndPtr->window, hwnd );
@@ -623,189 +633,45 @@
 
     /* Set the window menu */
 
-    if ((style & WS_CAPTION) && !(style & WS_CHILD))
+    if ((cs->style & WS_CAPTION) && !(cs->style & WS_CHILD))
     {
-        if (menu) SetMenu(hwnd, menu);
+        if (cs->hMenu) SetMenu(hwnd, cs->hMenu);
         else
         {
 #if 0  /* FIXME: should check if classPtr->menuNameW can be used as is */
             if (classPtr->menuNameA)
-                menu = HIWORD(classPtr->menuNameA) ?
-                       LoadMenu( instance, SEGPTR_GET(classPtr->menuNameA) ) :
-                       LoadMenu( instance, (SEGPTR)classPtr->menuNameA );
+                cs->hMenu = HIWORD(classPtr->menuNameA) ?
+                       LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
+                       LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
 #else
             SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
-            if (menuName) menu = LoadMenu( instance, menuName );
+            if (menuName) cs->hMenu = LoadMenu( cs->hInstance, menuName );
 #endif
         }
-        if (menu) SetMenu( hwnd, menu );
+        if (cs->hMenu) SetMenu( hwnd, cs->hMenu );
     }
-    else wndPtr->wIDmenu = (UINT)menu;
+    else wndPtr->wIDmenu = (UINT)cs->hMenu;
 
-    return hwnd;
-}
+    /* Send the WM_CREATE message */
 
-
-/***********************************************************************
- *           WIN_FinalWindowInit
- */
-static HWND WIN_FinalWindowInit( WND *wndPtr, DWORD style )
-{
-    if (!(wndPtr->flags & WIN_NEED_SIZE))
+    if (unicode)
     {
-	/* send it anyway */
-	SendMessage16( wndPtr->hwndSelf, WM_SIZE, SIZE_RESTORED,
-		     MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
-                            wndPtr->rectClient.bottom-wndPtr->rectClient.top));
-        SendMessage16( wndPtr->hwndSelf, WM_MOVE, 0,
-                   MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
-    } 
-
-    WIN_SendParentNotify( wndPtr->hwndSelf, WM_CREATE, wndPtr->wIDmenu,
-                          (LONG)wndPtr->hwndSelf );
-    if (!IsWindow(wndPtr->hwndSelf)) return 0;
-
-    /* Show the window, maximizing or minimizing if needed */
-
-    if (wndPtr->dwStyle & WS_MINIMIZE)
-    {
-        wndPtr->dwStyle &= ~WS_MAXIMIZE;
-        WINPOS_FindIconPos( wndPtr->hwndSelf );
-        SetWindowPos(wndPtr->hwndSelf, 0, wndPtr->ptIconPos.x,
-                     wndPtr->ptIconPos.y, SYSMETRICS_CXICON, SYSMETRICS_CYICON,
-                     SWP_FRAMECHANGED |
-                     (style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0 );
-    }
-    else if (wndPtr->dwStyle & WS_MAXIMIZE)
-    {
-        POINT16 maxSize, maxPos, minTrack, maxTrack;
-        NC_GetMinMaxInfo( wndPtr->hwndSelf, &maxSize, &maxPos,
-                          &minTrack, &maxTrack );
-        SetWindowPos( wndPtr->hwndSelf, 0, maxPos.x, maxPos.y, maxSize.x,
-                      maxSize.y, SWP_FRAMECHANGED |
-                      (style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0 );
-    }
-    else if (style & WS_VISIBLE) ShowWindow( wndPtr->hwndSelf, SW_SHOW );
-
-    /* Call WH_SHELL hook */
-
-    if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
-        HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWCREATED, wndPtr->hwndSelf, 0 );
-
-    return wndPtr->hwndSelf;
-}
-
-
-/***********************************************************************
- *           CreateWindow16   (USER.41)
- */
-HWND16 CreateWindow16( SEGPTR className, SEGPTR windowName,
-                       DWORD style, INT16 x, INT16 y, INT16 width,
-                       INT16 height, HWND16 parent, HMENU16 menu,
-                       HINSTANCE16 instance, SEGPTR data ) 
-{
-    return CreateWindowEx16( 0, className, windowName, style,
-			   x, y, width, height, parent, menu, instance, data );
-}
-
-
-/***********************************************************************
- *           CreateWindowEx16   (USER.452)
- */
-HWND16 CreateWindowEx16( DWORD exStyle, SEGPTR className, SEGPTR windowName,
-                         DWORD style, INT16 x, INT16 y, INT16 width,
-                         INT16 height, HWND16 parent, HMENU16 menu,
-                         HINSTANCE16 instance, SEGPTR data ) 
-{
-    ATOM classAtom;
-    HWND16 hwnd;
-    WND *wndPtr;
-    LRESULT wmcreate;
-
-    dprintf_win( stddeb, "CreateWindowEx: " );
-    if (HIWORD(windowName))
-	dprintf_win( stddeb, "'%s' ", (char *)PTR_SEG_TO_LIN(windowName) );
-    else
-	dprintf_win( stddeb, "%04x ", LOWORD(windowName) );
-    if (HIWORD(className))
-        dprintf_win( stddeb, "'%s' ", (char *)PTR_SEG_TO_LIN(className) );
-    else
-        dprintf_win( stddeb, "%04x ", LOWORD(className) );
-
-    dprintf_win(stddeb, "%08lx %08lx %d,%d %dx%d %04x %04x %04x %08lx\n",
-		exStyle, style, x, y, width, height,
-		parent, menu, instance, (DWORD)data);
-
-    /* Find the class atom */
-
-    if (!(classAtom = GlobalFindAtom16( className )))
-    {
-        fprintf( stderr, "CreateWindowEx16: bad class name " );
-        if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
-        else fprintf( stderr, "'%s'\n", (char *)PTR_SEG_TO_LIN(className) );
-        return 0;
-    }
-
-    hwnd = WIN_CreateWindowEx( exStyle, classAtom, style, x, y, width, height,
-                               parent, menu, instance );
-    if (!hwnd) return 0;
-    wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
-
-      /* Send the WM_CREATE message */
-
-#ifndef WINELIB
-    if (WINPROC_GetWinProcType( wndPtr->lpfnWndProc ) == WIN_PROC_16)
-    {
-        /* Build the CREATESTRUCT on the 16-bit stack. */
-        /* This is really ugly, but some programs (notably the */
-        /* "Undocumented Windows" examples) want it that way.  */
-        if (!CallWndProcNCCREATE16( wndPtr->lpfnWndProc, wndPtr->hInstance,
-                  wndPtr->dwExStyle, className, windowName, wndPtr->dwStyle,
-                  wndPtr->rectWindow.left, wndPtr->rectWindow.top,
-                  wndPtr->rectWindow.right - wndPtr->rectWindow.left,
-                  wndPtr->rectWindow.bottom - wndPtr->rectWindow.top,
-                  parent, menu, wndPtr->hInstance, data, hwnd, WM_NCCREATE, 0,
-                  MAKELONG( IF1632_Saved16_sp-sizeof(CREATESTRUCT16),
-                            IF1632_Saved16_ss ) ))
-            wmcreate = -1;
+        if (!SendMessage32W( hwnd, WM_NCCREATE, 0, (LPARAM)cs)) wmcreate = -1;
         else
         {
             WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
                                    NULL, NULL, 0, &wndPtr->rectClient );
-            wmcreate = CallWndProcNCCREATE16( wndPtr->lpfnWndProc,
-                   wndPtr->hInstance, wndPtr->dwExStyle, className,
-                   windowName, wndPtr->dwStyle,
-                   wndPtr->rectWindow.left, wndPtr->rectWindow.top,
-                   wndPtr->rectWindow.right - wndPtr->rectWindow.left,
-                   wndPtr->rectWindow.bottom - wndPtr->rectWindow.top,
-                   parent, menu, wndPtr->hInstance, data, hwnd, WM_CREATE, 0,
-                   MAKELONG( IF1632_Saved16_sp-sizeof(CREATESTRUCT16),
-                             IF1632_Saved16_ss ) );
+            wmcreate = SendMessage32W( hwnd, WM_CREATE, 0, (LPARAM)cs );
         }
     }
-    else  /* We have a 32-bit window procedure */
-#endif  /* WINELIB */
+    else
     {
-        CREATESTRUCT32A cs;
-        cs.lpCreateParams = (LPVOID)data;
-        cs.hInstance      = wndPtr->hInstance;
-        cs.hMenu          = wndPtr->wIDmenu;
-        cs.hwndParent     = parent;
-        cs.cx             = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
-        cs.cy             = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
-        cs.x              = wndPtr->rectWindow.left;
-        cs.y              = wndPtr->rectWindow.top;
-        cs.style          = wndPtr->dwStyle | (style & WS_VISIBLE);
-        cs.lpszName       = PTR_SEG_TO_LIN(windowName);
-        cs.lpszClass      = PTR_SEG_TO_LIN(className);
-        cs.dwExStyle      = wndPtr->dwExStyle;
-
-        if (!SendMessage32A( hwnd, WM_NCCREATE, 0, (LPARAM)&cs)) wmcreate = -1;
+        if (!SendMessage32A( hwnd, WM_NCCREATE, 0, (LPARAM)cs)) wmcreate = -1;
         else
         {
             WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
                                    NULL, NULL, 0, &wndPtr->rectClient );
-            wmcreate = SendMessage32A( hwnd, WM_CREATE, 0, (LPARAM)&cs );
+            wmcreate = SendMessage32A( hwnd, WM_CREATE, 0, (LPARAM)cs );
         }
     }
     
@@ -817,8 +683,102 @@
 	return 0;
     }
 
-    dprintf_win(stddeb, "CreateWindowEx16: return %04x\n", hwnd);
-    return WIN_FinalWindowInit( wndPtr, style );
+    /* Send the size messages */
+
+    if (!(wndPtr->flags & WIN_NEED_SIZE))
+    {
+	/* send it anyway */
+	SendMessage16( hwnd, WM_SIZE, SIZE_RESTORED,
+                   MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
+                            wndPtr->rectClient.bottom-wndPtr->rectClient.top));
+        SendMessage16( hwnd, WM_MOVE, 0, MAKELONG( wndPtr->rectClient.left,
+                                                   wndPtr->rectClient.top ));
+    } 
+
+    WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LONG)hwnd );
+    if (!IsWindow(hwnd)) return 0;
+
+    /* Show the window, maximizing or minimizing if needed */
+
+    if (wndPtr->dwStyle & WS_MINIMIZE)
+    {
+        wndPtr->dwStyle &= ~WS_MAXIMIZE;
+        WINPOS_FindIconPos( hwnd );
+        SetWindowPos( hwnd, 0, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y,
+                      SYSMETRICS_CXICON, SYSMETRICS_CYICON, SWP_FRAMECHANGED |
+                      (cs->style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0 );
+    }
+    else if (wndPtr->dwStyle & WS_MAXIMIZE)
+    {
+        POINT16 maxSize, maxPos, minTrack, maxTrack;
+        NC_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
+        SetWindowPos( hwnd, 0, maxPos.x, maxPos.y, maxSize.x, maxSize.y,
+            SWP_FRAMECHANGED | (cs->style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0 );
+    }
+    else if (cs->style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
+
+    /* Call WH_SHELL hook */
+
+    if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
+        HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
+
+    dprintf_win(stddeb, "CreateWindowEx: returning %04x\n", hwnd);
+    return hwnd;
+}
+
+
+/***********************************************************************
+ *           CreateWindow16   (USER.41)
+ */
+HWND16 CreateWindow16( LPCSTR className, LPCSTR windowName,
+                       DWORD style, INT16 x, INT16 y, INT16 width,
+                       INT16 height, HWND16 parent, HMENU16 menu,
+                       HINSTANCE16 instance, LPVOID data ) 
+{
+    return CreateWindowEx16( 0, className, windowName, style,
+			   x, y, width, height, parent, menu, instance, data );
+}
+
+
+/***********************************************************************
+ *           CreateWindowEx16   (USER.452)
+ */
+HWND16 CreateWindowEx16( DWORD exStyle, LPCSTR className, LPCSTR windowName,
+                         DWORD style, INT16 x, INT16 y, INT16 width,
+                         INT16 height, HWND16 parent, HMENU16 menu,
+                         HINSTANCE16 instance, LPVOID data ) 
+{
+    ATOM classAtom;
+    CREATESTRUCT32A cs;
+
+    /* Find the class atom */
+
+    if (!(classAtom = GlobalFindAtom32A( className )))
+    {
+        fprintf( stderr, "CreateWindowEx16: bad class name " );
+        if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
+        else fprintf( stderr, "'%s'\n", className );
+        return 0;
+    }
+
+    /* Fix the coordinates */
+
+    cs.x  = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)x;
+    cs.y  = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)y;
+    cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)width;
+    cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)height;
+
+    /* Create the window */
+
+    cs.lpCreateParams = data;
+    cs.hInstance      = (HINSTANCE32)instance;
+    cs.hMenu          = (HMENU32)menu;
+    cs.hwndParent     = (HWND32)parent;
+    cs.style          = style;
+    cs.lpszName       = windowName;
+    cs.lpszClass      = className;
+    cs.dwExStyle      = exStyle;
+    return WIN_CreateWindowEx( &cs, classAtom, FALSE );
 }
 
 
@@ -831,9 +791,6 @@
                           HINSTANCE32 instance, LPVOID data )
 {
     ATOM classAtom;
-    HWND16 hwnd;
-    WND *wndPtr;
-    LRESULT wmcreate;
     CREATESTRUCT32A cs;
 
     /* Find the class atom */
@@ -846,51 +803,21 @@
         return 0;
     }
 
-    /* Fix the coordinates */
-
-    if (x == CW_USEDEFAULT32) x = y = (UINT32)CW_USEDEFAULT16;
-    if (width == CW_USEDEFAULT32) width = height = (UINT32)CW_USEDEFAULT16;
-
-    /* Create the window structure */
-
-    hwnd = WIN_CreateWindowEx( exStyle, classAtom, style, x, y, width, height,
-                               parent, menu, instance );
-    if (!hwnd) return 0;
-    wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
-
-    /* Send the WM_CREATE message */
+    /* Create the window */
 
     cs.lpCreateParams = data;
-    cs.hInstance      = wndPtr->hInstance;
-    cs.hMenu          = wndPtr->wIDmenu;
+    cs.hInstance      = instance;
+    cs.hMenu          = menu;
     cs.hwndParent     = parent;
-    cs.cx             = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
-    cs.cy             = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
-    cs.x              = wndPtr->rectWindow.left;
-    cs.y              = wndPtr->rectWindow.top;
-    cs.style          = wndPtr->dwStyle | (style & WS_VISIBLE);
+    cs.x              = x;
+    cs.y              = y;
+    cs.cx             = width;
+    cs.cy             = height;
+    cs.style          = style;
     cs.lpszName       = windowName;
     cs.lpszClass      = className;
-    cs.dwExStyle      = wndPtr->dwExStyle;
-
-    if (!SendMessage32A( hwnd, WM_NCCREATE, 0, (LPARAM)&cs )) wmcreate = -1;
-    else
-    {
-        WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
-                               NULL, NULL, 0, &wndPtr->rectClient );
-        wmcreate = SendMessage32A( hwnd, WM_CREATE, 0, (LPARAM)&cs );
-    }
-
-    if (wmcreate == -1)
-    {
-	  /* Abort window creation */
-	dprintf_win(stddeb,"CreateWindowEx32A: wmcreate==-1, aborting\n");
-        WIN_DestroyWindow( hwnd );
-	return 0;
-    }
-
-    dprintf_win(stddeb, "CreateWindowEx32A: return %04x\n", hwnd);
-    return WIN_FinalWindowInit( wndPtr, style );
+    cs.dwExStyle      = exStyle;
+    return WIN_CreateWindowEx( &cs, classAtom, FALSE );
 }
 
 
@@ -903,9 +830,6 @@
                           HINSTANCE32 instance, LPVOID data )
 {
     ATOM classAtom;
-    HWND16 hwnd;
-    WND *wndPtr;
-    LRESULT wmcreate;
     CREATESTRUCT32W cs;
 
     /* Find the class atom */
@@ -916,51 +840,23 @@
         return 0;
     }
 
-    /* Fix the coordinates */
-
-    if (x == CW_USEDEFAULT32) x = y = (UINT32)CW_USEDEFAULT16;
-    if (width == CW_USEDEFAULT32) width = height = (UINT32)CW_USEDEFAULT16;
-
-    /* Create the window structure */
-
-    hwnd = WIN_CreateWindowEx( exStyle, classAtom, style, x, y, width, height,
-                               parent, menu, instance );
-    if (!hwnd) return 0;
-    wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
-
-    /* Send the WM_CREATE message */
+    /* Create the window */
 
     cs.lpCreateParams = data;
-    cs.hInstance      = wndPtr->hInstance;
-    cs.hMenu          = wndPtr->wIDmenu;
+    cs.hInstance      = instance;
+    cs.hMenu          = menu;
     cs.hwndParent     = parent;
-    cs.cx             = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
-    cs.cy             = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
-    cs.x              = wndPtr->rectWindow.left;
-    cs.y              = wndPtr->rectWindow.top;
-    cs.style          = wndPtr->dwStyle | (style & WS_VISIBLE);
+    cs.x              = x;
+    cs.y              = y;
+    cs.cx             = width;
+    cs.cy             = height;
+    cs.style          = style;
     cs.lpszName       = windowName;
     cs.lpszClass      = className;
-    cs.dwExStyle      = wndPtr->dwExStyle;
-
-    if (!SendMessage32W( hwnd, WM_NCCREATE, 0, (LPARAM)&cs )) wmcreate = -1;
-    else
-    {
-        WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
-                               NULL, NULL, 0, &wndPtr->rectClient );
-        wmcreate = SendMessage32W( hwnd, WM_CREATE, 0, (LPARAM)&cs );
-    }
-
-    if (wmcreate == -1)
-    {
-	  /* Abort window creation */
-	dprintf_win(stddeb,"CreateWindowEx32W: wmcreate==-1, aborting\n");
-        WIN_DestroyWindow( hwnd );
-	return 0;
-    }
-
-    dprintf_win(stddeb, "CreateWindowEx32W: return %04x\n", hwnd);
-    return WIN_FinalWindowInit( wndPtr, style );
+    cs.dwExStyle      = exStyle;
+    /* Note: we rely on the fact that CREATESTRUCT32A and */
+    /* CREATESTRUCT32W have the same layout. */
+    return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE );
 }
 
 
@@ -975,8 +871,8 @@
     
       /* Initialization */
 
-    if (hwnd == pWndDesktop->hwndSelf) return FALSE; /* Can't destroy desktop*/
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
+    if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
 
       /* Top-level window */
 
@@ -1010,6 +906,8 @@
         else break;
     }
 
+    CLIPBOARD_DisOwn( hwnd );
+
       /* Send destroy messages and destroy children */
 
     SendMessage16( hwnd, WM_DESTROY, 0, 0 );
@@ -1252,7 +1150,7 @@
     WND * wndPtr; 
 
     if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
-    return (WINPROC_GetWinProcType( wndPtr->lpfnWndProc ) == WIN_PROC_32W);
+    return (WINPROC_GetWinProcType( wndPtr->winproc ) == WIN_PROC_32W);
 }
 
 
@@ -1311,44 +1209,64 @@
 
 
 /**********************************************************************
- *	     GetWindowLong    (USER.135)
+ *	     GetWindowLong16    (USER.135)
  */
-LONG GetWindowLong( HWND32 hwnd, INT32 offset )
+LONG GetWindowLong16( HWND16 hwnd, INT16 offset )
+{
+    LONG ret = GetWindowLong32A( (HWND32)hwnd, offset );
+    if (offset == GWL_WNDPROC) return (LONG)WINPROC_GetFunc16( (HANDLE32)ret );
+    return ret;
+}
+
+
+/**********************************************************************
+ *	     GetWindowLong32A    (USER32.304)
+ */
+LONG GetWindowLong32A( HWND32 hwnd, INT32 offset )
 {
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr) return 0;
     if (offset >= 0) return *(LONG *)(((char *)wndPtr->wExtra) + offset);
     switch(offset)
     {
-        case GWL_USERDATA:   return 0;
+        case GWL_USERDATA:   return wndPtr->userdata;
         case GWL_STYLE:      return wndPtr->dwStyle;
         case GWL_EXSTYLE:    return wndPtr->dwExStyle;
         case GWL_ID:         return wndPtr->wIDmenu;
-        case GWL_WNDPROC:    return (LONG)wndPtr->lpfnWndProc;
+        case GWL_WNDPROC:    return (LONG)WINPROC_GetFunc32( wndPtr->winproc );
         case GWL_HWNDPARENT: return wndPtr->parent ?
                                         (HWND32)wndPtr->parent->hwndSelf : 0;
         case GWL_HINSTANCE:  return (HINSTANCE32)wndPtr->hInstance;
         default:
-            fprintf( stderr, "GetWindowLong: unknown offset %d\n", offset );
+            fprintf( stderr, "GetWindowLong32A: unknown offset %d\n", offset );
     }
     return 0;
 }
 
 
 /**********************************************************************
+ *	     GetWindowLong32W    (USER32.305)
+ */
+LONG GetWindowLong32W( HWND32 hwnd, INT32 offset )
+{
+    return GetWindowLong32A( hwnd, offset );
+}
+
+
+/**********************************************************************
  *	     SetWindowLong16    (USER.136)
  */
 LONG SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
 {
-    WND *wndPtr;
-    switch(offset)
+    if (offset == GWL_WNDPROC)
     {
-    case GWL_WNDPROC:
-        wndPtr = WIN_FindWndPtr( hwnd );
-        return (LONG)WIN_SetWndProc( wndPtr, (WNDPROC16)newval, WIN_PROC_16 );
-    default:
-        return SetWindowLong32A( hwnd, offset, newval );
+        HANDLE32 ret;
+        WND *wndPtr = WIN_FindWndPtr( hwnd );
+        if (!wndPtr) return 0;
+        ret = WIN_SetWndProc( wndPtr, (HANDLE32)newval, WIN_PROC_16 );
+        return (LONG)WINPROC_GetFunc16( ret );
     }
+    return SetWindowLong32A( hwnd, offset, newval );
 }
 
 
@@ -1367,11 +1285,12 @@
         case GWL_HINSTANCE:
             return SetWindowWord( hwnd, offset, (WORD)newval );
 	case GWL_WNDPROC:
-            return (LONG)WIN_SetWndProc( wndPtr, (WNDPROC16)newval,
-                                         WIN_PROC_32A );
-        case GWL_USERDATA: return 0;
-	case GWL_STYLE:   ptr = &wndPtr->dwStyle; break;
-        case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle; break;
+            return (LONG)WINPROC_GetFunc32( WIN_SetWndProc( wndPtr,
+                                                            (HANDLE32)newval,
+                                                            WIN_PROC_32A ));
+        case GWL_USERDATA: ptr = &wndPtr->userdata; break;
+	case GWL_STYLE:    ptr = &wndPtr->dwStyle; break;
+        case GWL_EXSTYLE:  ptr = &wndPtr->dwExStyle; break;
 	default:
             fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
             return 0;
@@ -1387,15 +1306,15 @@
  */
 LONG SetWindowLong32W( HWND32 hwnd, INT32 offset, LONG newval )
 {
-    WND *wndPtr;
-    switch(offset)
+    if (offset == GCL_WNDPROC)
     {
-    case GWL_WNDPROC:
-        wndPtr = WIN_FindWndPtr( hwnd );
-        return (LONG)WIN_SetWndProc( wndPtr, (WNDPROC16)newval, WIN_PROC_32W );
-    default:
-        return SetWindowLong32A( hwnd, offset, newval );
+        WND *wndPtr = WIN_FindWndPtr( hwnd );
+        if (!wndPtr) return 0;
+        return (LONG)WINPROC_GetFunc32( WIN_SetWndProc( wndPtr,
+                                                        (HANDLE32)newval,
+                                                        WIN_PROC_32W ));
     }
+    return SetWindowLong32A( hwnd, offset, newval );
 }
 
 
diff --git a/windows/winpos.c b/windows/winpos.c
index 74a8942..5088673 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -15,6 +15,7 @@
 #include "queue.h"
 #include "stackframe.h"
 #include "winpos.h"
+#include "dce.h"
 #include "nonclient.h"
 #include "stddebug.h"
 /* #define DEBUG_WIN */
@@ -27,6 +28,7 @@
 extern void 	FOCUS_SwitchFocus( HWND , HWND );
 extern HRGN 	DCE_GetVisRgn( HWND, WORD );
 extern HWND	CARET_GetHwnd();
+extern BOOL     DCE_InvalidateDCE(WND*, RECT16* );
 
 /* ----- internal variables ----- */
 
@@ -1346,10 +1348,10 @@
 	     OffsetRgn( newVisRgn, Wnd->rectClient.left, Wnd->rectClient.top);
 	     CombineRgn( oldVisRgn, oldVisRgn, newVisRgn, RGN_OR );
 
-             hDC = GetDCEx( Wnd->parent->hwndSelf, oldVisRgn, DCX_INTERSECTRGN | DCX_CACHE | DCX_CLIPSIBLINGS);
+             hDC = GetDCEx( Wnd->parent->hwndSelf, oldVisRgn, DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CACHE | DCX_CLIPSIBLINGS);
 
-             BitBlt(hDC, xto, yto, lpOldClientRect->right - lpOldClientRect->left + 1, 
-				   lpOldClientRect->bottom - lpOldClientRect->top + 1,
+             BitBlt(hDC, xto, yto, lpOldClientRect->right - lpOldClientRect->left, 
+				   lpOldClientRect->bottom - lpOldClientRect->top,
 				   hDC, xfrom, yfrom, SRCCOPY );
     
              ReleaseDC( Wnd->parent->hwndSelf, hDC); 
@@ -1563,6 +1565,18 @@
 				    newClientRect.top != wndPtr->rectClient.top) )
 	    winpos.flags &= ~SWP_NOCLIENTMOVE;
 
+    /* Update active DCEs */
+
+    if( !(flags & SWP_NOZORDER) || (flags & SWP_HIDEWINDOW) || (flags & SWP_SHOWWINDOW)
+                                || (memcmp(&newWindowRect,&wndPtr->rectWindow,sizeof(RECT16))
+                                    && wndPtr->dwStyle & WS_VISIBLE ) )
+      {
+        RECT16 rect;
+
+        UnionRect16(&rect,&newWindowRect,&wndPtr->rectWindow);
+        DCE_InvalidateDCE(wndPtr->parent, &rect);
+      }
+
     /* Perform the moving and resizing */
 
     if (wndPtr->window)
@@ -1628,12 +1642,9 @@
 			   (result >= WVR_HREDRAW && result < WVR_VALIDRECTS);
 
 	    if( (winpos.flags & SWP_NOPOSCHANGE) != SWP_NOPOSCHANGE )
-	      {
 	        /* optimize cleanup by BitBlt'ing where possible */
 
 	        WINPOS_SizeMoveClean(wndPtr, visRgn, &oldWindowRect, &oldClientRect, bNoCopy);
-	        DeleteObject(visRgn);
-	      }
 	    else
 	       if( winpos.flags & SWP_FRAMECHANGED )
         	  RedrawWindow32( winpos.hwnd, NULL, 0, RDW_NOCHILDREN | RDW_FRAME ); 
diff --git a/windows/winproc.c b/windows/winproc.c
index 16ce933..05d2a24 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -19,88 +19,96 @@
 
 typedef struct
 {
-    WNDPROC32       func;        /* 32-bit function, or 0 if free */
-    unsigned int    count : 30;  /* Reference count, or next free if func==0 */
-    WINDOWPROCTYPE  type : 2;    /* Function type */
+    UINT32          magic;    /* Magic number */
+    WINDOWPROCTYPE  type;     /* Function type */
+    UINT32          count;    /* Reference count */
+    UINT32          func;     /* 16- or 32-bit function */
 } WINDOWPROC;
 
-#define NB_WINPROCS    1024  /* Must be < 64K; 1024 should be enough for now */
+#define WINPROC_MAGIC  ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
 
-static WINDOWPROC winProcs[NB_WINPROCS];
-static int lastWinProc = 0;
-static int freeWinProc = NB_WINPROCS;
 
-/* Check if a win proc was created by WINPROC_AllocWinProc */
-#define IS_ALLOCATED_WINPROC(func)  (HIWORD(func) == 0xffff)
+static HANDLE32 WinProcHeap = 0;
+
+
+/**********************************************************************
+ *	     WINPROC_GetPtr
+ *
+ * Return a pointer to the win proc.
+ */
+static WINDOWPROC *WINPROC_GetPtr( HANDLE32 handle )
+{
+    WINDOWPROC *proc;
+
+    /* Check for a linear pointer */
+
+    if (HEAP_IsInsideHeap( WinProcHeap, 0, (LPVOID)handle ))
+    {
+        proc = (WINDOWPROC *)handle;
+        if (proc->magic == WINPROC_MAGIC) return proc;
+    }
+
+    /* Check for a segmented pointer */
+
+    if (!IsBadReadPtr( (SEGPTR)handle, sizeof(WINDOWPROC) ))
+    {
+        proc = (WINDOWPROC *)PTR_SEG_TO_LIN(handle);
+        if (proc->magic == WINPROC_MAGIC) return proc;
+    }
+
+    return NULL;
+}
+
 
 /**********************************************************************
  *	     WINPROC_AllocWinProc
  *
  * Allocate a new window procedure.
  */
-WNDPROC16 WINPROC_AllocWinProc( WNDPROC32 func, WINDOWPROCTYPE type )
+HANDLE32 WINPROC_AllocWinProc( UINT32 func, WINDOWPROCTYPE type )
 {
     WINDOWPROC *proc;
-    if (!func) return (WNDPROC16)0;  /* Null win proc remains null */
-    if (IS_ALLOCATED_WINPROC(func))  /* Already allocated? */
+
+    /* Create the heap if necessary */
+
+    if (!WinProcHeap)
     {
-        if (LOWORD(func) >= NB_WINPROCS) return (WNDPROC16)0;
-        proc = &winProcs[LOWORD(func)];
-        if (!proc->func) return (WNDPROC16)0;
+        if (!(WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return 0;
+    }
+
+    /* Check if function is already a win proc */
+
+    if ((proc = WINPROC_GetPtr( (HANDLE32)func )))
+    {
         proc->count++;
-        return (WNDPROC16)func;
+        return (HANDLE32)func;
     }
-    if (freeWinProc < NB_WINPROCS)  /* There is a free entry */
-    {
-        proc = &winProcs[freeWinProc];
-        proc->func = func;
-        func = (WNDPROC32)MAKELONG( freeWinProc, 0xffff );
-        freeWinProc = proc->count;  /* Next free entry */
-        proc->count = 1;
-        proc->type  = type;
-        return (WNDPROC16)func;
-    }
-    if (lastWinProc < NB_WINPROCS)  /* There's a free entry at the end */
-    {
-        proc = &winProcs[lastWinProc];
-        proc->func = func;
-        func = (WNDPROC32)MAKELONG( lastWinProc, 0xffff );
-        lastWinProc++;
-        proc->count = 1;
-        proc->type  = type;
-        return (WNDPROC16)func;
-    }
-    fprintf( stderr, "WINPROC_AllocWinProc: out of window procedures.\n"
-                     "Please augment NB_WINPROCS in winproc.c\n" );
-    return (WNDPROC16)0;
+
+    /* Now allocate a new one */
+
+    if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
+    proc->magic = WINPROC_MAGIC;
+    proc->type  = type;
+    proc->count = 1;
+    proc->func  = func;
+    return (HANDLE32)proc;
 }
 
 
 /**********************************************************************
- *	     WINPROC_GetWinProcType
+ *	     WINPROC_CopyWinProc
  *
- * Return the type of a window procedure.
+ * Copy a window procedure.
  */
-WINDOWPROCTYPE WINPROC_GetWinProcType( WNDPROC16 func )
+HANDLE32 WINPROC_CopyWinProc( HANDLE32 handle )
 {
-    WORD id = LOWORD(func);
-    if (!IS_ALLOCATED_WINPROC(func)) return WIN_PROC_16;
-    if ((id >= NB_WINPROCS) || !winProcs[id].func) return WIN_PROC_INVALID;
-    return winProcs[id].type;
-}
-
-
-/**********************************************************************
- *	     WINPROC_GetWinProcFunc
- *
- * Return the 32-bit window procedure for a winproc.
- */
-WNDPROC32 WINPROC_GetWinProcFunc( WNDPROC16 func )
-{
-    WORD id = LOWORD(func);
-    if (!IS_ALLOCATED_WINPROC(func)) return NULL;
-    if (id >= NB_WINPROCS) return NULL;
-    return winProcs[id].func;
+    WINDOWPROC *proc;
+    if ((proc = WINPROC_GetPtr( (HANDLE32)handle )))
+    {
+        proc->count++;
+        return handle;
+    }
+    return (HANDLE32)0;
 }
 
 
@@ -109,26 +117,63 @@
  *
  * Free a window procedure.
  */
-void WINPROC_FreeWinProc( WNDPROC16 func )
+void WINPROC_FreeWinProc( HANDLE32 handle )
 {
-    WORD id = LOWORD(func);
-    if (!IS_ALLOCATED_WINPROC(func)) return;
-    if ((id >= NB_WINPROCS) || !winProcs[id].func)
+    WINDOWPROC *proc;
+
+    if (!(proc = WINPROC_GetPtr( handle )))
     {
-        fprintf( stderr, "WINPROC_FreeWinProc: invalid proc %08x\n",
-                 (UINT32)func );
+        fprintf( stderr, "WINPROC_FreeWinProc: invalid proc %08x\n", handle );
         return;
     }
-    if (--winProcs[id].count == 0)
+    if (--proc->count == 0)
     {
-        winProcs[id].func = 0;
-        winProcs[id].count = freeWinProc;
-        freeWinProc = id;
+        proc->magic = 0;  /* Just in case */
+        HeapFree( WinProcHeap, 0, proc );
     }
 }
 
 
 /**********************************************************************
+ *	     WINPROC_GetWinProcType
+ *
+ * Return the window procedure type.
+ */
+WINDOWPROCTYPE WINPROC_GetWinProcType( HANDLE32 handle )
+{
+    WINDOWPROC *proc = WINPROC_GetPtr( handle );
+    if (!proc) return WIN_PROC_INVALID;
+    return proc->type;
+}
+
+
+/**********************************************************************
+ *	     WINPROC_GetFunc16
+ *
+ * Return the 16-bit function pointer, or NULL if none.
+ */
+WNDPROC16 WINPROC_GetFunc16( HANDLE32 handle )
+{
+    WINDOWPROC *proc = WINPROC_GetPtr( handle );
+    if (!proc) return (WNDPROC16)0;
+    return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0, proc );
+}
+
+
+/**********************************************************************
+ *	     WINPROC_GetFunc32
+ *
+ * Return the 32-bit function pointer, or NULL if none.
+ */
+WNDPROC32 WINPROC_GetFunc32( HANDLE32 handle )
+{
+    WINDOWPROC *proc = WINPROC_GetPtr( handle );
+    if (!proc) return (WNDPROC32)0;
+    return (WNDPROC32)proc;
+}
+
+
+/**********************************************************************
  *	     WINPROC_CallProc32ATo32W
  *
  * Call a window procedure, translating args from Ansi to Unicode.
@@ -148,8 +193,8 @@
             result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)str );
             STRING32_UniToAnsi( (LPSTR)lParam, str );
             HeapFree( SystemHeap, 0, str );
-            return strlen( (LPSTR)lParam ) + 1;
         }
+        return result;  /* FIXME? */
 
     case WM_SETTEXT:
         {
@@ -198,8 +243,8 @@
             result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)str );
             STRING32_AnsiToUni( (LPWSTR)lParam, str );
             HeapFree( SystemHeap, 0, str );
-            return STRING32_lstrlenW( (LPWSTR)lParam ) + 1;  /* FIXME? */
         }
+        return result;  /* FIXME? */
 
     case WM_SETTEXT:
         {
@@ -214,11 +259,13 @@
     case WM_CREATE:
         {
             CREATESTRUCT32A cs = *(CREATESTRUCT32A *)lParam;
-            cs.lpszName  = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName );
-            cs.lpszClass = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName );
+            if (HIWORD(cs.lpszName))
+                cs.lpszName  = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName );
+            if (HIWORD(cs.lpszClass))
+                cs.lpszClass = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName );
             result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&cs );
-            free( (LPVOID)cs.lpszName );
-            free( (LPVOID)cs.lpszClass );
+            if (HIWORD(cs.lpszName)) free( (LPVOID)cs.lpszName );
+            if (HIWORD(cs.lpszClass)) free( (LPVOID)cs.lpszClass );
         }
         return result;
 	
@@ -563,13 +610,21 @@
             cls  = SEGPTR_STRDUP( cs32->lpszClass );
             cs->lpszName  = SEGPTR_GET(name);
             cs->lpszClass = SEGPTR_GET(cls);
+#ifdef WINELIB
             result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam,
                                     (LPARAM)SEGPTR_GET(cs) );
-            STRUCT32_CREATESTRUCT16to32A( cs, cs32 );
-            if (PTR_SEG_TO_LIN(cs->lpszName) != name)
-                cs32->lpszName  = (LPCSTR)PTR_SEG_TO_LIN( cs->lpszName );
-            if (PTR_SEG_TO_LIN(cs->lpszClass) != cls)
-                cs32->lpszClass = (LPCSTR)PTR_SEG_TO_LIN( cs->lpszClass );
+#else
+            /* Build the CREATESTRUCT on the 16-bit stack. */
+            /* This is really ugly, but some programs (notably the */
+            /* "Undocumented Windows" examples) want it that way.  */
+            result = CallWndProcNCCREATE16( func, ds, cs->dwExStyle,
+                      cs->lpszClass, cs->lpszName, cs->style, cs->x, cs->y,
+                      cs->cx, cs->cy, cs->hwndParent, cs->hMenu, cs->hInstance,
+                      (LONG)cs->lpCreateParams, hwnd, msg, (WPARAM16)wParam,
+                      MAKELONG( IF1632_Saved16_sp-sizeof(CREATESTRUCT16),
+                                IF1632_Saved16_ss ) );
+#endif  /* WINELIB */
+            /* We don't bother to translate the structure back */
             SEGPTR_FREE(name);
             SEGPTR_FREE(cls);
             SEGPTR_FREE(cs);
@@ -580,6 +635,10 @@
         if ((wParam == WM_CREATE) || (wParam == WM_DESTROY))
             return CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam,
                                   MAKELPARAM( (HWND16)lParam, LOWORD(wParam)));
+        else
+            return CallWndProc16( func, ds, hwnd, msg,
+                                  (WPARAM16)wParam, lParam );
+
     case WM_SETTEXT:
         {
             LPSTR str = SEGPTR_STRDUP( (LPSTR)lParam );
@@ -650,12 +709,14 @@
     case WM_CREATE:
         {
             CREATESTRUCT32A cs = *(CREATESTRUCT32A *)lParam;
-            cs.lpszName  = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName );
-            cs.lpszClass = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName );
+            if (HIWORD(cs.lpszName))
+                cs.lpszName  = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName );
+            if (HIWORD(cs.lpszClass))
+                cs.lpszClass = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName );
             result = WINPROC_CallProc32ATo16( func, ds, hwnd, msg, wParam,
                                               (LPARAM)&cs );
-            free( (LPVOID)cs.lpszName );
-            free( (LPVOID)cs.lpszClass );
+            if (HIWORD(cs.lpszName)) free( (LPVOID)cs.lpszName );
+            if (HIWORD(cs.lpszClass)) free( (LPVOID)cs.lpszClass );
         }
         return result;
 	
@@ -683,22 +744,31 @@
                           WPARAM16 wParam, LPARAM lParam )
 {
     WND *wndPtr;
+    WINDOWPROC *proc = WINPROC_GetPtr( (HANDLE32)func );
 
-    switch(WINPROC_GetWinProcType(func))
+    if (!proc)
     {
-    case WIN_PROC_16:
         wndPtr = WIN_FindWndPtr( hwnd );
         return CallWndProc16( (FARPROC)func,
                               wndPtr ? wndPtr->hInstance : CURRENT_DS,
                               hwnd, msg, wParam, lParam );
+    }
+
+    switch(proc->type)
+    {
+    case WIN_PROC_16:
+        wndPtr = WIN_FindWndPtr( hwnd );
+        return CallWndProc16( (FARPROC)proc->func,
+                              wndPtr ? wndPtr->hInstance : CURRENT_DS,
+                              hwnd, msg, wParam, lParam );
     case WIN_PROC_32A:
-        return WINPROC_CallProc16To32A( WINPROC_GetWinProcFunc(func),
+        return WINPROC_CallProc16To32A( (WNDPROC32)proc->func,
                                         hwnd, msg, wParam, lParam );
     case WIN_PROC_32W:
-        return WINPROC_CallProc16To32W( WINPROC_GetWinProcFunc(func),
+        return WINPROC_CallProc16To32W( (WNDPROC32)proc->func,
                                         hwnd, msg, wParam, lParam );
     default:
-        fprintf(stderr, "CallWindowProc16: invalid func %08x\n", (UINT32)func);
+        fprintf( stderr, "CallWindowProc16: invalid proc %p\n", proc );
         return 0;
     }
 }
@@ -711,22 +781,25 @@
                            WPARAM32 wParam, LPARAM lParam )
 {
     WND *wndPtr;
+    WINDOWPROC *proc = WINPROC_GetPtr( (HANDLE32)func );
 
-    switch(WINPROC_GetWinProcType( (WNDPROC16)func ))
+    if (!proc) return CallWndProc32( func, hwnd, msg, wParam, lParam );
+
+    switch(proc->type)
     {
     case WIN_PROC_16:
         wndPtr = WIN_FindWndPtr( hwnd );
-        return WINPROC_CallProc32ATo16( (FARPROC)func,
+        return WINPROC_CallProc32ATo16( (FARPROC)proc->func,
                                        wndPtr ? wndPtr->hInstance : CURRENT_DS,
                                        hwnd, msg, wParam, lParam );
     case WIN_PROC_32A:
-        return CallWndProc32( WINPROC_GetWinProcFunc( (WNDPROC16)func ),
+        return CallWndProc32( (WNDPROC32)proc->func,
                               hwnd, msg, wParam, lParam );
     case WIN_PROC_32W:
-        return WINPROC_CallProc32ATo32W(WINPROC_GetWinProcFunc((WNDPROC16)func),
-                                        hwnd, msg, wParam, lParam );
+        return WINPROC_CallProc32ATo32W( (WNDPROC32)proc->func,
+                                         hwnd, msg, wParam, lParam );
     default:
-        fprintf(stderr,"CallWindowProc32A: invalid func %08x\n",(UINT32)func);
+        fprintf( stderr, "CallWindowProc32A: invalid proc %p\n", proc );
         return 0;
     }
 }
@@ -739,22 +812,25 @@
                            WPARAM32 wParam, LPARAM lParam )
 {
     WND *wndPtr;
+    WINDOWPROC *proc = WINPROC_GetPtr( (HANDLE32)func );
 
-    switch(WINPROC_GetWinProcType( (WNDPROC16)func ))
+    if (!proc) return CallWndProc32( func, hwnd, msg, wParam, lParam );
+
+    switch(proc->type)
     {
     case WIN_PROC_16:
         wndPtr = WIN_FindWndPtr( hwnd );
-        return WINPROC_CallProc32WTo16( (FARPROC)func,
+        return WINPROC_CallProc32WTo16( (FARPROC)proc->func,
                                        wndPtr ? wndPtr->hInstance : CURRENT_DS,
                                        hwnd, msg, wParam, lParam );
     case WIN_PROC_32A:
-        return WINPROC_CallProc32WTo32A(WINPROC_GetWinProcFunc((WNDPROC16)func),
-                                        hwnd, msg, wParam, lParam );
+        return WINPROC_CallProc32WTo32A( (WNDPROC32)proc->func,
+                                         hwnd, msg, wParam, lParam );
     case WIN_PROC_32W:
-        return CallWndProc32( WINPROC_GetWinProcFunc( (WNDPROC16)func ),
+        return CallWndProc32( (WNDPROC32)proc->func,
                               hwnd, msg, wParam, lParam );
     default:
-        fprintf(stderr,"CallWindowProc32W: invalid func %08x\n",(UINT32)func);
+        fprintf( stderr, "CallWindowProc32W: invalid proc %p\n", proc );
         return 0;
     }
 }