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