user32: Factorize graphics drivers' SetParent into user32

Pierre d'Herbemont pdherbemont at free.fr
Sun Dec 10 16:21:28 CST 2006


As the title say.

Pierre.
---
  dlls/user32/driver.c              |    8 +++---
  dlls/user32/user_private.h        |    2 +-
  dlls/user32/win.c                 |   40 
++++++++++++++++++++++++++++++++++++-
  dlls/winex11.drv/window.c         |   40 
++----------------------------------
  dlls/winex11.drv/winex11.drv.spec |    2 +-
  5 files changed, 48 insertions(+), 44 deletions(-)
-------------- next part --------------
diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index b5bf7a8..7a6fad1 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -365,9 +365,9 @@ static void nulldrv_SetFocus( HWND hwnd
 {
 }
 
-static HWND nulldrv_SetParent( HWND hwnd, HWND parent )
+static BOOL nulldrv_SetParent( HWND hwnd, HWND parent, HWND old_parent )
 {
-    return 0;
+    return FALSE;
 }
 
 static BOOL nulldrv_SetWindowPos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
@@ -684,9 +684,9 @@ static void loaderdrv_SetFocus( HWND hwn
     load_driver()->pSetFocus( hwnd );
 }
 
-static HWND loaderdrv_SetParent( HWND hwnd, HWND parent )
+static BOOL loaderdrv_SetParent( HWND hwnd, HWND parent, HWND old_parent )
 {
-    return load_driver()->pSetParent( hwnd, parent );
+    return 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..69286a3 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);
+    BOOL   (*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 ecc270e..d261cee 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -2654,6 +2654,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))
     {
@@ -2680,7 +2684,41 @@ 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;
+    
+    if(!USER_Driver->pSetParent( full_handle, parent, old_parent ))
+        return 0;
+
+    /* 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 4f1a74c..907bbdc 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -1120,40 +1120,15 @@ XIC X11DRV_get_ic( HWND hwnd )
 /*****************************************************************
  *		SetParent   (X11DRV.@)
  */
-HWND X11DRV_SetParent( HWND hwnd, HWND parent )
+BOOL 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;
-        }
-
-    }
-    SERVER_END_REQ;
-    WIN_ReleasePtr( wndPtr );
-    if (!ret) return 0;
 
     if (parent != old_parent)
     {
         struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
 
-        if (!data) return 0;
+        if (!data) return FALSE;
 
         if (parent != GetDesktopWindow()) /* a child window */
         {
@@ -1176,16 +1151,7 @@ HWND X11DRV_SetParent( HWND hwnd, HWND p
         }
     }
 
-    /* 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;
+    return TRUE;
 }
 
 
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-patches mailing list