Make sure that functions returning an HWND always return a full 32-bit
handle.

diff --git a/windows/clipboard.c b/windows/clipboard.c
index 9a2d1e3..422d71f0 100644
--- a/windows/clipboard.c
+++ b/windows/clipboard.c
@@ -12,9 +12,6 @@
  * The internal implementation talks to a "clipboard driver" to fill or
  * expose the cache to the native device. (Currently only the X11 and
  * TTY clipboard  driver are available)
- *
- * TODO: 
- *
  */
 
 #include <stdlib.h>
@@ -31,6 +28,7 @@
 #include "wine/winbase16.h"
 #include "heap.h"
 #include "user.h"
+#include "win.h"
 #include "clipboard.h"
 #include "debugtools.h"
 
@@ -45,10 +43,10 @@
 static HANDLE hClipLock   = 0;
 static BOOL bCBHasChanged  = FALSE;
 
-HWND hWndClipWindow = 0;          /* window that last opened clipboard */
-HWND hWndClipOwner  = 0;          /* current clipboard owner */
-HANDLE16 hTaskClipOwner = 0;      /* clipboard owner's task  */
-static HWND hWndViewer     = 0;   /* start of viewers chain */
+static HWND hWndClipWindow;        /* window that last opened clipboard */
+static HWND hWndClipOwner;         /* current clipboard owner */
+static HANDLE16 hTaskClipOwner;    /* clipboard owner's task  */
+static HWND hWndViewer;            /* start of viewers chain */
 
 static WORD LastRegFormat = CF_REGFORMATBASE;
 
@@ -737,7 +735,7 @@
         hClipLock = GetCurrentTask();
 
         /* Save current user of the clipboard */
-        hWndClipWindow = hWnd;
+        hWndClipWindow = WIN_GetFullHandle( hWnd );
         bCBHasChanged = FALSE;
         bRet = TRUE;
     }
@@ -1320,7 +1318,7 @@
 
     TRACE("(%04x): returning %04x\n", hWnd, hwndPrev);
 
-    hWndViewer = hWnd;
+    hWndViewer = WIN_GetFullHandle( hWnd );
     return hwndPrev;
 }
 
@@ -1368,7 +1366,7 @@
     else
 	WARN("hWndViewer is lost\n");
 
-    if( hWnd == hWndViewer ) hWndViewer = hWndNext;
+    if( hWnd == hWndViewer ) hWndViewer = WIN_GetFullHandle( hWndNext );
 
     return bRet;
 }
@@ -1474,4 +1472,3 @@
 	/* FIXME: Use serial numbers */
 	return 0;
 }
-
diff --git a/windows/dce.c b/windows/dce.c
index d206458..2065cb3 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -70,7 +70,6 @@
 {
     FARPROC16 hookProc;
     DCE * dce;
-    WND* wnd;
     
     if (!(dce = HeapAlloc( GetProcessHeap(), 0, sizeof(DCE) ))) return NULL;
     if (!(dce->hDC = CreateDCA( "DISPLAY", NULL, NULL, NULL )))
@@ -80,32 +79,31 @@
     }
     if (!defaultDCstate) defaultDCstate = GetDCState16( dce->hDC );
 
-    wnd = WIN_FindWndPtr(hWnd);
-    
     /* store DCE handle in DC hook data field */
 
     hookProc = GetProcAddress16( GetModuleHandle16("USER"), (LPCSTR)362 );
     SetDCHook( dce->hDC, hookProc, (DWORD)dce );
 
-    dce->hwndCurrent = hWnd;
+    dce->hwndCurrent = WIN_GetFullHandle( hWnd );
     dce->hClipRgn    = 0;
