Author: jimtabor
Date: Tue Jul 4 09:56:25 2006
New Revision: 22818
URL:
http://svn.reactos.org/svn/reactos?rev=22818&view=rev
Log:
- NtUser/CreateWindowExA/W:
- 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.
Modified:
trunk/reactos/dll/win32/user32/windows/mdi.c
trunk/reactos/dll/win32/user32/windows/window.c
trunk/reactos/subsystems/win32/win32k/ntuser/window.c
Modified: trunk/reactos/dll/win32/user32/windows/mdi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/m…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/mdi.c (original)
+++ trunk/reactos/dll/win32/user32/windows/mdi.c Tue Jul 4 09:56:25 2006
@@ -246,16 +246,6 @@
}
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
/**********************************************************************
Modified: trunk/reactos/dll/win32/user32/windows/window.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/w…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/window.c (original)
+++ trunk/reactos/dll/win32/user32/windows/window.c Tue Jul 4 09:56:25 2006
@@ -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 @@
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 @@
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 @@
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 @@
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 @@
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))
{
@@ -310,6 +454,13 @@
lpParam,
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);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/window.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c Tue Jul 4 09:56:25 2006
@@ -1411,7 +1411,6 @@
POINT Pos;
SIZE Size;
PW32THREADINFO ti = NULL;
-
#if 0
POINT MaxSize, MaxPos, MinTrack, MaxTrack;
@@ -1420,7 +1419,6 @@
POINT MaxPos;
#endif
CREATESTRUCTW Cs;
- MDICREATESTRUCTW mdi;
CBT_CREATEWNDW CbtCreate;
LRESULT Result;
BOOL MenuChanged;
@@ -1627,59 +1625,6 @@
else
{
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 );
- }
- }
}
/*
@@ -1694,17 +1639,17 @@
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 @@
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 @@
Pos.x = max(rc.left, 0);
if(Pos.y > rc.top)
Pos.y = max(rc.top, 0);
- }
+ }
}
else
{
- if (dwExStyle & WS_EX_MDICHILD)
- {
- 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;
- }
- else
- {
- /* 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;
- }
+ /* 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;
}
}
@@ -2090,13 +2005,6 @@
WM_PARENTNOTIFY,
MAKEWPARAM(WM_CREATE, Window->IDMenu),
(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))