Fix bug #129. Unfortunetly this causes another bug to appear (that is not caused...
[reactos.git] / reactos / subsys / win32k / ntuser / winpos.c
index 5c5b557..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.63 2003/12/23 17:56:55 weiden 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>
 /* 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)))
 
-BOOL STDCALL
-NtUserGetClientOrigin(HWND hWnd, LPPOINT Point)
+#define HAS_THINFRAME(Style, ExStyle) \
+            (((Style) & WS_BORDER) || (!((Style) & (WS_CHILD | WS_POPUP))))
+
+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;
+}
+
+BOOL STDCALL
+NtUserGetClientOrigin(HWND hWnd, LPPOINT Point)
+{
+  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;
 }
 
 /*******************************************************************
@@ -96,19 +121,34 @@ NtUserGetClientOrigin(HWND hWnd, LPPOINT Point)
 VOID FASTCALL
 WinPosActivateOtherWindow(PWINDOW_OBJECT Window)
 {
-   for (;;)
-   {
-      Window = IntGetParent(Window);
-      if (!Window || IntIsDesktopWindow(Window))
-      {
-         IntSetFocusMessageQueue(NULL);
-         return;
-      }
-      if (IntSetForegroundWindow(Window))
-      {
-         return;
-      }
-   }
+  PWINDOW_OBJECT Child;
+  PWINDOW_OBJECT TabooWindow = Window;
+
+  for (;;)
+    {
+      if (NULL == Window || IntIsDesktopWindow(Window))
+        {
+          IntSetFocusMessageQueue(NULL);
+          return;
+        }
+      Window = Window->Parent;
+      ExAcquireFastMutex(&(Window->ChildrenListLock));
+      Child = Window->FirstChild;
+      while (NULL != Child)
+        {
+          if (Child != TabooWindow)
+            {
+              ExReleaseFastMutex(&(Window->ChildrenListLock));
+              if (IntSetForegroundWindow(Child))
+                {
+                  return;
+                }
+              ExAcquireFastMutex(&(Window->ChildrenListLock));
+            }
+          Child = Child->NextSibling;
+        }
+      ExReleaseFastMutex(&(Window->ChildrenListLock));
+    }
 }
 
 VOID STATIC FASTCALL
@@ -117,70 +157,29 @@ WinPosFindIconPos(HWND hWnd, POINT *Pos)
   /* FIXME */
 }
 
