Tue Feb 1 21:14:47 1994 Bob Amstadt (bob@pooh) * [loader/selector.c] Added function CreateNewSegments(). Modified IPCCopySelector to allow aliasing to any arbitrary memory space. * [memory/global.c] Fixed potential bug in GlobalGetFreeSegments(). * [memory/linear.c] Created functions GlobalLinearLock() and GlobalLinearUnlock(). Tue Feb 1 05:51:43 1994 julliard@di.epfl.ch (Alexandre Julliard) * [controls/widgets.c] Removed CAPTION window class. * [loader/cursor.c] Bug fix in LoadCursor(): don't allocate memory every time for built-in cursors. * [windows/clipping.c] Invalidate child windows in InvalidateRgn(). * [windows/defwnd.c] Added repaint of the caption when changing window text. * [windows/event.c] Modified SetCapture() to allow keyboard events while capturing. * [windows/message.c] New function MSG_GetHardwareMessage(), to do mouse tracking without returning control to the Windows program. * [windows/nonclient.c] A couple of changes in frame drawing for DLGMODALFRAME windows. Rewritten window moving code, to use MSG_GetHardwareMessage() instead of non-client mouse events (this is the way Windows does it), and to send WM_ENTERSIZEMOVE messages. Removed WM_NCBUTTONUP and WM_NCMOUSEMOVE handlers. * [windows/win.c] Allocate temporary structures on the USER heap instead of using GlobalAlloc(). * [windows/winpos.c] Added function WINPOS_GetMinMaxInfo() to get sizing informations. Jan 31, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [windows/nonclient.c] Call to StdDrawScrollBar() during NC's drawing. Call to NC_ScrollBarButtonDown() on NC mouse events WM_LBUTTONDOWN. Call to NC_ScrollBarButtonUp() on NC mouse events WM_LBUTTONUP. Call to NC_ScrollBarMouseMove() on NC mouse events WM_MOUSEMOVE. * [controls/menu.c] New GetSubMenu() function. Move GetMenu() & SetMenu() functions from 'windows/win.c'. * [controls/listbox.c] Start changes to satisfy recent changes in scrollbars/windows. * [loader/resource.c] Put some code in LoadAccelerators() stub. New TranslateAccelerator() function. * [windows/win.c] Remove GetMenu() & SetMenu() functions. Call to NC_CreateScrollBars() if required by CreateWindow(). Mon Jan 24 10:40:10 EST 1994 John Richardson (jrichard@cs.uml.edu) * [window/win.c] Added functions EnumWindows, EnumChildWindows, and helper WIN_EnumChildWin. EnumWindows won't list all wine windows because GetDesktopWindow isn't complete. However, the code is in place for it to work correctly and only needs GetDesktopWindow to do so. Tue Jan 25 05:51:47 1994 julliard@di.epfl.ch (Alexandre Julliard) * [windows/defwnd.c] Added handling of activation messages (WM_ACTIVATE, WM_NCACTIVATE, WM_MOUSEACTIVATE) * [windows/event.c] De-activate the window when losing input focus. * [windows/focus.c] Bug fix in SetFocus(). * [windows/message.c] Added activation of the window on mouse-clicks. * [windows/nonclient.c] Changed non-client area painting to use the correct colors depending upon the activation state. Added WM_NCACTIVATE message handling. Fixed a couple of bugs in window moving and resizing. * [windows/winpos.c] Implemented Get/SetActiveWindow(). Implemented SWP_NOACTIVATE flag in SetWindowPos(). Jan 17, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [misc/message.c] MessageBox has a CaptionBar for his title except for MB_SYSTEMMODAL with MB_ICONHAND. * [windows/nonclient.c] Call to NC_TrackSysMenu on SysMenu button mouse click. * [windows/defwnd.c] Call to NC_TrackSysMenu on Alt key (VK_MENU). * [controls/menu.c] New GetSystemMenu() function. New CopySystemMenu() internal function. New NC_TrackSysMenu() internal function. * [include/windows.h] New WM_INITMENU, WM_INITMENUPOPUP, WM_MENUSELECT & WM_MENUCHAR defines.
599 lines
17 KiB
C
599 lines
17 KiB
C
/*
|
|
* Window position related functions.
|
|
*
|
|
* Copyright 1993 Alexandre Julliard
|
|
*/
|
|
|
|
static char Copyright[] = "Copyright Alexandre Julliard, 1993";
|
|
|
|
#include "sysmetrics.h"
|
|
#include "user.h"
|
|
#include "win.h"
|
|
|
|
extern Display * display;
|
|
|
|
static HWND hwndActive = 0; /* Currently active window */
|
|
|
|
|
|
/***********************************************************************
|
|
* GetWindowRect (USER.32)
|
|
*/
|
|
void GetWindowRect( HWND hwnd, LPRECT rect )
|
|
{
|
|
WND * wndPtr = WIN_FindWndPtr( hwnd );
|
|
if (!wndPtr) return;
|
|
|
|
*rect = wndPtr->rectWindow;
|
|
if (wndPtr->hwndParent)
|
|
MapWindowPoints( wndPtr->hwndParent, 0, (POINT *)rect, 2 );
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* GetClientRect (USER.33)
|
|
*/
|
|
void GetClientRect( HWND hwnd, LPRECT rect )
|
|
{
|
|
WND * wndPtr = WIN_FindWndPtr( hwnd );
|
|
|
|
rect->left = rect->top = rect->right = rect->bottom = 0;
|
|
if (wndPtr)
|
|
{
|
|
rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left;
|
|
rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
|
|
}
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
* ClientToScreen (USER.28)
|
|
*/
|
|
void ClientToScreen( HWND hwnd, LPPOINT lppnt )
|
|
{
|
|
MapWindowPoints( hwnd, 0, lppnt, 1 );
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
* ScreenToClient (USER.29)
|
|
*/
|
|
void ScreenToClient( HWND hwnd, LPPOINT lppnt )
|
|
{
|
|
MapWindowPoints( 0, hwnd, lppnt, 1 );
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
* WindowFromPoint (USER.30)
|
|
*/
|
|
HWND WindowFromPoint( POINT pt )
|
|
{
|
|
RECT rect;
|
|
HWND hwnd = firstWindow;
|
|
while (hwnd)
|
|
{
|
|
GetWindowRect( hwnd, &rect );
|
|
if (PtInRect( &rect, pt )) return hwnd;
|
|
hwnd = GetWindow( hwnd, GW_HWNDNEXT );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
* ChildWindowFromPoint (USER.191)
|
|
*/
|
|
HWND ChildWindowFromPoint( HWND hwndParent, POINT pt )
|
|
{
|
|
RECT rect;
|
|
HWND hwnd;
|
|
|
|
GetWindowRect( hwndParent, &rect );
|
|
if (!PtInRect( &rect, pt )) return 0;
|
|
hwnd = GetTopWindow( hwndParent );
|
|
while (hwnd)
|
|
{
|
|
GetWindowRect( hwnd, &rect );
|
|
if (PtInRect( &rect, pt )) return hwnd;
|
|
hwnd = GetWindow( hwnd, GW_HWNDNEXT );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
* MapWindowPoints (USER.258)
|
|
*/
|
|
void MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, WORD count )
|
|
{
|
|
WND * wndPtr;
|
|
POINT * curpt;
|
|
POINT origin = { 0, 0 };
|
|
WORD i;
|
|
|
|
/* Translate source window origin to screen coords */
|
|
while(hwndFrom)
|
|
{
|
|
wndPtr = WIN_FindWndPtr( hwndFrom );
|
|
origin.x += wndPtr->rectClient.left;
|
|
origin.y += wndPtr->rectClient.top;
|
|
hwndFrom = wndPtr->hwndParent;
|
|
}
|
|
|
|
/* Translate origin to destination window coords */
|
|
while(hwndTo)
|
|
{
|
|
wndPtr = WIN_FindWndPtr( hwndTo );
|
|
origin.x -= wndPtr->rectClient.left;
|
|
origin.y -= wndPtr->rectClient.top;
|
|
hwndTo = wndPtr->hwndParent;
|
|
}
|
|
|
|
/* Translate points */
|
|
for (i = 0, curpt = lppt; i < count; i++, curpt++)
|
|
{
|
|
curpt->x += origin.x;
|
|
curpt->y += origin.y;
|
|
}
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* IsIconic (USER.31)
|
|
*/
|
|
BOOL IsIconic(HWND hWnd)
|
|
{
|
|
WND * wndPtr = WIN_FindWndPtr(hWnd);
|
|
if (wndPtr == NULL) return FALSE;
|
|
return (wndPtr->dwStyle & WS_MINIMIZE) != 0;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* IsZoomed (USER.272)
|
|
*/
|
|
BOOL IsZoomed(HWND hWnd)
|
|
{
|
|
WND * wndPtr = WIN_FindWndPtr(hWnd);
|
|
if (wndPtr == NULL) return FALSE;
|
|
return (wndPtr->dwStyle & WS_MAXIMIZE) != 0;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
* GetActiveWindow (USER.60)
|
|
*/
|
|
HWND GetActiveWindow()
|
|
{
|
|
return hwndActive;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
* SetActiveWindow (USER.59)
|
|
*/
|
|
HWND SetActiveWindow( HWND hwnd )
|
|
{
|
|
HWND prev = hwndActive;
|
|
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
|
if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return 0;
|
|
SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
|
|
return prev;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* BringWindowToTop (USER.45)
|
|
*/
|
|
BOOL BringWindowToTop( HWND hwnd )
|
|
{
|
|
return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* MoveWindow (USER.56)
|
|
*/
|
|
BOOL MoveWindow( HWND hwnd, short x, short y, short cx, short cy, BOOL repaint)
|
|
{
|
|
int flags = SWP_NOZORDER | SWP_NOACTIVATE;
|
|
if (!repaint) flags |= SWP_NOREDRAW;
|
|
#ifdef DEBUG_WIN
|
|
printf( "MoveWindow: %d %d,%d %dx%d %d\n", hwnd, x, y, cx, cy, repaint );
|
|
#endif
|
|
return SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* ShowWindow (USER.42)
|
|
*/
|
|
BOOL ShowWindow( HWND hwnd, int cmd )
|
|
{
|
|
WND * wndPtr = WIN_FindWndPtr( hwnd );
|
|
BOOL wasVisible;
|
|
int swpflags = 0;
|
|
|
|
#ifdef DEBUG_WIN
|
|
printf("ShowWindow: hwnd=%d, cmd=%d\n", hwnd, cmd);
|
|
#endif
|
|
|
|
if (!wndPtr) return FALSE;
|
|
wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0;
|
|
switch(cmd)
|
|
{
|
|
case SW_HIDE:
|
|
if (!wasVisible) return FALSE; /* Nothing to do */
|
|
swpflags |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE |
|
|
SWP_NOACTIVATE | SWP_NOZORDER;
|
|
break;
|
|
|
|
case SW_SHOWMINNOACTIVE:
|
|
case SW_SHOWMINIMIZED:
|
|
case SW_SHOWMAXIMIZED:
|
|
case SW_MINIMIZE:
|
|
wndPtr->dwStyle |= WS_MINIMIZE;
|
|
swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE |
|
|
SWP_NOACTIVATE | SWP_NOZORDER;
|
|
break;
|
|
|
|
case SW_SHOWNA:
|
|
case SW_MAXIMIZE:
|
|
case SW_SHOW:
|
|
swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
|
|
break;
|
|
|
|
case SW_NORMAL:
|
|
case SW_SHOWNORMAL:
|
|
case SW_SHOWNOACTIVATE:
|
|
case SW_RESTORE:
|
|
wndPtr->dwStyle &= ~WS_MINIMIZE;
|
|
wndPtr->dwStyle &= ~WS_MAXIMIZE;
|
|
swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
|
|
if (cmd == SW_SHOWNOACTIVATE)
|
|
{
|
|
swpflags |= SWP_NOZORDER;
|
|
if (GetActiveWindow()) swpflags |= SWP_NOACTIVATE;
|
|
}
|
|
break;
|
|
}
|
|
SendMessage( hwnd, WM_SHOWWINDOW, (cmd != SW_HIDE), 0 );
|
|
SetWindowPos( hwnd, 0, 0, 0, 0, 0, swpflags );
|
|
|
|
/* Send WM_SIZE and WM_MOVE messages if not already done */
|
|
if (!(wndPtr->flags & WIN_GOT_SIZEMSG))
|
|
{
|
|
int wParam = SIZE_RESTORED;
|
|
if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED;
|
|
else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED;
|
|
wndPtr->flags |= WIN_GOT_SIZEMSG;
|
|
SendMessage( hwnd, WM_SIZE, wParam,
|
|
MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
|
|
wndPtr->rectClient.bottom-wndPtr->rectClient.top));
|
|
SendMessage( hwnd, WM_MOVE, 0,
|
|
MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
|
|
}
|
|
return wasVisible;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* GetInternalWindowPos (USER.460)
|
|
*/
|
|
WORD GetInternalWindowPos( HWND hwnd, LPRECT rectWnd, LPPOINT ptIcon )
|
|
{
|
|
WINDOWPLACEMENT wndpl;
|
|
if (!GetWindowPlacement( hwnd, &wndpl )) return 0;
|
|
if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
|
|
if (ptIcon) *ptIcon = wndpl.ptMinPosition;
|
|
return wndpl.showCmd;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* SetInternalWindowPos (USER.461)
|
|
*/
|
|
void SetInternalWindowPos( HWND hwnd, WORD showCmd, LPRECT rect, LPPOINT pt )
|
|
{
|
|
WINDOWPLACEMENT wndpl;
|
|
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
|
|
|
wndpl.length = sizeof(wndpl);
|
|
wndpl.flags = (pt != NULL) ? WPF_SETMINPOSITION : 0;
|
|
wndpl.showCmd = showCmd;
|
|
if (pt) wndpl.ptMinPosition = *pt;
|
|
wndpl.rcNormalPosition = (rect != NULL) ? *rect : wndPtr->rectNormal;
|
|
wndpl.ptMaxPosition = wndPtr->ptMaxPos;
|
|
SetWindowPlacement( hwnd, &wndpl );
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* GetWindowPlacement (USER.370)
|
|
*/
|
|
BOOL GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
|
|
{
|
|
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
|
if (!wndPtr) return FALSE;
|
|
|
|
wndpl->length = sizeof(*wndpl);
|
|
wndpl->flags = 0;
|
|
wndpl->showCmd = IsZoomed(hwnd) ? SW_SHOWMAXIMIZED :
|
|
(IsIconic(hwnd) ? SW_SHOWMINIMIZED : SW_SHOWNORMAL);
|
|
wndpl->ptMinPosition = wndPtr->ptIconPos;
|
|
wndpl->ptMaxPosition = wndPtr->ptMaxPos;
|
|
wndpl->rcNormalPosition = wndPtr->rectNormal;
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* SetWindowPlacement (USER.371)
|
|
*/
|
|
BOOL SetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
|
|
{
|
|
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
|
if (!wndPtr) return FALSE;
|
|
|
|
if (wndpl->flags & WPF_SETMINPOSITION)
|
|
wndPtr->ptIconPos = wndpl->ptMinPosition;
|
|
if ((wndpl->flags & WPF_RESTORETOMAXIMIZED) &&
|
|
(wndpl->showCmd == SW_SHOWMINIMIZED)) wndPtr->flags |= WIN_RESTORE_MAX;
|
|
wndPtr->ptMaxPos = wndpl->ptMaxPosition;
|
|
wndPtr->rectNormal = wndpl->rcNormalPosition;
|
|
ShowWindow( hwnd, wndpl->showCmd );
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
* WINPOS_GetMinMaxInfo
|
|
*
|
|
* Send a WM_GETMINMAXINFO to the window.
|
|
*/
|
|
void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos,
|
|
POINT *minTrack, POINT *maxTrack )
|
|
{
|
|
HANDLE minmaxHandle;
|
|
MINMAXINFO MinMax, *pMinMax;
|
|
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
|
|
|
MinMax.ptMaxSize.x = SYSMETRICS_CXSCREEN;
|
|
MinMax.ptMaxSize.y = SYSMETRICS_CYSCREEN;
|
|
MinMax.ptMaxPosition = wndPtr->ptMaxPos;
|
|
MinMax.ptMinTrackSize.x = SYSMETRICS_CXMINTRACK;
|
|
MinMax.ptMinTrackSize.y = SYSMETRICS_CYMINTRACK;
|
|
MinMax.ptMaxTrackSize.x = SYSMETRICS_CXSCREEN;
|
|
MinMax.ptMaxTrackSize.y = SYSMETRICS_CYSCREEN;
|
|
|
|
minmaxHandle = USER_HEAP_ALLOC( LMEM_MOVEABLE, sizeof(MINMAXINFO) );
|
|
if (minmaxHandle)
|
|
{
|
|
pMinMax = (MINMAXINFO *) USER_HEAP_ADDR( minmaxHandle );
|
|
memcpy( pMinMax, &MinMax, sizeof(MinMax) );
|
|
SendMessage( hwnd, WM_GETMINMAXINFO, 0, (LONG)pMinMax );
|
|
}
|
|
else pMinMax = &MinMax;
|
|
|
|
if (maxSize) *maxSize = pMinMax->ptMaxSize;
|
|
if (maxPos) *maxPos = pMinMax->ptMaxPosition;
|
|
if (minTrack) *minTrack = pMinMax->ptMinTrackSize;
|
|
if (maxTrack) *maxTrack = pMinMax->ptMaxTrackSize;
|
|
if (minmaxHandle) USER_HEAP_FREE( minmaxHandle );
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
* WINPOS_ChangeActiveWindow
|
|
*
|
|
* Change the active window and send the corresponding messages.
|
|
*/
|
|
HWND WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg )
|
|
{
|
|
HWND prevActive = hwndActive;
|
|
if (hwnd == hwndActive) return 0;
|
|
if (hwndActive)
|
|
{
|
|
if (!SendMessage( hwndActive, WM_NCACTIVATE, FALSE, 0 )) return 0;
|
|
SendMessage( hwndActive, WM_ACTIVATE, WA_INACTIVE,
|
|
MAKELONG( IsIconic(hwndActive), hwnd ) );
|
|
/* Send WM_ACTIVATEAPP here */
|
|
}
|
|
|
|
hwndActive = hwnd;
|
|
if (hwndActive)
|
|
{
|
|
/* Send WM_ACTIVATEAPP here */
|
|
SendMessage( hwnd, WM_NCACTIVATE, TRUE, 0 );
|
|
SendMessage( hwnd, WM_ACTIVATE, mouseMsg ? WA_CLICKACTIVE : WA_ACTIVE,
|
|
MAKELONG( IsIconic(hwnd), prevActive ) );
|
|
}
|
|
return prevActive;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* SetWindowPos (USER.232)
|
|
*/
|
|
/* Unimplemented flags: SWP_NOREDRAW
|
|
*/
|
|
/* Note: all this code should be in the DeferWindowPos() routines,
|
|
* and SetWindowPos() should simply call them. This will be implemented
|
|
* some day...
|
|
*/
|
|
BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, short x, short y,
|
|
short cx, short cy, WORD flags )
|
|
{
|
|
WINDOWPOS *winPos;
|
|
HANDLE hmem = 0;
|
|
RECT newWindowRect, newClientRect;
|
|
WND *wndPtr;
|
|
int calcsize_result = 0;
|
|
XWindowChanges winChanges;
|
|
int changeMask = 0;
|
|
|
|
#ifdef DEBUG_WIN
|
|
printf( "SetWindowPos: %d %d %d,%d %dx%d 0x%x\n",
|
|
hwnd, hwndInsertAfter, x, y, cx, cy, flags );
|
|
#endif
|
|
|
|
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
|
|
if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW))
|
|
flags |= SWP_NOMOVE | SWP_NOSIZE;
|
|
|
|
/* Send WM_WINDOWPOSCHANGING message */
|
|
|
|
if (!(hmem = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(WINDOWPOS) )))
|
|
return FALSE;
|
|
winPos = (WINDOWPOS *)USER_HEAP_ADDR( hmem );
|
|
winPos->hwnd = hwnd;
|
|
winPos->hwndInsertAfter = hwndInsertAfter;
|
|
winPos->x = x;
|
|
winPos->y = y;
|
|
winPos->cx = cx;
|
|
winPos->cy = cy;
|
|
winPos->flags = flags;
|
|
SendMessage( hwnd, WM_WINDOWPOSCHANGING, 0, (LONG)winPos );
|
|
|
|
/* Calculate new position and size */
|
|
|
|
newWindowRect = wndPtr->rectWindow;
|
|
newClientRect = wndPtr->rectClient;
|
|
|
|
if (!(winPos->flags & SWP_NOSIZE))
|
|
{
|
|
newWindowRect.right = newWindowRect.left + winPos->cx;
|
|
newWindowRect.bottom = newWindowRect.top + winPos->cy;
|
|
}
|
|
|
|
if (!(winPos->flags & SWP_NOMOVE))
|
|
{
|
|
newWindowRect.left = winPos->x;
|
|
newWindowRect.top = winPos->y;
|
|
newWindowRect.right += winPos->x - wndPtr->rectWindow.left;
|
|
newWindowRect.bottom += winPos->y - wndPtr->rectWindow.top;
|
|
}
|
|
|
|
/* Reposition window in Z order */
|
|
|
|
if (!(winPos->flags & SWP_NOZORDER))
|
|
{
|
|
hwndInsertAfter = winPos->hwndInsertAfter;
|
|
|
|
/* TOPMOST not supported yet */
|
|
if ((hwndInsertAfter == HWND_TOPMOST) ||
|
|
(hwndInsertAfter == HWND_NOTOPMOST)) hwndInsertAfter = HWND_TOP;
|
|
|
|
/* Make sure hwndInsertAfter is a sibling of hwnd */
|
|
if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM))
|
|
if (wndPtr->hwndParent != GetParent(hwndInsertAfter)) goto Abort;
|
|
|
|
WIN_UnlinkWindow( hwnd );
|
|
WIN_LinkWindow( hwnd, hwndInsertAfter );
|
|
}
|
|
|
|
/* Recalculate client area position */
|
|
|
|
if (winPos->flags & SWP_FRAMECHANGED)
|
|
{
|
|
/* Send WM_NCCALCSIZE message */
|
|
NCCALCSIZE_PARAMS *params;
|
|
HANDLE hparams;
|
|
|
|
if (!(hparams = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(*params) )))
|
|
goto Abort;
|
|
params = (NCCALCSIZE_PARAMS *) USER_HEAP_ADDR( hparams );
|
|
params->rgrc[0] = newWindowRect;
|
|
params->rgrc[1] = wndPtr->rectWindow;
|
|
params->rgrc[2] = wndPtr->rectClient;
|
|
params->lppos = winPos;
|
|
calcsize_result = SendMessage(hwnd, WM_NCCALCSIZE, TRUE, (LONG)params);
|
|
USER_HEAP_FREE( hparams );
|
|
newClientRect = params->rgrc[0];
|
|
/* Handle result here */
|
|
}
|
|
else
|
|
{
|
|
newClientRect.left = newWindowRect.left + wndPtr->rectClient.left
|
|
- wndPtr->rectWindow.left;
|
|
newClientRect.top = newWindowRect.top + wndPtr->rectClient.top
|
|
- wndPtr->rectWindow.top;
|
|
newClientRect.right = newWindowRect.right + wndPtr->rectClient.right
|
|
- wndPtr->rectWindow.right;
|
|
newClientRect.bottom = newWindowRect.bottom + wndPtr->rectClient.bottom
|
|
- wndPtr->rectWindow.bottom;
|
|
}
|
|
|
|
/* Perform the moving and resizing */
|
|
|
|
if (!(winPos->flags & SWP_NOMOVE))
|
|
{
|
|
WND * parentPtr;
|
|
winChanges.x = newWindowRect.left;
|
|
winChanges.y = newWindowRect.top;
|
|
if (wndPtr->hwndParent)
|
|
{
|
|
parentPtr = WIN_FindWndPtr(wndPtr->hwndParent);
|
|
winChanges.x += parentPtr->rectClient.left-parentPtr->rectWindow.left;
|
|
winChanges.y += parentPtr->rectClient.top-parentPtr->rectWindow.top;
|
|
}
|
|
changeMask |= CWX | CWY;
|
|
}
|
|
if (!(winPos->flags & SWP_NOSIZE))
|
|
{
|
|
winChanges.width = newWindowRect.right - newWindowRect.left;
|
|
winChanges.height = newWindowRect.bottom - newWindowRect.top;
|
|
changeMask |= CWWidth | CWHeight;
|
|
}
|
|
if (!(winPos->flags & SWP_NOZORDER))
|
|
{
|
|
if (hwndInsertAfter == HWND_TOP) winChanges.stack_mode = Above;
|
|
else winChanges.stack_mode = Below;
|
|
if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM))
|
|
{
|
|
WND * insertPtr = WIN_FindWndPtr( hwndInsertAfter );
|
|
winChanges.sibling = insertPtr->window;
|
|
changeMask |= CWSibling;
|
|
}
|
|
changeMask |= CWStackMode;
|
|
}
|
|
if (changeMask) XConfigureWindow( display, wndPtr->window,
|
|
changeMask, &winChanges );
|
|
|
|
if (winPos->flags & SWP_SHOWWINDOW)
|
|
{
|
|
wndPtr->dwStyle |= WS_VISIBLE;
|
|
XMapWindow( display, wndPtr->window );
|
|
}
|
|
else if (winPos->flags & SWP_HIDEWINDOW)
|
|
{
|
|
wndPtr->dwStyle &= ~WS_VISIBLE;
|
|
XUnmapWindow( display, wndPtr->window );
|
|
}
|
|
|
|
if (!(winPos->flags & SWP_NOACTIVATE))
|
|
{
|
|
if (!(wndPtr->dwStyle & WS_CHILD))
|
|
WINPOS_ChangeActiveWindow( hwnd, FALSE );
|
|
}
|
|
|
|
/* Send WM_NCPAINT message if needed */
|
|
if ((winPos->flags & (SWP_FRAMECHANGED | SWP_SHOWWINDOW)) ||
|
|
(!(winPos->flags & SWP_NOSIZE)) ||
|
|
(!(winPos->flags & SWP_NOMOVE)) ||
|
|
(!(winPos->flags & SWP_NOACTIVATE)) ||
|
|
(!(winPos->flags & SWP_NOZORDER)))
|
|
SendMessage( hwnd, WM_NCPAINT, 1, 0L );
|
|
|
|
/* Finally send the WM_WINDOWPOSCHANGED message */
|
|
wndPtr->rectWindow = newWindowRect;
|
|
wndPtr->rectClient = newClientRect;
|
|
SendMessage( hwnd, WM_WINDOWPOSCHANGED, 0, (LONG)winPos );
|
|
USER_HEAP_FREE( hmem );
|
|
|
|
return TRUE;
|
|
|
|
Abort: /* Fatal error encountered */
|
|
if (hmem) USER_HEAP_FREE( hmem );
|
|
return FALSE;
|
|
}
|