- NtUser/CreateWindowExA/W:
authorJames Tabor <james.tabor@reactos.org>
Tue, 4 Jul 2006 05:56:25 +0000 (05:56 +0000)
committerJames Tabor <james.tabor@reactos.org>
Tue, 4 Jul 2006 05:56:25 +0000 (05:56 +0000)
  - During testing I found one application not working with the new mdi support changes. VIDE from the Vgui C++ project was creating a bugcheck trying to access kernel space. Just for precautions I moved the kernel code back into user32. After testing the application, it worked fine. So, I'm reordering the execution of CreateWindowEx. Keeping a small part in kernel space and the rest in user. This has caused code duplication in user32, but I want to set this straight first. I will sort out the code duplication later. Sorry for the mess.

svn path=/trunk/; revision=22818

reactos/dll/win32/user32/windows/mdi.c
reactos/dll/win32/user32/windows/window.c
reactos/subsystems/win32/win32k/ntuser/window.c

index ec160e9..ab315ba 100644 (file)
@@ -247,16 +247,6 @@ static BOOL is_close_enabled(HWND hwnd, HMENU hSysMenu)
     return TRUE;
 }
 
-#ifdef __REACTOS__
-INT
-MDI_GetId(HWND hWndClient)
-{
-    MDICLIENTINFO * ci = get_client_info( hWndClient );
-    if(ci) return ci->idFirstChild + ci->nActiveChildren;
-    return 0;
-}
-#endif
-
 
 /**********************************************************************
  *                     MDI_GetWindow
index bc44e13..4ee6d19 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /* INCLUDES ******************************************************************/
-
+#define DEBUG
 #include <user32.h>
 
 #include <wine/debug.h>
@@ -18,7 +18,9 @@
 BOOL ControlsInitialized = FALSE;
 
 LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
-INT MDI_GetId(HWND hWndClient);
+void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta, UINT *id );
+
+#define CW_USEDEFAULT16 0x00008000
 
 /* FUNCTIONS *****************************************************************/
 
@@ -160,6 +162,7 @@ CreateWindowExA(DWORD dwExStyle,
   UNICODE_STRING ClassName;
   WNDCLASSEXA wce;
   HWND Handle;
+  MDICREATESTRUCTA mdi;
 
 #if 0
   DbgPrint("[window] CreateWindowExA style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent);
@@ -187,7 +190,72 @@ CreateWindowExA(DWORD dwExStyle,
 
   if (dwExStyle & WS_EX_MDICHILD)
   {
-    if (!(dwStyle & WS_POPUP)) hMenu = (HMENU) MDI_GetId(hWndParent);
+      POINT mPos[2];
+      UINT id = 0;
+  /* lpParams of WM_[NC]CREATE is different for MDI children.
+   * MDICREATESTRUCT members have the originally passed values.
+   *
+   * Note: we rely on the fact that MDICREATESTRUCTA and MDICREATESTRUCTW
+   * have the same layout.
+   */
+      mdi.szClass = (LPCSTR)&lpClassName;
+      mdi.szTitle = (LPCSTR)&lpWindowName;
+      mdi.hOwner = hInstance;
+      mdi.x = x;
+      mdi.y = y;
+      mdi.cx = nWidth;
+      mdi.cy = nHeight;
+      mdi.style = dwStyle;
+      mdi.lParam = (LPARAM)lpParam;
+
+      lpParam = (LPVOID)&mdi;
+
+      if (GetWindowLongW(hWndParent, GWL_STYLE) & MDIS_ALLCHILDSTYLES)
+      {
+        if (dwStyle & WS_POPUP)
+        {
+           DPRINT1("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
+           return(0);
+        }
+        dwStyle |= (WS_CHILD | WS_CLIPSIBLINGS);
+      }
+      else
+      {
+        dwStyle &= ~WS_POPUP;
+        dwStyle |= (WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION |
+                WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
+      }
+
+      HWND top_child = GetWindow(hWndParent, GW_CHILD);
+
+      if (top_child)
+      {
+        /* Restore current maximized child */
+        if((dwStyle & WS_VISIBLE) && IsZoomed(top_child))
+        {
+           DPRINT("Restoring current maximized child %p\n", top_child);
+           SendMessageW( top_child, WM_SETREDRAW, FALSE, 0 );
+           ShowWindow(top_child, SW_RESTORE);
+           SendMessageW( top_child, WM_SETREDRAW, TRUE, 0 );
+        }
+      }
+    
+      MDI_CalcDefaultChildPos(hWndParent, -1, mPos, 0, &id);
+
+      if (!(dwStyle & WS_POPUP)) hMenu = (HMENU)id;
+
+      if (dwStyle & (WS_CHILD | WS_POPUP))
+      {
+         if (x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
+         {
+            x = mPos[0].x;
+            y = mPos[0].y;
+         }
+         if (nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16 || !nWidth)
+             nWidth = mPos[1].x;
+         if (nHeight == CW_USEDEFAULT || nHeight == CW_USEDEFAULT16 || !nHeight)
+             nHeight = mPos[1].y;
+      }
   }
 
   if (!RtlCreateUnicodeStringFromAsciiz(&WindowName, (PCSZ)lpWindowName))
@@ -228,6 +296,14 @@ CreateWindowExA(DWORD dwExStyle,
   DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle);
 #endif
 
+   if ((dwStyle & WS_VISIBLE) && (dwExStyle & WS_EX_MDICHILD))
+   {
+      SendMessageW(hWndParent, WM_MDIREFRESHMENU, 0, 0);
+      SetWindowPos(Handle, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW |
+                                                SWP_NOMOVE | SWP_NOSIZE);
+   }
+
+
   RtlFreeUnicodeString(&WindowName);
 
   if (!IS_ATOM(lpClassName))
@@ -260,6 +336,8 @@ CreateWindowExW(DWORD dwExStyle,
   UNICODE_STRING ClassName;
   WNDCLASSEXW wce;
   HANDLE Handle;
+  MDICREATESTRUCTW mdi;
+  
 #if 0
   DbgPrint("[window] CreateWindowExA style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent);
 #endif
@@ -270,10 +348,76 @@ CreateWindowExW(DWORD dwExStyle,
       ControlsInitialized = ControlsInit(lpClassName);
     }
 
+
   if (dwExStyle & WS_EX_MDICHILD)
-    {
-      if (!(dwStyle & WS_POPUP)) hMenu = (HMENU) MDI_GetId(hWndParent);
-    }
+  {
+      POINT mPos[2];
+      UINT id = 0;
+  /* lpParams of WM_[NC]CREATE is different for MDI children.
+   * MDICREATESTRUCT members have the originally passed values.
+   *
+   * Note: we rely on the fact that MDICREATESTRUCTA and MDICREATESTRUCTW
+   * have the same layout.
+   */
+      mdi.szClass = (LPWSTR)&lpClassName;
+      mdi.szTitle = (LPWSTR)&lpWindowName;
+      mdi.hOwner = hInstance;
+      mdi.x = x;
+      mdi.y = y;
+      mdi.cx = nWidth;
+      mdi.cy = nHeight;
+      mdi.style = dwStyle;
+      mdi.lParam = (LPARAM)lpParam;
+
+      lpParam = (LPVOID)&mdi;
+
+      if (GetWindowLongW(hWndParent, GWL_STYLE) & MDIS_ALLCHILDSTYLES)
+      {
+        if (dwStyle & WS_POPUP)
+        {
+           DPRINT1("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
+           return(0);
+        }
+        dwStyle |= (WS_CHILD | WS_CLIPSIBLINGS);
+      }
+      else
+      {
+        dwStyle &= ~WS_POPUP;
+        dwStyle |= (WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION |
+                WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX );
+      }
+
+      HWND top_child = GetWindow(hWndParent, GW_CHILD);
+
+      if (top_child)
+      {
+        /* Restore current maximized child */
+        if((dwStyle & WS_VISIBLE) && IsZoomed(top_child))
+        {
+           DPRINT("Restoring current maximized child %p\n", top_child);
+           SendMessageW( top_child, WM_SETREDRAW, FALSE, 0 );
+           ShowWindow(top_child, SW_RESTORE);
+           SendMessageW( top_child, WM_SETREDRAW, TRUE, 0 );
+        }
+      }
+
+      MDI_CalcDefaultChildPos(hWndParent, -1, mPos, 0, &id);
+
+      if (!(dwStyle & WS_POPUP)) hMenu = (HMENU)id;
+      if (dwStyle &(WS_CHILD | WS_POPUP))
+      {
+
+         if (x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
+         {
+            x = mPos[0].x;
+            y = mPos[0].y;
+         }
+         if (nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16 || !nWidth)
+             nWidth = mPos[1].x;
+         if (nHeight == CW_USEDEFAULT || nHeight == CW_USEDEFAULT16 || !nHeight)
+             nHeight = mPos[1].y;
+      }
+  }
 
   if (IS_ATOM(lpClassName))
     {
@@ -311,6 +455,13 @@ CreateWindowExW(DWORD dwExStyle,
                                SW_SHOW,
                                TRUE);
 
+   if ((dwStyle & WS_VISIBLE) && (dwExStyle & WS_EX_MDICHILD))
+   {
+      SendMessageW(hWndParent, WM_MDIREFRESHMENU, 0, 0);
+      SetWindowPos((HWND)Handle, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW |
+                                                SWP_NOMOVE | SWP_NOSIZE);
+   }
+
 #if 0
   DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle);
 #endif
index ed79120..4bda35f 100644 (file)
@@ -1411,7 +1411,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    POINT Pos;
    SIZE Size;
    PW32THREADINFO ti = NULL;
-   
 #if 0
 
    POINT MaxSize, MaxPos, MinTrack, MaxTrack;
@@ -1420,7 +1419,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    POINT MaxPos;
 #endif
    CREATESTRUCTW Cs;
-   MDICREATESTRUCTW mdi;
    CBT_CREATEWNDW CbtCreate;
    LRESULT Result;
    BOOL MenuChanged;
@@ -1629,59 +1627,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
       RtlInitUnicodeString(&Window->WindowName, NULL);
    }
 
-   if (dwExStyle & WS_EX_MDICHILD)
-   {
-      PWINDOW_OBJECT top_child;
-     
-  /* lpParams of WM_[NC]CREATE is different for MDI children.
-   * MDICREATESTRUCT members have the originally passed values.
-   *
-   * Note: we rely on the fact that MDICREATESTRUCTA and MDICREATESTRUCTW
-   * have the same layout.
-   */
-      mdi.szClass = (LPWSTR)ClassName;
-      mdi.szTitle = (LPWSTR)WindowName;
-      mdi.hOwner = hInstance;
-      mdi.x = x;
-      mdi.y = y;
-      mdi.cx = nWidth;
-      mdi.cy = nHeight;
-      mdi.style = dwStyle;
-      mdi.lParam = (LPARAM)lpParam;
-
-      lpParam = (LPVOID)&mdi;
-      if (ParentWindow->Style & MDIS_ALLCHILDSTYLES)
-      {
-        if (dwStyle & WS_POPUP)
-        {
-           DPRINT1("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
-           SetLastWin32Error(ERROR_INVALID_PARAMETER);  
-           RETURN((HWND)0);
-        }
-        dwStyle |= (WS_CHILD | WS_CLIPSIBLINGS);
-      }
-      else
-      {
-        dwStyle &= ~WS_POPUP;
-        dwStyle |= (WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION |
-                WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
-      }
-
-      top_child = ParentWindow->FirstChild;
-
-      if (top_child)
-      {
-        /* Restore current maximized child */
-        if((dwStyle & WS_VISIBLE) && (top_child->Style & WS_MAXIMIZE))
-        {
-           DPRINT("Restoring current maximized child %p\n", top_child);
-           co_IntSendMessage( top_child->hSelf, WM_SETREDRAW, FALSE, 0 );
-           co_WinPosShowWindow(top_child, SW_RESTORE);
-           co_IntSendMessage( top_child->hSelf, WM_SETREDRAW, TRUE, 0 );
-        }
-      }
-   }
-
    /*
     * This has been tested for WS_CHILD | WS_VISIBLE.  It has not been
     * tested for WS_POPUP
@@ -1694,17 +1639,17 @@ co_IntCreateWindowEx(DWORD dwExStyle,
       dwExStyle &= ~WS_EX_WINDOWEDGE;
 
    /* Correct the window style. */
-    if (!(dwStyle & WS_CHILD))
-    {
+   if (!(dwStyle & WS_CHILD))
+   {
       dwStyle |= WS_CLIPSIBLINGS;
       DPRINT("3: Style is now %lx\n", dwStyle);
       if (!(dwStyle & WS_POPUP))
       {
-          dwStyle |= WS_CAPTION;
-          Window->Flags |= WINDOWOBJECT_NEED_SIZE;
-          DPRINT("4: Style is now %lx\n", dwStyle);
+         dwStyle |= WS_CAPTION;
+         Window->Flags |= WINDOWOBJECT_NEED_SIZE;
+         DPRINT("4: Style is now %lx\n", dwStyle);
       }
-    }
+   }
 
    /* create system menu */
    if((dwStyle & WS_SYSMENU) &&
@@ -1791,11 +1736,12 @@ co_IntCreateWindowEx(DWORD dwExStyle,
             Pos.x = rc.left;
             Pos.y = rc.top;
          }
+
 /* 
    According to wine, the ShowMode is set to y if x == CW_USEDEFAULT(16) and
    y is something else. and Quote!
  */
-
+       
 /* Never believe Microsoft's documentation... CreateWindowEx doc says
  * that if an overlapped window is created with WS_VISIBLE style bit
  * set and the x parameter is set to CW_USEDEFAULT, the system ignores
@@ -1840,51 +1786,20 @@ co_IntCreateWindowEx(DWORD dwExStyle,
             Pos.x = max(rc.left, 0);
          if(Pos.y > rc.top)
             Pos.y = max(rc.top, 0);
-      }     
+      }
    }
    else
    {
-      if (dwExStyle & WS_EX_MDICHILD)
+      /* if CW_USEDEFAULT(16) is set for non-overlapped windows, both values are set to zero) */
+      if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
       {
-         POINT mPos[2];
-         RECT rect;
-         INT nstagger, total = 0, spacing = UserGetSystemMetrics(SM_CYCAPTION) +
-                                           UserGetSystemMetrics(SM_CYFRAME) -1;
-         PWINDOW_OBJECT Child;
-
-         for (Child = ParentWindow->FirstChild; Child; Child = Child->NextSibling)
-            ++total;
-
-         IntGetClientRect(ParentWindow, &rect);
-
-         nstagger = (rect.bottom - rect.top)/(3 * spacing);
-         mPos[1].x = (rect.right - rect.left - nstagger * spacing);
-         mPos[1].y = (rect.bottom - rect.top - nstagger * spacing);
-         mPos[0].x = mPos[0].y = spacing * (total%(nstagger+1));
-
-         if (x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
-         {
-            Pos.x = mPos[0].x;
-            Pos.y = mPos[0].y;
-         }
-         if (nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16 || !nWidth)
-             Size.cx = mPos[1].x;
-         if (nHeight == CW_USEDEFAULT || nHeight == CW_USEDEFAULT16 || !nHeight)
-             Size.cy = mPos[1].y;
+         Pos.x = 0;
+         Pos.y = 0;
       }
-      else
+      if(nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16)
       {
-        /* if CW_USEDEFAULT(16) is set for non-overlapped windows, both values are set to zero) */
-         if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
-         {
-            Pos.x = 0;
-            Pos.y = 0;
-         }
-         if(nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16)
-         {
-            Size.cx = 0;
-            Size.cy = 0;
-         }
+         Size.cx = 0;
+         Size.cy = 0;
       }
    }
 
@@ -2092,13 +2007,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
                         (LPARAM)Window->hSelf);
    }
 
-   if ((dwStyle & WS_VISIBLE) && (dwExStyle & WS_EX_MDICHILD))
-   {
-      co_IntSendMessage(ParentWindow->hSelf, WM_MDIREFRESHMENU, 0, 0);
-      co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW |
-                                                SWP_NOMOVE | SWP_NOSIZE);
-   }
-
    if ((!hWndParent) && (!HasOwner))
    {
       DPRINT("Sending CREATED notify\n");