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