[3/3] user32: SetParent() needs to map window rectangle to the new parent.
Dmitry Timoshkov
dmitry at codeweavers.com
Thu Feb 10 02:49:14 CST 2011
---
dlls/user32/tests/msg.c | 2 +-
dlls/user32/win.c | 8 +++++
server/window.c | 69 ++++++++++++++++++++++++++++++++---------------
3 files changed, 56 insertions(+), 23 deletions(-)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index b3ca5d0..20976ef 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -12734,7 +12734,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");
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index ba0a4ad..3c6429e 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -2782,6 +2782,7 @@ HWND WINAPI SetParent( HWND hwnd, HWND parent )
HWND old_parent = 0;
BOOL was_visible;
WND *wndPtr;
+ RECT rc;
POINT pt;
BOOL ret;
@@ -2827,6 +2828,13 @@ HWND WINAPI SetParent( HWND hwnd, HWND parent )
pt.x = wndPtr->rectWindow.left;
pt.y = wndPtr->rectWindow.top;
+ rc = wndPtr->rectWindow;
+ MapWindowPoints( old_parent, parent, (POINT *)&rc, 2 );
+ wndPtr->rectWindow = rc;
+ rc = wndPtr->rectClient;
+ MapWindowPoints( old_parent, parent, (POINT *)&rc, 2 );
+ wndPtr->rectClient = rc;
+
SERVER_START_REQ( set_parent )
{
req->handle = wine_server_user_handle( hwnd );
diff --git a/server/window.c b/server/window.c
index 635dd9b..d9fd3dd 100644
--- a/server/window.c
+++ b/server/window.c
@@ -215,10 +215,45 @@ static void link_window( struct window *win, struct window *previous )
win->is_linked = 1;
}
+/* convert coordinates from client to screen coords */
+static inline void client_to_screen( struct window *win, int *x, int *y )
+{
+ for ( ; win && !is_desktop_window(win); win = win->parent)
+ {
+ *x += win->client_rect.left;
+ *y += win->client_rect.top;
+ }
+}
+
+/* convert coordinates from client to screen coords */
+static inline void client_to_screen_rect( struct window *win, rectangle_t *rect )
+{
+ for ( ; win && !is_desktop_window(win); win = win->parent)
+ {
+ rect->left += win->client_rect.left;
+ rect->right += win->client_rect.left;
+ rect->top += win->client_rect.top;
+ rect->bottom += win->client_rect.top;
+ }
+}
+
+/* convert coordinates from screen to client coords */
+static inline void screen_to_client_rect( struct window *win, rectangle_t *rect )
+{
+ for ( ; win && !is_desktop_window(win); win = win->parent)
+ {
+ rect->left -= win->client_rect.left;
+ rect->right -= win->client_rect.left;
+ rect->top -= win->client_rect.top;
+ rect->bottom -= win->client_rect.top;
+ }
+}
+
/* change the parent of a window (or unlink the window if the new parent is NULL) */
static int set_parent_window( struct window *win, struct window *parent )
{
struct window *ptr;
+ rectangle_t window_rect, client_rect;
/* make sure parent is not a child of window */
for (ptr = parent; ptr; ptr = ptr->parent)
@@ -230,11 +265,19 @@ static int set_parent_window( struct window *win, struct window *parent )
}
}
+ window_rect = win->window_rect;
+ client_to_screen_rect( win, &window_rect );
+ client_rect = win->client_rect;
+ client_to_screen_rect( win, &client_rect );
+
if (parent)
{
win->parent = parent;
link_window( win, WINPTR_TOP );
+ screen_to_client_rect( win, &window_rect );
+ screen_to_client_rect( win, &client_rect );
+
/* if parent belongs to a different thread and the window isn't */
/* top-level, attach the two threads */
if (parent->thread && parent->thread != win->thread && !is_desktop_window(parent))
@@ -246,6 +289,10 @@ static int set_parent_window( struct window *win, struct window *parent )
list_add_head( &win->parent->unlinked, &win->entry );
win->is_linked = 0;
}
+
+ win->window_rect = window_rect;
+ win->client_rect = client_rect;
+
return 1;
}
@@ -825,28 +872,6 @@ static struct region *intersect_window_region( struct region *region, struct win
}
-/* convert coordinates from client to screen coords */
-static inline void client_to_screen( struct window *win, int *x, int *y )
-{
- for ( ; win && !is_desktop_window(win); win = win->parent)
- {
- *x += win->client_rect.left;
- *y += win->client_rect.top;
- }
-}
-
-/* convert coordinates from client to screen coords */
-static inline void client_to_screen_rect( struct window *win, rectangle_t *rect )
-{
- for ( ; win && !is_desktop_window(win); win = win->parent)
- {
- rect->left += win->client_rect.left;
- rect->right += win->client_rect.left;
- rect->top += win->client_rect.top;
- rect->bottom += win->client_rect.top;
- }
-}
-
/* map the region from window to screen coordinates */
static inline void map_win_region_to_screen( struct window *win, struct region *region )
{
--
1.7.3.5
More information about the wine-patches
mailing list