Release 960811

Sun Aug 11 13:00:20 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [configure.in] [include/acconfig.h] [tools/build.c]
	Added check for underscore on external symbols.

	* [memory/selector.c] [memory/global.c]
	Fixed FreeSelector() to free only one selector.
	Added SELECTOR_FreeBlock() to free an array of selectors.

	* [objects/color.c]
	Fixed a bug in COLOR_ToLogical() that caused GetPixel() to fail on
	hi-color displays.

	* [tools/build.c] [if1632/crtdll.spec]
	Added 'extern' type, used for external variables or functions.

	* [windows/winpos.c]
	Allow de-activating a window in WINPOS_ChangeActiveWindow().

	* [windows/winproc.c]
	Added 32-to-16 translation for button messages.
	Fixed WINPROC_GetPtr() to avoid crashes on 32-bit procedures that
	happen to be valid SEGPTRs.

Sat Aug 10 18:22:25 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [windows/message.c]
	Removed a FIXME in MSG_PeekHardwareMsg(): produces correct 
	data for the JOURNALRECORD-hook (using EVENTMSG16 structure).

	* [if1632/gdi.spec] [include/windows.h] [objects/metafile.c]
	Introduced undocumented API function IsValidMetaFile(), plus a
 	minor fix in last patch of CopyMetaFile().

	* [objects/gdiobj.c]
	Removed a FIXME in IsGDIObject(): added magic word check.

Sun Aug 10 18:10:10 1996  Bruce Milner <Bruce.Milner@genetics.utah.edu>

	* [controls/statuswin.c]
	First pass at implementing the StatusWindow class.

	* [include/commctrl.h]
	Header file for common controls.

	* [controls/widgets.c]
	Added InitCommonControls().

	* [if1632/comctl32.spec]
	Add DrawStatusTextA, CreateStatusWindowA, InitCommonControls.

	* [win32/findfile.c] [if1632/kernel32.spec]
	Add FindNextFile32A, FindClose.
	Modified FindFirstFile32A so it works with FindNextFile32A.

	* [include/winbase.h]
	Fixed WIN32_FIND_DATA structure member names.

Sat Aug 10 09:00:00 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>

	* [windows/scroll.c]
	Changed scrolling routines to benefit from DCE code update.

Thu Aug  8 18:05:09 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [files/file.c]
	SearchPath* could get NULL for lastpart argument.

	* [if1632/build-spec.txt] [documentation/debugging]
	Varargs documentation added, debugging hints updated.

	* [if1632/crtdll.spec][misc/crtdll.c][misc/Makefile.in]
	Started to implement CRTDLL.

	* [if1632/wsock32.spec]
	Some thunks to standard libc functions (structures have the same
 	elements, but perhaps wrong offset due to packing).

	* [include/kernel32.h][include/windows.h][win32/*.c][loader/main.c]
	Merged kernel32.h into windows.h.

	* [misc/lstr.c]
	Enhanced FormatMessage().

	* [misc/main.c] [if1632/kernel.spec] [include/windows.h]
	GetVersion() updated to new naming standard.
	Changed language handling to support language ids.

	* [misc/shell.c]
	Enhanced FindExecutable, so it finds files in the search path too.

	* [win32/environment.c]
	GetCommandLine* updated.

	* [loader/resource.c] [loader/pe_resource.c]
	FindResourceEx32* added.
	Loading of messagetables added.
	Language handling now uses Wine default language id.
diff --git a/windows/dce.c b/windows/dce.c
index 58ada2a..b52d547 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -302,8 +302,9 @@
     int xoffset, yoffset;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
-      /* Get visible rectangle and create a region with it 
-       * FIXME: do we really need to calculate vis rgns for X windows? 
+      /* Get visible rectangle and create a region with it. 
+       * do we really need to calculate vis rgns for X windows? 
+       * - yes, to clip child windows.
        */
 
     if (!wndPtr || !DCE_GetVisRect( wndPtr, !(flags & DCX_WINDOW), &rect ))
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 87dc7d4..43b4ddc 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -319,7 +319,7 @@
 
     case WM_QUERYDRAGICON:
         {
-            HICON hI = 0;
+            HICON16 hI = 0;
             UINT16 len = 1;
             while(len < 64)
 		if( (hI = LoadIcon16(wndPtr->hInstance,MAKEINTRESOURCE(len))) )
diff --git a/windows/dialog.c b/windows/dialog.c
index 3fbcb14..21ff837 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -623,7 +623,7 @@
                             HWND16 owner, DLGPROC16 dlgProc, LPARAM param )
 {
     HWND16 hwnd = 0;
-    HRSRC hRsrc;
+    HRSRC16 hRsrc;
     HGLOBAL16 hmem;
     LPCVOID data;
 
diff --git a/windows/mdi.c b/windows/mdi.c
index 2ff08e2..3d1984c 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -841,7 +841,7 @@
 BOOL MDI_AugmentFrameMenu(MDICLIENTINFO* ci, WND *frame, HWND hChild)
 {
  WND*		child = WIN_FindWndPtr(hChild);
- HGLOBAL        handle;
+ HGLOBAL16      handle;
  HMENU  	hSysPopup = 0;
 
  dprintf_mdi(stddeb,"MDI_AugmentFrameMenu: frame %p,child %04x\n",frame,hChild);
diff --git a/windows/message.c b/windows/message.c
index 82d04dd..82870e4 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -13,6 +13,7 @@
 #include "win.h"
 #include "gdi.h"
 #include "sysmetrics.h"
+#include "heap.h"
 #include "hook.h"
 #include "spy.h"
 #include "stackframe.h"
@@ -259,13 +260,37 @@
         if ((msg->hwnd != GetDesktopWindow()) && 
             (GetWindowTask16(msg->hwnd) != GetCurrentTask()))
             continue;  /* Not for this task */
-        if (remove)
+        if (remove && HOOK_GetHook( WH_JOURNALRECORD, GetTaskQueue(0) ))
         {
-            MSG16 tmpMsg = *msg; /* FIXME */
-            HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION,
-                            0, (LPARAM)MAKE_SEGPTR(&tmpMsg) );
-            QUEUE_RemoveMsg( sysMsgQueue, pos );
+            EVENTMSG16 *event = SEGPTR_NEW(EVENTMSG16);
+            if (event)
+            {
+                event->message = msg->message;
+                event->time = msg->time;
+                if ((msg->message >= WM_KEYFIRST) &&
+                    (msg->message <= WM_KEYLAST))
+                {
+                    event->paramL = (msg->wParam & 0xFF) |
+                                    (HIWORD(msg->lParam) << 8);
+                    event->paramH = msg->lParam & 0x7FFF;  
+                    if (HIWORD(msg->lParam) & 0x0100)
+                        event->paramH |= 0x8000;  /* special_key - bit */
+                    HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION,
+                                    0, (LPARAM)SEGPTR_GET(event) );
+                }
+                else if ((msg->message >= WM_MOUSEFIRST) &&
+                         (msg->message <= WM_MOUSELAST))
+                {
+                    event->paramL = LOWORD(msg->lParam);       /* X pos */
+                    event->paramH = HIWORD(msg->lParam);       /* Y pos */ 
+                    ClientToScreen16( msg->hwnd, (LPPOINT16)&event->paramL );
+                    HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION,
+                                    0, (LPARAM)SEGPTR_GET(event) );
+                }
+                SEGPTR_FREE(event);
+            }
         }
+        if (remove) QUEUE_RemoveMsg( sysMsgQueue, pos );
         return TRUE;
     }
     return FALSE;
@@ -295,8 +320,8 @@
  *
  * Implementation of an inter-task SendMessage.
  */
-static LRESULT MSG_SendMessage( HQUEUE hDestQueue, HWND hwnd, UINT msg,
-                         WPARAM wParam, LPARAM lParam )
+static LRESULT MSG_SendMessage( HQUEUE16 hDestQueue, HWND hwnd, UINT msg,
+                                WPARAM wParam, LPARAM lParam )
 {
     MESSAGEQUEUE *queue, *destQ;
 
@@ -372,7 +397,7 @@
 {
     int pos, mask;
     MESSAGEQUEUE *msgQueue;
-    HQUEUE	  hQueue;
+    HQUEUE16 hQueue;
 
 #ifdef CONFIG_IPC
     DDE_TestDDE(hwnd);	/* do we have dde handling in the window ?*/
@@ -681,6 +706,8 @@
         fprintf( stderr, "SendMessage16: invalid hwnd %04x\n", hwnd );
         return 0;
     }
+    if (wndPtr->hmemTaskQ == QUEUE_GetDoomedQueue())
+        return 0;  /* Don't send anything if the task is dying */
     if (wndPtr->hmemTaskQ != GetTaskQueue(0))
         return MSG_SendMessage( wndPtr->hmemTaskQ, hwnd, msg, wParam, lParam );
 
@@ -731,6 +758,8 @@
         return ret;
     }
 
+    if (wndPtr->hmemTaskQ == QUEUE_GetDoomedQueue())
+        return 0;  /* Don't send anything if the task is dying */
     if (wndPtr->hmemTaskQ != GetTaskQueue(0))
     {
         fprintf( stderr, "SendMessage32A: intertask message not supported\n" );
@@ -771,6 +800,8 @@
         fprintf( stderr, "SendMessage32W: invalid hwnd %08x\n", hwnd );
         return 0;
     }
+    if (wndPtr->hmemTaskQ == QUEUE_GetDoomedQueue())
+        return 0;  /* Don't send anything if the task is dying */
     if (wndPtr->hmemTaskQ != GetTaskQueue(0))
     {
         fprintf( stderr, "SendMessage32W: intertask message not supported\n" );
diff --git a/windows/property.c b/windows/property.c
index 22bcf98..4b0796b 100644
--- a/windows/property.c
+++ b/windows/property.c
@@ -5,6 +5,7 @@
  */
 
 #define NO_TRANSITION_TYPES  /* This file is Win32-clean */
+#include <stdlib.h>
 #include <string.h>
 #include "win.h"
 #include "heap.h"
diff --git a/windows/queue.c b/windows/queue.c
index 1d3437e..3ae6306 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -22,18 +22,6 @@
 static MESSAGEQUEUE *sysMsgQueue = NULL;
 
 /***********************************************************************
- *	     QUEUE_GetDoomedQueue/QUEUE_SetDoomedQueue
- */
-HQUEUE QUEUE_GetDoomedQueue()
-{
-  return hDoomedQueue;
-}
-void QUEUE_SetDoomedQueue(HQUEUE hQueue)
-{
-  hDoomedQueue = hQueue;
-}
-
-/***********************************************************************
  *	     QUEUE_DumpQueue
  */
 void QUEUE_DumpQueue( HQUEUE16 hQueue )
@@ -75,7 +63,7 @@
  */
 void QUEUE_WalkQueues(void)
 {
-    HQUEUE hQueue = hFirstQueue;
+    HQUEUE16 hQueue = hFirstQueue;
 
     fprintf( stderr, "Queue Size Msgs Task\n" );
     while (hQueue)
@@ -96,13 +84,31 @@
 
 
 /***********************************************************************
+ *	     QUEUE_GetDoomedQueue/QUEUE_SetDoomedQueue
+ */
+HQUEUE16 QUEUE_GetDoomedQueue()
+{
+    return hDoomedQueue;
+}
+
+
+/***********************************************************************
+ *	     QUEUE_SetDoomedQueue
+ */
+void QUEUE_SetDoomedQueue( HQUEUE16 hQueue )
+{
+    hDoomedQueue = hQueue;
+}
+
+
+/***********************************************************************
  *           QUEUE_CreateMsgQueue
  *
  * Creates a message queue. Doesn't link it into queue list!
  */
-static HQUEUE QUEUE_CreateMsgQueue( int size )
+static HQUEUE16 QUEUE_CreateMsgQueue( int size )
 {
-    HQUEUE hQueue;
+    HQUEUE16 hQueue;
     MESSAGEQUEUE * msgQueue;
     int queueSize;
     TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
@@ -249,7 +255,7 @@
     WPARAM wParam;
     LPARAM lParam;
     LRESULT result = 0;
-    HQUEUE oldSender;
+    HQUEUE16 oldSender;
 
     printf( "ReceiveMessage\n" );
     if (!(queue->wakeBits & QS_SENDMESSAGE)) return;
@@ -395,7 +401,7 @@
 {
     HWND hwnd;
     WORD wakeBit;
-    HQUEUE hQueue;
+    HQUEUE16 hQueue;
     MESSAGEQUEUE *queue = NULL;
 
     if ((message >= WM_KEYFIRST) && (message <= WM_KEYLAST)) wakeBit = QS_KEY;
@@ -577,7 +583,7 @@
  */
 BOOL SetMessageQueue( int size )
 {
-    HQUEUE hQueue, hNewQueue;
+    HQUEUE16 hQueue, hNewQueue;
     MESSAGEQUEUE *queuePtr;
 
     dprintf_msg(stddeb,"SetMessageQueue: task %04x size %i\n", GetCurrentTask(), size); 
diff --git a/windows/scroll.c b/windows/scroll.c
index d00330b..7c11953 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -2,7 +2,7 @@
  * Scroll windows and DCs
  *
  * Copyright  David W. Metcalfe, 1993
- *	      Alex Korobka       1995
+ *	      Alex Korobka       1995,1996
  *
  *
  */
@@ -12,101 +12,17 @@
 #include "class.h"
 #include "win.h"
 #include "gdi.h"
+#include "region.h"
 #include "sysmetrics.h"
 #include "stddebug.h"
 /* #define DEBUG_SCROLL */
 #include "debug.h"
 
-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;
 
-
-/* -----------------------------------------------------------------------
- *	       SCROLL_TraceChildren
- * 
- * Returns a region invalidated by children, siblings, and/or ansectors
- * in the window rectangle or client rectangle
- *
- * dcx can have DCX_WINDOW, DCX_CLIPCHILDREN, DCX_CLIPSIBLINGS set
- */
-
-HRGN	SCROLL_TraceChildren( WND* wndScroll, short dx, short dy, WORD dcx)
-{
- HRGN		hRgnWnd;
- HRGN		hUpdateRgn,hCombineRgn;
-
- if( !wndScroll || ( !dx && !dy) ) return 0;
-
- if( dcx & DCX_WINDOW )
-	 hRgnWnd   = CreateRectRgnIndirect16(&wndScroll->rectWindow);
- else
-	{
-	 RECT32 rect = { 0, 0, wndScroll->rectClient.right - wndScroll->rectClient.left,
-			       wndScroll->rectClient.bottom - wndScroll->rectClient.top };
-
- 	 hRgnWnd   = CreateRectRgnIndirect32(&rect);
-	}
-
- hUpdateRgn  = DCE_GetVisRgn( wndScroll->hwndSelf, dcx );
- hCombineRgn = CreateRectRgn(0,0,0,0);
-
- if( !hUpdateRgn || !hCombineRgn )
-      {
-	DeleteObject( hUpdateRgn? hUpdateRgn : hCombineRgn);
-	DeleteObject(hRgnWnd);
-	return 0;
-      }
-
- OffsetRgn( hUpdateRgn, dx, dy);
- CombineRgn(hCombineRgn, hRgnWnd, hUpdateRgn, RGN_DIFF);
- 
- DeleteObject(hRgnWnd);
- DeleteObject(hUpdateRgn);
-
- return hCombineRgn;
-}
-
-
-/* ----------------------------------------------------------------------
- *	       SCROLL_ScrollChildren
- */
-BOOL	SCROLL_ScrollChildren( WND* wndScroll, short dx, short dy)
-{
- WND           *wndPtr = NULL;
- HRGN		hUpdateRgn;
- BOOL		b = 0;
-
- if( !wndScroll || ( !dx && !dy )) return 0;
-
- dprintf_scroll(stddeb,"SCROLL_ScrollChildren: hwnd %04x dx=%i dy=%i\n",wndScroll->hwndSelf,dx,dy);
-
- /* get a region in client rect invalidated by siblings and ansectors */
- hUpdateRgn = SCROLL_TraceChildren(wndScroll, dx , dy, DCX_CLIPSIBLINGS);
-
-   /* update children coordinates */
-   for (wndPtr = wndScroll->child; wndPtr; wndPtr = wndPtr->next)
-   {
-	/* we can check if window intersects with clipRect parameter
-	 * and do not move it if not - just a thought.     - AK
-	 */
-	SetWindowPos(wndPtr->hwndSelf, 0, wndPtr->rectWindow.left + dx,
-                     wndPtr->rectWindow.top  + dy, 0,0, SWP_NOZORDER |
-                     SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW |
-                     SWP_DEFERERASE );
-  } 
-
- /* invalidate uncovered region and paint frames */
- b = RedrawWindow32( wndScroll->hwndSelf, NULL, hUpdateRgn, 
-		     RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW | RDW_ALLCHILDREN ); 
-
- DeleteObject( hUpdateRgn);
- return b;
-}
-
-
 /*************************************************************************
  *             ScrollWindow         (USER.61)
  *
@@ -119,14 +35,13 @@
     HWND 	hCaretWnd = CARET_GetHwnd();
     WND*	wndScroll = WIN_FindWndPtr( hwnd );
 
-    dprintf_scroll(stddeb,"ScrollWindow: dx=%d, dy=%d, lpRect =%08lx clipRect=%i,%i,%i,%i\n", 
-	    dx, dy, (LONG)rect, (int)((clipRect)?clipRect->left:0),
+    dprintf_scroll(stddeb,"ScrollWindow: hwnd=%04x, dx=%d, dy=%d, lpRect =%08lx clipRect=%i,%i,%i,%i\n", 
+	    hwnd, dx, dy, (LONG)rect, (int)((clipRect)?clipRect->left:0),
                                 (int)((clipRect)?clipRect->top:0),
                                 (int)((clipRect)?clipRect->right:0), 
                                 (int)((clipRect)?clipRect->bottom:0));
 
-    /* if rect is NULL children have to be moved */
-    if ( !rect )
+    if ( !rect ) /* do not clip children */
        {
 	  GetClientRect16(hwnd, &rc);
 	  hrgnClip = CreateRectRgnIndirect16( &rc );
@@ -135,21 +50,17 @@
               HideCaret(hCaretWnd);
           else hCaretWnd = 0;
  
-	  /* children will be Blt'ed too */
 	  hdc      = GetDCEx(hwnd, hrgnClip, DCX_CACHE | DCX_CLIPSIBLINGS);
           DeleteObject(hrgnClip);
        }
-    else
+    else	/* clip children */
        {
 	  GetClientRect16(hwnd,&rc);
-	  dprintf_scroll(stddeb,"\trect=%i %i %i %i client=%i %i %i %i\n",
-			 (int)rect->left,(int)rect->top,(int)rect->right,
-			 (int)rect->bottom,(int)rc.left,(int)rc.top,
-			 (int)rc.right,(int)rc.bottom);
+	  CopyRect16(&rc, rect);
 
           if (hCaretWnd == hwnd) HideCaret(hCaretWnd);
           else hCaretWnd = 0;
-          CopyRect16(&rc, rect);
+
 	  hdc = GetDC(hwnd);
        }
 
@@ -158,34 +69,28 @@
     else
 	CopyRect16(&cliprc, clipRect);
 
-    /* move window update region (if any) */
-
-    if( wndScroll->hrgnUpdate > 1 )
-	OffsetRgn( wndScroll->hrgnUpdate, dx, dy );
-
     hrgnUpdate = CreateRectRgn(0, 0, 0, 0);
     ScrollDC(hdc, dx, dy, &rc, &cliprc, hrgnUpdate, NULL);
     ReleaseDC(hwnd, hdc);
 
-    if( !rect )
-      {
-         /* FIXME: this doesn't take into account hrgnUpdate */
+    if( !rect )		/* move child windows and update region */
+    { 
+      WND*	wndPtr;
 
-         if( !SCROLL_ScrollChildren( wndScroll, dx,dy) )
-	     InvalidateRgn(hwnd, hrgnUpdate, TRUE);
-      }
-    else
-      {
-        HRGN hrgnInv = SCROLL_TraceChildren( wndScroll ,dx,dy,DCX_CLIPCHILDREN |
-						              DCX_CLIPSIBLINGS );
-        if( hrgnInv )
-        {
-	    CombineRgn(hrgnUpdate,hrgnInv,hrgnUpdate,RGN_OR);
-            DeleteObject(hrgnInv);
-        }
+      if( wndScroll->hrgnUpdate > 1 )
+	OffsetRgn( wndScroll->hrgnUpdate, dx, dy );
 
-        RedrawWindow32( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW);
-      }
+      for (wndPtr = wndScroll->child; wndPtr; wndPtr = wndPtr->next)
+        SetWindowPos(wndPtr->hwndSelf, 0, wndPtr->rectWindow.left + dx,
+                     wndPtr->rectWindow.top  + dy, 0,0, SWP_NOZORDER |
+                     SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW |
+                     SWP_DEFERERASE );
+    }
+
+    /* RDW_ALLCHILDREN is to account for dialog controls */
+
+    RedrawWindow32( hwnd, NULL, hrgnUpdate, RDW_ALLCHILDREN |
+					    RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW);
 
     DeleteObject(hrgnUpdate);
     if( hCaretWnd ) ShowCaret(hCaretWnd);
@@ -210,15 +115,15 @@
                    dx, dy, hrgnUpdate, rcUpdate, cliprc, rc ? rc->left : 0,
                    rc ? rc->top : 0, rc ? rc->right : 0, rc ? rc->bottom : 0 );
 
-    if (rc == NULL || !hdc || !dc)
-	return FALSE;
+    if ( !dc || !hdc ) return FALSE;
 
     /* set clipping region */
 
+    if ( !rc ) GetClipBox16( hdc, &rectClip );
+    else rectClip = *rc;
+
     if (cliprc)
-	IntersectRect16(&rectClip,rc,cliprc);
-    else
-	rectClip = *rc;
+	IntersectRect16(&rectClip,&rectClip,cliprc);
 
     if( rectClip.left >= rectClip.right || rectClip.top >= rectClip.bottom )
 	return FALSE;
@@ -228,9 +133,7 @@
 
     if( hrgnClip )
       {
-        /* call UpdateGCRegion directly to avoid
-         * one more temporary region
-	 */ 
+        /* save a copy and change cliprgn directly */
 
         CombineRgn( hrgnScrollClip, hrgnClip, 0, RGN_COPY );
         SetRectRgn( hrgnClip, rectClip.left, rectClip.top, rectClip.right, rectClip.bottom );
@@ -238,33 +141,33 @@
 	CLIPPING_UpdateGCRegion( dc );
       }
     else
-        SelectClipRgn( hdc, hrgnScrollClip ); 
+        SelectClipRgn( hdc, hrgnScrollClip );
 
     /* translate coordinates */
 
     if (dx > 0)
     {
-	src.x = XDPTOLP(dc, rc->left);
-	dest.x = XDPTOLP(dc, rc->left + abs(dx));
+	src.x = XDPTOLP(dc, rectClip.left);
+	dest.x = XDPTOLP(dc, rectClip.left + abs(dx));
     }
     else
     {
-	src.x = XDPTOLP(dc, rc->left + abs(dx));
-	dest.x = XDPTOLP(dc, rc->left);
+	src.x = XDPTOLP(dc, rectClip.left + abs(dx));
+	dest.x = XDPTOLP(dc, rectClip.left);
     }
     if (dy > 0)
     {
-	src.y = YDPTOLP(dc, rc->top);
-	dest.y = YDPTOLP(dc, rc->top + abs(dy));
+	src.y = YDPTOLP(dc, rectClip.top);
+	dest.y = YDPTOLP(dc, rectClip.top + abs(dy));
     }
     else
     {
-	src.y = YDPTOLP(dc, rc->top + abs(dy));
-	dest.y = YDPTOLP(dc, rc->top);
+	src.y = YDPTOLP(dc, rectClip.top + abs(dy));
+	dest.y = YDPTOLP(dc, rectClip.top);
     }
 
-    width = rc->right - rc->left - abs(dx);
-    height = rc->bottom - rc->top - abs(dy);
+    width = rectClip.right - rectClip.left - abs(dx);
+    height = rectClip.bottom - rectClip.top - abs(dy);
 
     /* copy bits */
 
@@ -274,45 +177,38 @@
 
     /* compute update areas */
 
-    if (hrgnUpdate)
+    if (hrgnUpdate || rcUpdate)
     {
-	HRGN hrgn1,hrgn2;
+	HRGN   hrgn1 = (hrgnUpdate)?hrgnUpdate:CreateRectRgn( 0,0,0,0 );
 
-	if (dx > 0)
-	    hrgn1 = CreateRectRgn(rc->left, rc->top, rc->left+dx, rc->bottom);
-	else if (dx < 0)
-	    hrgn1 = CreateRectRgn(rc->right+dx, rc->top, rc->right, 
-				  rc->bottom);
+	if( dc->w.hVisRgn )
+	{
+	  CombineRgn( hrgn1, dc->w.hVisRgn, 0, RGN_COPY);
+	  CombineRgn( hrgn1, hrgn1, (hrgnClip)?hrgnClip:hrgnScrollClip, RGN_AND);
+	  OffsetRgn( hrgn1, dx, dy );
+	  CombineRgn( hrgn1, dc->w.hVisRgn, hrgn1, RGN_DIFF);
+	  RgnType = CombineRgn( hrgn1, hrgn1, (hrgnClip)?hrgnClip:hrgnScrollClip, RGN_AND);
+	}
 	else
-	    hrgn1 = CreateRectRgn(0, 0, 0, 0);
+	{
+	  RECT16	rect;
 
-	if (dy > 0)
-	    hrgn2 = CreateRectRgn(rc->left, rc->top, rc->right, rc->top+dy);
-	else if (dy < 0)
-	    hrgn2 = CreateRectRgn(rc->left, rc->bottom+dy, rc->right, 
-				  rc->bottom);
-	else
-	    hrgn2 = CreateRectRgn(0, 0, 0, 0);
+          rect = rectClip;				/* vertical band */
+          if (dx > 0) rect.right = rect.left + dx;
+          else if (dx < 0) rect.left = rect.right + dx;
+          else SetRectEmpty16( &rect );
+          SetRectRgn( hrgn1, rect.left, rect.top, rect.right, rect.bottom );
 
-	RgnType = CombineRgn(hrgnUpdate, hrgn1, hrgn2, RGN_OR);
-	DeleteObject(hrgn1);
-	DeleteObject(hrgn2);
-        if (rcUpdate) GetRgnBox16( hrgnUpdate, rcUpdate );
-    }
-    else if (rcUpdate)
-    {
-	RECT16 rx,ry;
+          rect = rectClip;				/* horizontal band */
+          if (dy > 0) rect.bottom = rect.top + dy;
+          else if (dy < 0) rect.top = rect.bottom + dy;
+          else SetRectEmpty16( &rect );
 
-	rx = ry = *rc;
-	if( dx > 0 )  	  rx.right = rc->left+dx; 
-	else if (dx < 0)  rx.left = rc->right+dx; 
-	else SetRectEmpty16( &rx );
+          RgnType = REGION_UnionRectWithRgn( hrgn1, &rect );
+	}
 
-        if( dy > 0 )      ry.bottom = rc->top+dy;
-        else if (dy < 0)  ry.top = rc->bottom+dy;
-        else SetRectEmpty16( &ry );
-
-	UnionRect16( rcUpdate, &rx, &ry );
+	if (rcUpdate) GetRgnBox16( hrgn1, rcUpdate );
+	if (!hrgnUpdate) DeleteObject( hrgn1 );
     }
 
     /* restore clipping region */
@@ -327,9 +223,8 @@
 /*************************************************************************
  *             ScrollWindowEx       (USER.319)
  *
- * FIXME: broken
+ * FIXME: broken, is there a program that actually uses it?
  *
- * SCROLL_TraceChildren can help
  */
 
 int ScrollWindowEx(HWND hwnd, short dx, short dy, LPRECT16 rect, LPRECT16 clipRect,
diff --git a/windows/win.c b/windows/win.c
index 845d9ac..63e8564 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -43,8 +43,7 @@
 static WORD wDragWidth = 4;
 static WORD wDragHeight= 3;
 
-extern HCURSOR CURSORICON_IconToCursor(HICON);
-extern HQUEUE  QUEUE_GetDoomedQueue();
+extern HCURSOR16 CURSORICON_IconToCursor(HICON16);
 
 /***********************************************************************
  *           WIN_FindWndPtr
@@ -343,7 +342,7 @@
 /***********************************************************************
  *	     WIN_DestroyQueueWindows
  */
-void WIN_DestroyQueueWindows( WND* wnd, HQUEUE hQueue )
+void WIN_DestroyQueueWindows( WND* wnd, HQUEUE16 hQueue )
 {
     WND* next;
 
@@ -905,8 +904,7 @@
 		      SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE );
     if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
 	ReleaseCapture();
-    if (!QUEUE_GetDoomedQueue())
-        WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LONG)hwnd );
+    WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LONG)hwnd );
 
     CLIPBOARD_DisOwn( hwnd );
 
@@ -1981,17 +1979,17 @@
  *
  */
 DWORD DragObject(HWND hwndScope, HWND hWnd, WORD wObj, HANDLE hOfStruct,
-                WORD szList , HCURSOR hCursor)
+                WORD szList , HCURSOR16 hCursor)
 {
  MSG16	 	msg;
  LPDRAGINFO	lpDragInfo;
  SEGPTR		spDragInfo;
- HCURSOR 	hDragCursor=0, hOldCursor=0, hBummer=0;
+ HCURSOR16 	hDragCursor=0, hOldCursor=0, hBummer=0;
  HANDLE		hDragInfo  = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
  WND           *wndPtr = WIN_FindWndPtr(hWnd);
  DWORD		dwRet = 0;
  short	 	dragDone = 0;
- HCURSOR	hCurrentCursor = 0;
+ HCURSOR16	hCurrentCursor = 0;
  HWND		hCurrentWnd = 0;
  WORD	        btemp;
 
diff --git a/windows/winpos.c b/windows/winpos.c
index 9e1a9cc..c6132bb 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -866,6 +866,7 @@
     WND                   *wndTemp         = WIN_FindWndPtr(hwndActive);
     CBTACTIVATESTRUCT16   *cbtStruct;
     WORD                   wIconized=0;
+    HANDLE hNewActiveQueue;
 
     /* FIXME: When proper support for cooperative multitasking is in place 
      *        hActiveQ will be global 
@@ -874,10 +875,10 @@
     HANDLE                 hActiveQ = 0;   
 
     /* paranoid checks */
-    if( !hWnd || hWnd == GetDesktopWindow() || hWnd == hwndActive )
+    if( hWnd == GetDesktopWindow() || hWnd == hwndActive )
 	return 0;
 
-    if( GetTaskQueue(0) != wndPtr->hmemTaskQ )
+    if (wndPtr && (GetTaskQueue(0) != wndPtr->hmemTaskQ))
 	return 0;
 
     if( wndTemp )
@@ -918,7 +919,7 @@
     hwndActive = hWnd;
 
     /* send palette messages */
-    if( SendMessage16( hWnd, WM_QUERYNEWPALETTE, 0, 0L) )
+    if (hWnd && SendMessage16( hWnd, WM_QUERYNEWPALETTE, 0, 0L))
 	SendMessage16((HWND16)-1, WM_PALETTEISCHANGING, (WPARAM)hWnd, 0L );
 
     /* if prev wnd is minimized redraw icon title 
@@ -932,7 +933,7 @@
   */
 
     /* managed windows will get ConfigureNotify event */  
-    if (!(wndPtr->dwStyle & WS_CHILD) && !(wndPtr->flags & WIN_MANAGED))
+    if (wndPtr && !(wndPtr->dwStyle & WS_CHILD) && !(wndPtr->flags & WIN_MANAGED))
     {
 	/* check Z-order and bring hWnd to the top */
 	for (wndTemp = WIN_GetDesktop()->child; wndTemp; wndTemp = wndTemp->next)
@@ -941,18 +942,18 @@
 	if( wndTemp != wndPtr )
 	    SetWindowPos(hWnd, HWND_TOP, 0,0,0,0, 
 			 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
+        if( !IsWindow(hWnd) ) return 0;
     }
 
-    if( !IsWindow(hWnd) ) return 0;
-
     if (hwndPrevActive)
     {
         wndTemp = WIN_FindWndPtr( hwndPrevActive );
         if (wndTemp) hActiveQ = wndTemp->hmemTaskQ;
     }
+    hNewActiveQueue = wndPtr ? wndPtr->hmemTaskQ : 0;
 
     /* send WM_ACTIVATEAPP if necessary */
-    if (hActiveQ != wndPtr->hmemTaskQ)
+    if (hActiveQ != hNewActiveQueue)
     {
         WND **list, **ppWnd;
 
@@ -964,7 +965,7 @@
                 if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
                 if ((*ppWnd)->hmemTaskQ != hActiveQ) continue;
                 SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
-                               0, QUEUE_GetQueueTask(wndPtr->hmemTaskQ) );
+                               0, QUEUE_GetQueueTask(hNewActiveQueue) );
             }
             HeapFree( SystemHeap, 0, list );
         }
@@ -975,7 +976,7 @@
             {
                 /* Make sure that the window still exists */
                 if (!IsWindow( (*ppWnd)->hwndSelf )) continue;
-                if ((*ppWnd)->hmemTaskQ != wndPtr->hmemTaskQ) continue;
+                if ((*ppWnd)->hmemTaskQ != hNewActiveQueue) continue;
                 SendMessage16( (*ppWnd)->hwndSelf, WM_ACTIVATEAPP,
                                1, QUEUE_GetQueueTask( hActiveQ ) );
             }
@@ -984,19 +985,22 @@
 	if (!IsWindow(hWnd)) return 0;
     }
 
-    /* walk up to the first unowned window */
-    wndTemp = wndPtr;
-    while (wndTemp->owner) wndTemp = wndTemp->owner;
-    /* and set last active owned popup */
-    wndTemp->hwndLastActive = hWnd;
+    if (hWnd)
+    {
+        /* walk up to the first unowned window */
+        wndTemp = wndPtr;
+        while (wndTemp->owner) wndTemp = wndTemp->owner;
+        /* and set last active owned popup */
+        wndTemp->hwndLastActive = hWnd;
 
-    wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
-    SendMessage16( hWnd, WM_NCACTIVATE, TRUE, 0 );
-    SendMessage32A( hWnd, WM_ACTIVATE,
+        wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
+        SendMessage16( hWnd, WM_NCACTIVATE, TRUE, 0 );
+        SendMessage32A( hWnd, WM_ACTIVATE,
 		 MAKEWPARAM( (fMouse) ? WA_CLICKACTIVE : WA_ACTIVE, wIconized),
 		 (LPARAM)hwndPrevActive );
 
-    if( !IsWindow(hWnd) ) return 0;
+        if( !IsWindow(hWnd) ) return 0;
+    }
 
     /* change focus if possible */
     if( fChangeFocus && GetFocus() )
@@ -1024,6 +1028,8 @@
 {
     WND *wndPtr = WIN_FindWndPtr(hWnd);
 
+    if (!hWnd) return WINPOS_SetActiveWindow( 0, mouseMsg, TRUE );
+
     if( !wndPtr ) return FALSE;
 
     /* child windows get WM_CHILDACTIVATE message */
diff --git a/windows/winproc.c b/windows/winproc.c
index 06057c0..79f99c4 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -147,6 +147,7 @@
     if (!IsBadReadPtr( (SEGPTR)handle, sizeof(WINDOWPROC)-sizeof(proc->thunk)))
     {
         ptr = (BYTE *)PTR_SEG_TO_LIN(handle);
+        if (!HEAP_IsInsideHeap( WinProcHeap, 0, ptr )) return NULL;
         /* It must be the thunk address */
         if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
         /* Now we have a pointer to the WINDOWPROC struct */
@@ -906,6 +907,13 @@
     *pwparam16 = (WPARAM16)LOWORD(wParam32);
     switch(msg32)
     {
+    case BM_GETCHECK32:
+    case BM_SETCHECK32:
+    case BM_GETSTATE32:
+    case BM_SETSTATE32:
+    case BM_SETSTYLE32:
+        *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK32);
+        return 0;
     case WM_ACTIVATE:
     case WM_CHARTOITEM:
     case WM_COMMAND: