Commit 221b0447 authored by Pierre d'Herbemont's avatar Pierre d'Herbemont Committed by Alexandre Julliard

user32: Factorize graphics driver SetParent into user32.

parent 39a5b076
......@@ -365,9 +365,8 @@ static void nulldrv_SetFocus( HWND hwnd )
{
}
static HWND nulldrv_SetParent( HWND hwnd, HWND parent )
static void nulldrv_SetParent( HWND hwnd, HWND parent, HWND old_parent )
{
return 0;
}
static BOOL nulldrv_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
......@@ -684,9 +683,9 @@ static void loaderdrv_SetFocus( HWND hwnd )
load_driver()->pSetFocus( hwnd );
}
static HWND loaderdrv_SetParent( HWND hwnd, HWND parent )
static void loaderdrv_SetParent( HWND hwnd, HWND parent, HWND old_parent )
{
return load_driver()->pSetParent( hwnd, parent );
load_driver()->pSetParent( hwnd, parent, old_parent );
}
static BOOL loaderdrv_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
......
......@@ -148,7 +148,7 @@ typedef struct tagUSER_DRIVER {
INT (*pReleaseDC)(HWND,HDC,BOOL);
BOOL (*pScrollDC)(HDC, INT, INT, const RECT *, const RECT *, HRGN, LPRECT);
void (*pSetFocus)(HWND);
HWND (*pSetParent)(HWND,HWND);
void (*pSetParent)(HWND,HWND,HWND);
BOOL (*pSetWindowPos)(HWND,HWND,const RECT *,const RECT *,UINT,const RECT *);
int (*pSetWindowRgn)(HWND,HRGN,BOOL);
void (*pSetWindowIcon)(HWND,UINT,HICON);
......
......@@ -2531,6 +2531,10 @@ HWND WINAPI GetAncestor( HWND hwnd, UINT type )
HWND WINAPI SetParent( HWND hwnd, HWND parent )
{
HWND full_handle;
HWND old_parent = 0;
BOOL was_visible;
WND *wndPtr;
BOOL ret;
if (is_broadcast(hwnd) || is_broadcast(parent))
{
......@@ -2557,7 +2561,40 @@ HWND WINAPI SetParent( HWND hwnd, HWND parent )
if (!(full_handle = WIN_IsCurrentThread( hwnd )))
return (HWND)SendMessageW( hwnd, WM_WINE_SETPARENT, (WPARAM)parent, 0 );
return USER_Driver->pSetParent( full_handle, parent );
/* Windows hides the window first, then shows it again
* including the WM_SHOWWINDOW messages and all */
was_visible = ShowWindow( hwnd, SW_HIDE );
wndPtr = WIN_GetPtr( hwnd );
if (!wndPtr || wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP) return 0;
SERVER_START_REQ( set_parent )
{
req->handle = hwnd;
req->parent = parent;
if ((ret = !wine_server_call( req )))
{
old_parent = reply->old_parent;
wndPtr->parent = parent = reply->full_parent;
}
}
SERVER_END_REQ;
WIN_ReleasePtr( wndPtr );
if (!ret) return 0;
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_TOPMOST, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | (was_visible ? SWP_SHOWWINDOW : 0) );
/* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
* for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
return old_parent;
}
......
......@@ -1230,72 +1230,33 @@ XIC X11DRV_get_ic( HWND hwnd )
/*****************************************************************
* SetParent (X11DRV.@)
*/
HWND X11DRV_SetParent( HWND hwnd, HWND parent )
void X11DRV_SetParent( HWND hwnd, HWND parent, HWND old_parent )
{
Display *display = thread_display();
WND *wndPtr;
BOOL ret;
HWND old_parent = 0;
/* Windows hides the window first, then shows it again
* including the WM_SHOWWINDOW messages and all */
BOOL was_visible = ShowWindow( hwnd, SW_HIDE );
wndPtr = WIN_GetPtr( hwnd );
if (!wndPtr || wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP) return 0;
SERVER_START_REQ( set_parent )
{
req->handle = hwnd;
req->parent = parent;
if ((ret = !wine_server_call( req )))
{
old_parent = reply->old_parent;
wndPtr->parent = parent = reply->full_parent;
}
struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
}
SERVER_END_REQ;
WIN_ReleasePtr( wndPtr );
if (!ret) return 0;
if (!data) return;
if (parent == old_parent) return;
if (parent != old_parent)
if (parent != GetDesktopWindow()) /* a child window */
{
struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
if (!data) return 0;
if (parent != GetDesktopWindow()) /* a child window */
if (old_parent == GetDesktopWindow())
{
if (old_parent == GetDesktopWindow())
/* destroy the old X windows */
destroy_whole_window( display, data );
destroy_icon_window( display, data );
if (data->managed)
{
/* destroy the old X windows */
destroy_whole_window( display, data );
destroy_icon_window( display, data );
if (data->managed)
{
data->managed = FALSE;
RemovePropA( data->hwnd, managed_prop );
}
data->managed = FALSE;
RemovePropA( data->hwnd, managed_prop );
}
}
else /* new top level window */
{
/* FIXME: we ignore errors since we can't really recover anyway */
create_whole_window( display, data, GetWindowLongW( hwnd, GWL_STYLE ) );
}
}
/* 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_TOPMOST, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | (was_visible ? SWP_SHOWWINDOW : 0) );
/* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
* for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
return old_parent;
else /* new top level window */
{
/* FIXME: we ignore errors since we can't really recover anyway */
create_whole_window( display, data, GetWindowLongW( hwnd, GWL_STYLE ) );
}
}
......
......@@ -103,7 +103,7 @@
@ cdecl ScrollDC(long long long ptr ptr long ptr) X11DRV_ScrollDC
@ cdecl SetClipboardData(long long long long) X11DRV_SetClipboardData
@ cdecl SetFocus(long) X11DRV_SetFocus
@ cdecl SetParent(long long) X11DRV_SetParent
@ cdecl SetParent(long long long) X11DRV_SetParent
@ cdecl SetWindowIcon(long long long) X11DRV_SetWindowIcon
@ cdecl SetWindowPos(long long ptr ptr long ptr) X11DRV_SetWindowPos
@ cdecl SetWindowRgn(long long long) X11DRV_SetWindowRgn
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment