Paul Gofman : user32: Fix coords in WINDOWPOS for WM_NCCALCSIZE sent from SetWindowPos().
Alexandre Julliard
julliard at winehq.org
Mon Apr 20 15:01:49 CDT 2020
Module: wine
Branch: oldstable
Commit: 9f35b608401f858069d01853a859d6c57521f089
URL: https://source.winehq.org/git/wine.git/?a=commit;h=9f35b608401f858069d01853a859d6c57521f089
Author: Paul Gofman <gofmanp at gmail.com>
Date: Fri Oct 18 13:05:14 2019 +0300
user32: Fix coords in WINDOWPOS for WM_NCCALCSIZE sent from SetWindowPos().
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=40777
Signed-off-by: Paul Gofman <gofmanp at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit 2ac268436b535ed35c82aa2d5c2518e5dfb3cd12)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>
---
dlls/user32/tests/msg.c | 86 ++++++++++++++++++++++++++++++++++++++++++-------
dlls/user32/winpos.c | 12 +++++++
2 files changed, 86 insertions(+), 12 deletions(-)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 366a138b52..2c96a9d10e 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -2184,9 +2184,27 @@ static void add_message_(int line, const struct recvd_message *msg)
seq->wParam = winpos->flags & 0xffff;
/* We are not interested in the flags that don't match under XP and Win9x */
seq->wParam &= ~SWP_NOZORDER;
+ seq->lParam = (!!winpos->cx) | ((!!winpos->cy) << 1)
+ | ((!!winpos->x) << 2) | ((!!winpos->y) << 3);
break;
}
+ case WM_NCCALCSIZE:
+ if (msg->wParam)
+ {
+ NCCALCSIZE_PARAMS *p = (NCCALCSIZE_PARAMS *)msg->lParam;
+ WINDOWPOS *winpos = p->lppos;
+
+ sprintf(seq->output, "%s: %p WM_NCCALCSIZE: winpos->cx %u, winpos->cy %u",
+ msg->descr, msg->hwnd, winpos->cx, winpos->cy);
+ seq->lParam = (!!winpos->cx) | ((!!winpos->cy) << 1)
+ | ((!!winpos->x) << 2) | ((!!winpos->y) << 3);
+ }
+ else
+ {
+ seq->lParam = 0;
+ }
+ break;
case WM_DRAWITEM:
{
DRAW_ITEM_STRUCT di;
@@ -5661,32 +5679,72 @@ done:
flush_sequence();
}
+static const struct message WmFrameChanged[] = {
+ { WM_WINDOWPOSCHANGING, sent|wparam|lparam, SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE, 0 },
+ { WM_NCCALCSIZE, sent|wparam|lparam, 1, 0xf },
+ { WM_WINDOWPOSCHANGED, sent|wparam|lparam, SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOREDRAW
+ |SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE, 0xf },
+ { WM_GETTEXT, sent|optional },
+ { 0 }
+};
+
+static const struct message WmFrameChanged_move[] = {
+ { WM_WINDOWPOSCHANGING, sent|wparam|lparam, SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE, 0 },
+ { WM_NCCALCSIZE, sent|wparam|lparam, 1, 0x3 },
+ { WM_WINDOWPOSCHANGED, sent|wparam|lparam, SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOREDRAW
+ |SWP_NOSIZE|SWP_NOCLIENTSIZE, 0x3 },
+ { WM_MOVE, sent|defwinproc, 0 },
+ { WM_GETTEXT, sent|optional },
+ { 0 }
+};
+
static void test_setwindowpos(void)
{
HWND hwnd;
RECT rc;
LRESULT res;
+ const INT X = 50;
+ const INT Y = 50;
const INT winX = 100;
const INT winY = 100;
const INT sysX = GetSystemMetrics(SM_CXMINTRACK);
hwnd = CreateWindowExA(0, "TestWindowClass", NULL, 0,
- 0, 0, winX, winY, 0,
+ X, Y, winX, winY, 0,
NULL, NULL, 0);
GetWindowRect(hwnd, &rc);
- expect(sysX, rc.right);
- expect(winY, rc.bottom);
+ expect(sysX + X, rc.right);
+ expect(winY + Y, rc.bottom);
flush_events();
flush_sequence();
- res = SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, winX, winY, 0);
+ res = SetWindowPos(hwnd, HWND_TOPMOST, 50, 50, winX, winY, 0);
ok_sequence(WmZOrder, "Z-Order", TRUE);
ok(res == TRUE, "SetWindowPos expected TRUE, got %ld\n", res);
+ GetWindowRect(hwnd, &rc);
+ expect(sysX + X, rc.right);
+ expect(winY + Y, rc.bottom);
+
+ res = SetWindowPos( hwnd, 0, 0, 0, 0, 0,
+ SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
+ ok_sequence(WmFrameChanged, "FrameChanged", FALSE);
+ ok(res == TRUE, "SetWindowPos expected TRUE, got %ld.\n", res);
+
+ GetWindowRect(hwnd, &rc);
+ expect(sysX + X, rc.right);
+ expect(winY + Y, rc.bottom);
+
+ res = SetWindowPos( hwnd, 0, 0, 0, 0, 0,
+ SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
+ ok_sequence(WmFrameChanged_move, "FrameChanged", FALSE);
+ ok(res == TRUE, "SetWindowPos expected TRUE, got %ld.\n", res);
+
GetWindowRect(hwnd, &rc);
expect(sysX, rc.right);
expect(winY, rc.bottom);
+
DestroyWindow(hwnd);
}
@@ -12856,27 +12914,31 @@ static void test_TrackMouseEvent(void)
static const struct message WmSetWindowRgn[] = {
- { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE },
- { WM_NCCALCSIZE, sent|wparam, 1 },
+ { WM_WINDOWPOSCHANGING, sent|wparam|lparam, SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE
+ |SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE, 0 },
+ { WM_NCCALCSIZE, sent|wparam|lparam, 1, 0xf },
{ WM_NCPAINT, sent|optional }, /* wparam != 1 */
{ WM_GETTEXT, sent|defwinproc|optional },
{ WM_ERASEBKGND, sent|optional },
- { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE },
+ { WM_WINDOWPOSCHANGED, sent|wparam|lparam, SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE, 0xf },
{ EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
{ 0 }
};
static const struct message WmSetWindowRgn_no_redraw[] = {
- { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOREDRAW },
- { WM_NCCALCSIZE, sent|wparam, 1 },
- { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOREDRAW },
+ { WM_WINDOWPOSCHANGING, sent|wparam|lparam, SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE
+ |SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOREDRAW, 0 },
+ { WM_NCCALCSIZE, sent|wparam|lparam, 1, 0xf },
+ { WM_WINDOWPOSCHANGED, sent|wparam|lparam, SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOREDRAW, 0xf },
{ EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
{ 0 }
};
static const struct message WmSetWindowRgn_clear[] = {
- { WM_WINDOWPOSCHANGING, sent/*|wparam*/, SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE/*|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE only on some Windows versions */ },
- { WM_NCCALCSIZE, sent|wparam, 1 },
+ { WM_WINDOWPOSCHANGING, sent/*|wparam|lparam*/, SWP_NOACTIVATE|SWP_FRAMECHANGED
+ |SWP_NOSIZE|SWP_NOMOVE/*|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE only on some Windows versions */, 0xf
+ /* Some newer Windows versions set window coordinates instead of zeros in WINDOWPOS structure */},
+ { WM_NCCALCSIZE, sent|wparam|lparam, 1, 0xf },
{ WM_NCPAINT, sent|optional },
{ WM_GETTEXT, sent|defwinproc|optional },
{ WM_ERASEBKGND, sent|optional }, /* FIXME: remove optional once Wine is fixed */
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c
index 4b39d0aa39..ef829df81b 100644
--- a/dlls/user32/winpos.c
+++ b/dlls/user32/winpos.c
@@ -1901,6 +1901,18 @@ static UINT SWP_DoNCCalcSize( WINDOWPOS *pWinpos, const RECT *old_window_rect, c
params.lppos = &winposCopy;
winposCopy = *pWinpos;
+ if (pWinpos->flags & SWP_NOMOVE)
+ {
+ winposCopy.x = old_window_rect->left;
+ winposCopy.y = old_window_rect->top;
+ }
+
+ if (pWinpos->flags & SWP_NOSIZE)
+ {
+ winposCopy.cx = old_window_rect->right - old_window_rect->left;
+ winposCopy.cy = old_window_rect->bottom - old_window_rect->top;
+ }
+
wvrFlags = SendMessageW( pWinpos->hwnd, WM_NCCALCSIZE, TRUE, (LPARAM)¶ms );
*new_client_rect = params.rgrc[0];
More information about the wine-cvs
mailing list