Newer
Older
* 1995, 1996, 1999 Alex Korobka
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include <stdarg.h>
#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "wine/winuser16.h"
#include "wine/server.h"
#include "controls.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(win);
#define HAS_DLGFRAME(style,exStyle) \
(((exStyle) & WS_EX_DLGMODALFRAME) || \
(((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
#define HAS_THICKFRAME(style) \
(((style) & WS_THICKFRAME) && \
!(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
#define EMPTYPOINT(pt) ((*(LONG*)&(pt)) == -1)
#define PLACE_MIN 0x0001
#define PLACE_MAX 0x0002
#define PLACE_RECT 0x0004
#define DWP_MAGIC ((INT)('W' | ('P' << 8) | ('O' << 16) | ('S' << 24)))
typedef struct
{
INT actualCount;
INT suggestedCount;
BOOL valid;
INT wMagic;
HWND hwndParent;
WINDOWPOS winPos[1];
} DWP;
static HWND hGlobalShellWindow=0; /*the shell*/
static HWND hGlobalTaskmanWindow=0;
static HWND hGlobalProgmanWindow=0;
/***********************************************************************
BOOL WINPOS_CreateInternalPosAtom()
atomInternalPos = (LPCSTR)(DWORD)GlobalAddAtomA(str);
return (atomInternalPos) ? TRUE : FALSE;
}
/***********************************************************************
* WINPOS_CheckInternalPos
*
* Called when a window is destroyed.
*/
void WINPOS_CheckInternalPos( HWND hwnd )
LPINTERNALPOS lpPos = (LPINTERNALPOS) GetPropA( hwnd, atomInternalPos );
DestroyWindow( lpPos->hwndIconTitle );
HeapFree( GetProcessHeap(), 0, lpPos );
/***********************************************************************
UINT WINAPI ArrangeIconicWindows( HWND parent )
RECT rectParent;
HWND hwndChild;
INT x, y, xspacing, yspacing;
GetClientRect( parent, &rectParent );
xspacing = GetSystemMetrics(SM_CXICONSPACING);
yspacing = GetSystemMetrics(SM_CYICONSPACING);
hwndChild = GetWindow( parent, GW_CHILD );
if( IsIconic( hwndChild ) )
WINPOS_ShowIconTitle( hwndChild, FALSE );
SetWindowPos( hwndChild, 0, x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2,
y - yspacing - GetSystemMetrics(SM_CYICON)/2, 0, 0,
if( IsWindow(hwndChild) )
WINPOS_ShowIconTitle(hwndChild , TRUE );
if (x <= rectParent.right - xspacing) x += xspacing;
else
{
x = rectParent.left;
y -= yspacing;
}
}
hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
/***********************************************************************
void WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore )
ShowWindow( hwnd, restore ? SW_RESTORE : SW_SHOWMINIMIZED );
/***********************************************************************
BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect )
BOOL ret = WIN_GetRectangles( hwnd, rect, NULL );
if (ret)
{
MapWindowPoints( GetAncestor( hwnd, GA_PARENT ), 0, (POINT *)rect, 2 );
TRACE( "hwnd %p (%ld,%ld)-(%ld,%ld)\n",
hwnd, rect->left, rect->top, rect->right, rect->bottom);
}
return ret;
/***********************************************************************
int WINAPI GetWindowRgn ( HWND hwnd, HRGN hrgn )
{
int nRet = ERROR;
WND *wndPtr = WIN_GetPtr( hwnd );
if (wndPtr == WND_OTHER_PROCESS)
{
if (IsWindow( hwnd ))
FIXME( "not supported on other process window %p\n", hwnd );
wndPtr = NULL;
}
if (!wndPtr)
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return ERROR;
if (wndPtr->hrgnWnd) nRet = CombineRgn( hrgn, wndPtr->hrgnWnd, 0, RGN_COPY );
WIN_ReleasePtr( wndPtr );
return nRet;
}
/***********************************************************************
*/
int WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL bRedraw )
RECT rect;
WND *wndPtr;
if (hrgn) /* verify that region really exists */
{
if (GetRgnBox( hrgn, &rect ) == ERROR) return FALSE;
}
if (USER_Driver.pSetWindowRgn)
return USER_Driver.pSetWindowRgn( hwnd, hrgn, bRedraw );
if ((wndPtr = WIN_GetPtr( hwnd )) == WND_OTHER_PROCESS)
if (IsWindow( hwnd ))
FIXME( "not supported on other process window %p\n", hwnd );
wndPtr = NULL;
}
if (!wndPtr)
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return FALSE;
if (wndPtr->hrgnWnd == hrgn)
WIN_ReleasePtr( wndPtr );
return TRUE;
if (wndPtr->hrgnWnd)
{
/* delete previous region */
DeleteObject(wndPtr->hrgnWnd);
wndPtr->hrgnWnd = 0;
}
wndPtr->hrgnWnd = hrgn;
WIN_ReleasePtr( wndPtr );
/* Size the window to the rectangle of the new region (if it isn't NULL) */
if (hrgn) SetWindowPos( hwnd, 0, rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
SWP_NOSIZE | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE |
SWP_NOZORDER | (bRedraw ? 0 : SWP_NOREDRAW) );
return TRUE;
/***********************************************************************
BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect )
BOOL ret;
rect->right = rect->bottom = 0;
if ((ret = WIN_GetRectangles( hwnd, NULL, rect )))
{
rect->right -= rect->left;
rect->bottom -= rect->top;
}
return ret;
}
/*******************************************************************
BOOL WINAPI ClientToScreen( HWND hwnd, LPPOINT lppnt )
MapWindowPoints( hwnd, 0, lppnt, 1 );
return TRUE;
}
/*******************************************************************
BOOL WINAPI ScreenToClient( HWND hwnd, LPPOINT lppnt )
MapWindowPoints( 0, hwnd, lppnt, 1 );
/***********************************************************************
* find_child_from_point
*
* Find the child that contains pt. Helper for WindowFromPoint.
* pt is in parent client coordinates.
* lparam is the param to pass in the WM_NCHITTEST message.
*/
static HWND find_child_from_point( HWND parent, POINT pt, INT *hittest, LPARAM lparam )
{
int i, res;
LONG style, exstyle;
RECT rectWindow, rectClient;
WND *wndPtr;
HWND *list = WIN_ListChildren( parent );
if (!list) return 0;
for (i = 0; list[i]; i++)
{
/* If point is in window, and window is visible, and it */
/* is enabled (or it's a top-level window), then explore */
/* its children. Otherwise, go to the next window. */
style = GetWindowLongW( list[i], GWL_STYLE );
if (!(style & WS_VISIBLE)) continue; /* not visible -> skip */
if ((style & (WS_POPUP | WS_CHILD | WS_DISABLED)) == (WS_CHILD | WS_DISABLED))
continue; /* disabled child -> skip */
exstyle = GetWindowLongW( list[i], GWL_EXSTYLE );
if ((exstyle & (WS_EX_LAYERED | WS_EX_TRANSPARENT)) == (WS_EX_LAYERED | WS_EX_TRANSPARENT))
continue; /* transparent -> skip */
if (!WIN_GetRectangles( list[i], &rectWindow, &rectClient )) continue;
if (!PtInRect( &rectWindow, pt )) continue; /* not in window -> skip */
/* FIXME: check window region for other processes too */
if ((wndPtr = WIN_GetPtr( list[i] )) && wndPtr != WND_OTHER_PROCESS)
if (wndPtr->hrgnWnd && !PtInRegion( wndPtr->hrgnWnd,
pt.x - rectWindow.left, pt.y - rectWindow.top ))
{
WIN_ReleasePtr( wndPtr );
continue; /* point outside window region -> skip */
}
WIN_ReleasePtr( wndPtr );
}
/* If window is minimized or disabled, return at once */
{
*hittest = HTCAPTION;
retvalue = list[i];
break;
{
*hittest = HTERROR;
retvalue = list[i];
break;
}
/* If point is in client area, explore children */
{
POINT new_pt;
new_pt.x = pt.x - rectClient.left;
new_pt.y = pt.y - rectClient.top;
if ((retvalue = find_child_from_point( list[i], new_pt, hittest, lparam ))) break;
}
/* Now it's inside window, send WM_NCCHITTEST (if same thread) */
if (!WIN_IsCurrentThread( list[i] ))
{
*hittest = HTCLIENT;
retvalue = list[i];
break;
}
if ((res = SendMessageA( list[i], WM_NCHITTEST, 0, lparam )) != HTTRANSPARENT)
{
*hittest = res; /* Found the window */
retvalue = list[i];
break;
/* continue search with next sibling */
HeapFree( GetProcessHeap(), 0, list );
return retvalue;
}
/***********************************************************************
* WINPOS_WindowFromPoint

Alexandre Julliard
committed
HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest )
POINT xy = pt;
int res;
TRACE("scope %p %ld,%ld\n", hwndScope, pt.x, pt.y);

Alexandre Julliard
committed
if (!hwndScope) hwndScope = GetDesktopWindow();
style = GetWindowLongW( hwndScope, GWL_STYLE );

Alexandre Julliard
committed
*hittest = HTERROR;
if (style & WS_DISABLED) return 0;
MapWindowPoints( GetDesktopWindow(), GetAncestor( hwndScope, GA_PARENT ), &xy, 1 );
RECT rectClient;
if (WIN_GetRectangles( hwndScope, NULL, &rectClient ) && PtInRect( &rectClient, xy ))
{
HWND ret;
xy.x -= rectClient.left;
xy.y -= rectClient.top;
if ((ret = find_child_from_point( hwndScope, xy, hittest, MAKELONG( pt.x, pt.y ) )))
{
}
/* If nothing found, try the scope window */
if (!WIN_IsCurrentThread( hwndScope ))
{
*hittest = HTCLIENT;
TRACE( "returning %p\n", hwndScope );
return hwndScope;
}
res = SendMessageA( hwndScope, WM_NCHITTEST, 0, MAKELONG( pt.x, pt.y ) );
if (res != HTTRANSPARENT)
{
*hittest = res; /* Found the window */
TRACE( "returning %p\n", hwndScope );
return hwndScope;
}
*hittest = HTNOWHERE;
TRACE( "nothing found\n" );
return 0;
/*******************************************************************
HWND WINAPI WindowFromPoint( POINT pt )

Alexandre Julliard
committed
INT hittest;
return WINPOS_WindowFromPoint( 0, pt, &hittest );
/*******************************************************************
HWND WINAPI ChildWindowFromPoint( HWND hwndParent, POINT pt )
return ChildWindowFromPointEx( hwndParent, pt, CWP_ALL );
/*******************************************************************
HWND WINAPI ChildWindowFromPointEx( HWND hwndParent, POINT pt, UINT uFlags)
{
/* pt is in the client coordinates */
HWND *list;
int i;
RECT rect;
GetClientRect( hwndParent, &rect );
if (!PtInRect( &rect, pt )) return 0;
if (!(list = WIN_ListChildren( hwndParent ))) return 0;
if (!WIN_GetRectangles( list[i], &rect, NULL )) continue;
if (!PtInRect( &rect, pt )) continue;
if (uFlags & (CWP_SKIPINVISIBLE|CWP_SKIPDISABLED))
{
LONG style = GetWindowLongW( list[i], GWL_STYLE );
if ((uFlags & CWP_SKIPINVISIBLE) && !(style & WS_VISIBLE)) continue;
if ((uFlags & CWP_SKIPDISABLED) && (style & WS_DISABLED)) continue;
}
if (uFlags & CWP_SKIPTRANSPARENT)
if (GetWindowLongW( list[i], GWL_EXSTYLE ) & WS_EX_TRANSPARENT) continue;
HeapFree( GetProcessHeap(), 0, list );
if (!retvalue) retvalue = hwndParent;
/*******************************************************************
* WINPOS_GetWinOffset
*
* Calculate the offset between the origin of the two windows. Used
* to implement MapWindowPoints.
*/
static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, POINT *offset )
WND * wndPtr;
/* Translate source window origin to screen coords */
HWND hwnd = hwndFrom;
while (hwnd)
if (hwnd == hwndTo) return;
if (!(wndPtr = WIN_GetPtr( hwnd )))
ERR( "bad hwndFrom = %p\n", hwnd );
return;
if (wndPtr == WND_OTHER_PROCESS) goto other_process;
offset->x += wndPtr->rectClient.left;
offset->y += wndPtr->rectClient.top;
hwnd = wndPtr->parent;
WIN_ReleasePtr( wndPtr );
/* Translate origin to destination window coords */
HWND hwnd = hwndTo;
while (hwnd)
if (!(wndPtr = WIN_GetPtr( hwnd )))
return;
if (wndPtr == WND_OTHER_PROCESS) goto other_process;
offset->x -= wndPtr->rectClient.left;
offset->y -= wndPtr->rectClient.top;
hwnd = wndPtr->parent;
WIN_ReleasePtr( wndPtr );
}
}
return;
other_process: /* one of the parents may belong to another process, do it the hard way */
offset->x = offset->y = 0;
SERVER_START_REQ( get_windows_offset )
{
req->from = hwndFrom;
req->to = hwndTo;
if (!wine_server_call( req ))
{
offset->x = reply->x;
offset->y = reply->y;
SERVER_END_REQ;
}
/*******************************************************************
void WINAPI MapWindowPoints16( HWND16 hwndFrom, HWND16 hwndTo,
LPPOINT16 lppt, UINT16 count )
POINT offset;
WINPOS_GetWinOffset( WIN_Handle32(hwndFrom), WIN_Handle32(hwndTo), &offset );
while (count--)
{
lppt->x += offset.x;
lppt->y += offset.y;
lppt++;
}
}
/*******************************************************************
INT WINAPI MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, UINT count )
POINT offset;
WINPOS_GetWinOffset( hwndFrom, hwndTo, &offset );
lppt->x += offset.x;
lppt->y += offset.y;
lppt++;
return MAKELONG( LOWORD(offset.x), LOWORD(offset.y) );
/***********************************************************************
BOOL WINAPI IsIconic(HWND hWnd)
return (GetWindowLongW( hWnd, GWL_STYLE ) & WS_MINIMIZE) != 0;
/***********************************************************************
BOOL WINAPI IsZoomed(HWND hWnd)
return (GetWindowLongW( hWnd, GWL_STYLE ) & WS_MAXIMIZE) != 0;
/*******************************************************************
*/
BOOL WINAPI AllowSetForegroundWindow( DWORD procid )
{
/* FIXME: If Win98/2000 style SetForegroundWindow behavior is
* implemented, then fix this function. */
return TRUE;
}
/*******************************************************************
*/
BOOL WINAPI LockSetForegroundWindow( UINT lockcode )
{
/* FIXME: If Win98/2000 style SetForegroundWindow behavior is
* implemented, then fix this function. */
return TRUE;
}
/*******************************************************************
HWND WINAPI SetShellWindow(HWND hwndshell)
{ WARN("(hWnd=%p) semi stub\n",hwndshell );
hGlobalShellWindow = WIN_GetFullHandle( hwndshell );
/*******************************************************************
HWND WINAPI GetShellWindow(void)
{ WARN("(hWnd=%p) semi stub\n",hGlobalShellWindow );
/***********************************************************************
BOOL WINAPI BringWindowToTop( HWND hwnd )
return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
/***********************************************************************
BOOL WINAPI MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy,
BOOL repaint )
int flags = SWP_NOZORDER | SWP_NOACTIVATE;
if (!repaint) flags |= SWP_NOREDRAW;
TRACE("%p %d,%d %dx%d %d\n", hwnd, x, y, cx, cy, repaint );
return SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
/***********************************************************************
* WINPOS_InitInternalPos
*/
static LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd, POINT pt, const RECT *restoreRect )
LPINTERNALPOS lpPos = (LPINTERNALPOS) GetPropA( wnd->hwndSelf,
/* this happens when the window is minimized/maximized
* for the first time (rectWindow is not adjusted yet) */
lpPos = HeapAlloc( GetProcessHeap(), 0, sizeof(INTERNALPOS) );
SetPropA( wnd->hwndSelf, atomInternalPos, (HANDLE)lpPos );
lpPos->hwndIconTitle = 0; /* defer until needs to be shown */
CONV_RECT32TO16( &wnd->rectWindow, &lpPos->rectNormal );
*(UINT*)&lpPos->ptIconPos = *(UINT*)&lpPos->ptMaxPos = 0xFFFFFFFF;
return lpPos;
}
/***********************************************************************
* WINPOS_RedrawIconTitle
*/
BOOL WINPOS_RedrawIconTitle( HWND hWnd )
LPINTERNALPOS lpPos = (LPINTERNALPOS)GetPropA( hWnd, atomInternalPos );
if( lpPos )
{
if( lpPos->hwndIconTitle )
{
SendMessageA( lpPos->hwndIconTitle, WM_SHOWWINDOW, TRUE, 0);
InvalidateRect( lpPos->hwndIconTitle, NULL, TRUE );
return TRUE;
}
}
return FALSE;
}
/***********************************************************************
* WINPOS_ShowIconTitle
*/
BOOL WINPOS_ShowIconTitle( HWND hwnd, BOOL bShow )
LPINTERNALPOS lpPos = (LPINTERNALPOS)GetPropA( hwnd, atomInternalPos );
if( lpPos && !(GetWindowLongA( hwnd, GWL_EXSTYLE) & WS_EX_MANAGED))
HWND title = lpPos->hwndIconTitle;
TRACE("%p %i\n", hwnd, (bShow != 0) );
if( !title )
lpPos->hwndIconTitle = title = ICONTITLE_Create( hwnd );
if (!IsWindowVisible(title))
{
SendMessageA( title, WM_SHOWWINDOW, TRUE, 0 );
SetWindowPos( title, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW );
}
else ShowWindow( title, SW_HIDE );
}
return FALSE;
}
/*******************************************************************
* WINPOS_GetMinMaxInfo
*
* Get the minimized and maximized information for a window.
*/
void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos,
POINT *minTrack, POINT *maxTrack )
MINMAXINFO MinMax;
INT xinc, yinc;
LONG style = GetWindowLongA( hwnd, GWL_STYLE );
LONG exstyle = GetWindowLongA( hwnd, GWL_EXSTYLE );
MinMax.ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
MinMax.ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN);
MinMax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
MinMax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK);
MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXSCREEN);
MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYSCREEN);
if (HAS_DLGFRAME( style, exstyle ))
xinc = GetSystemMetrics(SM_CXDLGFRAME);
yinc = GetSystemMetrics(SM_CYDLGFRAME);
if (HAS_THICKFRAME(style))
xinc += GetSystemMetrics(SM_CXFRAME);
yinc += GetSystemMetrics(SM_CYFRAME);
if (style & WS_BORDER)
xinc += GetSystemMetrics(SM_CXBORDER);
yinc += GetSystemMetrics(SM_CYBORDER);
MinMax.ptMaxSize.x += 2 * xinc;
MinMax.ptMaxSize.y += 2 * yinc;
lpPos = (LPINTERNALPOS)GetPropA( hwnd, atomInternalPos );
CONV_POINT16TO32( &lpPos->ptMaxPos, &MinMax.ptMaxPosition );
MinMax.ptMaxPosition.x = -xinc;
MinMax.ptMaxPosition.y = -yinc;
SendMessageA( hwnd, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
TRACE("%ld %ld / %ld %ld / %ld %ld / %ld %ld\n",
MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y);
MinMax.ptMaxTrackSize.x = max( MinMax.ptMaxTrackSize.x,
MinMax.ptMaxTrackSize.y = max( MinMax.ptMaxTrackSize.y,
MinMax.ptMinTrackSize.y );
if (maxSize) *maxSize = MinMax.ptMaxSize;
if (maxPos) *maxPos = MinMax.ptMaxPosition;
if (minTrack) *minTrack = MinMax.ptMinTrackSize;
if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
/***********************************************************************
*
* doesn't wait; returns immediately.
* used by threads to toggle windows in other (possibly hanging) threads
*/
BOOL WINAPI ShowWindowAsync( HWND hwnd, INT cmd )
if (is_broadcast(hwnd))
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if ((full_handle = WIN_IsCurrentThread( hwnd )))
return USER_Driver.pShowWindow( full_handle, cmd );
return SendNotifyMessageW( hwnd, WM_WINE_SHOWWINDOW, cmd, 0 );
/***********************************************************************
BOOL WINAPI ShowWindow( HWND hwnd, INT cmd )
{
HWND full_handle;
if (is_broadcast(hwnd))
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if ((full_handle = WIN_IsCurrentThread( hwnd )))
{
if (USER_Driver.pShowWindow)
return USER_Driver.pShowWindow( full_handle, cmd );
return FALSE;
}
return SendMessageW( hwnd, WM_WINE_SHOWWINDOW, cmd, 0 );
/***********************************************************************
UINT WINAPI GetInternalWindowPos( HWND hwnd, LPRECT rectWnd,
LPPOINT ptIcon )
WINDOWPLACEMENT wndpl;
if (GetWindowPlacement( hwnd, &wndpl ))
{
if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
if (ptIcon) *ptIcon = wndpl.ptMinPosition;
return wndpl.showCmd;
}
return 0;
/***********************************************************************
*
* Win95:
* Fails if wndpl->length of Win95 (!) apps is invalid.
BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
WND *pWnd = WIN_FindWndPtr( hwnd );
LPINTERNALPOS lpPos;
if(!pWnd ) return FALSE;
lpPos = WINPOS_InitInternalPos( pWnd, *(LPPOINT)&pWnd->rectWindow.left, &pWnd->rectWindow );
wndpl->length = sizeof(*wndpl);
if( pWnd->dwStyle & WS_MINIMIZE )
wndpl->showCmd = SW_SHOWMINIMIZED;
else
wndpl->showCmd = ( pWnd->dwStyle & WS_MAXIMIZE ) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL ;
if( pWnd->flags & WIN_RESTORE_MAX )
wndpl->flags = WPF_RESTORETOMAXIMIZED;
else
wndpl->flags = 0;
CONV_POINT16TO32( &lpPos->ptIconPos, &wndpl->ptMinPosition );
CONV_POINT16TO32( &lpPos->ptMaxPos, &wndpl->ptMaxPosition );
CONV_RECT16TO32( &lpPos->rectNormal, &wndpl->rcNormalPosition );
WIN_ReleaseWndPtr(pWnd);
return TRUE;
}
/***********************************************************************
static BOOL WINPOS_SetPlacement( HWND hwnd, const WINDOWPLACEMENT *wndpl, UINT flags )
WND *pWnd = WIN_FindWndPtr( hwnd );
if( pWnd )
{
LPINTERNALPOS lpPos = (LPINTERNALPOS)WINPOS_InitInternalPos( pWnd,
*(LPPOINT)&pWnd->rectWindow.left, &pWnd->rectWindow );
if( flags & PLACE_MIN ) CONV_POINT32TO16( &wndpl->ptMinPosition, &lpPos->ptIconPos );
if( flags & PLACE_MAX ) CONV_POINT32TO16( &wndpl->ptMaxPosition, &lpPos->ptMaxPos );
if( flags & PLACE_RECT) CONV_RECT32TO16( &wndpl->rcNormalPosition, &lpPos->rectNormal );
WINPOS_ShowIconTitle( pWnd->hwndSelf, FALSE );
if( wndpl->flags & WPF_SETMINPOSITION && !EMPTYPOINT(lpPos->ptIconPos))
SetWindowPos( hwnd, 0, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
else if( pWnd->dwStyle & WS_MAXIMIZE )
{
if( !EMPTYPOINT(lpPos->ptMaxPos) )
SetWindowPos( hwnd, 0, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
}
else if( flags & PLACE_RECT )
SetWindowPos( hwnd, 0, lpPos->rectNormal.left, lpPos->rectNormal.top,
lpPos->rectNormal.right - lpPos->rectNormal.left,
lpPos->rectNormal.bottom - lpPos->rectNormal.top,
SWP_NOZORDER | SWP_NOACTIVATE );
ShowWindow( hwnd, wndpl->showCmd );
if( IsWindow(hwnd) && pWnd->dwStyle & WS_MINIMIZE )
if( pWnd->dwStyle & WS_VISIBLE ) WINPOS_ShowIconTitle( pWnd->hwndSelf, TRUE );
/* SDK: ...valid only the next time... */
if( wndpl->flags & WPF_RESTORETOMAXIMIZED ) pWnd->flags |= WIN_RESTORE_MAX;
}
/***********************************************************************
*
* Win95:
* Fails if wndpl->length of Win95 (!) apps is invalid.
BOOL WINAPI SetWindowPlacement( HWND hwnd, const WINDOWPLACEMENT *wpl )
if (!wpl) return FALSE;
return WINPOS_SetPlacement( hwnd, wpl, PLACE_MIN | PLACE_MAX | PLACE_RECT );
/***********************************************************************
* AnimateWindow (USER32.@)
* Shows/Hides a window with an animation
* NO ANIMATION YET
*/
BOOL WINAPI AnimateWindow(HWND hwnd, DWORD dwTime, DWORD dwFlags)
{
FIXME("partial stub\n");
/* If trying to show/hide and it's already *
* shown/hidden or invalid window, fail with *
* invalid parameter */
if(!IsWindow(hwnd) ||
(IsWindowVisible(hwnd) && !(dwFlags & AW_HIDE)) ||
(!IsWindowVisible(hwnd) && (dwFlags & AW_HIDE)))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;