Fix bug #129. Unfortunetly this causes another bug to appear (that is not caused...
[reactos.git] / reactos / subsys / win32k / ntuser / winpos.c
index ffad59c..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.68 2003/12/26 00:58:33 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
@@ -121,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
@@ -142,54 +157,6 @@ 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 FASTCALL
 WinPosInitInternalPos(PWINDOW_OBJECT WindowObject, POINT pt, PRECT RestoreRect)
 {
@@ -200,7 +167,10 @@ WinPosInitInternalPos(PWINDOW_OBJECT WindowObject, POINT pt, PRECT RestoreRect)
       RECT WorkArea;
       PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop; /* Or rather get it from the window? */
       
-      WorkArea = *IntGetDesktopWorkArea(Desktop);
+      if(IntIsDesktopWindow(WindowObject->Parent))
+        WorkArea = *IntGetDesktopWorkArea(Desktop);
+      else
+        WorkArea = WindowObject->Parent->ClientRect;
       
       WindowObject->InternalPos = ExAllocatePool(NonPagedPool, sizeof(INTERNALPOS));
       if(!WindowObject->InternalPos)
@@ -208,9 +178,8 @@ WinPosInitInternalPos(PWINDOW_OBJECT WindowObject, POINT pt, PRECT RestoreRect)
         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);
@@ -218,7 +187,7 @@ 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);
@@ -265,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);
            }
@@ -284,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,
@@ -297,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;
@@ -313,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,
@@ -353,24 +324,22 @@ WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos)
   return(SwpFlags);
 }
 
-UINT FASTCALL
-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 = WorkArea.right - WorkArea.left;
-  MinMax.ptMaxSize.y = WorkArea.bottom - WorkArea.top;
-  MinMax.ptMinTrackSize.x = NtUserGetSystemMetrics(SM_CXMINTRACK);
-  MinMax.ptMinTrackSize.y = NtUserGetSystemMetrics(SM_CYMINTRACK);
-  MinMax.ptMaxTrackSize.x = MinMax.ptMaxSize.x;
-  MinMax.ptMaxTrackSize.y = MinMax.ptMaxSize.y;
+  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))
     {
@@ -391,20 +360,29 @@ WinPosGetMinMaxInfo(PWINDOW_OBJECT Window, POINT* MaxSize, POINT* MaxPos,
          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 -= WorkArea.left + XInc;
-      MinMax.ptMaxPosition.y -= WorkArea.top + 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);
@@ -419,34 +397,6 @@ 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 FASTCALL
 WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
                   RECT* WindowRect, RECT* ClientRect)
@@ -474,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 &&
@@ -527,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))
     {
@@ -571,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);
@@ -743,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;
          }
@@ -812,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);
 
@@ -843,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;
@@ -872,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
@@ -933,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;
@@ -963,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;
@@ -979,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
@@ -1004,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);
@@ -1013,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
@@ -1023,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)
@@ -1063,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);
@@ -1084,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
       {
@@ -1093,7 +1036,7 @@ 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);
 
@@ -1104,7 +1047,7 @@ 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
@@ -1152,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);
@@ -1207,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. 
@@ -1245,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)
     {
@@ -1269,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 */
@@ -1322,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 &&
@@ -1389,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
@@ -1400,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 */