mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-03 12:23:25 +00:00
- 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:
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user