-HWND STATIC FASTCALL
-WinPosNtGdiIconTitle(PWINDOW_OBJECT WindowObject)
-{
-  return(NULL);
-}
-
-BOOL STATIC FASTCALL
-WinPosShowIconTitle(PWINDOW_OBJECT WindowObject, BOOL Show)
-{
-  PWINDOW_OBJECT IconWindow;
-  NTSTATUS Status;
-
-  if (WindowObject->InternalPos)
-    {
-      HWND hWnd = WindowObject->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))
-               {
-                 IntSendMessage(hWnd, WM_SHOWWINDOW, TRUE, 0, TRUE);
-                 WinPosSetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE |
-                                    SWP_NOMOVE | SWP_NOACTIVATE | 
-                                    SWP_NOZORDER | SWP_SHOWWINDOW);
-               }
-             ObmDereferenceObject(IconWindow);
-           }
-       }
-      else
-       {
-         WinPosShowWindow(hWnd, SW_HIDE);
-       }
-    }
-  return(FALSE);
-}
-
-PINTERNALPOS STATIC STDCALL
+PINTERNALPOS FASTCALL
 WinPosInitInternalPos(PWINDOW_OBJECT WindowObject, POINT pt, PRECT RestoreRect)
 {
   INT XInc, YInc;
   
   if (WindowObject->InternalPos == NULL)
     {
+      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->IconTitle = 0;
       WindowObject->InternalPos->NormalRect = WindowObject->WindowRect;
-      if (HAS_DLGFRAME(WindowObject->Style, WindowObject->ExStyle))
+      if (HAS_DLGFRAME(WindowObject->Style, WindowObject->ExStyle) && !(WindowObject->Style & WS_MINIMIZE))
       {
         XInc = NtUserGetSystemMetrics(SM_CXDLGFRAME);
         YInc = NtUserGetSystemMetrics(SM_CYDLGFRAME);
@@ -188,21 +187,21 @@ WinPosInitInternalPos(PWINDOW_OBJECT WindowObject, POINT pt, PRECT RestoreRect)
       else
       {
         XInc = YInc = 0;
-        if (HAS_THICKFRAME(WindowObject->Style, WindowObject->ExStyle))
+        if (HAS_THICKFRAME(WindowObject->Style, WindowObject->ExStyle)&& !(WindowObject->Style & WS_MINIMIZE))
         {
           XInc += NtUserGetSystemMetrics(SM_CXFRAME);
           YInc += NtUserGetSystemMetrics(SM_CYFRAME);
         }
-        if (WindowObject->Style & WS_BORDER)
-        {
-          XInc += NtUserGetSystemMetrics(SM_CXBORDER);
-          YInc += NtUserGetSystemMetrics(SM_CYBORDER);
-        }
+        else if (HAS_THINFRAME(WindowObject->Style, WindowObject->ExStyle))
+       {
+         XInc += NtUserGetSystemMetrics(SM_CXBORDER);
+         YInc += NtUserGetSystemMetrics(SM_CYBORDER);
+       }
       }
-      WindowObject->InternalPos->MaxPos.x = -XInc;
-      WindowObject->InternalPos->MaxPos.y = -YInc;
-      WindowObject->InternalPos->IconPos.x = 0;
-      WindowObject->InternalPos->IconPos.y = 0;
+      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)
     {
@@ -219,7 +218,7 @@ WinPosInitInternalPos(PWINDOW_OBJECT WindowObject, POINT pt, PRECT RestoreRect)
   return(WindowObject->InternalPos);
 }
 
-UINT STDCALL
+UINT FASTCALL
 WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos)
 {
   POINT Size;
@@ -235,7 +234,7 @@ WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos)
     {
       if (WindowObject->Style & WS_MINIMIZE)
        {
-         if (!IntSendMessage(WindowObject->Self, WM_QUERYOPEN, 0, 0, TRUE))
+         if (!IntSendMessage(WindowObject->Self, WM_QUERYOPEN, 0, 0))
            {
              return(SWP_NOSIZE | SWP_NOMOVE);
            }
@@ -254,6 +253,8 @@ WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos)
              {
                WindowObject->Flags &= ~WINDOWOBJECT_RESTOREMAX;
              }
+           IntRedrawWindow(WindowObject, NULL, 0, RDW_VALIDATE | RDW_NOERASE |
+              RDW_NOINTERNALPAINT);
            WindowObject->Style |= WS_MINIMIZE;
            WinPosFindIconPos(WindowObject, &InternalPos->IconPos);
            NtGdiSetRect(NewPos, InternalPos->IconPos.x, InternalPos->IconPos.y,
@@ -267,9 +268,10 @@ 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_MAXIMIZE;
@@ -283,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,
@@ -293,12 +294,19 @@ 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;
                  }
                WindowObject->Style &= ~WS_MAXIMIZE;
                *NewPos = InternalPos->NormalRect;
@@ -316,20 +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;
-
+  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))
     {
@@ -344,26 +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;
 
   if (Window->InternalPos != NULL)
     {
-      MinMax.ptMaxPosition = Window->InternalPos->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);
@@ -378,35 +397,7 @@ WinPosGetMinMaxInfo(PWINDOW_OBJECT Window, POINT* MaxSize, POINT* MaxPos,
   return 0; //FIXME: what does it return?
 }
 
-#if 0
-BOOL STATIC FASTCALL
-WinPosChangeActiveWindow(HWND hWnd, BOOL MouseMsg)
-{
-  PWINDOW_OBJECT WindowObject;
-
-  WindowObject = IntGetWindowObject(hWnd);
-  if (WindowObject == NULL)
-    {
-      return FALSE;
-    }
-
-#if 0
-  IntSendMessage(hWnd,
-      WM_ACTIVATE,
-      MAKELONG(MouseMsg ? WA_CLICKACTIVE : WA_CLICKACTIVE,
-      (WindowObject->Style & WS_MINIMIZE) ? 1 : 0),
-      (LPARAM)IntGetDesktopWindow(),  /* FIXME: Previous active window */
-      TRUE);
-#endif
-  IntSetForegroundWindow(WindowObject);
-
-  IntReleaseWindowObject(WindowObject);
-
-  return TRUE;
-}
-#endif
-
-LONG STATIC STDCALL
+LONG STATIC FASTCALL
 WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
                   RECT* WindowRect, RECT* ClientRect)
 {
@@ -433,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 &&
@@ -476,7 +467,7 @@ WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
   return wvrFlags;
 }
 
-BOOL STDCALL
+BOOL FASTCALL
 WinPosDoWinPosChanging(PWINDOW_OBJECT WindowObject,
                       PWINDOWPOS WinPos,
                       PRECT WindowRect,
@@ -486,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))
     {
@@ -530,10 +519,6 @@ WinPosDoWinPosChanging(PWINDOW_OBJECT WindowObject,
 HWND FASTCALL
 WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter)
 {
-#if 0
-   /* FIXME */
-   return hWndInsertAfter;
-#endif
    HWND *List = NULL;
    HWND Owner = NtUserGetWindow(hWnd, GW_OWNER);
    LONG Style = NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE);
@@ -599,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;
@@ -702,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;
          }
@@ -726,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)
 {
@@ -771,11 +756,6 @@ 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);
 
@@ -802,15 +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, FALSE, TRUE);
+      VisBefore = VIS_ComputeVisibleRegion(Window, FALSE, FALSE, TRUE);
 
-      if (UnsafeIntGetRgnBox(VisBefore, &TempRect) == NULLREGION)
+      if (VisBefore != NULL &&
+          UnsafeIntGetRgnBox(VisBefore, &TempRect) == NULLREGION)
       {
          NtGdiDeleteObject(VisBefore);
          VisBefore = NULL;
@@ -831,7 +811,7 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
          if (WinPos.hwndInsertAfter == HWND_TOP)
             InsertAfterWindow = NULL;
          else if (WinPos.hwndInsertAfter == HWND_BOTTOM)
-            InsertAfterWindow = ParentWindow->LastChild;
+            InsertAfterWindow = IntGetWindowObject(ParentWindow->LastChild->Self);
          else
             InsertAfterWindow = IntGetWindowObject(WinPos.hwndInsertAfter);
          /* Do nothing if hwndInsertAfter is HWND_BOTTOM and Window is already
@@ -892,10 +872,10 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
    }
 
    /* Determine the new visible region */
-   VisAfter = VIS_ComputeVisibleRegion(
-      PsGetWin32Thread()->Desktop, Window, FALSE, FALSE, TRUE);
+   VisAfter = VIS_ComputeVisibleRegion(Window, FALSE, FALSE, TRUE);
 
-   if (UnsafeIntGetRgnBox(VisAfter, &TempRect) == NULLREGION)
+   if (VisAfter != NULL &&
+       UnsafeIntGetRgnBox(VisAfter, &TempRect) == NULLREGION)
    {
       NtGdiDeleteObject(VisAfter);
       VisAfter = NULL;
@@ -922,7 +902,7 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
        * we don't have to crop (can't take anything away from an empty
        * region...)
        */
-      if (!(WinPos.flags & (SWP_NOSIZE | SWP_NOZORDER)) && RgnType != ERROR &&
+      if (!(WinPos.flags & SWP_NOSIZE) && RgnType != ERROR &&
           RgnType != NULLREGION)
       {
          RECT ORect = OldClientRect;
@@ -938,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
@@ -963,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);
@@ -972,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
@@ -982,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, 0,
+         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)
@@ -1022,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);
@@ -1043,7 +1027,7 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
    {
       if ((Window->Style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
       {
-         IntSendMessage(WinPos.hwnd, WM_CHILDACTIVATE, 0, 0, TRUE);
+         IntSendMessage(WinPos.hwnd, WM_CHILDACTIVATE, 0, 0);
       }
       else
       {
@@ -1052,18 +1036,18 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
    }
 
    if ((WinPos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE)
-      IntSendWINDOWPOSCHANGEDMessage(WinPos.hwnd, &WinPos);
+      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
@@ -1111,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);
@@ -1166,7 +1150,7 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
   ShowFlag = (Cmd != SW_HIDE);
   if (ShowFlag != WasVisible)
     {
-      IntSendMessage(Wnd, WM_SHOWWINDOW, ShowFlag, 0, TRUE);
+      IntSendMessage(Wnd, WM_SHOWWINDOW, ShowFlag, 0);
       /* 
        * FIXME: Need to check the window wasn't destroyed during the 
        * window procedure. 
@@ -1204,11 +1188,6 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
     }
 
   /* FIXME: Check for window destruction. */
-  /* Show title for minimized windows. */
-  if (Window->Style & WS_MINIMIZE)
-    {
-      WinPosShowIconTitle(Window, TRUE);
-    }
 
   if (Window->Flags & WINDOWOBJECT_NEED_SIZE)
     {
@@ -1228,10 +1207,10 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
                      MAKELONG(Window->ClientRect.right - 
                               Window->ClientRect.left,
                               Window->ClientRect.bottom -
-                              Window->ClientRect.top), TRUE);
+                              Window->ClientRect.top));
       IntSendMessage(Wnd, WM_MOVE, 0,
                      MAKELONG(Window->ClientRect.left,
-                              Window->ClientRect.top), TRUE);
+                              Window->ClientRect.top));
     }
 
   /* Activate the window if activation is not requested and the window is not minimized */
