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/md... ============================================================================== --- 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/wi... ============================================================================== --- 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/ntu... ============================================================================== --- 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))