Windows truncates window's coordinates at 16 bits when moving or resizing a window

Dmitry Timoshkov dmitry at baikal.ru
Wed Mar 10 08:55:50 CST 2004


Hello,

while searching for another possible SetWindowPos I've found this one.

Changelog:
    Dmitry Timoshkov <dmitry at codeweavers.com>
    Windows truncates window's coordinates at 16 bits when moving or
    resizing a window.

diff -u cvs/hq/wine/dlls/user/tests/win.c wine/dlls/user/tests/win.c
--- cvs/hq/wine/dlls/user/tests/win.c	2004-02-07 19:17:49.000000000 +0800
+++ wine/dlls/user/tests/win.c	2004-03-10 21:55:09.000000000 +0800
@@ -443,6 +443,41 @@ static LRESULT WINAPI main_window_procA(
 	    SetWindowLongA(hwnd, GWL_USERDATA, 0x20031021);
 	    break;
 	}
+	case WM_WINDOWPOSCHANGING:
+	{
+	    BOOL is_win9x = GetWindowLongW(hwnd, GWL_WNDPROC) == 0;
+	    WINDOWPOS *winpos = (WINDOWPOS *)lparam;
+	    trace("main: WM_WINDOWPOSCHANGING\n");
+	    trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
+		   winpos->hwnd, winpos->hwndInsertAfter,
+		   winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags);
+	    if (!(winpos->flags & SWP_NOMOVE))
+	    {
+		ok(winpos->x >= -32768 && winpos->x <= 32767, "bad winpos->x %d\n", winpos->x);
+		ok(winpos->y >= -32768 && winpos->y <= 32767, "bad winpos->y %d\n", winpos->y);
+	    }
+	    /* Win9x does not fixup cx/xy for WM_WINDOWPOSCHANGING */
+	    if (!(winpos->flags & SWP_NOSIZE) && !is_win9x)
+	    {
+		ok(winpos->cx >= 0 && winpos->cx <= 32767, "bad winpos->cx %d\n", winpos->cx);
+		ok(winpos->cy >= 0 && winpos->cy <= 32767, "bad winpos->cy %d\n", winpos->cy);
+	    }
+	    break;
+	}
+	case WM_WINDOWPOSCHANGED:
+	{
+	    WINDOWPOS *winpos = (WINDOWPOS *)lparam;
+	    trace("main: WM_WINDOWPOSCHANGED\n");
+	    trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
+		   winpos->hwnd, winpos->hwndInsertAfter,
+		   winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags);
+	    ok(winpos->x >= -32768 && winpos->x <= 32767, "bad winpos->x %d\n", winpos->x);
+	    ok(winpos->y >= -32768 && winpos->y <= 32767, "bad winpos->y %d\n", winpos->y);
+
+	    ok(winpos->cx >= 0 && winpos->cx <= 32767, "bad winpos->cx %d\n", winpos->cx);
+	    ok(winpos->cy >= 0 && winpos->cy <= 32767, "bad winpos->cy %d\n", winpos->cy);
+	    break;
+	}
 	case WM_NCCREATE:
 	{
 	    BOOL got_getminmaxinfo = GetWindowLongA(hwnd, GWL_USERDATA) == 0x20031021;
@@ -1131,6 +1166,15 @@ static void test_icons(void)
     ok( res == icon2, "wrong big icon after set %p/%p\n", res, icon2 );
 }
 
+static void test_SetWindowPos(HWND hwnd)
+{
+    SetWindowPos(hwnd, 0, -32769, -40000, -32769, -90000, SWP_NOMOVE);
+    SetWindowPos(hwnd, 0, 32768, 40000, 32768, 40000, SWP_NOMOVE);
+
+    SetWindowPos(hwnd, 0, -32769, -40000, -32769, -90000, SWP_NOSIZE);
+    SetWindowPos(hwnd, 0, 32768, 40000, 32768, 40000, SWP_NOSIZE);
+}
+
 START_TEST(win)
 {
     pGetAncestor = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" );
@@ -1158,6 +1202,7 @@ START_TEST(win)
 
     test_mdi();
     test_icons();
+    test_SetWindowPos(hwndMain);
 
     UnhookWindowsHookEx(hhook);
 }
diff -u cvs/hq/wine/dlls/x11drv/winpos.c wine/dlls/x11drv/winpos.c
--- cvs/hq/wine/dlls/x11drv/winpos.c	2004-02-16 20:53:43.000000000 +0800
+++ wine/dlls/x11drv/winpos.c	2004-03-10 22:05:21.000000000 +0800
@@ -720,6 +720,17 @@ static BOOL fixup_flags( WINDOWPOS *winp
     }
     winpos->hwnd = wndPtr->hwndSelf;  /* make it a full handle */
 
+    /* Finally make sure that all coordinates are valid */
+    if (winpos->x < -32768) winpos->x = -32768;
+    else if (winpos->x > 32767) winpos->x = 32767;
+    if (winpos->y < -32768) winpos->y = -32768;
+    else if (winpos->y > 32767) winpos->y = 32767;
+
+    if (winpos->cx < 0) winpos->cx = 0;
+    else if (winpos->cx > 32767) winpos->cx = 32767;
+    if (winpos->cy < 0) winpos->cy = 0;
+    else if (winpos->cy > 32767) winpos->cy = 32767;
+
     if (wndPtr->dwStyle & WS_VISIBLE) winpos->flags &= ~SWP_SHOWWINDOW;
     else
     {
@@ -727,9 +738,6 @@ static BOOL fixup_flags( WINDOWPOS *winp
         if (!(winpos->flags & SWP_SHOWWINDOW)) winpos->flags |= SWP_NOREDRAW;
     }
 
-    if (winpos->cx < 0) winpos->cx = 0;
-    if (winpos->cy < 0) winpos->cy = 0;
-
     if ((wndPtr->rectWindow.right - wndPtr->rectWindow.left == winpos->cx) &&
         (wndPtr->rectWindow.bottom - wndPtr->rectWindow.top == winpos->cy))
         winpos->flags |= SWP_NOSIZE;    /* Already the right size */
@@ -914,6 +922,22 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *win
     /* Check window handle */
     if (winpos->hwnd == GetDesktopWindow()) return FALSE;
 
+    /* First make sure that coordinates are valid for WM_WINDOWPOSCHANGING */
+    if (!(winpos->flags & SWP_NOMOVE))
+    {
+        if (winpos->x < -32768) winpos->x = -32768;
+        else if (winpos->x > 32767) winpos->x = 32767;
+        if (winpos->y < -32768) winpos->y = -32768;
+        else if (winpos->y > 32767) winpos->y = 32767;
+    }
+    if (!(winpos->flags & SWP_NOSIZE))
+    {
+        if (winpos->cx < 0) winpos->cx = 0;
+        else if (winpos->cx > 32767) winpos->cx = 32767;
+        if (winpos->cy < 0) winpos->cy = 0;
+        else if (winpos->cy > 32767) winpos->cy = 32767;
+    }
+
     if (!SWP_DoWinPosChanging( winpos, &newWindowRect, &newClientRect )) return FALSE;
 
     /* Fix redundant flags */






More information about the wine-patches mailing list