win32u: Move NtUserSetWindowPos implementation from user32.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2022-03-15 14:27:14 +01:00 committed by Alexandre Julliard
parent d402df3196
commit 08b2fbcbd6
22 changed files with 707 additions and 188 deletions

View File

@ -306,7 +306,7 @@ static void CBForceDummyResize(LPHEADCOMBO lphc)
* message.
*/
lphc->wState |= CBF_NORESIZE;
SetWindowPos( lphc->self,
NtUserSetWindowPos( lphc->self,
NULL,
0, 0,
windowRect.right - windowRect.left,
@ -996,7 +996,7 @@ static void CBDropDown( LPHEADCOMBO lphc )
r.bottom = min( r.top + nDroppedHeight, mon_info.rcWork.bottom );
}
SetWindowPos( lphc->hWndLBox, HWND_TOPMOST, r.left, r.top, r.right - r.left, r.bottom - r.top,
NtUserSetWindowPos( lphc->hWndLBox, HWND_TOPMOST, r.left, r.top, r.right - r.left, r.bottom - r.top,
SWP_NOACTIVATE | SWP_SHOWWINDOW );
@ -1404,15 +1404,15 @@ static void CBResetPos(HEADCOMBO *combo, BOOL redraw)
/* NOTE: logs sometimes have WM_LBUTTONUP before a cascade of
* sizing messages */
if (combo->wState & CBF_EDIT)
SetWindowPos(combo->hWndEdit, 0, combo->textRect.left, combo->textRect.top,
NtUserSetWindowPos( combo->hWndEdit, 0, combo->textRect.left, combo->textRect.top,
combo->textRect.right - combo->textRect.left,
combo->textRect.bottom - combo->textRect.top,
SWP_NOZORDER | SWP_NOACTIVATE | (drop ? SWP_NOREDRAW : 0));
SWP_NOZORDER | SWP_NOACTIVATE | (drop ? SWP_NOREDRAW : 0) );
SetWindowPos(combo->hWndLBox, 0, combo->droppedRect.left, combo->droppedRect.top,
NtUserSetWindowPos( combo->hWndLBox, 0, combo->droppedRect.left, combo->droppedRect.top,
combo->droppedRect.right - combo->droppedRect.left,
combo->droppedRect.bottom - combo->droppedRect.top,
SWP_NOACTIVATE | SWP_NOZORDER | (drop ? SWP_NOREDRAW : 0));
SWP_NOACTIVATE | SWP_NOZORDER | (drop ? SWP_NOREDRAW : 0) );
if (drop)
{
@ -1470,8 +1470,8 @@ static void COMBO_Size( HEADCOMBO *lphc )
if (curComboHeight != newComboHeight)
{
lphc->wState |= CBF_NORESIZE;
SetWindowPos(lphc->self, 0, 0, 0, curComboWidth, newComboHeight,
SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOREDRAW);
NtUserSetWindowPos( lphc->self, 0, 0, 0, curComboWidth, newComboHeight,
SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOREDRAW );
lphc->wState &= ~CBF_NORESIZE;
}
}

View File

@ -691,7 +691,7 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
{
STYLESTRUCT *style = (STYLESTRUCT *)lParam;
if ((style->styleOld ^ style->styleNew) & (WS_CAPTION|WS_THICKFRAME|WS_VSCROLL|WS_HSCROLL))
SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER |
NtUserSetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER |
SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE );
}
break;

View File

@ -931,8 +931,8 @@ BOOL WINAPI EndDialog( HWND hwnd, INT_PTR retval )
/* Don't have to send a ShowWindow(SW_HIDE), just do
SetWindowPos with SWP_HIDEWINDOW as done in Windows */
SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE
| SWP_NOZORDER | SWP_NOACTIVATE | SWP_HIDEWINDOW);
NtUserSetWindowPos( hwnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE
| SWP_NOZORDER | SWP_NOACTIVATE | SWP_HIDEWINDOW );
if (hwnd == GetActiveWindow())
{

View File

@ -100,9 +100,9 @@ BOOL WINAPI SetShellWindowEx(HWND hwndShell, HWND hwndListView)
return FALSE;
if (hwndListView && hwndListView!=hwndShell)
SetWindowPos(hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
NtUserSetWindowPos( hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE );
SetWindowPos(hwndShell, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
NtUserSetWindowPos( hwndShell, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE );
SERVER_START_REQ(set_global_windows)
{

View File

@ -91,7 +91,7 @@ static BOOL ICONTITLE_SetTitlePos( HWND hwnd, HWND owner )
/* point is relative to owner, make it relative to parent */
MapWindowPoints( owner, GetParent(hwnd), &pt, 1 );
SetWindowPos( hwnd, owner, pt.x, pt.y, cx, cy, SWP_NOACTIVATE );
NtUserSetWindowPos( hwnd, owner, pt.x, pt.y, cx, cy, SWP_NOACTIVATE );
return TRUE;
}

View File

@ -497,7 +497,7 @@ static void LISTBOX_UpdateSize( LB_DESCR *descr )
{
TRACE("[%p]: changing height %d -> %d\n",
descr->self, descr->height, descr->height - remaining );
SetWindowPos( descr->self, 0, 0, 0, rect.right - rect.left,
NtUserSetWindowPos( descr->self, 0, 0, 0, rect.right - rect.left,
rect.bottom - rect.top - remaining,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE );
return;

View File

@ -518,12 +518,13 @@ static void MDI_SwitchActiveChild( MDICLIENTINFO *ci, HWND hwndTo, BOOL activate
SendMessageW( hwndPrev, WM_SETREDRAW, TRUE, 0 );
/* activate new MDI child */
SetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
NtUserSetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
/* maximize new MDI child */
ShowWindow( hwndTo, SW_MAXIMIZE );
}
/* activate new MDI child */
SetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | (activate ? 0 : SWP_NOACTIVATE) );
NtUserSetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | (activate ? 0 : SWP_NOACTIVATE) );
}
}
@ -721,8 +722,7 @@ static LONG MDICascade( HWND client, MDICLIENTINFO *ci )
style = GetWindowLongW(win_array[i], GWL_STYLE);
if (!(style & WS_SIZEBOX)) posOptions |= SWP_NOSIZE;
SetWindowPos( win_array[i], 0, pos[0].x, pos[0].y, pos[1].x, pos[1].y,
posOptions);
NtUserSetWindowPos( win_array[i], 0, pos[0].x, pos[0].y, pos[1].x, pos[1].y, posOptions );
}
}
HeapFree( GetProcessHeap(), 0, win_array );
@ -806,7 +806,7 @@ static void MDITile( HWND client, MDICLIENTINFO *ci, WPARAM wParam )
LONG style = GetWindowLongW(win_array[i], GWL_STYLE);
if (!(style & WS_SIZEBOX)) posOptions |= SWP_NOSIZE;
SetWindowPos(*pWnd, 0, x, y, xsize, ysize, posOptions);
NtUserSetWindowPos( *pWnd, 0, x, y, xsize, ysize, posOptions );
y += ysize;
pWnd++;
}
@ -1017,7 +1017,7 @@ static void MDI_UpdateFrameText( HWND frame, HWND hClient, BOOL repaint, LPCWSTR
DefWindowProcW( frame, WM_SETTEXT, 0, (LPARAM)lpBuffer );
if (repaint)
SetWindowPos( frame, 0,0,0,0,0, SWP_FRAMECHANGED |
NtUserSetWindowPos( frame, 0,0,0,0,0, SWP_FRAMECHANGED |
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
}
@ -1084,7 +1084,7 @@ LRESULT MDIClientWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPARAM
case WM_MDIACTIVATE:
{
if( ci->hwndActiveChild != (HWND)wParam )
SetWindowPos((HWND)wParam, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE);
NtUserSetWindowPos( (HWND)wParam, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
return 0;
}
@ -1141,8 +1141,8 @@ LRESULT MDIClientWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPARAM
HWND hwnd = wParam ? WIN_GetFullHandle((HWND)wParam) : ci->hwndActiveChild;
HWND next = MDI_GetWindow( ci, hwnd, !lParam, 0 );
MDI_SwitchActiveChild( ci, next, TRUE );
if(!lParam)
SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
if (!lParam)
NtUserSetWindowPos( hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
break;
}
@ -1211,8 +1211,8 @@ LRESULT MDIClientWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPARAM
TRACE("notification from %p (%i,%i)\n",child,pt.x,pt.y);
if( child && child != hwnd && child != ci->hwndActiveChild )
SetWindowPos(child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
if (child && child != hwnd && child != ci->hwndActiveChild)
NtUserSetWindowPos( child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
break;
}

View File

@ -1966,7 +1966,7 @@ static BOOL MENU_ShowPopup( HWND hwndOwner, HMENU hmenu, UINT id, UINT flags,
}
/* Display the window */
SetWindowPos( menu->hWnd, HWND_TOPMOST, x, y, menu->Width, menu->Height,
NtUserSetWindowPos( menu->hWnd, HWND_TOPMOST, x, y, menu->Width, menu->Height,
SWP_SHOWWINDOW | SWP_NOACTIVATE );
UpdateWindow( menu->hWnd );
return TRUE;
@ -4489,7 +4489,7 @@ BOOL WINAPI SetMenu( HWND hWnd, HMENU hMenu )
if(!MENU_SetMenu(hWnd, hMenu))
return FALSE;
SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
NtUserSetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
return TRUE;
}
@ -4540,7 +4540,7 @@ BOOL WINAPI DrawMenuBar( HWND hWnd )
}
}
return SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
return NtUserSetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
}

View File

@ -1861,9 +1861,6 @@ LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
{
case WM_WINE_DESTROYWINDOW:
return WIN_DestroyWindow( hwnd );
case WM_WINE_SETWINDOWPOS:
if (is_desktop_window( hwnd )) return 0;
return USER_SetWindowPos( (WINDOWPOS *)lparam, 0, 0 );
case WM_WINE_SHOWWINDOW:
if (is_desktop_window( hwnd )) return 0;
return ShowWindow( hwnd, wparam );

View File

@ -281,16 +281,16 @@ static void MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSW lpmb)
wtop = (mon_info.rcWork.top + mon_info.rcWork.bottom - wheight) / 2;
/* Resize and center the window */
SetWindowPos(hwnd, 0, wleft, wtop, wwidth, wheight,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
NtUserSetWindowPos( hwnd, 0, wleft, wtop, wwidth, wheight,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW );
/* Position the icon */
SetWindowPos(GetDlgItem(hwnd, MSGBOX_IDICON), 0, ileft, (tiheight - iheight) / 2, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
NtUserSetWindowPos( GetDlgItem(hwnd, MSGBOX_IDICON), 0, ileft, (tiheight - iheight) / 2, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW );
/* Position the text */
SetWindowPos(GetDlgItem(hwnd, MSGBOX_IDTEXT), 0, tleft, (tiheight - theight) / 2, twidth, theight,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
NtUserSetWindowPos( GetDlgItem(hwnd, MSGBOX_IDTEXT), 0, tleft, (tiheight - theight) / 2, twidth, theight,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW );
/* Position the buttons */
bpos = (wwidth - (bw + bspace) * buttons + bspace) / 2;
@ -303,15 +303,15 @@ static void MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSW lpmb)
NtUserSetFocus(hItem);
SendMessageW( hItem, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
}
SetWindowPos(hItem, 0, bpos, tiheight, bw, bh,
SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW);
NtUserSetWindowPos( hItem, 0, bpos, tiheight, bw, bh,
SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW );
bpos += bw + bspace;
}
}
/*handle modal message boxes*/
if (((lpmb->dwStyle & MB_TASKMODAL) && (lpmb->hwndOwner==NULL)) || (lpmb->dwStyle & MB_SYSTEMMODAL))
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
NtUserSetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE );
HeapFree( GetProcessHeap(), 0, buffer );
}

View File

@ -802,7 +802,7 @@ static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect, const REC
{
WIN_GetRectangles( list[i], COORDS_PARENT, &r, NULL );
if (!rect || IntersectRect(&dummy, &r, rect))
SetWindowPos( list[i], 0, r.left + dx, r.top + dy, 0, 0,
NtUserSetWindowPos( list[i], 0, r.left + dx, r.top + dy, 0, 0,
SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE |
SWP_NOREDRAW | SWP_DEFERERASE );
}

View File

@ -1995,8 +1995,8 @@ static BOOL SCROLL_ShowScrollBar( HWND hwnd, INT nBar, BOOL fShowH, BOOL fShowV
if ((old_style & clear_bits) != 0 || (old_style & set_bits) != set_bits)
{
/* frame has been changed, let the window redraw itself */
SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE
| SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
NtUserSetWindowPos( hwnd, 0, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
return TRUE;
}
return FALSE; /* no frame changes */

View File

@ -122,7 +122,7 @@ static HICON STATIC_SetIcon( HWND hwnd, HICON hicon, DWORD style )
}
else */
{
SetWindowPos( hwnd, 0, 0, 0, size.cx, size.cy, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
NtUserSetWindowPos( hwnd, 0, 0, 0, size.cx, size.cy, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
}
}
return prevIcon;
@ -157,7 +157,7 @@ static HBITMAP STATIC_SetBitmap( HWND hwnd, HBITMAP hBitmap, DWORD style )
}
else */
{
SetWindowPos( hwnd, 0, 0, 0, bm.bmWidth, bm.bmHeight,
NtUserSetWindowPos( hwnd, 0, 0, 0, bm.bmWidth, bm.bmHeight,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
}
@ -425,7 +425,8 @@ LRESULT StaticWndProc_common( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
else
rc.right = rc.left;
AdjustWindowRectEx(&rc, full_style, FALSE, GetWindowLongW(hwnd, GWL_EXSTYLE));
SetWindowPos(hwnd, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER);
NtUserSetWindowPos( hwnd, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
SWP_NOMOVE | SWP_NOZORDER );
}
switch (style) {

View File

@ -725,7 +725,7 @@
@ stdcall -arch=win64 SetWindowLongPtrW(long long long)
@ stdcall SetWindowLongW(long long long)
@ stdcall SetWindowPlacement(long ptr)
@ stdcall SetWindowPos(long long long long long long long)
@ stdcall SetWindowPos(long long long long long long long) NtUserSetWindowPos
@ stdcall SetWindowRgn(long long long) NtUserSetWindowRgn
@ stdcall SetWindowStationUser(long long)
@ stdcall SetWindowTextA(long str)

View File

@ -149,7 +149,6 @@ static const struct user_callbacks user_funcs =
SendMessageTimeoutW,
SendMessageW,
SendNotifyMessageW,
SetWindowPos,
ShowCaret,
WaitForInputIdle,
notify_ime,

View File

@ -88,12 +88,6 @@ static inline struct user_thread_info *get_user_thread_info(void)
return (struct user_thread_info *)NtCurrentTeb()->Win32ClientInfo;
}
/* check if hwnd is a broadcast magic handle */
static inline BOOL is_broadcast( HWND hwnd )
{
return (hwnd == HWND_BROADCAST || hwnd == HWND_TOPMOST);
}
extern HMODULE user32_module DECLSPEC_HIDDEN;
struct dce;

View File

@ -1561,7 +1561,7 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module,
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.left,
NtUserSetWindowPos( hwnd, 0, newPos.left, newPos.top, newPos.right - newPos.left,
newPos.bottom - newPos.top, swFlag );
}
@ -1589,7 +1589,7 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module,
{
SendMessageW(cs->hwndParent, WM_MDIREFRESHMENU, 0, 0);
/* ShowWindow won't activate child windows */
SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE );
NtUserSetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE );
}
}
@ -1761,7 +1761,7 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
if (is_child)
ShowWindow( hwnd, SW_HIDE );
else
SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE |
NtUserSetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE |
SWP_NOZORDER | SWP_NOACTIVATE | SWP_HIDEWINDOW );
}

View File

@ -519,7 +519,7 @@ BOOL WINAPI LockSetForegroundWindow( UINT lockcode )
*/
BOOL WINAPI BringWindowToTop( HWND hwnd )
{
return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
return NtUserSetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
}
@ -1000,7 +1000,7 @@ static BOOL show_window( HWND hwnd, INT cmd )
else WIN_SetStyle( hwnd, 0, WS_VISIBLE );
}
else
SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top,
NtUserSetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top,
newPos.right - newPos.left, newPos.bottom - newPos.top, swp );
if (cmd == SW_HIDE)
@ -1267,18 +1267,18 @@ static BOOL WINPOS_SetPlacement( HWND hwnd, const WINDOWPLACEMENT *wndpl, UINT f
{
if (flags & PLACE_MIN)
{
SetWindowPos( hwnd, 0, wp.ptMinPosition.x, wp.ptMinPosition.y, 0, 0,
NtUserSetWindowPos( hwnd, 0, wp.ptMinPosition.x, wp.ptMinPosition.y, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
}
}
else if( style & WS_MAXIMIZE )
{
if (flags & PLACE_MAX)
SetWindowPos( hwnd, 0, wp.ptMaxPosition.x, wp.ptMaxPosition.y, 0, 0,
NtUserSetWindowPos( hwnd, 0, wp.ptMaxPosition.x, wp.ptMaxPosition.y, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
}
else if( flags & PLACE_RECT )
SetWindowPos( hwnd, 0, wp.rcNormalPosition.left, wp.rcNormalPosition.top,
NtUserSetWindowPos( hwnd, 0, wp.rcNormalPosition.left, wp.rcNormalPosition.top,
wp.rcNormalPosition.right - wp.rcNormalPosition.left,
wp.rcNormalPosition.bottom - wp.rcNormalPosition.top,
SWP_NOZORDER | SWP_NOACTIVATE );
@ -1450,39 +1450,6 @@ LONG WINPOS_HandleWindowPosChanging( HWND hwnd, WINDOWPOS *winpos )
}
/***********************************************************************
* dump_winpos_flags
*/
static void dump_winpos_flags(UINT flags)
{
static const DWORD dumped_flags = (SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW |
SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_SHOWWINDOW |
SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOOWNERZORDER |
SWP_NOSENDCHANGING | SWP_DEFERERASE | SWP_ASYNCWINDOWPOS |
SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE | SWP_STATECHANGED);
TRACE("flags:");
if(flags & SWP_NOSIZE) TRACE(" SWP_NOSIZE");
if(flags & SWP_NOMOVE) TRACE(" SWP_NOMOVE");
if(flags & SWP_NOZORDER) TRACE(" SWP_NOZORDER");
if(flags & SWP_NOREDRAW) TRACE(" SWP_NOREDRAW");
if(flags & SWP_NOACTIVATE) TRACE(" SWP_NOACTIVATE");
if(flags & SWP_FRAMECHANGED) TRACE(" SWP_FRAMECHANGED");
if(flags & SWP_SHOWWINDOW) TRACE(" SWP_SHOWWINDOW");
if(flags & SWP_HIDEWINDOW) TRACE(" SWP_HIDEWINDOW");
if(flags & SWP_NOCOPYBITS) TRACE(" SWP_NOCOPYBITS");
if(flags & SWP_NOOWNERZORDER) TRACE(" SWP_NOOWNERZORDER");
if(flags & SWP_NOSENDCHANGING) TRACE(" SWP_NOSENDCHANGING");
if(flags & SWP_DEFERERASE) TRACE(" SWP_DEFERERASE");
if(flags & SWP_ASYNCWINDOWPOS) TRACE(" SWP_ASYNCWINDOWPOS");
if(flags & SWP_NOCLIENTSIZE) TRACE(" SWP_NOCLIENTSIZE");
if(flags & SWP_NOCLIENTMOVE) TRACE(" SWP_NOCLIENTMOVE");
if(flags & SWP_STATECHANGED) TRACE(" SWP_STATECHANGED");
if(flags & ~dumped_flags) TRACE(" %08x", flags & ~dumped_flags);
TRACE("\n");
}
/***********************************************************************
* map_dpi_winpos
*/
@ -1699,7 +1666,7 @@ static HWND SWP_DoOwnedPopups(HWND hwnd, HWND hwndInsertAfter)
if (list[i] == hwnd) break;
if (GetWindow( list[i], GW_OWNER ) != hwnd) continue;
TRACE( "moving %p owned by %p after %p\n", list[i], hwnd, hwndInsertAfter );
SetWindowPos( list[i], hwndInsertAfter, 0, 0, 0, 0,
NtUserSetWindowPos( list[i], hwndInsertAfter, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_DEFERERASE );
hwndInsertAfter = list[i];
}
@ -2233,44 +2200,6 @@ done:
return ret;
}
/***********************************************************************
* SetWindowPos (USER32.@)
*/
BOOL WINAPI SetWindowPos( HWND hwnd, HWND hwndInsertAfter,
INT x, INT y, INT cx, INT cy, UINT flags )
{
WINDOWPOS winpos;
TRACE("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
hwnd, hwndInsertAfter, x, y, cx, cy, flags);
if(TRACE_ON(win)) dump_winpos_flags(flags);
if (is_broadcast(hwnd))
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
winpos.hwnd = WIN_GetFullHandle(hwnd);
winpos.hwndInsertAfter = WIN_GetFullHandle(hwndInsertAfter);
winpos.x = x;
winpos.y = y;
winpos.cx = cx;
winpos.cy = cy;
winpos.flags = flags;
map_dpi_winpos( &winpos );
if (WIN_IsCurrentThread( hwnd ))
return USER_SetWindowPos( &winpos, 0, 0 );
if (flags & SWP_ASYNCWINDOWPOS)
return SendNotifyMessageW( winpos.hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)&winpos );
else
return SendMessageW( winpos.hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)&winpos );
}
/***********************************************************************
* BeginDeferWindowPos (USER32.@)
*/
@ -2460,7 +2389,7 @@ UINT WINAPI ArrangeIconicWindows( HWND parent )
{
if( IsIconic( hwndChild ) )
{
SetWindowPos( hwndChild, 0, pt.x, pt.y, 0, 0,
NtUserSetWindowPos( hwndChild, 0, pt.x, pt.y, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
get_next_minimized_child_pos( &rectParent, &metrics, width, height, &pt );
count++;
@ -2796,7 +2725,7 @@ void WINPOS_SysCommandSizeMove( HWND hwnd, WPARAM wParam )
{
RECT rect = sizingRect;
MapWindowPoints( 0, parent, (POINT *)&rect, 2 );
SetWindowPos( hwnd, 0, rect.left, rect.top,
NtUserSetWindowPos( hwnd, 0, rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
(hittest == HTCAPTION) ? SWP_NOSIZE : 0 );
}
@ -2829,7 +2758,7 @@ void WINPOS_SysCommandSizeMove( HWND hwnd, WPARAM wParam )
{
/* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
if (!DragFullWindows)
SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
NtUserSetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
sizingRect.right - sizingRect.left,
sizingRect.bottom - sizingRect.top,
( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
@ -2837,7 +2766,7 @@ void WINPOS_SysCommandSizeMove( HWND hwnd, WPARAM wParam )
else
{ /* restore previous size/position */
if(DragFullWindows)
SetWindowPos( hwnd, 0, origRect.left, origRect.top,
NtUserSetWindowPos( hwnd, 0, origRect.left, origRect.top,
origRect.right - origRect.left,
origRect.bottom - origRect.top,
( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );

View File

@ -41,6 +41,9 @@ LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
{
switch(msg)
{
case WM_WINE_SETWINDOWPOS:
if (is_desktop_window( hwnd )) return 0;
return set_window_pos( (WINDOWPOS *)lparam, 0, 0 );
case WM_WINE_SETACTIVEWINDOW:
if (!wparam && NtUserGetForegroundWindow() == hwnd) return 0;
return (LRESULT)NtUserSetActiveWindow( (HWND)wparam );

View File

@ -36,7 +36,6 @@ struct user_callbacks
LRESULT (WINAPI *pSendMessageTimeoutW)( HWND, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD_PTR );
LRESULT (WINAPI *pSendMessageW)( HWND, UINT, WPARAM, LPARAM );
BOOL (WINAPI *pSendNotifyMessageW)( HWND, UINT, WPARAM, LPARAM );
BOOL (WINAPI *pSetWindowPos)( HWND, HWND, INT, INT, INT, INT, UINT );
BOOL (WINAPI *pShowCaret)( HWND hwnd );
DWORD (WINAPI *pWaitForInputIdle)( HANDLE, DWORD );
void (CDECL *notify_ime)( HWND hwnd, UINT param );
@ -113,6 +112,12 @@ typedef struct tagWND
#define WND_OTHER_PROCESS ((WND *)1) /* returned by WIN_GetPtr on unknown window handles */
#define WND_DESKTOP ((WND *)2) /* returned by WIN_GetPtr on the desktop window */
/* check if hwnd is a broadcast magic handle */
static inline BOOL is_broadcast( HWND hwnd )
{
return hwnd == HWND_BROADCAST || hwnd == HWND_TOPMOST;
}
WND *next_thread_window_ptr( HWND *hwnd );
#define WM_IME_INTERNAL 0x287

View File

@ -329,6 +329,9 @@ extern void user_lock(void) DECLSPEC_HIDDEN;
extern void user_unlock(void) DECLSPEC_HIDDEN;
extern void user_check_not_lock(void) DECLSPEC_HIDDEN;
/* windc.c */
extern void erase_now( HWND hwnd, UINT rdw_flags ) DECLSPEC_HIDDEN;
/* window.c */
struct tagWND;
extern HWND get_desktop_window(void) DECLSPEC_HIDDEN;
@ -339,6 +342,7 @@ extern BOOL get_window_placement( HWND hwnd, WINDOWPLACEMENT *placement ) DECLSP
extern DWORD get_window_thread( HWND hwnd, DWORD *process ) DECLSPEC_HIDDEN;
extern HWND is_current_process_window( HWND hwnd ) DECLSPEC_HIDDEN;
extern HWND is_current_thread_window( HWND hwnd ) DECLSPEC_HIDDEN;
extern BOOL is_desktop_window( HWND hwnd ) DECLSPEC_HIDDEN;
extern BOOL is_iconic( HWND hwnd ) DECLSPEC_HIDDEN;
extern DWORD get_window_long( HWND hwnd, INT offset ) DECLSPEC_HIDDEN;
extern BOOL get_window_rect( HWND hwnd, RECT *rect, UINT dpi ) DECLSPEC_HIDDEN;
@ -348,6 +352,7 @@ extern BOOL get_window_rects( HWND hwnd, enum coords_relative relative, RECT *wi
extern HWND *list_window_children( HDESK desktop, HWND hwnd, UNICODE_STRING *class,
DWORD tid ) DECLSPEC_HIDDEN;
extern void map_window_region( HWND from, HWND to, HRGN hrgn ) DECLSPEC_HIDDEN;
extern BOOL set_window_pos( WINDOWPOS *winpos, int parent_x, int parent_y ) DECLSPEC_HIDDEN;
extern void update_window_state( HWND hwnd ) DECLSPEC_HIDDEN;
/* to release pointers retrieved by win_get_ptr */

View File

@ -39,6 +39,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(win);
static void *user_handles[NB_USER_HANDLES];
#define SWP_AGG_NOGEOMETRYCHANGE \
(SWP_NOSIZE | SWP_NOCLIENTSIZE | SWP_NOZORDER)
#define SWP_AGG_NOPOSCHANGE \
(SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE | SWP_NOZORDER)
#define SWP_AGG_STATUSFLAGS \
(SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
#define SWP_AGG_NOCLIENTCHANGE \
(SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)
/***********************************************************************
* alloc_user_handle
*/
@ -207,7 +216,7 @@ HWND get_full_window_handle( HWND hwnd )
*
* Check if window is the desktop or the HWND_MESSAGE top parent.
*/
static BOOL is_desktop_window( HWND hwnd )
BOOL is_desktop_window( HWND hwnd )
{
struct user_thread_info *thread_info = get_user_thread_info();
@ -1289,15 +1298,6 @@ int WINAPI NtUserSetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
return ret;
}
/*******************************************************************
* NtUserSetWindowPos (win32u.@)
*/
BOOL WINAPI NtUserSetWindowPos( HWND hwnd, HWND after, INT x, INT y, INT cx, INT cy, UINT flags )
{
/* FIXME: move implementation from user32 */
return user_callbacks && user_callbacks->pSetWindowPos( hwnd, after, x, y, cx, cy, flags );
}
/***********************************************************************
* NtUserMoveWindow (win32u.@)
*/
@ -1912,6 +1912,592 @@ void map_window_region( HWND from, HWND to, HRGN hrgn )
free( data );
}
/***********************************************************************
* dump_winpos_flags
*/
static void dump_winpos_flags( UINT flags )
{
static const DWORD dumped_flags = (SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW |
SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_SHOWWINDOW |
SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOOWNERZORDER |
SWP_NOSENDCHANGING | SWP_DEFERERASE | SWP_ASYNCWINDOWPOS |
SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE | SWP_STATECHANGED);
TRACE( "flags:" );
if(flags & SWP_NOSIZE) TRACE( " SWP_NOSIZE" );
if(flags & SWP_NOMOVE) TRACE( " SWP_NOMOVE" );
if(flags & SWP_NOZORDER) TRACE( " SWP_NOZORDER" );
if(flags & SWP_NOREDRAW) TRACE( " SWP_NOREDRAW" );
if(flags & SWP_NOACTIVATE) TRACE( " SWP_NOACTIVATE" );
if(flags & SWP_FRAMECHANGED) TRACE( " SWP_FRAMECHANGED" );
if(flags & SWP_SHOWWINDOW) TRACE( " SWP_SHOWWINDOW" );
if(flags & SWP_HIDEWINDOW) TRACE( " SWP_HIDEWINDOW" );
if(flags & SWP_NOCOPYBITS) TRACE( " SWP_NOCOPYBITS" );
if(flags & SWP_NOOWNERZORDER) TRACE( " SWP_NOOWNERZORDER" );
if(flags & SWP_NOSENDCHANGING) TRACE( " SWP_NOSENDCHANGING" );
if(flags & SWP_DEFERERASE) TRACE( " SWP_DEFERERASE" );
if(flags & SWP_ASYNCWINDOWPOS) TRACE( " SWP_ASYNCWINDOWPOS" );
if(flags & SWP_NOCLIENTSIZE) TRACE( " SWP_NOCLIENTSIZE" );
if(flags & SWP_NOCLIENTMOVE) TRACE( " SWP_NOCLIENTMOVE" );
if(flags & SWP_STATECHANGED) TRACE( " SWP_STATECHANGED" );
if(flags & ~dumped_flags) TRACE( " %08x", flags & ~dumped_flags );
TRACE( "\n" );
}
/***********************************************************************
* map_dpi_winpos
*/
static void map_dpi_winpos( WINDOWPOS *winpos )
{
UINT dpi_from = get_thread_dpi();
UINT dpi_to = get_dpi_for_window( winpos->hwnd );
if (!dpi_from) dpi_from = get_win_monitor_dpi( winpos->hwnd );
if (dpi_from == dpi_to) return;
winpos->x = muldiv( winpos->x, dpi_to, dpi_from );
winpos->y = muldiv( winpos->y, dpi_to, dpi_from );
winpos->cx = muldiv( winpos->cx, dpi_to, dpi_from );
winpos->cy = muldiv( winpos->cy, dpi_to, dpi_from );
}
/***********************************************************************
* calc_winpos
*/
static BOOL calc_winpos( WINDOWPOS *winpos, RECT *old_window_rect, RECT *old_client_rect,
RECT *new_window_rect, RECT *new_client_rect )
{
WND *win;
/* Send WM_WINDOWPOSCHANGING message */
if (!(winpos->flags & SWP_NOSENDCHANGING)
&& !((winpos->flags & SWP_AGG_NOCLIENTCHANGE) && (winpos->flags & SWP_SHOWWINDOW)))
send_message( winpos->hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)winpos );
if (!(win = get_win_ptr( winpos->hwnd )) ||
win == WND_OTHER_PROCESS || win == WND_DESKTOP) return FALSE;
/* Calculate new position and size */
get_window_rects( winpos->hwnd, COORDS_PARENT, old_window_rect, old_client_rect, get_thread_dpi() );
*new_window_rect = *old_window_rect;
*new_client_rect = *old_client_rect;
if (!(winpos->flags & SWP_NOSIZE))
{
if (win->dwStyle & WS_MINIMIZE)
{
new_window_rect->right = new_window_rect->left + get_system_metrics( SM_CXMINIMIZED );
new_window_rect->bottom = new_window_rect->top + get_system_metrics( SM_CYMINIMIZED );
}
else
{
new_window_rect->right = new_window_rect->left + winpos->cx;
new_window_rect->bottom = new_window_rect->top + winpos->cy;
}
}
if (!(winpos->flags & SWP_NOMOVE))
{
/* If the window is toplevel minimized off-screen, force keep it there */
if ((win->dwStyle & WS_MINIMIZE) &&
win->window_rect.left <= -32000 && win->window_rect.top <= -32000 &&
(!win->parent || win->parent == get_desktop_window()))
{
winpos->x = -32000;
winpos->y = -32000;
}
new_window_rect->left = winpos->x;
new_window_rect->top = winpos->y;
new_window_rect->right += winpos->x - old_window_rect->left;
new_window_rect->bottom += winpos->y - old_window_rect->top;
offset_rect( new_client_rect, winpos->x - old_window_rect->left,
winpos->y - old_window_rect->top );
}
winpos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x current %s style %08x new %s\n",
winpos->hwnd, winpos->hwndInsertAfter, winpos->x, winpos->y,
winpos->cx, winpos->cy, winpos->flags,
wine_dbgstr_rect( old_window_rect ), win->dwStyle,
wine_dbgstr_rect( new_window_rect ));
release_win_ptr( win );
return TRUE;
}
/***********************************************************************
* get_valid_rects
*
* Compute the valid rects from the old and new client rect and WVR_* flags.
* Helper for WM_NCCALCSIZE handling.
*/
static inline void get_valid_rects( const RECT *old_client, const RECT *new_client, UINT flags,
RECT *valid )
{
int cx, cy;
if (flags & WVR_REDRAW)
{
SetRectEmpty( &valid[0] );
SetRectEmpty( &valid[1] );
return;
}
if (flags & WVR_VALIDRECTS)
{
if (!intersect_rect( &valid[0], &valid[0], new_client ) ||
!intersect_rect( &valid[1], &valid[1], old_client ))
{
SetRectEmpty( &valid[0] );
SetRectEmpty( &valid[1] );
return;
}
flags = WVR_ALIGNLEFT | WVR_ALIGNTOP;
}
else
{
valid[0] = *new_client;
valid[1] = *old_client;
}
/* make sure the rectangles have the same size */
cx = min( valid[0].right - valid[0].left, valid[1].right - valid[1].left );
cy = min( valid[0].bottom - valid[0].top, valid[1].bottom - valid[1].top );
if (flags & WVR_ALIGNBOTTOM)
{
valid[0].top = valid[0].bottom - cy;
valid[1].top = valid[1].bottom - cy;
}
else
{
valid[0].bottom = valid[0].top + cy;
valid[1].bottom = valid[1].top + cy;
}
if (flags & WVR_ALIGNRIGHT)
{
valid[0].left = valid[0].right - cx;
valid[1].left = valid[1].right - cx;
}
else
{
valid[0].right = valid[0].left + cx;
valid[1].right = valid[1].left + cx;
}
}
static UINT calc_ncsize( WINDOWPOS *winpos, const RECT *old_window_rect, const RECT *old_client_rect,
const RECT *new_window_rect, RECT *new_client_rect, RECT *valid_rects,
int parent_x, int parent_y )
{
UINT wvr_flags = 0;
/* Send WM_NCCALCSIZE message to get new client area */
if ((winpos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE)
{
NCCALCSIZE_PARAMS params;
WINDOWPOS winposCopy;
params.rgrc[0] = *new_window_rect;
params.rgrc[1] = *old_window_rect;
params.rgrc[2] = *old_client_rect;
params.lppos = &winposCopy;
winposCopy = *winpos;
if (winpos->flags & SWP_NOMOVE)
{
winposCopy.x = old_window_rect->left;
winposCopy.y = old_window_rect->top;
}
if (winpos->flags & SWP_NOSIZE)
{
winposCopy.cx = old_window_rect->right - old_window_rect->left;
winposCopy.cy = old_window_rect->bottom - old_window_rect->top;
}
wvr_flags = send_message( winpos->hwnd, WM_NCCALCSIZE, TRUE, (LPARAM)&params );
*new_client_rect = params.rgrc[0];
TRACE( "hwnd %p old win %s old client %s new win %s new client %s\n", winpos->hwnd,
wine_dbgstr_rect(old_window_rect), wine_dbgstr_rect(old_client_rect),
wine_dbgstr_rect(new_window_rect), wine_dbgstr_rect(new_client_rect) );
if (new_client_rect->left != old_client_rect->left - parent_x ||
new_client_rect->top != old_client_rect->top - parent_y)
winpos->flags &= ~SWP_NOCLIENTMOVE;
if ((new_client_rect->right - new_client_rect->left !=
old_client_rect->right - old_client_rect->left))
winpos->flags &= ~SWP_NOCLIENTSIZE;
else
wvr_flags &= ~WVR_HREDRAW;
if (new_client_rect->bottom - new_client_rect->top !=
old_client_rect->bottom - old_client_rect->top)
winpos->flags &= ~SWP_NOCLIENTSIZE;
else
wvr_flags &= ~WVR_VREDRAW;
valid_rects[0] = params.rgrc[1];
valid_rects[1] = params.rgrc[2];
}
else
{
if (!(winpos->flags & SWP_NOMOVE) &&
(new_client_rect->left != old_client_rect->left - parent_x ||
new_client_rect->top != old_client_rect->top - parent_y))
winpos->flags &= ~SWP_NOCLIENTMOVE;
}
if (winpos->flags & (SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_SHOWWINDOW | SWP_HIDEWINDOW))
{
SetRectEmpty( &valid_rects[0] );
SetRectEmpty( &valid_rects[1] );
}
else get_valid_rects( old_client_rect, new_client_rect, wvr_flags, valid_rects );
return wvr_flags;
}
/* fix redundant flags and values in the WINDOWPOS structure */
static BOOL fixup_swp_flags( WINDOWPOS *winpos, const RECT *old_window_rect, int parent_x, int parent_y )
{
HWND parent;
WND *win = get_win_ptr( winpos->hwnd );
BOOL ret = TRUE;
if (!win || win == WND_OTHER_PROCESS)
{
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return FALSE;
}
winpos->hwnd = win->obj.handle; /* make it a full handle */
/* Finally make sure that all coordinates are valid */
if (winpos->x < -32768) winpos->x = -32768;
else if (winpos->x > 32767) winpos->x = 32767;
if (winpos->y < -32768) winpos->y = -32768;
else if (winpos->y > 32767) winpos->y = 32767;
if (winpos->cx < 0) winpos->cx = 0;
else if (winpos->cx > 32767) winpos->cx = 32767;
if (winpos->cy < 0) winpos->cy = 0;
else if (winpos->cy > 32767) winpos->cy = 32767;
parent = NtUserGetAncestor( winpos->hwnd, GA_PARENT );
if (!is_window_visible( parent )) winpos->flags |= SWP_NOREDRAW;
if (win->dwStyle & WS_VISIBLE) winpos->flags &= ~SWP_SHOWWINDOW;
else
{
winpos->flags &= ~SWP_HIDEWINDOW;
if (!(winpos->flags & SWP_SHOWWINDOW)) winpos->flags |= SWP_NOREDRAW;
}
if ((old_window_rect->right - old_window_rect->left == winpos->cx) &&
(old_window_rect->bottom - old_window_rect->top == winpos->cy))
winpos->flags |= SWP_NOSIZE; /* Already the right size */
if ((old_window_rect->left - parent_x == winpos->x) && (old_window_rect->top - parent_y == winpos->y))
winpos->flags |= SWP_NOMOVE; /* Already the right position */
if ((win->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD)
{
if (!(winpos->flags & (SWP_NOACTIVATE|SWP_HIDEWINDOW)) && /* Bring to the top when activating */
(winpos->flags & SWP_NOZORDER ||
(winpos->hwndInsertAfter != HWND_TOPMOST && winpos->hwndInsertAfter != HWND_NOTOPMOST)))
{
winpos->flags &= ~SWP_NOZORDER;
winpos->hwndInsertAfter = HWND_TOP;
}
}
/* Check hwndInsertAfter */
if (winpos->flags & SWP_NOZORDER) goto done;
if (winpos->hwndInsertAfter == HWND_TOP)
{
if (get_window_relative( winpos->hwnd, GW_HWNDFIRST ) == winpos->hwnd)
winpos->flags |= SWP_NOZORDER;
}
else if (winpos->hwndInsertAfter == HWND_BOTTOM)
{
if (!(win->dwExStyle & WS_EX_TOPMOST) &&
get_window_relative( winpos->hwnd, GW_HWNDLAST ) == winpos->hwnd)
winpos->flags |= SWP_NOZORDER;
}
else if (winpos->hwndInsertAfter == HWND_TOPMOST)
{
if ((win->dwExStyle & WS_EX_TOPMOST) &&
get_window_relative( winpos->hwnd, GW_HWNDFIRST ) == winpos->hwnd)
winpos->flags |= SWP_NOZORDER;
}
else if (winpos->hwndInsertAfter == HWND_NOTOPMOST)
{
if (!(win->dwExStyle & WS_EX_TOPMOST))
winpos->flags |= SWP_NOZORDER;
}
else
{
if ((winpos->hwnd == winpos->hwndInsertAfter) ||
(winpos->hwnd == get_window_relative( winpos->hwndInsertAfter, GW_HWNDNEXT )))
winpos->flags |= SWP_NOZORDER;
}
done:
release_win_ptr( win );
return ret;
}
/***********************************************************************
* swp_owner_popups
*
* fix Z order taking into account owned popups -
* basically we need to maintain them above the window that owns them
*
* FIXME: hide/show owned popups when owner visibility changes.
*/
static HWND swp_owner_popups( HWND hwnd, HWND after )
{
HWND owner, *list = NULL;
unsigned int i;
TRACE( "(%p) after = %p\n", hwnd, after );
if (get_window_long( hwnd, GWL_STYLE ) & WS_CHILD) return after;
if ((owner = get_window_relative( hwnd, GW_OWNER )))
{
/* make sure this popup stays above the owner */
if (after != HWND_TOPMOST)
{
if (!(list = list_window_children( 0, get_desktop_window(), NULL, 0 ))) return after;
for (i = 0; list[i]; i++)
{
BOOL topmost = (get_window_long( list[i], GWL_EXSTYLE ) & WS_EX_TOPMOST) != 0;
if (list[i] == owner)
{
if (i > 0) after = list[i-1];
else after = topmost ? HWND_TOPMOST : HWND_TOP;
break;
}
if (after == HWND_TOP || after == HWND_NOTOPMOST)
{
if (!topmost) break;
}
else if (list[i] == after) break;
}
}
}
if (after == HWND_BOTTOM) goto done;
if (!list && !(list = list_window_children( 0, get_desktop_window(), NULL, 0 ))) goto done;
i = 0;
if (after == HWND_TOP || after == HWND_NOTOPMOST)
{
if (after == HWND_NOTOPMOST ||
!(get_window_long( hwnd, GWL_EXSTYLE ) & WS_EX_TOPMOST))
{
/* skip all the topmost windows */
while (list[i] && (get_window_long( list[i], GWL_EXSTYLE ) & WS_EX_TOPMOST)) i++;
}
}
else if (after != HWND_TOPMOST)
{
/* skip windows that are already placed correctly */
for (i = 0; list[i]; i++)
{
if (list[i] == after) break;
if (list[i] == hwnd) goto done; /* nothing to do if window is moving backwards in z-order */
}
}
for ( ; list[i]; i++)
{
if (list[i] == hwnd) break;
if (get_window_relative( list[i], GW_OWNER ) != hwnd) continue;
TRACE( "moving %p owned by %p after %p\n", list[i], hwnd, after );
NtUserSetWindowPos( list[i], after, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_DEFERERASE );
after = list[i];
}
done:
free( list );
return after;
}
/* NtUserSetWindowPos implementation */
BOOL set_window_pos( WINDOWPOS *winpos, int parent_x, int parent_y )
{
RECT old_window_rect, old_client_rect, new_window_rect, new_client_rect, valid_rects[2];
UINT orig_flags;
BOOL ret = FALSE;
DPI_AWARENESS_CONTEXT context;
orig_flags = winpos->flags;
/* First, check z-order arguments. */
if (!(winpos->flags & SWP_NOZORDER))
{
/* fix sign extension */
if (winpos->hwndInsertAfter == (HWND)0xffff) winpos->hwndInsertAfter = HWND_TOPMOST;
else if (winpos->hwndInsertAfter == (HWND)0xfffe) winpos->hwndInsertAfter = HWND_NOTOPMOST;
if (!(winpos->hwndInsertAfter == HWND_TOP ||
winpos->hwndInsertAfter == HWND_BOTTOM ||
winpos->hwndInsertAfter == HWND_TOPMOST ||
winpos->hwndInsertAfter == HWND_NOTOPMOST))
{
HWND parent = NtUserGetAncestor( winpos->hwnd, GA_PARENT );
HWND insertafter_parent = NtUserGetAncestor( winpos->hwndInsertAfter, GA_PARENT );
/* hwndInsertAfter must be a sibling of the window */
if (!insertafter_parent) return FALSE;
if (insertafter_parent != parent) return TRUE;
}
}
/* Make sure that coordinates are valid for WM_WINDOWPOSCHANGING */
if (!(winpos->flags & SWP_NOMOVE))
{
if (winpos->x < -32768) winpos->x = -32768;
else if (winpos->x > 32767) winpos->x = 32767;
if (winpos->y < -32768) winpos->y = -32768;
else if (winpos->y > 32767) winpos->y = 32767;
}
if (!(winpos->flags & SWP_NOSIZE))
{
if (winpos->cx < 0) winpos->cx = 0;
else if (winpos->cx > 32767) winpos->cx = 32767;
if (winpos->cy < 0) winpos->cy = 0;
else if (winpos->cy > 32767) winpos->cy = 32767;
}
context = set_thread_dpi_awareness_context( get_window_dpi_awareness_context( winpos->hwnd ));
if (!calc_winpos( winpos, &old_window_rect, &old_client_rect,
&new_window_rect, &new_client_rect )) goto done;
/* Fix redundant flags */
if (!fixup_swp_flags( winpos, &old_window_rect, parent_x, parent_y )) goto done;
if((winpos->flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) != SWP_NOZORDER)
{
if (NtUserGetAncestor( winpos->hwnd, GA_PARENT ) == get_desktop_window())
winpos->hwndInsertAfter = swp_owner_popups( winpos->hwnd, winpos->hwndInsertAfter );
}
/* Common operations */
calc_ncsize( winpos, &old_window_rect, &old_client_rect,
&new_window_rect, &new_client_rect, valid_rects, parent_x, parent_y );
if (!user_callbacks || !user_callbacks->set_window_pos( winpos->hwnd, winpos->hwndInsertAfter, winpos->flags,
&new_window_rect, &new_client_rect, valid_rects ))
goto done;
if (user_callbacks)
{
if (winpos->flags & SWP_HIDEWINDOW)
user_callbacks->pHideCaret( winpos->hwnd );
else if (winpos->flags & SWP_SHOWWINDOW)
user_callbacks->pShowCaret( winpos->hwnd );
}
if (!(winpos->flags & (SWP_NOACTIVATE|SWP_HIDEWINDOW)))
{
/* child windows get WM_CHILDACTIVATE message */
if ((get_window_long( winpos->hwnd, GWL_STYLE ) & (WS_CHILD | WS_POPUP)) == WS_CHILD)
send_message( winpos->hwnd, WM_CHILDACTIVATE, 0, 0 );
else if (user_callbacks)
set_foreground_window( winpos->hwnd, FALSE );
}
if(!(orig_flags & SWP_DEFERERASE))
{
/* erase parent when hiding or resizing child */
if ((orig_flags & SWP_HIDEWINDOW) ||
(!(orig_flags & SWP_SHOWWINDOW) &&
(winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOGEOMETRYCHANGE))
{
HWND parent = NtUserGetAncestor( winpos->hwnd, GA_PARENT );
if (!parent || parent == get_desktop_window()) parent = winpos->hwnd;
erase_now( parent, 0 );
}
/* Give newly shown windows a chance to redraw */
if(((winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE)
&& !(orig_flags & SWP_AGG_NOCLIENTCHANGE) && (orig_flags & SWP_SHOWWINDOW))
{
erase_now(winpos->hwnd, 0);
}
}
/* And last, send the WM_WINDOWPOSCHANGED message */
TRACE( "\tstatus flags = %04x\n", winpos->flags & SWP_AGG_STATUSFLAGS );
if (((winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE)
&& !((orig_flags & SWP_AGG_NOCLIENTCHANGE) && (orig_flags & SWP_SHOWWINDOW)))
{
/* WM_WINDOWPOSCHANGED is sent even if SWP_NOSENDCHANGING is set
and always contains final window position.
*/
winpos->x = new_window_rect.left;
winpos->y = new_window_rect.top;
winpos->cx = new_window_rect.right - new_window_rect.left;
winpos->cy = new_window_rect.bottom - new_window_rect.top;
send_message( winpos->hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)winpos );
}
ret = TRUE;
done:
set_thread_dpi_awareness_context( context );
return ret;
}
/*******************************************************************
* NtUserSetWindowPos (win32u.@)
*/
BOOL WINAPI NtUserSetWindowPos( HWND hwnd, HWND after, INT x, INT y, INT cx, INT cy, UINT flags )
{
WINDOWPOS winpos;
TRACE( "hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n", hwnd, after, x, y, cx, cy, flags );
if(TRACE_ON(win)) dump_winpos_flags(flags);
if (is_broadcast( hwnd ))
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
winpos.hwnd = get_full_window_handle( hwnd );
winpos.hwndInsertAfter = get_full_window_handle( after );
winpos.x = x;
winpos.y = y;
winpos.cx = cx;
winpos.cy = cy;
winpos.flags = flags;
map_dpi_winpos( &winpos );
if (is_current_thread_window( hwnd ))
return set_window_pos( &winpos, 0, 0 );
if (flags & SWP_ASYNCWINDOWPOS)
return NtUserMessageCall( winpos.hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)&winpos,
0, FNID_SENDNOTIFYMESSAGE, FALSE );
else
return send_message( winpos.hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)&winpos );
}
/*******************************************************************
* update_window_state
*