-    dce->next        = firstDCE;
-    firstDCE = dce;
 
     if( type != DCE_CACHE_DC ) /* owned or class DC */
     {
 	dce->DCXflags = DCX_DCEBUSY;
 	if( hWnd )
 	{
-	    if( wnd->dwStyle & WS_CLIPCHILDREN ) dce->DCXflags |= DCX_CLIPCHILDREN;
-	    if( wnd->dwStyle & WS_CLIPSIBLINGS ) dce->DCXflags |= DCX_CLIPSIBLINGS;
+            LONG style = GetWindowLongW( hWnd, GWL_STYLE );
+            if (style & WS_CLIPCHILDREN) dce->DCXflags |= DCX_CLIPCHILDREN;
+            if (style & WS_CLIPSIBLINGS) dce->DCXflags |= DCX_CLIPSIBLINGS;
 	}
 	SetHookFlags16(dce->hDC,DCHF_INVALIDATEVISRGN);
     }
     else dce->DCXflags = DCX_CACHE | DCX_DCEEMPTY;
-
-    WIN_ReleaseWndPtr(wnd);
     
+    USER_Lock();
+    dce->next = firstDCE;
+    firstDCE = dce;
+    USER_Unlock();
     return dce;
 }
 
@@ -115,7 +113,7 @@
  */
 DCE* DCE_FreeDCE( DCE *dce )
 {
-    DCE **ppDCE;
+    DCE **ppDCE, *ret;
 
     if (!dce) return NULL;
 
@@ -125,6 +123,8 @@
 
     while (*ppDCE && (*ppDCE != dce)) ppDCE = &(*ppDCE)->next;
     if (*ppDCE == dce) *ppDCE = dce->next;
+    ret = *ppDCE;
+    USER_Unlock();
 
     SetDCHook(dce->hDC, NULL, 0L);
 
@@ -133,9 +133,7 @@
 	DeleteObject(dce->hClipRgn);
     HeapFree( GetProcessHeap(), 0, dce );
 
-    USER_Unlock();
-    
-    return *ppDCE;
+    return ret;
 }
 
 /***********************************************************************
@@ -146,22 +144,21 @@
 void DCE_FreeWindowDCE( HWND hwnd )
 {
     DCE *pDCE;
+    WND *pWnd = WIN_FindWndPtr( hwnd );
 
-    USER_Lock();
     pDCE = firstDCE;
+    hwnd = pWnd->hwndSelf;  /* make it a full handle */
 
     while( pDCE )
     {
 	if( pDCE->hwndCurrent == hwnd )
 	{
-            WND *pWnd = WIN_FindWndPtr( hwnd );
 	    if( pDCE == pWnd->dce ) /* owned or Class DCE*/
 	    {
                 if (pWnd->clsStyle & CS_OWNDC)	/* owned DCE*/
 		{
                     pDCE = DCE_FreeDCE( pDCE );
                     pWnd->dce = NULL;
-                    WIN_ReleaseWndPtr( pWnd );
                     continue;
                 }
 		else if( pDCE->DCXflags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN) )	/* Class DCE*/
@@ -181,8 +178,7 @@
                      * We should change this to WARN when Wine is more stable
                      * (for 1.0?).
                      */
-		    ERR("[%04x] GetDC() without ReleaseDC()!\n", 
-			pWnd->hwndSelf);
+		    ERR("[%08x] GetDC() without ReleaseDC()!\n",hwnd);
 		    DCE_ReleaseDC( pDCE );
 		}
 
@@ -190,12 +186,11 @@
 		pDCE->DCXflags |= DCX_DCEEMPTY;
 		pDCE->hwndCurrent = 0;
 	    }
-            WIN_ReleaseWndPtr( pWnd );
 	}
 	pDCE = pDCE->next;
     }
     
-    USER_Unlock();
+    WIN_ReleaseWndPtr( pWnd );
 }
 
 
@@ -403,6 +398,7 @@
 
     if (!hwnd) hwnd = GetDesktopWindow();
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
+    hwnd = wndPtr->hwndSelf;  /* make it a full handle */
 
     /* fixup flags */
 
diff --git a/windows/dialog.c b/windows/dialog.c
index ca15e7f..b950172 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -1953,6 +1953,9 @@
 {
     HWND hwnd, retvalue;
 
+    hwndDlg = WIN_GetFullHandle( hwndDlg );
+    hwndCtrl = WIN_GetFullHandle( hwndCtrl );
+
     if(hwndCtrl)
     {
         /* if the hwndCtrl is the child of the control in the hwndDlg,
@@ -2108,6 +2111,8 @@
 HWND WINAPI GetNextDlgTabItem( HWND hwndDlg, HWND hwndCtrl,
                                    BOOL fPrevious )
 {
+    hwndDlg = WIN_GetFullHandle( hwndDlg );
+    hwndCtrl = WIN_GetFullHandle( hwndCtrl );
     return DIALOG_GetNextTabItem(hwndDlg,hwndDlg,hwndCtrl,fPrevious); 
 }
 
diff --git a/windows/focus.c b/windows/focus.c
index 57582d5..175d39d 100644
--- a/windows/focus.c
+++ b/windows/focus.c
@@ -74,6 +74,7 @@
         /* Check if we can set the focus to this window */
         WND *wndPtr;
 
+        hwnd = WIN_GetFullHandle( hwnd );
         for (;;)
         {
             HWND parent;
diff --git a/windows/input.c b/windows/input.c
index f371e61..018e669 100644
--- a/windows/input.c
+++ b/windows/input.c
@@ -493,7 +493,7 @@
         if (wndPtr)
         {
             TRACE_(win)("(0x%04x)\n", hwnd );
-            captureWnd   = hwnd;
+            captureWnd   = wndPtr->hwndSelf;
             captureHT    = ht;
         }
     }
diff --git a/windows/win.c b/windows/win.c
index 6869cda..aa6162f 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -147,17 +147,50 @@
 
 
 /***********************************************************************
- *           WIN_GetFullHandle
+ *           get_wnd_ptr
  *
- * Get the full 32-bit window handle from a possibly truncated handle.
+ * Return a pointer to the WND structure if local to the process.
+ * If ret value is non-NULL, the user lock is held.
  */
-HWND WIN_GetFullHandle( HWND hwnd )
+static WND *get_wnd_ptr( HWND hwnd )
 {
-    if (!HIWORD(hwnd))
+    WND * ptr;
+
+    if (!hwnd) return NULL;
+
+    USER_Lock();
+    if ((ptr = user_handles[LOWORD(hwnd)]))
+    {
+        if (ptr->dwMagic == WND_MAGIC && (!HIWORD(hwnd) || hwnd == ptr->hwndSelf))
+            return ptr;
+    }
+    USER_Unlock();
+    return NULL;
+}
+
+
+/***********************************************************************
+ *           WIN_Handle32
+ *
+ * Convert a 16-bit window handle to a full 32-bit handle.
+ */
+HWND WIN_Handle32( HWND16 hwnd16 )
+{
+    WND *ptr;
+    HWND hwnd = (HWND)hwnd16;
+
+    if (!hwnd || hwnd == HWND_BROADCAST) return hwnd;
+
+    if ((ptr = get_wnd_ptr( hwnd )))
+    {
+        hwnd = ptr->hwndSelf;
+        USER_Unlock();
+    }
+    else  /* may belong to another process */
     {
         SERVER_START_REQ( get_window_info )
         {
-            req->handle = hwnd;
+            req->handle = (user_handle_t)hwnd16;
             if (!SERVER_CALL_ERR()) hwnd = req->full_handle;
         }
         SERVER_END_REQ;
@@ -177,27 +210,19 @@
 
     if (!hwnd) return NULL;
 
-    USER_Lock();
-    if (!(ptr = user_handles[LOWORD(hwnd)]))
+    if ((ptr = get_wnd_ptr( hwnd )))
     {
-        /* check other processes */
-        if (IsWindow( hwnd ))
-        {
-            ERR( "window %04x belongs to other process\n", hwnd );
-            /* DbgBreakPoint(); */
-        }
-        goto error;
+        /* increment destruction monitoring */
+        ptr->irefCount++;
+        return ptr;
     }
-    if (ptr->dwMagic != WND_MAGIC) goto error;
-    /* verify that handle highword (if any) matches the window */
-    if (HIWORD(hwnd) && hwnd != ptr->hwndSelf) goto error;
-    /*and increment destruction monitoring*/
-     ptr->irefCount++;
-    return ptr;
 
- error:
-    /* Unlock all WND structures for thread safeness*/
-    USER_Unlock();
+    /* check other processes */
+    if (IsWindow( hwnd ))
+    {
+        ERR( "window %04x belongs to other process\n", hwnd );
+        /* DbgBreakPoint(); */
+    }
     SetLastError( ERROR_INVALID_WINDOW_HANDLE );
     return NULL;
 }
@@ -2078,24 +2103,24 @@
 BOOL WINAPI IsWindow( HWND hwnd )
 {
     WND *ptr;
-    BOOL ret = FALSE;
+    BOOL ret;
 
     USER_Lock();
     if ((ptr = user_handles[LOWORD(hwnd)]))
     {
         ret = ((ptr->dwMagic == WND_MAGIC) && (!HIWORD(hwnd) || hwnd == ptr->hwndSelf));
+        USER_Unlock();
+        return ret;
     }
     USER_Unlock();
 
-    if (!ret)  /* check other processes */
+    /* check other processes */
+    SERVER_START_REQ( get_window_info )
     {
-        SERVER_START_REQ( get_window_info )
-        {
-            req->handle = hwnd;
-            ret = !SERVER_CALL_ERR();
-        }
-        SERVER_END_REQ;
+        req->handle = hwnd;
+        ret = !SERVER_CALL_ERR();
     }
+    SERVER_END_REQ;
     return ret;
 }
 
@@ -2601,9 +2626,8 @@
     WND *wndPtr =WIN_FindWndPtr(hwnd);
     if (!wndPtr) return hwnd;
     retval = wndPtr->hwndLastActive;
+    if (!IsWindow( retval )) retval = wndPtr->hwndSelf;
     WIN_ReleaseWndPtr(wndPtr);
-    if ((retval != hwnd) && (!IsWindow(retval)))
-       retval = hwnd;
     return retval;
 }
 
diff --git a/windows/winpos.c b/windows/winpos.c
index 8a9be5e..843864a 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -374,6 +374,7 @@
 
     if (!hwndScope) hwndScope = GetDesktopWindow();
     if (!(wndScope = WIN_FindWndPtr( hwndScope ))) return 0;
+    hwndScope = wndScope->hwndSelf;  /* make it a full handle */
 
     *hittest = HTERROR;
     wndPtr = WIN_LockWndPtr(wndScope->child);
@@ -892,7 +893,7 @@
 HWND WINAPI SetShellWindow(HWND hwndshell)
 {   WARN("(hWnd=%08x) semi stub\n",hwndshell );
 
-    hGlobalShellWindow = hwndshell;
+    hGlobalShellWindow = WIN_GetFullHandle( hwndshell );
     return hGlobalShellWindow;
 }
 
@@ -1423,6 +1424,9 @@
             hwndActive = PERQDATA_GetActiveWnd( pOldActiveQueue->pQData );
     }
 
+    if ((wndPtr = WIN_FindWndPtr(hWnd)))
+        hWnd = wndPtr->hwndSelf;  /* make it a full handle */
+
     /* paranoid checks */
     if( hWnd == GetDesktopWindow() || (bRet = (hWnd == hwndActive)) )
 	goto CLEANUP_END;
@@ -1430,7 +1434,6 @@
 /*  if (wndPtr && (GetFastQueue16() != wndPtr->hmemTaskQ))
  *	return 0;
  */
-    wndPtr = WIN_FindWndPtr(hWnd);
     hOldActiveQueue = hActiveQueue;
 
     if( (wndTemp = WIN_FindWndPtr(hwndActive)) )