- NtUser/CreateWindowExA/W:

- Add support for WS_EX_MDICHILD. Reordered sequence for setting WindowObject and callers styles.
  - Synced mdi.c from Wine. Added support function MDI_GetId help return IDMenu.
  - Thanks to GreatLord for helping.

svn path=/trunk/; revision=22792
This commit is contained in:
James Tabor
2006-07-03 04:33:29 +00:00
parent 0ffb1da110
commit 8307280bc9
4 changed files with 584 additions and 864 deletions
File diff suppressed because it is too large Load Diff
+14 -8
View File
@@ -18,6 +18,7 @@
BOOL ControlsInitialized = FALSE;
LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
INT MDI_GetId(HWND hWndClient);
/* FUNCTIONS *****************************************************************/
@@ -186,10 +187,7 @@ CreateWindowExA(DWORD dwExStyle,
if (dwExStyle & WS_EX_MDICHILD)
{
if (!IS_ATOM(lpClassName))
RtlFreeUnicodeString(&ClassName);
return CreateMDIWindowA(lpClassName, lpWindowName, dwStyle, x, y,
nWidth, nHeight, hWndParent, hInstance, (LPARAM)lpParam);
if (!(dwStyle & WS_POPUP)) hMenu = (HMENU) MDI_GetId(hWndParent);
}
if (!RtlCreateUnicodeStringFromAsciiz(&WindowName, (PCSZ)lpWindowName))
@@ -221,7 +219,7 @@ CreateWindowExA(DWORD dwExStyle,
nHeight,
hWndParent,
hMenu,
hInstance,
hInstance,
lpParam,
SW_SHOW,
FALSE);
@@ -262,6 +260,9 @@ CreateWindowExW(DWORD dwExStyle,
UNICODE_STRING ClassName;
WNDCLASSEXW wce;
HANDLE Handle;
#if 0
DbgPrint("[window] CreateWindowExA style %d, exstyle %d, parent %d\n", dwStyle, dwExStyle, hWndParent);
#endif
/* Register built-in controls if not already done */
if (! ControlsInitialized)
@@ -270,8 +271,9 @@ CreateWindowExW(DWORD dwExStyle,
}
if (dwExStyle & WS_EX_MDICHILD)
return CreateMDIWindowW(lpClassName, lpWindowName, dwStyle, x, y,
nWidth, nHeight, hWndParent, hInstance, (LPARAM)lpParam);
{
if (!(dwStyle & WS_POPUP)) hMenu = (HMENU) MDI_GetId(hWndParent);
}
if (IS_ATOM(lpClassName))
{
@@ -304,11 +306,15 @@ CreateWindowExW(DWORD dwExStyle,
nHeight,
hWndParent,
hMenu,
hInstance,
hInstance,
lpParam,
SW_SHOW,
TRUE);
#if 0
DbgPrint("[window] NtUserCreateWindowEx() == %d\n", Handle);
#endif
return (HWND)Handle;
}
+1 -1
View File
@@ -132,7 +132,7 @@ User32 -
reactos/dll/win32/user32/windows/defwnd.c # Forked
reactos/dll/win32/user32/windows/draw.c # Forked at Wine-20020904 (uitools.c)
reactos/dll/win32/user32/windows/mdi.c # Out of sync
reactos/dll/win32/user32/windows/mdi.c # Synced at 20060703
reactos/dll/win32/user32/windows/menu.c # Forked
reactos/dll/win32/user32/windows/messagebox.c # Forked
reactos/dll/win32/user32/windows/rect.c # Forked (uitools.c)
+151 -26
View File
@@ -1411,6 +1411,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
POINT Pos;
SIZE Size;
PW32THREADINFO ti = NULL;
#if 0
POINT MaxSize, MaxPos, MinTrack, MaxTrack;
@@ -1419,6 +1420,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
POINT MaxPos;
#endif
CREATESTRUCTW Cs;
MDICREATESTRUCTW mdi;
CBT_CREATEWNDW CbtCreate;
LRESULT Result;
BOOL MenuChanged;
@@ -1429,6 +1431,11 @@ co_IntCreateWindowEx(DWORD dwExStyle,
ParentWindowHandle = PsGetWin32Thread()->Desktop->DesktopWindow;
OwnerWindowHandle = NULL;
if ((!(dwStyle & WS_CHILD)) && (dwExStyle & WS_EX_MDICHILD))
{
dwStyle |= WS_CHILD; // Forced Child!
}
if (hWndParent == HWND_MESSAGE)
{
/*
@@ -1626,6 +1633,62 @@ 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;
/*
(|| WS_CHILD) is done at the top. So~ Here is just a bit in a 32/64 bit word.
*/
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
@@ -1636,19 +1699,11 @@ co_IntCreateWindowEx(DWORD dwExStyle,
dwExStyle |= WS_EX_WINDOWEDGE;
else
dwExStyle &= ~WS_EX_WINDOWEDGE;
/* Correct the window style. */
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);
}
}
/*
These affect only the style loading into the WindowObject structure.
*/
Window->ExStyle = dwExStyle;
Window->Style = dwStyle & ~WS_VISIBLE;
/* create system menu */
if((dwStyle & WS_SYSMENU) &&
@@ -1662,6 +1717,23 @@ co_IntCreateWindowEx(DWORD dwExStyle,
}
}
/* Correct the window style. */
if (!(Window->Style & WS_CHILD))
{
Window->Style |= WS_CLIPSIBLINGS;
if (!(Window->Style & WS_POPUP))
{
Window->Style |= WS_CAPTION;
Window->Flags |= WINDOWOBJECT_NEED_SIZE;
}
}
if ((Window->ExStyle & WS_EX_DLGMODALFRAME) ||
(Window->Style & (WS_DLGFRAME | WS_THICKFRAME)))
Window->ExStyle |= WS_EX_WINDOWEDGE;
else
Window->ExStyle &= ~WS_EX_WINDOWEDGE;
/* Insert the window into the thread's window list. */
InsertTailList (&PsGetWin32Thread()->WindowListHead, &Window->ThreadListEntry);
@@ -1677,9 +1749,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
Size.cx = nWidth;
Size.cy = nHeight;
Window->ExStyle = dwExStyle;
Window->Style = dwStyle & ~WS_VISIBLE;
/* call hook */
Cs.lpCreateParams = lpParam;
Cs.hInstance = hInstance;
@@ -1735,9 +1804,27 @@ 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!
*/
/* According to wine, the ShowMode is set to y if x == CW_USEDEFAULT(16) and
y is something else */
/* 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
* the y parameter. However, disassembling NT implementation (WIN32K.SYS)
* reveals that
*
* 1) not only it checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
* 2) it does not ignore the y parameter as the docs claim; instead, it
* uses it as second parameter to ShowWindow() unless y is either
* CW_USEDEFAULT or CW_USEDEFAULT16.
*
* The fact that we didn't do 2) caused bogus windows pop up when wine
* was running apps that were using this obscure feature. Example -
* calc.exe that comes with Win98 (only Win98, it's different from
* the one that comes with Win95 and NT)
*/
if(y != CW_USEDEFAULT && y != CW_USEDEFAULT16)
{
dwShowMode = y;
@@ -1766,20 +1853,51 @@ co_IntCreateWindowEx(DWORD dwExStyle,
Pos.x = max(rc.left, 0);
if(Pos.y > rc.top)
Pos.y = max(rc.top, 0);
}
}
}
else
{
/* if CW_USEDEFAULT(16) is set for non-overlapped windows, both values are set to zero) */
if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
if (dwExStyle & WS_EX_MDICHILD)
{
Pos.x = 0;
Pos.y = 0;
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;
}
if(nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16)
else
{
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;
}
}
}
@@ -1987,6 +2105,13 @@ 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");