user32: Moved the ShowWindow implementation from winex11 back to user32.

This commit is contained in:
Alexandre Julliard 2008-02-28 16:09:39 +01:00
parent 63dd1a02ca
commit 936ab3a644
9 changed files with 339 additions and 357 deletions

View File

@ -119,7 +119,6 @@ static const USER_DRIVER *load_driver(void)
GET_USER_FUNC(SetWindowIcon);
GET_USER_FUNC(SetWindowStyle);
GET_USER_FUNC(SetWindowText);
GET_USER_FUNC(ShowWindow);
GET_USER_FUNC(SysCommandSizeMove);
GET_USER_FUNC(WindowMessage);
#undef GET_USER_FUNC
@ -396,11 +395,6 @@ static void nulldrv_SetWindowText( HWND hwnd, LPCWSTR text )
{
}
static BOOL nulldrv_ShowWindow( HWND hwnd, INT cmd )
{
return FALSE;
}
static void nulldrv_SysCommandSizeMove( HWND hwnd, WPARAM wparam )
{
}
@ -465,7 +459,6 @@ static const USER_DRIVER null_driver =
nulldrv_SetWindowIcon,
nulldrv_SetWindowStyle,
nulldrv_SetWindowText,
nulldrv_ShowWindow,
nulldrv_SysCommandSizeMove,
nulldrv_WindowMessage
};
@ -721,11 +714,6 @@ static void loaderdrv_SetWindowText( HWND hwnd, LPCWSTR text )
load_driver()->pSetWindowText( hwnd, text );
}
static BOOL loaderdrv_ShowWindow( HWND hwnd, INT cmd )
{
return load_driver()->pShowWindow( hwnd, cmd );
}
static void loaderdrv_SysCommandSizeMove( HWND hwnd, WPARAM wparam )
{
load_driver()->pSysCommandSizeMove( hwnd, wparam );
@ -791,7 +779,6 @@ static const USER_DRIVER lazy_load_driver =
loaderdrv_SetWindowIcon,
loaderdrv_SetWindowStyle,
loaderdrv_SetWindowText,
loaderdrv_ShowWindow,
loaderdrv_SysCommandSizeMove,
loaderdrv_WindowMessage
};

View File

@ -789,7 +789,6 @@
#
@ cdecl HOOK_CallHooks(long long long long long)
@ cdecl USER_Unlock()
@ cdecl WINPOS_ActivateOtherWindow(long)
@ cdecl WINPOS_GetMinMaxInfo(long ptr ptr ptr ptr)
@ cdecl WINPOS_ShowIconTitle(long long)
@ cdecl WIN_GetPtr(long)

View File

@ -155,7 +155,6 @@ typedef struct tagUSER_DRIVER {
void (*pSetWindowIcon)(HWND,UINT,HICON);
void (*pSetWindowStyle)(HWND,DWORD);
void (*pSetWindowText)(HWND,LPCWSTR);
BOOL (*pShowWindow)(HWND,INT);
void (*pSysCommandSizeMove)(HWND,WPARAM);
LRESULT (*pWindowMessage)(HWND,UINT,WPARAM,LPARAM);
} USER_DRIVER;

View File

@ -868,7 +868,7 @@ static void dump_window_styles( DWORD style, DWORD exstyle )
*/
static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, LPCWSTR className, UINT flags )
{
INT cx, cy, sw = SW_SHOW;
INT cx, cy, style, sw = SW_SHOW;
LRESULT result;
RECT rect;
WND *wndPtr;
@ -1153,6 +1153,10 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, LPCWSTR className, UINT flags
result = SendMessageA( hwnd, WM_CREATE, 0, (LPARAM)cs );
if (result == -1) goto failed;
/* call the driver */
if (!USER_Driver->pCreateWindow( hwnd )) goto failed;
NotifyWinEvent(EVENT_OBJECT_CREATE, hwnd, OBJID_WINDOW, 0);
/* send the size messages */
@ -1168,9 +1172,19 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, LPCWSTR className, UINT flags
}
else WIN_ReleasePtr( wndPtr );
/* call the driver */
/* Show the window, maximizing or minimizing if needed */
if (!USER_Driver->pCreateWindow( hwnd )) goto failed;
style = WIN_SetStyle( hwnd, 0, WS_MAXIMIZE | WS_MINIMIZE );
if (style & (WS_MINIMIZE | WS_MAXIMIZE))
{
RECT newPos;
UINT swFlag = (style & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
swFlag = WINPOS_MinMaximize( hwnd, swFlag, &newPos );
swFlag |= SWP_FRAMECHANGED; /* Frame always gets changed */
if (!(style & WS_VISIBLE) || (style & WS_CHILD) || GetActiveWindow()) swFlag |= SWP_NOACTIVATE;
SetWindowPos( hwnd, 0, newPos.left, newPos.top, newPos.right, newPos.bottom, swFlag );
}
/* Notify the parent window only */

View File

@ -859,6 +859,323 @@ void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos,
if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
}
/***********************************************************************
* WINPOS_FindIconPos
*
* Find a suitable place for an iconic window.
*/
static POINT WINPOS_FindIconPos( HWND hwnd, POINT pt )
{
RECT rect, rectParent;
HWND parent, child;
HRGN hrgn, tmp;
int xspacing, yspacing;
parent = GetAncestor( hwnd, GA_PARENT );
GetClientRect( parent, &rectParent );
if ((pt.x >= rectParent.left) && (pt.x + GetSystemMetrics(SM_CXICON) < rectParent.right) &&
(pt.y >= rectParent.top) && (pt.y + GetSystemMetrics(SM_CYICON) < rectParent.bottom))
return pt; /* The icon already has a suitable position */
xspacing = GetSystemMetrics(SM_CXICONSPACING);
yspacing = GetSystemMetrics(SM_CYICONSPACING);
/* Check if another icon already occupies this spot */
/* FIXME: this is completely inefficient */
hrgn = CreateRectRgn( 0, 0, 0, 0 );
tmp = CreateRectRgn( 0, 0, 0, 0 );
for (child = GetWindow( parent, GW_HWNDFIRST ); child; child = GetWindow( child, GW_HWNDNEXT ))
{
WND *childPtr;
if (child == hwnd) continue;
if ((GetWindowLongW( child, GWL_STYLE ) & (WS_VISIBLE|WS_MINIMIZE)) != (WS_VISIBLE|WS_MINIMIZE))
continue;
if (!(childPtr = WIN_GetPtr( child )) || childPtr == WND_OTHER_PROCESS)
continue;
SetRectRgn( tmp, childPtr->rectWindow.left, childPtr->rectWindow.top,
childPtr->rectWindow.right, childPtr->rectWindow.bottom );
CombineRgn( hrgn, hrgn, tmp, RGN_OR );
WIN_ReleasePtr( childPtr );
}
DeleteObject( tmp );
for (rect.bottom = rectParent.bottom; rect.bottom >= yspacing; rect.bottom -= yspacing)
{
for (rect.left = rectParent.left; rect.left <= rectParent.right - xspacing; rect.left += xspacing)
{
rect.right = rect.left + xspacing;
rect.top = rect.bottom - yspacing;
if (!RectInRegion( hrgn, &rect ))
{
/* No window was found, so it's OK for us */
pt.x = rect.left + (xspacing - GetSystemMetrics(SM_CXICON)) / 2;
pt.y = rect.top + (yspacing - GetSystemMetrics(SM_CYICON)) / 2;
DeleteObject( hrgn );
return pt;
}
}
}
DeleteObject( hrgn );
pt.x = pt.y = 0;
return pt;
}
/***********************************************************************
* WINPOS_MinMaximize
*/
UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
{
WND *wndPtr;
UINT swpFlags = 0;
POINT size;
LONG old_style;
WINDOWPLACEMENT wpl;
TRACE("%p %u\n", hwnd, cmd );
wpl.length = sizeof(wpl);
GetWindowPlacement( hwnd, &wpl );
if (HOOK_CallHooks( WH_CBT, HCBT_MINMAX, (WPARAM)hwnd, cmd, TRUE ))
return SWP_NOSIZE | SWP_NOMOVE;
if (IsIconic( hwnd ))
{
switch (cmd)
{
case SW_SHOWMINNOACTIVE:
case SW_SHOWMINIMIZED:
case SW_FORCEMINIMIZE:
case SW_MINIMIZE:
return SWP_NOSIZE | SWP_NOMOVE;
}
if (!SendMessageW( hwnd, WM_QUERYOPEN, 0, 0 )) return SWP_NOSIZE | SWP_NOMOVE;
swpFlags |= SWP_NOCOPYBITS;
}
switch( cmd )
{
case SW_SHOWMINNOACTIVE:
case SW_SHOWMINIMIZED:
case SW_FORCEMINIMIZE:
case SW_MINIMIZE:
if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
if( wndPtr->dwStyle & WS_MAXIMIZE) wndPtr->flags |= WIN_RESTORE_MAX;
else wndPtr->flags &= ~WIN_RESTORE_MAX;
WIN_ReleasePtr( wndPtr );
old_style = WIN_SetStyle( hwnd, WS_MINIMIZE, WS_MAXIMIZE );
wpl.ptMinPosition = WINPOS_FindIconPos( hwnd, wpl.ptMinPosition );
if (!(old_style & WS_MINIMIZE)) swpFlags |= SWP_STATECHANGED;
SetRect( rect, wpl.ptMinPosition.x, wpl.ptMinPosition.y,
GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) );
swpFlags |= SWP_NOCOPYBITS;
break;
case SW_MAXIMIZE:
old_style = GetWindowLongW( hwnd, GWL_STYLE );
if ((old_style & WS_MAXIMIZE) && (old_style & WS_VISIBLE)) return SWP_NOSIZE | SWP_NOMOVE;
WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL );
old_style = WIN_SetStyle( hwnd, WS_MAXIMIZE, WS_MINIMIZE );
if (old_style & WS_MINIMIZE) WINPOS_ShowIconTitle( hwnd, FALSE );
if (!(old_style & WS_MAXIMIZE)) swpFlags |= SWP_STATECHANGED;
SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
break;
case SW_SHOWNOACTIVATE:
case SW_SHOWNORMAL:
case SW_RESTORE:
old_style = WIN_SetStyle( hwnd, 0, WS_MINIMIZE | WS_MAXIMIZE );
if (old_style & WS_MINIMIZE)
{
BOOL restore_max;
WINPOS_ShowIconTitle( hwnd, FALSE );
if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
restore_max = (wndPtr->flags & WIN_RESTORE_MAX) != 0;
WIN_ReleasePtr( wndPtr );
if (restore_max)
{
/* Restore to maximized position */
WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL);
WIN_SetStyle( hwnd, WS_MAXIMIZE, 0 );
swpFlags |= SWP_STATECHANGED;
SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
break;
}
}
else if (!(old_style & WS_MAXIMIZE)) break;
swpFlags |= SWP_STATECHANGED;
/* Restore to normal position */
*rect = wpl.rcNormalPosition;
rect->right -= rect->left;
rect->bottom -= rect->top;
break;
}
return swpFlags;
}
/***********************************************************************
* show_window
*
* Implementation of ShowWindow and ShowWindowAsync.
*/
static BOOL show_window( HWND hwnd, INT cmd )
{
WND *wndPtr;
HWND parent;
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
BOOL wasVisible = (style & WS_VISIBLE) != 0;
BOOL showFlag = TRUE;
RECT newPos = {0, 0, 0, 0};
UINT swp = 0;
TRACE("hwnd=%p, cmd=%d, wasVisible %d\n", hwnd, cmd, wasVisible);
switch(cmd)
{
case SW_HIDE:
if (!wasVisible) return FALSE;
showFlag = FALSE;
swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE;
if (hwnd != GetActiveWindow())
swp |= SWP_NOACTIVATE | SWP_NOZORDER;
break;
case SW_SHOWMINNOACTIVE:
swp |= SWP_NOACTIVATE | SWP_NOZORDER;
/* fall through */
case SW_MINIMIZE:
case SW_FORCEMINIMIZE: /* FIXME: Does not work if thread is hung. */
if (style & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
/* fall through */
case SW_SHOWMINIMIZED:
swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
swp |= WINPOS_MinMaximize( hwnd, cmd, &newPos );
if ((style & WS_MINIMIZE) && wasVisible) return TRUE;
break;
case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
if (!wasVisible) swp |= SWP_SHOWWINDOW;
swp |= SWP_FRAMECHANGED;
swp |= WINPOS_MinMaximize( hwnd, SW_MAXIMIZE, &newPos );
if ((style & WS_MAXIMIZE) && wasVisible) return TRUE;
break;
case SW_SHOWNA:
swp |= SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
if (style & WS_CHILD) swp |= SWP_NOZORDER;
break;
case SW_SHOW:
if (wasVisible) return TRUE;
swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
if (style & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
break;
case SW_SHOWNOACTIVATE:
swp |= SWP_NOACTIVATE | SWP_NOZORDER;
/* fall through */
case SW_RESTORE:
/* fall through */
case SW_SHOWNORMAL: /* same as SW_NORMAL: */
case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
if (!wasVisible) swp |= SWP_SHOWWINDOW;
if (style & (WS_MINIMIZE | WS_MAXIMIZE))
{
swp |= SWP_FRAMECHANGED;
swp |= WINPOS_MinMaximize( hwnd, cmd, &newPos );
}
else
{
if (wasVisible) return TRUE;
swp |= SWP_NOSIZE | SWP_NOMOVE;
}
if (style & WS_CHILD && !(swp & SWP_STATECHANGED)) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
break;
}
if ((showFlag != wasVisible || cmd == SW_SHOWNA) && cmd != SW_SHOWMAXIMIZED && !(swp & SWP_STATECHANGED))
{
SendMessageW( hwnd, WM_SHOWWINDOW, showFlag, 0 );
if (!IsWindow( hwnd )) return wasVisible;
}
parent = GetAncestor( hwnd, GA_PARENT );
if (parent && !IsWindowVisible( parent ) && !(swp & SWP_STATECHANGED))
{
/* if parent is not visible simply toggle WS_VISIBLE and return */
if (showFlag) WIN_SetStyle( hwnd, WS_VISIBLE, 0 );
else WIN_SetStyle( hwnd, 0, WS_VISIBLE );
}
else
SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top,
newPos.right, newPos.bottom, LOWORD(swp) );
if (cmd == SW_HIDE)
{
HWND hFocus;
/* FIXME: This will cause the window to be activated irrespective
* of whether it is owned by the same thread. Has to be done
* asynchronously.
*/
if (hwnd == GetActiveWindow())
WINPOS_ActivateOtherWindow(hwnd);
/* Revert focus to parent */
hFocus = GetFocus();
if (hwnd == hFocus || IsChild(hwnd, hFocus))
{
HWND parent = GetAncestor(hwnd, GA_PARENT);
if (parent == GetDesktopWindow()) parent = 0;
SetFocus(parent);
}
}
if (IsIconic(hwnd)) WINPOS_ShowIconTitle( hwnd, TRUE );
if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return wasVisible;
if (wndPtr->flags & WIN_NEED_SIZE)
{
/* should happen only in CreateWindowEx() */
int wParam = SIZE_RESTORED;
RECT client = wndPtr->rectClient;
wndPtr->flags &= ~WIN_NEED_SIZE;
if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED;
else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED;
WIN_ReleasePtr( wndPtr );
SendMessageW( hwnd, WM_SIZE, wParam,
MAKELONG( client.right - client.left, client.bottom - client.top ));
SendMessageW( hwnd, WM_MOVE, 0, MAKELONG( client.left, client.top ));
}
else WIN_ReleasePtr( wndPtr );
/* if previous state was minimized Windows sets focus to the window */
if (style & WS_MINIMIZE) SetFocus( hwnd );
return wasVisible;
}
/***********************************************************************
* ShowWindowAsync (USER32.@)
*
@ -876,7 +1193,7 @@ BOOL WINAPI ShowWindowAsync( HWND hwnd, INT cmd )
}
if ((full_handle = WIN_IsCurrentThread( hwnd )))
return USER_Driver->pShowWindow( full_handle, cmd );
return show_window( full_handle, cmd );
return SendNotifyMessageW( hwnd, WM_WINE_SHOWWINDOW, cmd, 0 );
}
@ -895,7 +1212,7 @@ BOOL WINAPI ShowWindow( HWND hwnd, INT cmd )
return FALSE;
}
if ((full_handle = WIN_IsCurrentThread( hwnd )))
return USER_Driver->pShowWindow( full_handle, cmd );
return show_window( full_handle, cmd );
return SendMessageW( hwnd, WM_WINE_SHOWWINDOW, cmd, 0 );
}

View File

@ -1376,33 +1376,12 @@ BOOL X11DRV_CreateDesktopWindow( HWND hwnd )
BOOL X11DRV_CreateWindow( HWND hwnd )
{
Display *display = thread_display();
DWORD style;
if (hwnd == GetDesktopWindow() && root_window != DefaultRootWindow( display ))
{
/* the desktop win data can't be created lazily */
if (!create_desktop_win_data( display, hwnd )) return FALSE;
}
/* Show the window, maximizing or minimizing if needed */
style = GetWindowLongW( hwnd, GWL_STYLE );
if (style & (WS_MINIMIZE | WS_MAXIMIZE))
{
extern UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect ); /*FIXME*/
RECT newPos;
UINT swFlag = (style & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
WIN_SetStyle( hwnd, 0, WS_MAXIMIZE | WS_MINIMIZE );
swFlag = WINPOS_MinMaximize( hwnd, swFlag, &newPos );
swFlag |= SWP_FRAMECHANGED; /* Frame always gets changed */
if (!(style & WS_VISIBLE) || (style & WS_CHILD) || GetActiveWindow()) swFlag |= SWP_NOACTIVATE;
SetWindowPos( hwnd, 0, newPos.left, newPos.top,
newPos.right, newPos.bottom, swFlag );
}
return TRUE;
}

View File

@ -110,7 +110,6 @@
@ cdecl SetWindowRgn(long long long) X11DRV_SetWindowRgn
@ cdecl SetWindowStyle(ptr long) X11DRV_SetWindowStyle
@ cdecl SetWindowText(long wstr) X11DRV_SetWindowText
@ cdecl ShowWindow(long long) X11DRV_ShowWindow
@ cdecl SysCommandSizeMove(long long) X11DRV_SysCommandSizeMove
@ cdecl WindowMessage(long long long long) X11DRV_WindowMessage

View File

@ -434,320 +434,6 @@ void X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, UINT swp_flags,
}
/***********************************************************************
* WINPOS_FindIconPos
*
* Find a suitable place for an iconic window.
*/
static POINT WINPOS_FindIconPos( HWND hwnd, POINT pt )
{
RECT rect, rectParent;
HWND parent, child;
HRGN hrgn, tmp;
int xspacing, yspacing;
parent = GetAncestor( hwnd, GA_PARENT );
GetClientRect( parent, &rectParent );
if ((pt.x >= rectParent.left) && (pt.x + GetSystemMetrics(SM_CXICON) < rectParent.right) &&
(pt.y >= rectParent.top) && (pt.y + GetSystemMetrics(SM_CYICON) < rectParent.bottom))
return pt; /* The icon already has a suitable position */
xspacing = GetSystemMetrics(SM_CXICONSPACING);
yspacing = GetSystemMetrics(SM_CYICONSPACING);
/* Check if another icon already occupies this spot */
/* FIXME: this is completely inefficient */
hrgn = CreateRectRgn( 0, 0, 0, 0 );
tmp = CreateRectRgn( 0, 0, 0, 0 );
for (child = GetWindow( parent, GW_HWNDFIRST ); child; child = GetWindow( child, GW_HWNDNEXT ))
{
WND *childPtr;
if (child == hwnd) continue;
if ((GetWindowLongW( child, GWL_STYLE ) & (WS_VISIBLE|WS_MINIMIZE)) != (WS_VISIBLE|WS_MINIMIZE))
continue;
if (!(childPtr = WIN_GetPtr( child )) || childPtr == WND_OTHER_PROCESS)
continue;
SetRectRgn( tmp, childPtr->rectWindow.left, childPtr->rectWindow.top,
childPtr->rectWindow.right, childPtr->rectWindow.bottom );
CombineRgn( hrgn, hrgn, tmp, RGN_OR );
WIN_ReleasePtr( childPtr );
}
DeleteObject( tmp );
for (rect.bottom = rectParent.bottom; rect.bottom >= yspacing; rect.bottom -= yspacing)
{
for (rect.left = rectParent.left; rect.left <= rectParent.right - xspacing; rect.left += xspacing)
{
rect.right = rect.left + xspacing;
rect.top = rect.bottom - yspacing;
if (!RectInRegion( hrgn, &rect ))
{
/* No window was found, so it's OK for us */
pt.x = rect.left + (xspacing - GetSystemMetrics(SM_CXICON)) / 2;
pt.y = rect.top + (yspacing - GetSystemMetrics(SM_CYICON)) / 2;
DeleteObject( hrgn );
return pt;
}
}
}
DeleteObject( hrgn );
pt.x = pt.y = 0;
return pt;
}
/***********************************************************************
* WINPOS_MinMaximize
*/
UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
{
WND *wndPtr;
UINT swpFlags = 0;
POINT size;
LONG old_style;
WINDOWPLACEMENT wpl;
TRACE("%p %u\n", hwnd, cmd );
wpl.length = sizeof(wpl);
GetWindowPlacement( hwnd, &wpl );
if (HOOK_CallHooks( WH_CBT, HCBT_MINMAX, (WPARAM)hwnd, cmd, TRUE ))
return SWP_NOSIZE | SWP_NOMOVE;
if (IsIconic( hwnd ))
{
switch (cmd)
{
case SW_SHOWMINNOACTIVE:
case SW_SHOWMINIMIZED:
case SW_FORCEMINIMIZE:
case SW_MINIMIZE:
return SWP_NOSIZE | SWP_NOMOVE;
}
if (!SendMessageW( hwnd, WM_QUERYOPEN, 0, 0 )) return SWP_NOSIZE | SWP_NOMOVE;
swpFlags |= SWP_NOCOPYBITS;
}
switch( cmd )
{
case SW_SHOWMINNOACTIVE:
case SW_SHOWMINIMIZED:
case SW_FORCEMINIMIZE:
case SW_MINIMIZE:
if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
if( wndPtr->dwStyle & WS_MAXIMIZE) wndPtr->flags |= WIN_RESTORE_MAX;
else wndPtr->flags &= ~WIN_RESTORE_MAX;
WIN_ReleasePtr( wndPtr );
old_style = WIN_SetStyle( hwnd, WS_MINIMIZE, WS_MAXIMIZE );
wpl.ptMinPosition = WINPOS_FindIconPos( hwnd, wpl.ptMinPosition );
if (!(old_style & WS_MINIMIZE)) swpFlags |= SWP_STATECHANGED;
SetRect( rect, wpl.ptMinPosition.x, wpl.ptMinPosition.y,
GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) );
swpFlags |= SWP_NOCOPYBITS;
break;
case SW_MAXIMIZE:
old_style = GetWindowLongW( hwnd, GWL_STYLE );
if ((old_style & WS_MAXIMIZE) && (old_style & WS_VISIBLE)) return SWP_NOSIZE | SWP_NOMOVE;
WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL );
old_style = WIN_SetStyle( hwnd, WS_MAXIMIZE, WS_MINIMIZE );
if (old_style & WS_MINIMIZE) WINPOS_ShowIconTitle( hwnd, FALSE );
if (!(old_style & WS_MAXIMIZE)) swpFlags |= SWP_STATECHANGED;
SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
break;
case SW_SHOWNOACTIVATE:
case SW_SHOWNORMAL:
case SW_RESTORE:
old_style = WIN_SetStyle( hwnd, 0, WS_MINIMIZE | WS_MAXIMIZE );
if (old_style & WS_MINIMIZE)
{
BOOL restore_max;
WINPOS_ShowIconTitle( hwnd, FALSE );
if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
restore_max = (wndPtr->flags & WIN_RESTORE_MAX) != 0;
WIN_ReleasePtr( wndPtr );
if (restore_max)
{
/* Restore to maximized position */
WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL);
WIN_SetStyle( hwnd, WS_MAXIMIZE, 0 );
swpFlags |= SWP_STATECHANGED;
SetRect( rect, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, size.x, size.y );
break;
}
}
else if (!(old_style & WS_MAXIMIZE)) break;
swpFlags |= SWP_STATECHANGED;
/* Restore to normal position */
*rect = wpl.rcNormalPosition;
rect->right -= rect->left;
rect->bottom -= rect->top;
break;
}
return swpFlags;
}
/***********************************************************************
* ShowWindow (X11DRV.@)
*/
BOOL X11DRV_ShowWindow( HWND hwnd, INT cmd )
{
WND *wndPtr;
HWND parent;
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
BOOL wasVisible = (style & WS_VISIBLE) != 0;
BOOL showFlag = TRUE;
RECT newPos = {0, 0, 0, 0};
UINT swp = 0;
TRACE("hwnd=%p, cmd=%d, wasVisible %d\n", hwnd, cmd, wasVisible);
switch(cmd)
{
case SW_HIDE:
if (!wasVisible) return FALSE;
showFlag = FALSE;
swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE;
if (hwnd != GetActiveWindow())
swp |= SWP_NOACTIVATE | SWP_NOZORDER;
break;
case SW_SHOWMINNOACTIVE:
swp |= SWP_NOACTIVATE | SWP_NOZORDER;
/* fall through */
case SW_MINIMIZE:
case SW_FORCEMINIMIZE: /* FIXME: Does not work if thread is hung. */
if (style & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
/* fall through */
case SW_SHOWMINIMIZED:
swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
swp |= WINPOS_MinMaximize( hwnd, cmd, &newPos );
if ((style & WS_MINIMIZE) && wasVisible) return TRUE;
break;
case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
if (!wasVisible) swp |= SWP_SHOWWINDOW;
swp |= SWP_FRAMECHANGED;
swp |= WINPOS_MinMaximize( hwnd, SW_MAXIMIZE, &newPos );
if ((style & WS_MAXIMIZE) && wasVisible) return TRUE;
break;
case SW_SHOWNA:
swp |= SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
if (style & WS_CHILD) swp |= SWP_NOZORDER;
break;
case SW_SHOW:
if (wasVisible) return TRUE;
swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
if (style & WS_CHILD) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
break;
case SW_SHOWNOACTIVATE:
swp |= SWP_NOACTIVATE | SWP_NOZORDER;
/* fall through */
case SW_RESTORE:
/* fall through */
case SW_SHOWNORMAL: /* same as SW_NORMAL: */
case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
if (!wasVisible) swp |= SWP_SHOWWINDOW;
if (style & (WS_MINIMIZE | WS_MAXIMIZE))
{
swp |= SWP_FRAMECHANGED;
swp |= WINPOS_MinMaximize( hwnd, cmd, &newPos );
}
else
{
if (wasVisible) return TRUE;
swp |= SWP_NOSIZE | SWP_NOMOVE;
}
if (style & WS_CHILD && !(swp & SWP_STATECHANGED)) swp |= SWP_NOACTIVATE | SWP_NOZORDER;
break;
}
if ((showFlag != wasVisible || cmd == SW_SHOWNA) && cmd != SW_SHOWMAXIMIZED && !(swp & SWP_STATECHANGED))
{
SendMessageW( hwnd, WM_SHOWWINDOW, showFlag, 0 );
if (!IsWindow( hwnd )) return wasVisible;
}
parent = GetAncestor( hwnd, GA_PARENT );
if (parent && !IsWindowVisible( parent ) && !(swp & SWP_STATECHANGED))
{
/* if parent is not visible simply toggle WS_VISIBLE and return */
if (showFlag) WIN_SetStyle( hwnd, WS_VISIBLE, 0 );
else WIN_SetStyle( hwnd, 0, WS_VISIBLE );
}
else
SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top,
newPos.right, newPos.bottom, LOWORD(swp) );
if (cmd == SW_HIDE)
{
HWND hFocus;
/* FIXME: This will cause the window to be activated irrespective
* of whether it is owned by the same thread. Has to be done
* asynchronously.
*/
if (hwnd == GetActiveWindow())
WINPOS_ActivateOtherWindow(hwnd);
/* Revert focus to parent */
hFocus = GetFocus();
if (hwnd == hFocus || IsChild(hwnd, hFocus))
{
HWND parent = GetAncestor(hwnd, GA_PARENT);
if (parent == GetDesktopWindow()) parent = 0;
SetFocus(parent);
}
}
if (IsIconic(hwnd)) WINPOS_ShowIconTitle( hwnd, TRUE );
if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return wasVisible;
if (wndPtr->flags & WIN_NEED_SIZE)
{
/* should happen only in CreateWindowEx() */
int wParam = SIZE_RESTORED;
RECT client = wndPtr->rectClient;
wndPtr->flags &= ~WIN_NEED_SIZE;
if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED;
else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED;
WIN_ReleasePtr( wndPtr );
SendMessageW( hwnd, WM_SIZE, wParam,
MAKELONG( client.right - client.left, client.bottom - client.top ));
SendMessageW( hwnd, WM_MOVE, 0, MAKELONG( client.left, client.top ));
}
else WIN_ReleasePtr( wndPtr );
/* if previous state was minimized Windows sets focus to the window */
if (style & WS_MINIMIZE) SetFocus( hwnd );
return wasVisible;
}
/**********************************************************************
* X11DRV_MapNotify
*/

View File

@ -115,8 +115,10 @@ extern LONG WINPOS_HandleWindowPosChanging(HWND hwnd, WINDOWPOS *winpos) DECLSPE
extern HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest ) DECLSPEC_HIDDEN;
extern void WINPOS_CheckInternalPos( HWND hwnd ) DECLSPEC_HIDDEN;
extern void WINPOS_ActivateOtherWindow( HWND hwnd ) DECLSPEC_HIDDEN;
extern UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect ) DECLSPEC_HIDDEN;
extern BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *window_rect, const RECT *client_rect, const RECT *valid_rects );
const RECT *window_rect, const RECT *client_rect,
const RECT *valid_rects ) DECLSPEC_HIDDEN;
#endif /* __WINE_WIN_H */