Fix bug #129. Unfortunetly this causes another bug to appear (that is not caused...
[reactos.git] / reactos / subsys / win32k / ntuser / winpos.c
index 77bf801..5cb1e75 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: winpos.c,v 1.43 2003/11/20 09:18:49 navaraf Exp $
+/* $Id: winpos.c,v 1.83 2004/01/21 18:39:24 navaraf Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -29,6 +29,7 @@
 /* INCLUDES ******************************************************************/
 
 #include <ddk/ntddk.h>
+#include <internal/safe.h>
 #include <win32k/win32k.h>
 #include <include/object.h>
 #include <include/guicheck.h>
 #include <include/class.h>
 #include <include/error.h>
 #include <include/winsta.h>
-#include <windows.h>
+#include <include/desktop.h>
 #include <include/winpos.h>
 #include <include/rect.h>
 #include <include/callback.h>
 #include <include/painting.h>
 #include <include/dce.h>
 #include <include/vis.h>
+#include <include/focus.h>
 
 #define NDEBUG
 #include <debug.h>
 #define  SWP_AGG_STATUSFLAGS \
     (SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
 
-ATOM AtomInternalPos = (ATOM) NULL;
-
 /* FUNCTIONS *****************************************************************/
 
 #define HAS_DLGFRAME(Style, ExStyle) \
-       (((ExStyle) & WS_EX_DLGMODALFRAME) || \
-        (((Style) & WS_DLGFRAME) && !((Style) & WS_BORDER)))
+            (((ExStyle) & WS_EX_DLGMODALFRAME) || \
+            (((Style) & WS_DLGFRAME) && (!((Style) & WS_THICKFRAME))))
 
 #define HAS_THICKFRAME(Style, ExStyle) \
-       (((Style) & WS_THICKFRAME) && \
-        !((Style) & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)
+            (((Style) & WS_THICKFRAME) && \
+            (!(((Style) & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)))
 
-VOID FASTCALL
-WinPosSetupInternalPos(VOID)
-{
-  AtomInternalPos = NtAddAtom(L"SysIP", (ATOM*)(PULONG)&AtomInternalPos);
-}
+#define HAS_THINFRAME(Style, ExStyle) \
+            (((Style) & WS_BORDER) || (!((Style) & (WS_CHILD | WS_POPUP))))
 
-BOOL STDCALL
-NtUserGetClientOrigin(HWND hWnd, LPPOINT Point)
+BOOL FASTCALL
+IntGetClientOrigin(HWND hWnd, LPPOINT Point)
 {
   PWINDOW_OBJECT WindowObject;
-
+  
   WindowObject = IntGetWindowObject(hWnd);
   if (WindowObject == NULL)
     {
       Point->x = Point->y = 0;
-      return(TRUE);
+      return FALSE;
     }
   Point->x = WindowObject->ClientRect.left;
   Point->y = WindowObject->ClientRect.top;
-  return(TRUE);
+  
+  IntReleaseWindowObject(WindowObject);
+  return TRUE;
 }
 
-/*******************************************************************
- *         can_activate_window
- *
- * Check if we can activate the specified window.
- */
-static BOOL FASTCALL
-can_activate_window(HWND hwnd)
+BOOL STDCALL
+NtUserGetClientOrigin(HWND hWnd, LPPOINT Point)
 {
-  LONG style;
-
-  if (! hwnd)
-    {
-      return FALSE;
-    }
-  style = NtUserGetWindowLong(hwnd, GWL_STYLE, FALSE);
-  if (! (style & WS_VISIBLE))
-    {
-      return FALSE;
-    }
-  if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD)
-    {
-      return FALSE;
-    }
-  return ! (style & WS_DISABLED);
+  BOOL Ret;
+  POINT pt;
+  NTSTATUS Status;
+  
+  Ret = IntGetClientOrigin(hWnd, &pt);
+  
+  Status = MmCopyToCaller(Point, &pt, sizeof(POINT));
+  if(!NT_SUCCESS(Status))
+  {
+    SetLastNtError(Status);
+    return FALSE;
+  }
+  
+  return Ret;
 }
 
 /*******************************************************************
@@ -126,140 +118,107 @@ can_activate_window(HWND hwnd)
  *
  *  Activates window other than pWnd.
  */
-void FASTCALL
+VOID FASTCALL
 WinPosActivateOtherWindow(PWINDOW_OBJECT Window)
 {
-  HWND hwndTo;
-#if 0
-  HWND fg;
-#endif
-
-  if ((NtUserGetWindowLong(Window->Self, GWL_STYLE, FALSE) & WS_POPUP)
-      && (hwndTo = NtUserGetWindow(Window->Self, GW_OWNER)))
-    {
-      hwndTo = NtUserGetAncestor(hwndTo, GA_ROOT);
-      if (can_activate_window(hwndTo)) goto done;
-    }
+  PWINDOW_OBJECT Child;
+  PWINDOW_OBJECT TabooWindow = Window;
 
-  hwndTo = Window->Self;
   for (;;)
     {
-      if (!(hwndTo = NtUserGetWindow(hwndTo, GW_HWNDNEXT)))
+      if (NULL == Window || IntIsDesktopWindow(Window))
         {
-          break;
+          IntSetFocusMessageQueue(NULL);
+          return;
         }
-      if (can_activate_window(hwndTo))
+      Window = Window->Parent;
+      ExAcquireFastMutex(&(Window->ChildrenListLock));
+      Child = Window->FirstChild;
+      while (NULL != Child)
         {
-          break;
-        }
-    }
-
-done:
-#ifdef TODO
-  fg = NtUserGetForegroundWindow();
-/*    TRACE("win = %p fg = %p\n", hwndTo, fg); */
-  if (! fg || (hwnd == fg))
-    {
-      if (NtUserSetForegroundWindow(hwndTo))
-        {
-          return;
+          if (Child != TabooWindow)
+            {
+              ExReleaseFastMutex(&(Window->ChildrenListLock));
+              if (IntSetForegroundWindow(Child))
+                {
+                  return;
+                }
+              ExAcquireFastMutex(&(Window->ChildrenListLock));
+            }
+          Child = Child->NextSibling;
         }
-    }
-#endif
-
-  if (! NtUserSetActiveWindow(hwndTo))
-    {
-      NtUserSetActiveWindow(NULL);
+      ExReleaseFastMutex(&(Window->ChildrenListLock));
     }
 }
 
-POINT STATIC FASTCALL
-WinPosFindIconPos(HWND hWnd, POINT Pos)
+VOID STATIC FASTCALL
+WinPosFindIconPos(HWND hWnd, POINT *Pos)
 {
-  POINT point;
-  //FIXME
-  return point;
+  /* FIXME */
 }
 
-HWND STATIC FASTCALL
-WinPosNtGdiIconTitle(PWINDOW_OBJECT WindowObject)
-{
-  return(NULL);
-}
-
-BOOL STATIC FASTCALL
-WinPosShowIconTitle(PWINDOW_OBJECT WindowObject, BOOL Show)
+PINTERNALPOS FASTCALL
+WinPosInitInternalPos(PWINDOW_OBJECT WindowObject, POINT pt, PRECT RestoreRect)
 {
-  PINTERNALPOS InternalPos = (PINTERNALPOS)IntGetProp(WindowObject, AtomInternalPos);
-  PWINDOW_OBJECT IconWindow;
-  NTSTATUS Status;
-
-  if (InternalPos)
+  INT XInc, YInc;
+  
+  if (WindowObject->InternalPos == NULL)
     {
-      HWND hWnd = InternalPos->IconTitle;
-
-      if (hWnd == NULL)
-       {
-         hWnd = WinPosNtGdiIconTitle(WindowObject);
-       }
-      if (Show)
-       {
-         Status = 
-           ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->
-                                      HandleTable,
-                                      hWnd,
-                                      otWindow,
-                                      (PVOID*)&IconWindow);
-         if (NT_SUCCESS(Status))
-           {
-             if (!(IconWindow->Style & WS_VISIBLE))
-               {
-                 NtUserSendMessage(hWnd, WM_SHOWWINDOW, TRUE, 0);
-                 WinPosSetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE |
-                                    SWP_NOMOVE | SWP_NOACTIVATE | 
-                                    SWP_NOZORDER | SWP_SHOWWINDOW);
-               }
-             ObmDereferenceObject(IconWindow);
-           }
-       }
+      RECT WorkArea;
+      PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop; /* Or rather get it from the window? */
+      
+      if(IntIsDesktopWindow(WindowObject->Parent))
+        WorkArea = *IntGetDesktopWorkArea(Desktop);
       else
+        WorkArea = WindowObject->Parent->ClientRect;
+      
+      WindowObject->InternalPos = ExAllocatePool(NonPagedPool, sizeof(INTERNALPOS));
+      if(!WindowObject->InternalPos)
+      {
+        DPRINT1("Failed to allocate INTERNALPOS structure for window 0x%x\n", WindowObject->Self);
+        return NULL;
+      }
+      WindowObject->InternalPos->NormalRect = WindowObject->WindowRect;
+      if (HAS_DLGFRAME(WindowObject->Style, WindowObject->ExStyle) && !(WindowObject->Style & WS_MINIMIZE))
+      {
+        XInc = NtUserGetSystemMetrics(SM_CXDLGFRAME);
+        YInc = NtUserGetSystemMetrics(SM_CYDLGFRAME);
+      }
+      else
+      {
+        XInc = YInc = 0;
+        if (HAS_THICKFRAME(WindowObject->Style, WindowObject->ExStyle)&& !(WindowObject->Style & WS_MINIMIZE))
+        {
+          XInc += NtUserGetSystemMetrics(SM_CXFRAME);
+          YInc += NtUserGetSystemMetrics(SM_CYFRAME);
+        }
+        else if (HAS_THINFRAME(WindowObject->Style, WindowObject->ExStyle))
        {
-         WinPosShowWindow(hWnd, SW_HIDE);
+         XInc += NtUserGetSystemMetrics(SM_CXBORDER);
+         YInc += NtUserGetSystemMetrics(SM_CYBORDER);
        }
-    }
-  return(FALSE);
-}
-
-PINTERNALPOS STATIC STDCALL
-WinPosInitInternalPos(PWINDOW_OBJECT WindowObject, POINT pt, PRECT RestoreRect)
-{
-  PINTERNALPOS InternalPos = (PINTERNALPOS)IntGetProp(WindowObject, AtomInternalPos);
-  if (InternalPos == NULL)
-    {
-      InternalPos = 
-       ExAllocatePool(NonPagedPool, sizeof(INTERNALPOS));
-      IntSetProp(WindowObject, AtomInternalPos, InternalPos);
-      InternalPos->IconTitle = 0;
-      InternalPos->NormalRect = WindowObject->WindowRect;
-      InternalPos->IconPos.x = InternalPos->MaxPos.x = 0xFFFFFFFF;
-      InternalPos->IconPos.y = InternalPos->MaxPos.y = 0xFFFFFFFF;
+      }
+      WindowObject->InternalPos->MaxPos.x = WorkArea.left - XInc;
+      WindowObject->InternalPos->MaxPos.y = WorkArea.top - YInc;
+      WindowObject->InternalPos->IconPos.x = WorkArea.left;
+      WindowObject->InternalPos->IconPos.y = WorkArea.bottom - NtUserGetSystemMetrics(SM_CYMINIMIZED);
     }
   if (WindowObject->Style & WS_MINIMIZE)
     {
-      InternalPos->IconPos = pt;
+      WindowObject->InternalPos->IconPos = pt;
     }
   else if (WindowObject->Style & WS_MAXIMIZE)
     {
-      InternalPos->MaxPos = pt;
+      WindowObject->InternalPos->MaxPos = pt;
     }
   else if (RestoreRect != NULL)
     {
-      InternalPos->NormalRect = *RestoreRect;
+      WindowObject->InternalPos->NormalRect = *RestoreRect;
     }
-  return(InternalPos);
+  return(WindowObject->InternalPos);
 }
 
