Commit dc70553c authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

Merge the MDI and common window creation code. Change the way MDI

children are managed in MDIClient. Add support for MDICREATESTRUCT A<->W conversions. Add support for WM_MDIREFRESHMENU.
parent 52bf6c2b
......@@ -86,6 +86,7 @@ typedef struct
#define WIN_INTERNAL_PAINT 0x0010 /* Internal WM_PAINT message pending */
#define WIN_NEED_SIZE 0x0040 /* Internal WM_SIZE is needed */
#define WIN_NCACTIVATED 0x0080 /* last WM_NCACTIVATE was positive */
#define WIN_ISMDICLIENT 0x0100 /* Window is an MDIClient */
#define WIN_ISDIALOG 0x0200 /* Window is a dialog */
#define WIN_ISWIN32 0x0400 /* Understands Win32 messages */
#define WIN_NEEDS_SHOW_OWNEDPOPUP 0x0800 /* WM_SHOWWINDOW:SC_SHOW must be sent in the next ShowOwnedPopup call */
......@@ -114,6 +115,7 @@ extern BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL );
extern HWND *WIN_ListParents( HWND hwnd );
extern HWND *WIN_ListChildren( HWND hwnd );
extern BOOL WIN_InternalShowOwnedPopups( HWND owner, BOOL fShow, BOOL unmanagedOnly );
extern void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta );
inline static HWND WIN_GetFullHandle( HWND hwnd )
{
......
......@@ -805,8 +805,29 @@ static void WIN_FixCoordinates( CREATESTRUCTA *cs, INT *sw)
{
if (cs->style & (WS_CHILD | WS_POPUP))
{
if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16) cs->x = cs->y = 0;
if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16) cs->cx = cs->cy = 0;
if (cs->dwExStyle & WS_EX_MDICHILD)
{
POINT pos[2];
MDI_CalcDefaultChildPos(cs->hwndParent, -1, pos, 0);
if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16)
{
cs->x = pos[0].x;
cs->y = pos[0].y;
}
if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16 || !cs->cx)
cs->cx = pos[1].x;
if (cs->cy == CW_USEDEFAULT || cs->cy == CW_USEDEFAULT16 || !cs->cy)
cs->cy = pos[1].y;
}
else
{
if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16)
cs->x = cs->y = 0;
if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16)
cs->cx = cs->cy = 0;
}
}
else /* overlapped window */
{
......@@ -979,7 +1000,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
{
INT sw = SW_SHOW;
WND *wndPtr;
HWND hwnd, parent, owner;
HWND hwnd, parent, owner, top_child = 0;
BOOL unicode = (type == WIN_PROC_32W);
TRACE("%s %s ex=%08lx style=%08lx %d,%d %dx%d parent=%p menu=%p inst=%p params=%p\n",
......@@ -993,6 +1014,62 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
TRACE("winproc type is %d (%s)\n", type, (type == WIN_PROC_16) ? "WIN_PROC_16" :
((type == WIN_PROC_32A) ? "WIN_PROC_32A" : "WIN_PROC_32W") );
/* Fix the styles for MDI children */
if (cs->dwExStyle & WS_EX_MDICHILD)
{
MDICREATESTRUCTA mdi_cs;
UINT flags = 0;
wndPtr = WIN_GetPtr(cs->hwndParent);
if (wndPtr && wndPtr != WND_OTHER_PROCESS)
{
flags = wndPtr->flags;
WIN_ReleasePtr(wndPtr);
}
if (!(flags & WIN_ISMDICLIENT))
{
WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n", cs->hwndParent);
return 0;
}
/* cs->lpCreateParams 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_cs.szClass = cs->lpszClass;
mdi_cs.szTitle = cs->lpszName;
mdi_cs.hOwner = cs->hInstance;
mdi_cs.x = cs->x;
mdi_cs.y = cs->y;
mdi_cs.cx = cs->cx;
mdi_cs.cy = cs->cy;
mdi_cs.style = cs->style;
mdi_cs.lParam = (LPARAM)cs->lpCreateParams;
cs->lpCreateParams = (LPVOID)&mdi_cs;
if (GetWindowLongW(cs->hwndParent, GWL_STYLE) & MDIS_ALLCHILDSTYLES)
{
if (cs->style & WS_POPUP)
{
TRACE("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
return 0;
}
cs->style |= WS_CHILD | WS_CLIPSIBLINGS;
}
else
{
cs->style &= ~WS_POPUP;
cs->style |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION |
WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
}
top_child = GetWindow(cs->hwndParent, GW_CHILD);
}
/* Find the parent window */
parent = GetDesktopWindow();
......@@ -1136,6 +1213,21 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
send_parent_notify( hwnd, WM_CREATE );
if (!IsWindow( hwnd )) return 0;
if (cs->dwExStyle & WS_EX_MDICHILD)
{
if (top_child)
{
/* Restore current maximized child */
if((cs->style & WS_VISIBLE) && IsZoomed(top_child))
{
TRACE("Restoring current maximized child %p\n", top_child);
ShowWindow(top_child, SW_SHOWNOACTIVATE);
}
}
SendMessageW(cs->hwndParent, WM_MDIREFRESHMENU, 0, 0);
}
if (cs->style & WS_VISIBLE)
{
/* in case WS_VISIBLE got set in the meantime */
......@@ -1237,9 +1329,6 @@ HWND WINAPI CreateWindowExA( DWORD exStyle, LPCSTR className,
CREATESTRUCTA cs;
char buffer[256];
if(exStyle & WS_EX_MDICHILD)
return CreateMDIWindowA(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
/* Find the class atom */
if (HIWORD(className))
......@@ -1293,9 +1382,6 @@ HWND WINAPI CreateWindowExW( DWORD exStyle, LPCWSTR className,
CREATESTRUCTW cs;
WCHAR buffer[256];
if(exStyle & WS_EX_MDICHILD)
return CreateMDIWindowW(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
/* Find the class atom */
if (HIWORD(className))
......@@ -1409,6 +1495,9 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
SetFocus( parent );
}
if (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
SendMessageW(GetAncestor(hwnd, GA_PARENT), WM_MDIREFRESHMENU, 0, 0);
/* Call hooks */
if (HOOK_CallHooks( WH_CBT, HCBT_DESTROYWND, (WPARAM)hwnd, 0, TRUE )) return FALSE;
......
......@@ -671,6 +671,25 @@ INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plpara
RtlCreateUnicodeStringFromAsciiz(&usBuffer,(LPCSTR)xs->cs.lpszClass);
xs->lpszClass = xs->cs.lpszClass = usBuffer.Buffer;
}
if (GetWindowLongA(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
{
MDICREATESTRUCTW *mdi_cs = (MDICREATESTRUCTW *)HeapAlloc(GetProcessHeap(), 0,
sizeof(*mdi_cs));
*mdi_cs = *(MDICREATESTRUCTW *)xs->cs.lpCreateParams;
if (HIWORD(mdi_cs->szTitle))
{
RtlCreateUnicodeStringFromAsciiz(&usBuffer, (LPCSTR)mdi_cs->szTitle);
mdi_cs->szTitle = usBuffer.Buffer;
}
if (HIWORD(mdi_cs->szClass))
{
RtlCreateUnicodeStringFromAsciiz(&usBuffer, (LPCSTR)mdi_cs->szClass);
mdi_cs->szClass = usBuffer.Buffer;
}
xs->cs.lpCreateParams = mdi_cs;
}
*plparam = (LPARAM)xs;
}
return 1;
......@@ -829,6 +848,16 @@ LRESULT WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
struct s *xs = (struct s *)lParam;
if (xs->lpszName) HeapFree( GetProcessHeap(), 0, xs->lpszName );
if (xs->lpszClass) HeapFree( GetProcessHeap(), 0, xs->lpszClass );
if (GetWindowLongA(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
{
MDICREATESTRUCTW *mdi_cs = (MDICREATESTRUCTW *)xs->cs.lpCreateParams;
if (HIWORD(mdi_cs->szTitle))
HeapFree(GetProcessHeap(), 0, (LPVOID)mdi_cs->szTitle);
if (HIWORD(mdi_cs->szClass))
HeapFree(GetProcessHeap(), 0, (LPVOID)mdi_cs->szClass);
HeapFree(GetProcessHeap(), 0, mdi_cs);
}
HeapFree( GetProcessHeap(), 0, xs );
}
break;
......@@ -952,6 +981,25 @@ INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plpara
if (HIWORD(cs->lpszClass))
cs->lpszClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
(LPCWSTR)cs->lpszClass);
if (GetWindowLongA(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
{
MDICREATESTRUCTA *mdi_cs = (MDICREATESTRUCTA *)HeapAlloc(GetProcessHeap(), 0,
sizeof(*mdi_cs));
if (!mdi_cs)
{
HeapFree(GetProcessHeap(), 0, cs);
return -1;
}
*mdi_cs = *(MDICREATESTRUCTA *)cs->lpCreateParams;
if (HIWORD(mdi_cs->szTitle))
mdi_cs->szTitle = HEAP_strdupWtoA(GetProcessHeap(), 0,
(LPCWSTR)mdi_cs->szTitle);
if (HIWORD(mdi_cs->szClass))
mdi_cs->szClass = HEAP_strdupWtoA(GetProcessHeap(), 0,
(LPCWSTR)mdi_cs->szClass);
cs->lpCreateParams = (LPVOID)mdi_cs;
}
*plparam = (LPARAM)cs;
}
return 1;
......@@ -1100,6 +1148,15 @@ void WINPROC_UnmapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam
HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszName );
if (HIWORD(cs->lpszClass))
HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszClass );
if (GetWindowLongA(hwnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
{
MDICREATESTRUCTA *mdi_cs = (MDICREATESTRUCTA *)cs->lpCreateParams;
if (HIWORD(mdi_cs->szTitle))
HeapFree(GetProcessHeap(), 0, (LPVOID)mdi_cs->szTitle);
if (HIWORD(mdi_cs->szClass))
HeapFree(GetProcessHeap(), 0, (LPVOID)mdi_cs->szClass);
HeapFree(GetProcessHeap(), 0, mdi_cs);
}
HeapFree( GetProcessHeap(), 0, cs );
}
break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment