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