-UINT STDCALL
+UINT FASTCALL
 WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos)
 {
   POINT Size;
@@ -275,7 +234,7 @@ WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos)
     {
       if (WindowObject->Style & WS_MINIMIZE)
        {
-         if (!NtUserSendMessage(WindowObject->Self, WM_QUERYOPEN, 0, 0))
+         if (!IntSendMessage(WindowObject->Self, WM_QUERYOPEN, 0, 0))
            {
              return(SWP_NOSIZE | SWP_NOMOVE);
            }
@@ -292,14 +251,15 @@ WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos)
              }
            else
              {
-               WindowObject->Style &= ~WINDOWOBJECT_RESTOREMAX;
+               WindowObject->Flags &= ~WINDOWOBJECT_RESTOREMAX;
              }
+           IntRedrawWindow(WindowObject, NULL, 0, RDW_VALIDATE | RDW_NOERASE |
+              RDW_NOINTERNALPAINT);
            WindowObject->Style |= WS_MINIMIZE;
-           InternalPos->IconPos = WinPosFindIconPos(WindowObject,
-                                                    InternalPos->IconPos);
+           WinPosFindIconPos(WindowObject, &InternalPos->IconPos);
            NtGdiSetRect(NewPos, InternalPos->IconPos.x, InternalPos->IconPos.y,
-                       NtUserGetSystemMetrics(SM_CXICON),
-                       NtUserGetSystemMetrics(SM_CYICON));
+                       NtUserGetSystemMetrics(SM_CXMINIMIZED),
+                       NtUserGetSystemMetrics(SM_CYMINIMIZED));
            SwpFlags |= SWP_NOCOPYBITS;
            break;
          }
@@ -308,12 +268,13 @@ WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos)
          {
            WinPosGetMinMaxInfo(WindowObject, &Size, &InternalPos->MaxPos, 
                                NULL, NULL);
+           DPRINT1("Maximize: %d,%d %dx%d\n",
+              InternalPos->MaxPos.x, InternalPos->MaxPos.y, Size.x, Size.y);
            if (WindowObject->Style & WS_MINIMIZE)
              {
-               WinPosShowIconTitle(WindowObject, FALSE);
                WindowObject->Style &= ~WS_MINIMIZE;
              }
-           WindowObject->Style |= WS_MINIMIZE;
+           WindowObject->Style |= WS_MAXIMIZE;
            NtGdiSetRect(NewPos, InternalPos->MaxPos.x, InternalPos->MaxPos.y,
                        Size.x, Size.y);
            break;
@@ -324,7 +285,6 @@ WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos)
            if (WindowObject->Style & WS_MINIMIZE)
              {
                WindowObject->Style &= ~WS_MINIMIZE;
-               WinPosShowIconTitle(WindowObject, FALSE);
                if (WindowObject->Flags & WINDOWOBJECT_RESTOREMAX)
                  {
                    WinPosGetMinMaxInfo(WindowObject, &Size,
@@ -334,17 +294,21 @@ WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos)
                                InternalPos->MaxPos.y, Size.x, Size.y);
                    break;
                  }
+               else
+                 {
+                   *NewPos = InternalPos->NormalRect;
+                   NewPos->right -= NewPos->left;
+                   NewPos->bottom -= NewPos->top;
+                   break;
+                 }
              }
            else
              {
                if (!(WindowObject->Style & WS_MAXIMIZE))
                  {
-                   return(-1);
+                   return 0;
                  }
-               else
-                 {
-                   WindowObject->Style &= ~WS_MAXIMIZE;
-                 }           
+               WindowObject->Style &= ~WS_MAXIMIZE;
                *NewPos = InternalPos->NormalRect;
                NewPos->right -= NewPos->left;
                NewPos->bottom -= NewPos->top;
@@ -360,21 +324,22 @@ WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos)
   return(SwpFlags);
 }
 
-UINT STDCALL
-WinPosGetMinMaxInfo(PWINDOW_OBJECT Window, POINT* MaxSize, POINT* MaxPos,
-                   POINT* MinTrack, POINT* MaxTrack)
+VOID FASTCALL
+WinPosFillMinMaxInfoStruct(PWINDOW_OBJECT Window, MINMAXINFO *Info)
 {
-  MINMAXINFO MinMax;
   INT XInc, YInc;
-  INTERNALPOS* Pos;
-
+  RECT WorkArea;
+  PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop; /* Or rather get it from the window? */
+  
+  WorkArea = *IntGetDesktopWorkArea(Desktop);
+  
   /* Get default values. */
-  MinMax.ptMaxSize.x = NtUserGetSystemMetrics(SM_CXSCREEN);
-  MinMax.ptMaxSize.y = NtUserGetSystemMetrics(SM_CYSCREEN);
-  MinMax.ptMinTrackSize.x = NtUserGetSystemMetrics(SM_CXMINTRACK);
-  MinMax.ptMinTrackSize.y = NtUserGetSystemMetrics(SM_CYMINTRACK);
-  MinMax.ptMaxTrackSize.x = NtUserGetSystemMetrics(SM_CXSCREEN);
-  MinMax.ptMaxTrackSize.y = NtUserGetSystemMetrics(SM_CYSCREEN);
+  Info->ptMaxSize.x = WorkArea.right - WorkArea.left;
+  Info->ptMaxSize.y = WorkArea.bottom - WorkArea.top;
+  Info->ptMinTrackSize.x = NtUserGetSystemMetrics(SM_CXMINTRACK);
+  Info->ptMinTrackSize.y = NtUserGetSystemMetrics(SM_CYMINTRACK);
+  Info->ptMaxTrackSize.x = Info->ptMaxSize.x;
+  Info->ptMaxTrackSize.y = Info->ptMaxSize.y;
 
   if (HAS_DLGFRAME(Window->Style, Window->ExStyle))
     {
@@ -389,27 +354,35 @@ WinPosGetMinMaxInfo(PWINDOW_OBJECT Window, POINT* MaxSize, POINT* MaxPos,
          XInc += NtUserGetSystemMetrics(SM_CXFRAME);
          YInc += NtUserGetSystemMetrics(SM_CYFRAME);
        }
-      if (Window->Style & WS_BORDER)
+      else if (HAS_THINFRAME(Window->Style, Window->ExStyle))
        {
          XInc += NtUserGetSystemMetrics(SM_CXBORDER);
          YInc += NtUserGetSystemMetrics(SM_CYBORDER);
        }
     }
-  MinMax.ptMaxSize.x += 2 * XInc;
-  MinMax.ptMaxSize.y += 2 * YInc;
+  Info->ptMaxSize.x += 2 * XInc;
+  Info->ptMaxSize.y += 2 * YInc;
 
-  Pos = (PINTERNALPOS)IntGetProp(Window, AtomInternalPos);
-  if (Pos != NULL)
+  if (Window->InternalPos != NULL)
     {
-      MinMax.ptMaxPosition = Pos->MaxPos;
+      Info->ptMaxPosition = Window->InternalPos->MaxPos;
     }
   else
     {
-      MinMax.ptMaxPosition.x -= XInc;
-      MinMax.ptMaxPosition.y -= YInc;
+      Info->ptMaxPosition.x -= WorkArea.left + XInc;
+      Info->ptMaxPosition.y -= WorkArea.top + YInc;
     }
+}
 
-  IntSendMessage(Window->Self, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax, TRUE);
+UINT FASTCALL
+WinPosGetMinMaxInfo(PWINDOW_OBJECT Window, POINT* MaxSize, POINT* MaxPos,
+                   POINT* MinTrack, POINT* MaxTrack)
+{
+  MINMAXINFO MinMax;
+  
+  WinPosFillMinMaxInfoStruct(Window, &MinMax);
+  
+  IntSendMessage(Window->Self, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax);
 
   MinMax.ptMaxTrackSize.x = max(MinMax.ptMaxTrackSize.x,
                                MinMax.ptMinTrackSize.x);
@@ -424,29 +397,7 @@ WinPosGetMinMaxInfo(PWINDOW_OBJECT Window, POINT* MaxSize, POINT* MaxPos,
   return 0; //FIXME: what does it return?
 }
 
-BOOL STATIC FASTCALL
-WinPosChangeActiveWindow(HWND hWnd, BOOL MouseMsg)
-{
-  PWINDOW_OBJECT WindowObject;
-
-  WindowObject = IntGetWindowObject(hWnd);
-  if (WindowObject == NULL)
-    {
-      return FALSE;
-    }
-
-  NtUserSendMessage(hWnd,
-    WM_ACTIVATE,
-         MAKELONG(MouseMsg ? WA_CLICKACTIVE : WA_CLICKACTIVE,
-      (WindowObject->Style & WS_MINIMIZE) ? 1 : 0),
-      (LPARAM)IntGetDesktopWindow());  /* FIXME: Previous active window */
-
-  IntReleaseWindowObject(WindowObject);
-
-  return TRUE;
-}
-
-LONG STATIC STDCALL
+LONG STATIC FASTCALL
 WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
                   RECT* WindowRect, RECT* ClientRect)
 {
@@ -473,7 +424,7 @@ WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
       params.lppos = &winposCopy;
       winposCopy = *WinPos;
 
-      wvrFlags = IntSendNCCALCSIZEMessage(Window->Self, TRUE, NULL, &params);
+      wvrFlags = IntSendMessage(Window->Self, WM_NCCALCSIZE, TRUE, (LPARAM) &params);
 
       /* If the application send back garbage, ignore it */
       if (params.rgrc[0].left <= params.rgrc[0].right &&
@@ -516,7 +467,7 @@ WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
   return wvrFlags;
 }
 
-BOOL STDCALL
+BOOL FASTCALL
 WinPosDoWinPosChanging(PWINDOW_OBJECT WindowObject,
                       PWINDOWPOS WinPos,
                       PRECT WindowRect,
@@ -526,13 +477,11 @@ WinPosDoWinPosChanging(PWINDOW_OBJECT WindowObject,
 
   if (!(WinPos->flags & SWP_NOSENDCHANGING))
     {
-      IntSendWINDOWPOSCHANGINGMessage(WindowObject->Self, WinPos);
+      IntSendMessage(WindowObject->Self, WM_WINDOWPOSCHANGING, 0, (LPARAM) WinPos);
     }
   
   *WindowRect = WindowObject->WindowRect;
-  *ClientRect = 
-    (WindowObject->Style & WS_MINIMIZE) ? WindowObject->WindowRect :
-    WindowObject->ClientRect;
+  *ClientRect = WindowObject->ClientRect;
 
   if (!(WinPos->flags & SWP_NOSIZE))
     {
@@ -570,7 +519,62 @@ WinPosDoWinPosChanging(PWINDOW_OBJECT WindowObject,
 HWND FASTCALL
 WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter)
 {
-   /* FIXME */
+   HWND *List = NULL;
+   HWND Owner = NtUserGetWindow(hWnd, GW_OWNER);
+   LONG Style = NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE);
+   PWINDOW_OBJECT DesktopWindow;
+   int i;
+
+   if ((Style & WS_POPUP) && Owner)
+   {
+      /* Make sure this popup stays above the owner */
+      HWND hWndLocalPrev = HWND_TOP;
+
+      if (hWndInsertAfter != HWND_TOP)
+      {
+         DesktopWindow = IntGetWindowObject(IntGetDesktopWindow());
+         List = IntWinListChildren(DesktopWindow);
+         IntReleaseWindowObject(DesktopWindow);
+         if (List != NULL)
+         {
+            for (i = 0; List[i]; i++)
+            {
+               if (List[i] == Owner) break;
+               if (List[i] != hWnd) hWndLocalPrev = List[i];
+               if (hWndLocalPrev == hWndInsertAfter) break;
+            }
+            hWndInsertAfter = hWndLocalPrev;
+         }
+      }
+   }
+   else if (Style & WS_CHILD)
+   {
+      return hWndInsertAfter;
+   }
+
+   if (!List)
+   {
+      DesktopWindow = IntGetWindowObject(IntGetDesktopWindow());
+      List = IntWinListChildren(DesktopWindow);
+      IntReleaseWindowObject(DesktopWindow);
+   }
+   if (List != NULL)
+   {
+      for (i = 0; List[i]; i++)
+      {
+         if (List[i] == hWnd)
+            break;
+         if ((NtUserGetWindowLong(List[i], GWL_STYLE, FALSE) & WS_POPUP) &&
+             NtUserGetWindow(List[i], GW_OWNER) == hWnd)
+         {
+            WinPosSetWindowPos(List[i], hWndInsertAfter, 0, 0, 0, 0,
+               SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
+            hWndInsertAfter = List[i];
+         }
+      }
+      ExFreePool(List);
+   }
+
    return hWndInsertAfter;
 }
 
@@ -580,7 +584,7 @@ WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter)
  * Update WindowRect and ClientRect of Window and all of its children
  * We keep both WindowRect and ClientRect in screen coordinates internally
  */
-static VOID
+VOID STATIC FASTCALL
 WinPosInternalMoveWindow(PWINDOW_OBJECT Window, INT MoveX, INT MoveY)
 {
   PWINDOW_OBJECT Child;
@@ -642,14 +646,11 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWINDOW_OBJECT Window)
       WinPos->flags |= SWP_NOMOVE;    
    }
 
-   /* FIXME: We don't have NtUserGetForegroundWindow yet. */
-#if 0
    if (WinPos->hwnd == NtUserGetForegroundWindow())
    {
       WinPos->flags |= SWP_NOACTIVATE;   /* Already active */
    }
    else
-#endif
    if ((Window->Style & (WS_POPUP | WS_CHILD)) != WS_CHILD)
    {
       /* Bring to the top when activating */
@@ -686,7 +687,7 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWINDOW_OBJECT Window)
           (WinPos->hwndInsertAfter != HWND_BOTTOM))
       {
          if (NtUserGetAncestor(WinPos->hwndInsertAfter, GA_PARENT) !=
-             Window->Parent)
+             Window->Parent->Self)
          {
             return FALSE;
          }
@@ -710,7 +711,7 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWINDOW_OBJECT Window)
 }
 
 /* x and y are always screen relative */
-BOOLEAN STDCALL
+BOOLEAN FASTCALL
 WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
                   INT cy, UINT flags)
 {
@@ -732,19 +733,22 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
 
    /* FIXME: Get current active window from active queue. */
 
-   /* Check if the window is for a desktop. */
-   if (Wnd == IntGetDesktopWindow())
+   Window = IntGetWindowObject(Wnd);
+   if (!Window)
    {
+      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
       return FALSE;
    }
 
-   Window = IntGetWindowObject(Wnd);
-   if (!Window)
+   /*
+    * Only allow CSRSS to mess with the desktop window
+    */
+   if (Wnd == IntGetDesktopWindow() &&
+       Window->OwnerThread->ThreadsProcess != PsGetCurrentProcess())
    {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
       return FALSE;
    }
-  
+
    WinPos.hwnd = Wnd;
    WinPos.hwndInsertAfter = WndInsertAfter;
    WinPos.x = x;
@@ -752,11 +756,8 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
    WinPos.cx = cx;
    WinPos.cy = cy;
    WinPos.flags = flags;
-   if (Window->Style & WS_CHILD)
-   {
-      WinPos.x -= Window->Parent->ClientRect.left;
-      WinPos.y -= Window->Parent->ClientRect.top;
-   }
+
+   WinPosDoWinPosChanging(Window, &WinPos, &NewWindowRect, &NewClientRect);
 
    /* Fix up the flags. */
    if (!WinPosFixupFlags(&WinPos, Window))
@@ -766,12 +767,10 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
       return FALSE;
    }
 
-   WinPosDoWinPosChanging(Window, &WinPos, &NewWindowRect, &NewClientRect);
-
    /* Does the window still exist? */
    if (!IntIsWindow(WinPos.hwnd))
    {
-      /* FIXME: SetLastWin32Error */
+      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
       return FALSE;
    }
 
@@ -783,16 +782,15 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
    }
   
    /* Compute the visible region before the window position is changed */
-   if ((!(WinPos.flags & (SWP_NOREDRAW | SWP_SHOWWINDOW)) &&
-       WinPos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | 
-                       SWP_HIDEWINDOW | SWP_FRAMECHANGED)) != 
+   if (!(WinPos.flags & (SWP_NOREDRAW | SWP_SHOWWINDOW)) &&
+       (WinPos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | 
+                        SWP_HIDEWINDOW | SWP_FRAMECHANGED)) != 
        (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER))
    {
-      VisBefore = VIS_ComputeVisibleRegion(
-         PsGetWin32Thread()->Desktop, Window, FALSE,
-         Window->Style & WS_CLIPCHILDREN, Window->Style & WS_CLIPSIBLINGS);
+      VisBefore = VIS_ComputeVisibleRegion(Window, FALSE, FALSE, TRUE);
 
-      if (UnsafeIntGetRgnBox(VisBefore, &TempRect) == NULLREGION)
+      if (VisBefore != NULL &&
+          UnsafeIntGetRgnBox(VisBefore, &TempRect) == NULLREGION)
       {
          NtGdiDeleteObject(VisBefore);
          VisBefore = NULL;
@@ -810,16 +808,21 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
       ParentWindow = Window->Parent;
       if (ParentWindow)
       {
-         if (WndInsertAfter == HWND_TOP)
+         if (WinPos.hwndInsertAfter == HWND_TOP)
             InsertAfterWindow = NULL;
-         else if (WndInsertAfter == HWND_BOTTOM)
-            InsertAfterWindow = ParentWindow->LastChild;
+         else if (WinPos.hwndInsertAfter == HWND_BOTTOM)
+            InsertAfterWindow = IntGetWindowObject(ParentWindow->LastChild->Self);
          else
             InsertAfterWindow = IntGetWindowObject(WinPos.hwndInsertAfter);
-         ExAcquireFastMutexUnsafe(&ParentWindow->ChildrenListLock);
-         IntUnlinkWindow(Window);
-         IntLinkWindow(Window, ParentWindow, InsertAfterWindow);
-         ExReleaseFastMutexUnsafe(&ParentWindow->ChildrenListLock);
+         /* Do nothing if hwndInsertAfter is HWND_BOTTOM and Window is already
+            the last window */
+         if (InsertAfterWindow != Window)
+         {
+             ExAcquireFastMutexUnsafe(&ParentWindow->ChildrenListLock);
+             IntUnlinkWindow(Window);
+             IntLinkWindow(Window, ParentWindow, InsertAfterWindow);
+             ExReleaseFastMutexUnsafe(&ParentWindow->ChildrenListLock);
+         }
          if (InsertAfterWindow != NULL)
             IntReleaseWindowObject(InsertAfterWindow);
       }
@@ -844,7 +847,9 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
 
    /* FIXME: Actually do something with WVR_VALIDRECTS */
 
-   if (!(WinPos.flags & SWP_NOMOVE))
+   if (! (WinPos.flags & SWP_NOMOVE)
+       && (NewWindowRect.left != OldWindowRect.left
+           || NewWindowRect.top != OldWindowRect.top))
    {
       WinPosInternalMoveWindow(Window,
                                NewWindowRect.left - OldWindowRect.left,
@@ -861,32 +866,16 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
                       RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ALLCHILDREN);
       Window->Style &= ~WS_VISIBLE;
    }
-   else
+   else if (WinPos.flags & SWP_SHOWWINDOW)
    {
       Window->Style |= WS_VISIBLE;
    }
 
-#if 0
-   if (WvrFlags & WVR_REDRAW)
-   {
-      IntRedrawWindow(Window, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME);
-   }
-#endif
-
-   if (!(WinPos.flags & SWP_NOACTIVATE))
-   {
-      WinPosChangeActiveWindow(WinPos.hwnd, FALSE);
-   }
-
-   /* FIXME: Check some conditions before doing this. */
-   IntSendWINDOWPOSCHANGEDMessage(WinPos.hwnd, &WinPos);
-
    /* Determine the new visible region */
-   VisAfter = VIS_ComputeVisibleRegion(
-      PsGetWin32Thread()->Desktop, Window, FALSE,
-      Window->Style & WS_CLIPCHILDREN, Window->Style & WS_CLIPSIBLINGS);
+   VisAfter = VIS_ComputeVisibleRegion(Window, FALSE, FALSE, TRUE);
 
-   if (UnsafeIntGetRgnBox(VisAfter, &TempRect) == NULLREGION)
+   if (VisAfter != NULL &&
+       UnsafeIntGetRgnBox(VisAfter, &TempRect) == NULLREGION)
    {
       NtGdiDeleteObject(VisAfter);
       VisAfter = NULL;
@@ -900,7 +889,7 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
     * change.
     */
    if (VisBefore != NULL && VisAfter != NULL && !(WinPos.flags & SWP_NOCOPYBITS) &&
-       ((WinPos.flags & SWP_NOSIZE) || !(Window->Class->style & (CS_HREDRAW | CS_VREDRAW))))
+       ((WinPos.flags & SWP_NOSIZE) || !(WvrFlags & WVR_REDRAW)))
    {
       CopyRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
       RgnType = NtGdiCombineRgn(CopyRgn, VisAfter, VisBefore, RGN_AND);
@@ -929,6 +918,10 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
       {
          NtGdiCombineRgn(CopyRgn, CopyRgn, Window->UpdateRegion, RGN_DIFF);
       }
+      if (Window->NCUpdateRegion != NULL)
+      {
+         NtGdiCombineRgn(CopyRgn, CopyRgn, Window->NCUpdateRegion, RGN_DIFF);
+      }
                  
       /*
        * Now, get the bounding box of the copy region. If it's empty
@@ -954,6 +947,7 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
           * to create a copy of CopyRgn and pass that. We need CopyRgn later 
           */
          HRGN ClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
+
          NtGdiCombineRgn(ClipRgn, CopyRgn, NULL, RGN_COPY);
          Dc = NtUserGetDCEx(Wnd, ClipRgn, DCX_WINDOW | DCX_CACHE |
             DCX_INTERSECTRGN | DCX_CLIPSIBLINGS);
@@ -963,6 +957,7 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
             CopyRect.left + (OldWindowRect.left - NewWindowRect.left),
             CopyRect.top + (OldWindowRect.top - NewWindowRect.top), SRCCOPY);
          NtUserReleaseDC(Wnd, Dc);
+         IntValidateParent(Window, CopyRgn);
       }
    }
    else
@@ -973,25 +968,24 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
    /* We need to redraw what wasn't visible before */
    if (VisAfter != NULL)
    {
+      DirtyRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
       if (CopyRgn != NULL)
       {
-         DirtyRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
          RgnType = NtGdiCombineRgn(DirtyRgn, VisAfter, CopyRgn, RGN_DIFF);
-         if (RgnType != ERROR && RgnType != NULLREGION)
-         {
-            NtGdiOffsetRgn(DirtyRgn,
-               Window->WindowRect.left - Window->ClientRect.left,
-               Window->WindowRect.top - Window->ClientRect.top);
-            IntRedrawWindow(Window, NULL, DirtyRgn,
-               RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
-         }
-         NtGdiDeleteObject(DirtyRgn);
       }
       else
       {
-         IntRedrawWindow(Window, NULL, NULL,
+         RgnType = NtGdiCombineRgn(DirtyRgn, VisAfter, 0, RGN_COPY);
+      }
+      if (RgnType != ERROR && RgnType != NULLREGION)
+      {
+         NtGdiOffsetRgn(DirtyRgn,
+            Window->WindowRect.left - Window->ClientRect.left,
+            Window->WindowRect.top - Window->ClientRect.top);
+         IntRedrawWindow(Window, NULL, DirtyRgn,
             RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
       }
+      NtGdiDeleteObject(DirtyRgn);
    }
 
    if (CopyRgn != NULL)
@@ -1013,8 +1007,7 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
 
       if (RgnType != ERROR && RgnType != NULLREGION)
       {
-         VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, Window,
-            ExposedRgn);
+         VIS_WindowLayoutChanged(Window, ExposedRgn);
       }
       NtGdiDeleteObject(ExposedRgn);
       NtGdiDeleteObject(VisBefore);
@@ -1025,16 +1018,36 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
       NtGdiDeleteObject(VisAfter);
    }
 
+   if (!(WinPos.flags & SWP_NOREDRAW))
+   {
+      IntRedrawWindow(Window, NULL, 0, RDW_ALLCHILDREN | RDW_ERASENOW);
+   }
+
+   if (!(WinPos.flags & SWP_NOACTIVATE))
+   {
+      if ((Window->Style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
+      {
+         IntSendMessage(WinPos.hwnd, WM_CHILDACTIVATE, 0, 0);
+      }
+      else
+      {
+         IntSetForegroundWindow(Window);
+      }
+   }
+
+   if ((WinPos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE)
+      IntSendMessage(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM) &WinPos);
+
    IntReleaseWindowObject(Window);
 
    return TRUE;
 }
 
-LRESULT STDCALL
+LRESULT FASTCALL
 WinPosGetNonClientSize(HWND Wnd, RECT* WindowRect, RECT* ClientRect)
 {
   *ClientRect = *WindowRect;
-  return(IntSendNCCALCSIZEMessage(Wnd, FALSE, ClientRect, NULL));
+  return(IntSendMessage(Wnd, WM_NCCALCSIZE, FALSE, (LPARAM) ClientRect));
 }
 
 BOOLEAN FASTCALL
@@ -1042,13 +1055,18 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
 {
   BOOLEAN WasVisible;
   PWINDOW_OBJECT Window;
+  NTSTATUS Status;
   UINT Swp = 0;
-  RECT NewPos = {0, 0, 0, 0};
+  RECT NewPos;
   BOOLEAN ShowFlag;
-/*  HRGN VisibleRgn;*/
-
-  Window = IntGetWindowObject(Wnd);
-  if (!Window)
+//  HRGN VisibleRgn;
+
+  Status = 
+    ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable,
+                              Wnd,
+                              otWindow,
+                              (PVOID*)&Window);
+  if (!NT_SUCCESS(Status))
     {
       return(FALSE);
     }
@@ -1077,7 +1095,7 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
       /* Fall through. */
     case SW_MINIMIZE:
       {
-       Swp |= SWP_FRAMECHANGED;
+       Swp |= SWP_FRAMECHANGED | SWP_NOACTIVATE;
        if (!(Window->Style & WS_MINIMIZE))
          {
            Swp |= WinPosMinMaximize(Window, SW_MINIMIZE, &NewPos);
@@ -1132,7 +1150,7 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
   ShowFlag = (Cmd != SW_HIDE);
   if (ShowFlag != WasVisible)
     {
-      NtUserSendMessage(Wnd, WM_SHOWWINDOW, ShowFlag, 0);
+      IntSendMessage(Wnd, WM_SHOWWINDOW, ShowFlag, 0);
       /* 
        * FIXME: Need to check the window wasn't destroyed during the 
        * window procedure. 
@@ -1146,7 +1164,7 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
       Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
     }
 
-  WinPosSetWindowPos(Wnd, HWND_TOP, NewPos.left, NewPos.top,
+  WinPosSetWindowPos(Window->Self, HWND_TOP, NewPos.left, NewPos.top,
     NewPos.right, NewPos.bottom, LOWORD(Swp));
 
   if (Cmd == SW_HIDE)
@@ -1156,33 +1174,24 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
        * asynchronously.
        */
 
-      if (Wnd == IntGetActiveWindow())
+      if (Window->Self == NtUserGetActiveWindow())
         {
           WinPosActivateOtherWindow(Window);
         }
 
       /* Revert focus to parent */
-      if (Wnd == IntGetFocusWindow() ||
-         IntIsChildWindow(Wnd, IntGetFocusWindow()))
-       {
-         IntSetFocusWindow(Window->Parent->Self);
-       }
+      if (Wnd == IntGetThreadFocusWindow() ||
+          IntIsChildWindow(Wnd, IntGetThreadFocusWindow()))
+        {
+          NtUserSetFocus(Window->Parent->Self);
+        }
     }
 
-  if (!IntIsWindow(Wnd))
-    {
-      IntReleaseWindowObject(Window);
-      return WasVisible;
-    }
-  else if (Window->Style & WS_MINIMIZE)
-    {
-      WinPosShowIconTitle(Window, TRUE);
-    }
+  /* FIXME: Check for window destruction. */
 
   if (Window->Flags & WINDOWOBJECT_NEED_SIZE)
     {
-      /* should happen only in CreateWindowEx() */
-      int wParam = SIZE_RESTORED;
+      WPARAM wParam = SIZE_RESTORED;
 
       Window->Flags &= ~WINDOWOBJECT_NEED_SIZE;
       if (Window->Style & WS_MAXIMIZE)
@@ -1194,24 +1203,26 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
          wParam = SIZE_MINIMIZED;
        }
 
-      NtUserSendMessage(Wnd, WM_SIZE, wParam,
-                       MAKELONG(Window->ClientRect.right - 
-                                Window->ClientRect.left,
-                                Window->ClientRect.bottom -
-                                Window->ClientRect.top));
-      NtUserSendMessage(Wnd, WM_MOVE, 0,
-                       MAKELONG(Window->ClientRect.left,
-                                Window->ClientRect.top));
+      IntSendMessage(Wnd, WM_SIZE, wParam,
+                     MAKELONG(Window->ClientRect.right - 
+                              Window->ClientRect.left,
+                              Window->ClientRect.bottom -
+                              Window->ClientRect.top));
+      IntSendMessage(Wnd, WM_MOVE, 0,
+                     MAKELONG(Window->ClientRect.left,
+                              Window->ClientRect.top));
     }
 
   /* Activate the window if activation is not requested and the window is not minimized */
+/*
   if (!(Swp & (SWP_NOACTIVATE | SWP_HIDEWINDOW)) && !(Window->Style & WS_MINIMIZE))
     {
       WinPosChangeActiveWindow(Wnd, FALSE);
     }
+*/
 
-  IntReleaseWindowObject(Window);
-  return WasVisible;
+  ObmDereferenceObject(Window);
+  return(WasVisible);
 }
 
 BOOL STATIC FASTCALL
@@ -1223,7 +1234,7 @@ WinPosPtInWindow(PWINDOW_OBJECT Window, POINT Point)
         Point.y < Window->WindowRect.bottom);
 }
 
-USHORT STATIC STDCALL
+USHORT STATIC FASTCALL
 WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, POINT Point,
                     PWINDOW_OBJECT* Window)
 {
@@ -1238,17 +1249,17 @@ WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, POINT Point,
           (Current->Style & (WS_CHILD | WS_POPUP)) != WS_CHILD) &&
          WinPosPtInWindow(Current, Point))
        {
+         if(*Window)
+           ObmDereferenceObject(*Window);
+         ObmReferenceObjectByPointer(Current, otWindow);
+         
          *Window = Current;
+         
          if (Current->Style & WS_DISABLED)
            {
                  ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock);
              return(HTERROR);
            }
-         if (Current->Style & WS_MINIMIZE)
-           {
-                 ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock);
-             return(HTCAPTION);
-           }
          if (Point.x >= Current->ClientRect.left &&
              Point.x < Current->ClientRect.right &&
              Point.y >= Current->ClientRect.top &&
@@ -1269,7 +1280,7 @@ WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, POINT Point,
   return(0);
 }
 
