Pierre d'Herbemont : user32:
Factorize graphics driver SetParent into user32.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Dec 12 14:29:53 CST 2006
Module: wine
Branch: master
Commit: 221b044740e97c1af710b4222fdeafb8e8d6bf9c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=221b044740e97c1af710b4222fdeafb8e8d6bf9c
Author: Pierre d'Herbemont <pdherbemont at free.fr>
Date: Sun Dec 10 23:21:28 2006 +0100
user32: Factorize graphics driver SetParent into user32.
---
dlls/user32/driver.c | 7 ++--
dlls/user32/user_private.h | 2 +-
dlls/user32/win.c | 39 +++++++++++++++++++-
dlls/winex11.drv/window.c | 73 +++++++++----------------------------
dlls/winex11.drv/winex11.drv.spec | 2 +-
5 files changed, 60 insertions(+), 63 deletions(-)
diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index b5bf7a8..0c93a67 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -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 hwn
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,
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 5fad289..ae27884 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -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);
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index 9ee1c00..42b7696 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -2531,6 +2531,10 @@ HWND WINAPI GetAncestor( HWND hwnd, UINT
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 p
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;
}
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 58b0c9c..26bd8e1 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -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 ) );
+ }
}
diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec
index 1387979..95b3d94 100644
--- a/dlls/winex11.drv/winex11.drv.spec
+++ b/dlls/winex11.drv/winex11.drv.spec
@@ -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
More information about the wine-cvs
mailing list