@@ -1255,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)
 {
@@ -1281,11 +1260,6 @@ WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, POINT Point,
                  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 &&
@@ -1306,7 +1280,7 @@ WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, POINT Point,
   return(0);
 }
 
-USHORT STDCALL
+USHORT FASTCALL
 WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, POINT WinPoint, 
                      PWINDOW_OBJECT* Window)
 {
@@ -1348,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
@@ -1359,4 +1333,54 @@ WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, POINT WinPoint,
   return(HitTest);
 }
 
+BOOL
+STDCALL
+NtUserGetMinMaxInfo(
+  HWND hwnd,
+  MINMAXINFO *MinMaxInfo,
+  BOOL SendMessage)
+{
+  POINT Size;
+  PINTERNALPOS InternalPos;
+  PWINDOW_OBJECT Window;
+  MINMAXINFO SafeMinMax;
+  NTSTATUS Status;
+  
+  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)
+    {
+      WinPosGetMinMaxInfo(Window, &SafeMinMax.ptMaxSize, &SafeMinMax.ptMaxPosition, 
+                          &SafeMinMax.ptMinTrackSize, &SafeMinMax.ptMaxTrackSize);
+    }
+    else
+    {
+      WinPosFillMinMaxInfoStruct(Window, &SafeMinMax);
+    }
+    Status = MmCopyToCaller(MinMaxInfo, &SafeMinMax, sizeof(MINMAXINFO));
+    if(!NT_SUCCESS(Status))
+    {
+      IntReleaseWindowObject(Window);
+      SetLastNtError(Status);
+      return FALSE;
+    }
+    IntReleaseWindowObject(Window);
+    return TRUE;
+  }
+  
+  IntReleaseWindowObject(Window);
+  return FALSE;
+}
+
 /* EOF */