-USHORT STDCALL
+USHORT FASTCALL
 WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, POINT WinPoint, 
                      PWINDOW_OBJECT* Window)
 {
@@ -1279,6 +1290,12 @@ WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, POINT WinPoint,
   USHORT HitTest;
 
   *Window = NULL;
+  
+  if(!ScopeWin)
+  {
+    DPRINT1("WinPosWindowFromPoint(): ScopeWin == NULL!\n");
+    return(HTERROR);
+  }
 
   if (ScopeWin->Style & WS_DISABLED)
     {
@@ -1305,7 +1322,7 @@ WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, POINT WinPoint,
   if ((*Window)->MessageQueue == PsGetWin32Thread()->MessageQueue)
     {
       HitTest = IntSendMessage((*Window)->Self, WM_NCHITTEST, 0,
-                               MAKELONG(Point.x, Point.y), FALSE);
+                               MAKELONG(Point.x, Point.y));
       /* FIXME: Check for HTTRANSPARENT here. */
     }
   else
@@ -1317,119 +1334,53 @@ WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, POINT WinPoint,
 }
 
 BOOL
-WinPosSetActiveWindow(PWINDOW_OBJECT Window, BOOL Mouse, BOOL ChangeFocus)
+STDCALL
+NtUserGetMinMaxInfo(
+  HWND hwnd,
+  MINMAXINFO *MinMaxInfo,
+  BOOL SendMessage)
 {
-  PUSER_MESSAGE_QUEUE ActiveQueue;
-  HWND PrevActive;
-
-  ActiveQueue = IntGetFocusMessageQueue();
-  if (ActiveQueue != NULL)
-    {
-      PrevActive = ActiveQueue->ActiveWindow;
-    }
-  else
-    {
-      PrevActive = NULL;
-    }
-
-  if (Window->Self == IntGetActiveDesktop() || Window->Self == PrevActive)
-    {
-      return(FALSE);
-    }
-  if (PrevActive != NULL)
-    {
-      PWINDOW_OBJECT PrevActiveWindow = IntGetWindowObject(PrevActive);
-      if(PrevActiveWindow)
-      {
-        WORD Iconised = HIWORD(PrevActiveWindow->Style & WS_MINIMIZE);
-        if (!IntSendMessage(PrevActive, WM_NCACTIVATE, FALSE, 0, TRUE))
-             {
-               /* FIXME: Check if the new window is system modal. */
-               return(FALSE);
-             }
-        IntSendMessage(PrevActive, 
-                       WM_ACTIVATE, 
-                       MAKEWPARAM(WA_INACTIVE, Iconised), 
-                       (LPARAM)Window->Self,
-                       TRUE);
-        /* FIXME: Check if anything changed while processing the message. */
-        IntReleaseWindowObject(PrevActiveWindow);
-      }
-      else
-      {
-        if(ActiveQueue)
-          ActiveQueue->ActiveWindow = NULL;
-        PrevActive = NULL;
-      }
-    }
-
-  if (Window != NULL)
-    {
-      Window->MessageQueue->ActiveWindow = Window->Self;
-    }
-  else if (ActiveQueue != NULL)
-    {
-      ActiveQueue->ActiveWindow = NULL;
-    }
-  /* FIXME:  Unset this flag for inactive windows */
-  //if ((Window->Style) & WS_CHILD) Window->Flags |= WIN_NCACTIVATED;
-
-  /* FIXME: Send palette messages. */
-
-  /* FIXME: Redraw icon title of previously active window. */
-
-  /* FIXME: Bring the window to the top. */  
-
-  /* FIXME: Send WM_ACTIVATEAPP */
+  POINT Size;
+  PINTERNALPOS InternalPos;
+  PWINDOW_OBJECT Window;
+  MINMAXINFO SafeMinMax;
+  NTSTATUS Status;
   
-  IntSetFocusMessageQueue(Window->MessageQueue);
-
-  /* FIXME: Send activate messages. */
-
-  /* FIXME: Change focus. */
-
-  /* FIXME: Redraw new window icon title. */
-
-  return(TRUE);
-}
-
-HWND STDCALL
-NtUserGetActiveWindow(VOID)
-{
-  PUSER_MESSAGE_QUEUE ActiveQueue;
-
-  ActiveQueue = IntGetFocusMessageQueue();
-  if (ActiveQueue == NULL)
+  Window = IntGetWindowObject(hwnd);
+  if(!Window)
+  {
+    SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+    return FALSE;
+  }
+
+  Size.x = Window->WindowRect.left;
+  Size.y = Window->WindowRect.top;
+  InternalPos = WinPosInitInternalPos(Window, Size, 
+                                     &Window->WindowRect); 
+  if(InternalPos)
+  {
+    if(SendMessage)
     {
-      return(NULL);
+      WinPosGetMinMaxInfo(Window, &SafeMinMax.ptMaxSize, &SafeMinMax.ptMaxPosition, 
+                          &SafeMinMax.ptMinTrackSize, &SafeMinMax.ptMaxTrackSize);
     }
-  return(ActiveQueue->ActiveWindow);
-}
-
-HWND STDCALL
-NtUserSetActiveWindow(HWND hWnd)
-{
-  PWINDOW_OBJECT Window;
-  PUSER_MESSAGE_QUEUE ThreadQueue;
-  HWND Prev;
-
-  Window = IntGetWindowObject(hWnd);
-  if (Window == NULL || (Window->Style & (WS_DISABLED | WS_CHILD)))
+    else
     {
-      IntReleaseWindowObject(Window);
-      return(0);
+      WinPosFillMinMaxInfoStruct(Window, &SafeMinMax);
     }
-  ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
-  if (Window->MessageQueue != ThreadQueue)
+    Status = MmCopyToCaller(MinMaxInfo, &SafeMinMax, sizeof(MINMAXINFO));
+    if(!NT_SUCCESS(Status))
     {
       IntReleaseWindowObject(Window);
-      return(0);
+      SetLastNtError(Status);
+      return FALSE;
     }
-  Prev = Window->MessageQueue->ActiveWindow;
-  WinPosSetActiveWindow(Window, FALSE, FALSE);
+    IntReleaseWindowObject(Window);
+    return TRUE;
+  }
+  
   IntReleaseWindowObject(Window);
-  return(Prev);
+  return FALSE;
 }
 
-
 /* EOF */