[PATCH] user32: Removed 16-bit windows position trunc in WINPOS_SetPlacement.

Kees Beets kbeets68 at gmail.com
Thu May 4 14:18:31 CDT 2017


Fixes https://bugs.winehq.org/show_bug.cgi?id=38231

Replaced SetWindowPos in WINPOS_SetPlacement with an implementation that
does not truncate windows positions to 16-bit. Fixes a bug in Adobe
Lightroom under wine that is not present under windows (7, 8, 10),
while still running all win tests successfully.

Tested on Ubuntu 16.04. 0 failures in win tests.

Signed-off-by: Kees Beets <kbeets68 at gmail.com>
---
 dlls/user32/message.c      |  3 +++
 dlls/user32/user_private.h |  2 ++
 dlls/user32/winpos.c       | 50 +++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index d13a9b0..be4d2a9 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -1859,6 +1859,9 @@ 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_SETWINDOWPLACEMENT:
+        if (is_desktop_window( hwnd )) return 0;
+        return USER_SetWindowPlacement( (WINDOWPOS *)lparam );
     case WM_WINE_SHOWWINDOW:
         if (is_desktop_window( hwnd )) return 0;
         return ShowWindow( hwnd, wparam );
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index b4a756c..64d28d6 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -53,6 +53,7 @@ enum wine_internal_message
     WM_WINE_KEYBOARD_LL_HOOK,
     WM_WINE_MOUSE_LL_HOOK,
     WM_WINE_CLIPCURSOR,
+    WM_WINE_SETWINDOWPLACEMENT,
     WM_WINE_FIRST_DRIVER_MSG = 0x80001000,  /* range of messages reserved for the USER driver */
     WM_WINE_LAST_DRIVER_MSG = 0x80001fff
 };
@@ -248,6 +249,7 @@ extern void USER_CheckNotLock(void) DECLSPEC_HIDDEN;
 extern BOOL USER_IsExitingThread( DWORD tid ) DECLSPEC_HIDDEN;
 
 extern BOOL USER_SetWindowPos( WINDOWPOS * winpos ) DECLSPEC_HIDDEN;
+extern BOOL USER_SetWindowPlacement( WINDOWPOS * winpos ) DECLSPEC_HIDDEN;
 
 typedef LRESULT (*winproc_callback_t)( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
                                        LRESULT *result, void *arg );
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c
index c2b35ec..7c1f0a1 100644
--- a/dlls/user32/winpos.c
+++ b/dlls/user32/winpos.c
@@ -1388,6 +1388,7 @@ static BOOL WINPOS_SetPlacement( HWND hwnd, const WINDOWPLACEMENT *wndpl, UINT f
     DWORD style;
     WND *pWnd = WIN_GetPtr( hwnd );
     WINDOWPLACEMENT wp = *wndpl;
+    WINDOWPOS winpos;
 
     if (flags & PLACE_MIN) make_point_onscreen( &wp.ptMinPosition );
     if (flags & PLACE_MAX) make_point_onscreen( &wp.ptMaxPosition );
@@ -1426,10 +1427,26 @@ static BOOL WINPOS_SetPlacement( HWND hwnd, const WINDOWPLACEMENT *wndpl, UINT f
                           SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
     }
     else if( flags & PLACE_RECT )
-        SetWindowPos( hwnd, 0, wp.rcNormalPosition.left, wp.rcNormalPosition.top,
-                      wp.rcNormalPosition.right - wp.rcNormalPosition.left,
-                      wp.rcNormalPosition.bottom - wp.rcNormalPosition.top,
-                      SWP_NOZORDER | SWP_NOACTIVATE );
+    {
+        if (is_broadcast(hwnd))
+        {
+            SetLastError( ERROR_INVALID_PARAMETER );
+            return FALSE;
+        }
+
+        winpos.hwnd = WIN_GetFullHandle(hwnd);
+        winpos.hwndInsertAfter = WIN_GetFullHandle(0);
+        winpos.x = wp.rcNormalPosition.left;
+        winpos.y = wp.rcNormalPosition.top;
+        winpos.cx = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
+        winpos.cy = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;
+        winpos.flags = SWP_NOZORDER | SWP_NOACTIVATE;
+
+        if (WIN_IsCurrentThread( hwnd ))
+            USER_SetWindowPlacement(&winpos);
+        else
+            SendMessageW( winpos.hwnd, WM_WINE_SETWINDOWPLACEMENT, 0, (LPARAM)&winpos );
+    }
 
     ShowWindow( hwnd, wndpl->showCmd );
 
@@ -2288,6 +2305,30 @@ BOOL USER_SetWindowPos( WINDOWPOS * winpos )
 }
 
 /***********************************************************************
+ *		USER_SetWindowPlacement
+ *
+ *     User32 internal function
+ */
+BOOL USER_SetWindowPlacement( WINDOWPOS * winpos )
+{
+    RECT newWindowRect, newClientRect, valid_rects[2];
+
+    if (!SWP_DoWinPosChanging( winpos, &newWindowRect, &newClientRect )) return FALSE;
+
+    /* Common operations */
+    SWP_DoNCCalcSize( winpos, &newWindowRect, &newClientRect, valid_rects );
+    if (!set_window_pos( winpos->hwnd, winpos->hwndInsertAfter, winpos->flags, &newWindowRect, &newClientRect, valid_rects )) return FALSE;
+
+    winpos->x = newWindowRect.left;
+    winpos->y = newWindowRect.top;
+    winpos->cx = newWindowRect.right - newWindowRect.left;
+    winpos->cy = newWindowRect.bottom - newWindowRect.top;
+    SendMessageW( winpos->hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)winpos );
+
+    return TRUE;
+}
+
+/***********************************************************************
  *		SetWindowPos (USER32.@)
  */
 BOOL WINAPI SetWindowPos( HWND hwnd, HWND hwndInsertAfter,
@@ -2319,7 +2360,6 @@ BOOL WINAPI SetWindowPos( HWND hwnd, HWND hwndInsertAfter,
     return SendMessageW( winpos.hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)&winpos );
 }
 
-
 /***********************************************************************
  *		BeginDeferWindowPos (USER32.@)
  */
-- 
2.7.4




More information about the wine-patches mailing list