user32: Moved the ShowWindow implementation from winex11 back to user32.
This commit is contained in:
parent
63dd1a02ca
commit
936ab3a644
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue