diff --git a/dlls/user32/message.c b/dlls/user32/message.c index d2e6a757269..79ea577ba8d 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -1858,7 +1858,7 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR return WIN_DestroyWindow( hwnd ); case WM_WINE_SETWINDOWPOS: if (is_desktop_window( hwnd )) return 0; - return USER_SetWindowPos( (WINDOWPOS *)lparam ); + return USER_SetWindowPos( (WINDOWPOS *)lparam, 0, 0 ); case WM_WINE_SHOWWINDOW: if (is_desktop_window( hwnd )) return 0; return ShowWindow( hwnd, wparam ); diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 69841d3dc6d..a0f2cbeef04 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -15433,7 +15433,7 @@ static void test_SetParent(void) SetParent(child, parent2); flush_events(); - ok_sequence(WmSetParentSeq_1, "SetParent() visible WS_CHILD", TRUE); + ok_sequence(WmSetParentSeq_1, "SetParent() visible WS_CHILD", FALSE); ok(GetWindowLongA(child, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n"); ok(!IsWindowVisible(child), "IsWindowVisible() should return FALSE\n"); diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 30ab511f57e..9699297b681 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -254,7 +254,7 @@ extern void SYSPARAMS_Init(void) DECLSPEC_HIDDEN; extern void USER_CheckNotLock(void) DECLSPEC_HIDDEN; extern BOOL USER_IsExitingThread( DWORD tid ) DECLSPEC_HIDDEN; -extern BOOL USER_SetWindowPos( WINDOWPOS * winpos ) DECLSPEC_HIDDEN; +extern BOOL USER_SetWindowPos( WINDOWPOS * winpos, int parent_x, int parent_y ) DECLSPEC_HIDDEN; typedef LRESULT (*winproc_callback_t)( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result, void *arg ); diff --git a/dlls/user32/win.c b/dlls/user32/win.c index 7bb0088af50..0d694a1230c 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -3014,12 +3014,13 @@ HWND WINAPI GetAncestor( HWND hwnd, UINT type ) */ HWND WINAPI SetParent( HWND hwnd, HWND parent ) { + WINDOWPOS winpos; HWND full_handle; HWND old_parent = 0; BOOL was_visible; WND *wndPtr; - POINT pt; BOOL ret; + RECT window_rect, old_screen_rect, new_screen_rect; TRACE("(%p %p)\n", hwnd, parent); @@ -3062,8 +3063,8 @@ HWND WINAPI SetParent( HWND hwnd, HWND parent ) wndPtr = WIN_GetPtr( hwnd ); if (!wndPtr || wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP) return 0; - pt.x = wndPtr->rectWindow.left; - pt.y = wndPtr->rectWindow.top; + WIN_GetRectangles( hwnd, COORDS_PARENT, &window_rect, NULL ); + WIN_GetRectangles( hwnd, COORDS_SCREEN, &old_screen_rect, NULL ); SERVER_START_REQ( set_parent ) { @@ -3082,11 +3083,17 @@ HWND WINAPI SetParent( HWND hwnd, HWND parent ) USER_Driver->pSetParent( full_handle, parent, old_parent ); - /* SetParent additionally needs to make hwnd the topmost window - in the x-order and send the expected WM_WINDOWPOSCHANGING and - WM_WINDOWPOSCHANGED notification messages. - */ - SetWindowPos( hwnd, HWND_TOP, pt.x, pt.y, 0, 0, SWP_NOSIZE ); + winpos.hwnd = hwnd; + winpos.hwndInsertAfter = HWND_TOP; + winpos.x = window_rect.left; + winpos.y = window_rect.top; + winpos.cx = 0; + winpos.cy = 0; + winpos.flags = SWP_NOSIZE; + + WIN_GetRectangles( hwnd, COORDS_SCREEN, &new_screen_rect, NULL ); + USER_SetWindowPos( &winpos, new_screen_rect.left - old_screen_rect.left, + new_screen_rect.top - old_screen_rect.top ); if (was_visible) ShowWindow( hwnd, SW_SHOW ); diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c index 434fe6e70b3..19ab297fe69 100644 --- a/dlls/user32/winpos.c +++ b/dlls/user32/winpos.c @@ -1855,7 +1855,8 @@ done: * SWP_DoNCCalcSize */ static UINT SWP_DoNCCalcSize( WINDOWPOS *pWinpos, const RECT *old_window_rect, const RECT *old_client_rect, - const RECT *new_window_rect, RECT *new_client_rect, RECT *validRects ) + const RECT *new_window_rect, RECT *new_client_rect, RECT *validRects, + int parent_x, int parent_y ) { UINT wvrFlags = 0; @@ -1879,8 +1880,8 @@ static UINT SWP_DoNCCalcSize( WINDOWPOS *pWinpos, const RECT *old_window_rect, c 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 || - new_client_rect->top != old_client_rect->top) + if (new_client_rect->left != old_client_rect->left - parent_x || + new_client_rect->top != old_client_rect->top - parent_y) pWinpos->flags &= ~SWP_NOCLIENTMOVE; if( (new_client_rect->right - new_client_rect->left != @@ -1901,8 +1902,8 @@ static UINT SWP_DoNCCalcSize( WINDOWPOS *pWinpos, const RECT *old_window_rect, c else { if (!(pWinpos->flags & SWP_NOMOVE) && - (new_client_rect->left != old_client_rect->left || - new_client_rect->top != old_client_rect->top)) + (new_client_rect->left != old_client_rect->left - parent_x || + new_client_rect->top != old_client_rect->top - parent_y)) pWinpos->flags &= ~SWP_NOCLIENTMOVE; } @@ -1917,7 +1918,7 @@ static UINT SWP_DoNCCalcSize( WINDOWPOS *pWinpos, const RECT *old_window_rect, c } /* fix redundant flags and values in the WINDOWPOS structure */ -static BOOL fixup_flags( WINDOWPOS *winpos, const RECT *old_window_rect ) +static BOOL fixup_flags( WINDOWPOS *winpos, const RECT *old_window_rect, int parent_x, int parent_y ) { HWND parent; WND *wndPtr = WIN_GetPtr( winpos->hwnd ); @@ -1955,7 +1956,7 @@ static BOOL fixup_flags( WINDOWPOS *winpos, const RECT *old_window_rect ) (old_window_rect->bottom - old_window_rect->top == winpos->cy)) winpos->flags |= SWP_NOSIZE; /* Already the right size */ - if ((old_window_rect->left == winpos->x) && (old_window_rect->top == winpos->y)) + 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 ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD) @@ -2203,7 +2204,7 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, * * User32 internal function */ -BOOL USER_SetWindowPos( WINDOWPOS * winpos ) +BOOL USER_SetWindowPos( 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; @@ -2251,7 +2252,7 @@ BOOL USER_SetWindowPos( WINDOWPOS * winpos ) &new_window_rect, &new_client_rect )) return FALSE; /* Fix redundant flags */ - if (!fixup_flags( winpos, &old_window_rect )) return FALSE; + if (!fixup_flags( winpos, &old_window_rect, parent_x, parent_y )) return FALSE; if((winpos->flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) != SWP_NOZORDER) { @@ -2262,7 +2263,7 @@ BOOL USER_SetWindowPos( WINDOWPOS * winpos ) /* Common operations */ SWP_DoNCCalcSize( winpos, &old_window_rect, &old_client_rect, - &new_window_rect, &new_client_rect, valid_rects ); + &new_window_rect, &new_client_rect, valid_rects, parent_x, parent_y ); if (!set_window_pos( winpos->hwnd, winpos->hwndInsertAfter, winpos->flags, &new_window_rect, &new_client_rect, valid_rects )) @@ -2350,7 +2351,7 @@ BOOL WINAPI SetWindowPos( HWND hwnd, HWND hwndInsertAfter, winpos.flags = flags; if (WIN_IsCurrentThread( hwnd )) - return USER_SetWindowPos(&winpos); + return USER_SetWindowPos( &winpos, 0, 0 ); return SendMessageW( winpos.hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)&winpos ); } @@ -2499,7 +2500,7 @@ BOOL WINAPI EndDeferWindowPos( HDWP hdwp ) winpos->cx, winpos->cy, winpos->flags); if (WIN_IsCurrentThread( winpos->hwnd )) - USER_SetWindowPos( winpos ); + USER_SetWindowPos( winpos, 0, 0 ); else SendMessageW( winpos->hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)winpos ); }