user32: Make GetWindowPlacement() work for other process windows. Take 2.

Dmitry Timoshkov dmitry at codeweavers.com
Mon Aug 30 06:00:19 CDT 2010


This patch fixes the problem reported in the bug 12001.

This version of the patch uses an internal message to fetch window state
from a foreign thread. Another aproach could be to store the window state in
the server, but that would require to introduce another server call for it.
---
 dlls/user32/message.c      |   13 ++++++++++
 dlls/user32/spy.c          |    1 +
 dlls/user32/user_private.h |    2 +
 dlls/user32/winpos.c       |   57 ++++++++++++++++++++++++--------------------
 4 files changed, 47 insertions(+), 26 deletions(-)

diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index b073e1c..6f74353 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -783,6 +783,8 @@ static size_t pack_message( HWND hwnd, UINT message, WPARAM wparam, LPARAM lpara
     case WM_GETMINMAXINFO:
         push_data( data, (MINMAXINFO *)lparam, sizeof(MINMAXINFO) );
         return sizeof(MINMAXINFO);
+    case WM_WINE_GETWINDOWPLACEMENT:
+        return sizeof(WINDOWPLACEMENT);
     case WM_DRAWITEM:
     {
         DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lparam;
@@ -1143,6 +1145,9 @@ static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lpa
     case WM_GETMINMAXINFO:
         minsize = sizeof(MINMAXINFO);
         break;
+    case WM_WINE_GETWINDOWPLACEMENT:
+        if (!get_buffer_space( buffer, sizeof(WINDOWPLACEMENT) )) return FALSE;
+        break;
     case WM_DRAWITEM:
     {
         DRAWITEMSTRUCT dis;
@@ -1520,6 +1525,9 @@ static void pack_reply( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam,
     case WM_GETMINMAXINFO:
         push_data( data, (MINMAXINFO *)lparam, sizeof(MINMAXINFO) );
         break;
+    case WM_WINE_GETWINDOWPLACEMENT:
+        push_data( data, (WINDOWPLACEMENT *)lparam, sizeof(WINDOWPLACEMENT) );
+        break;
     case WM_MEASUREITEM:
     {
         MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lparam;
@@ -1674,6 +1682,9 @@ static void unpack_reply( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam,
     case WM_GETMINMAXINFO:
         memcpy( (MINMAXINFO *)lparam, buffer, min( sizeof(MINMAXINFO), size ));
         break;
+    case WM_WINE_GETWINDOWPLACEMENT:
+        memcpy( (WINDOWPLACEMENT *)lparam, buffer, min( sizeof(WINDOWPLACEMENT), size ));
+        break;
     case WM_MEASUREITEM:
         if (size >= sizeof(ps->mis))
         {
@@ -1846,6 +1857,8 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR
     case WM_WINE_SETWINDOWPOS:
         if (is_desktop_window( hwnd )) return 0;
         return USER_SetWindowPos( (WINDOWPOS *)lparam );
+    case WM_WINE_GETWINDOWPLACEMENT:
+        return USER_GetWindowPlacement( hwnd, (WINDOWPLACEMENT *)lparam );
     case WM_WINE_SHOWWINDOW:
         if (is_desktop_window( hwnd )) return 0;
         return ShowWindow( hwnd, wparam );
diff --git a/dlls/user32/spy.c b/dlls/user32/spy.c
index 26bd741..741da2c 100644
--- a/dlls/user32/spy.c
+++ b/dlls/user32/spy.c
@@ -1125,6 +1125,7 @@ static const char * const WINEMessageTypeNames[SPY_MAX_WINEMSGNUM + 1] =
 {
     "WM_WINE_DESTROYWINDOW",
     "WM_WINE_SETWINDOWPOS",
+    "WM_WINE_GETWINDOWPLACEMENT",
     "WM_WINE_SHOWWINDOW",
     "WM_WINE_SETPARENT",
     "WM_WINE_SETWINDOWLONG",
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 23b4269..1538fa4 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -40,6 +40,7 @@ enum wine_internal_message
 {
     WM_WINE_DESTROYWINDOW = 0x80000000,
     WM_WINE_SETWINDOWPOS,
+    WM_WINE_GETWINDOWPLACEMENT,
     WM_WINE_SHOWWINDOW,
     WM_WINE_SETPARENT,
     WM_WINE_SETWINDOWLONG,
@@ -221,6 +222,7 @@ extern void SYSPARAMS_Init(void) DECLSPEC_HIDDEN;
 extern void USER_CheckNotLock(void) DECLSPEC_HIDDEN;
 extern BOOL USER_IsExitingThread( DWORD tid ) DECLSPEC_HIDDEN;
 
+extern BOOL USER_GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl ) DECLSPEC_HIDDEN;
 extern BOOL USER_SetWindowPos( WINDOWPOS * winpos ) DECLSPEC_HIDDEN;
 
 typedef LRESULT (*winproc_callback_t)( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c
index e5e4e0c..907f152 100644
--- a/dlls/user32/winpos.c
+++ b/dlls/user32/winpos.c
@@ -831,6 +831,7 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
 
     TRACE("%p %u\n", hwnd, cmd );
 
+    /* update internal window state */
     wpl.length = sizeof(wpl);
     GetWindowPlacement( hwnd, &wpl );
 
@@ -1137,36 +1138,13 @@ UINT WINAPI GetInternalWindowPos( HWND hwnd, LPRECT rectWnd,
     return 0;
 }
 
-
-/***********************************************************************
- *		GetWindowPlacement (USER32.@)
- *
- * Win95:
- * Fails if wndpl->length of Win95 (!) apps is invalid.
- */
-BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
+BOOL USER_GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
 {
     WND *pWnd = WIN_GetPtr( hwnd );
 
-    if (!pWnd) return FALSE;
+    TRACE("hwnd %p, wndpl %p\n", hwnd, wndpl);
 
-    if (pWnd == WND_DESKTOP)
-    {
-        wndpl->length  = sizeof(*wndpl);
-        wndpl->showCmd = SW_SHOWNORMAL;
-        wndpl->flags = 0;
-        wndpl->ptMinPosition.x = -1;
-        wndpl->ptMinPosition.y = -1;
-        wndpl->ptMaxPosition.x = -1;
-        wndpl->ptMaxPosition.y = -1;
-        GetWindowRect( hwnd, &wndpl->rcNormalPosition );
-        return TRUE;
-    }
-    if (pWnd == WND_OTHER_PROCESS)
-    {
-        if (IsWindow( hwnd )) FIXME( "not supported on other process window %p\n", hwnd );
-        return FALSE;
-    }
+    if (!pWnd || pWnd == WND_OTHER_PROCESS) return FALSE;
 
     /* update the placement according to the current style */
     if (pWnd->dwStyle & WS_MINIMIZE)
@@ -1205,6 +1183,33 @@ BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
     return TRUE;
 }
 
+/***********************************************************************
+ *		GetWindowPlacement (USER32.@)
+ *
+ * Win95:
+ * Fails if wndpl->length of Win95 (!) apps is invalid.
+ */
+BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
+{
+    if (hwnd == GetDesktopWindow())
+    {
+        wndpl->length  = sizeof(*wndpl);
+        wndpl->showCmd = SW_SHOWNORMAL;
+        wndpl->flags = 0;
+        wndpl->ptMinPosition.x = -1;
+        wndpl->ptMinPosition.y = -1;
+        wndpl->ptMaxPosition.x = -1;
+        wndpl->ptMaxPosition.y = -1;
+        GetWindowRect( hwnd, &wndpl->rcNormalPosition );
+        return TRUE;
+    }
+
+    if (WIN_IsCurrentThread( hwnd ))
+        return USER_GetWindowPlacement( hwnd, wndpl );
+
+    return SendMessageW( hwnd, WM_WINE_GETWINDOWPLACEMENT, 0, (LPARAM)wndpl );
+}
+
 /* make sure the specified rect is visible on screen */
 static void make_rect_onscreen( RECT *rect )
 {
-- 
1.7.0.6




More information about the wine-patches mailing list