user32: Take into account the offset between old and new parent in SetParent().

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2018-05-07 12:00:17 +02:00
parent bc956d8aa6
commit e95d0c6849
5 changed files with 31 additions and 23 deletions

View File

@ -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 );

View File

@ -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");

View File

@ -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 );

View File

@ -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 );

View File

@ -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 );
}