[PATCH resend 1/2] user32: Fix WM_NCPAINT for windows crossing screen boarders and add tests

Fabian Maurer dark.shadow4 at web.de
Wed Jan 25 21:38:29 CST 2017


Windows that are partially off-screen still receive
WM_NCPAINT with wParam==1 instead of an actual HRGN

Signed-off-by: Fabian Maurer <dark.shadow4 at web.de>
---
 dlls/user32/painting.c  | 10 ++++++++++
 dlls/user32/tests/msg.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/dlls/user32/painting.c b/dlls/user32/painting.c
index 622dcad845..62d29bdfe5 100644
--- a/dlls/user32/painting.c
+++ b/dlls/user32/painting.c
@@ -662,7 +662,17 @@ static HRGN send_ncpaint( HWND hwnd, HWND *child, UINT *flags )
             if (type == SIMPLEREGION)
             {
                 RECT window;
+                LONG screenx = GetSystemMetrics(SM_CXSCREEN);
+                LONG screeny = GetSystemMetrics(SM_CYSCREEN);
+
                 GetWindowRect( hwnd, &window );
+
+                /* Clamp the window region to screen bounds */
+                if(window.right > screenx) window.right = screenx;
+                if(window.bottom > screeny) window.bottom = screeny;
+                if(window.left < 0) window.left = 0;
+                if(window.top < 0) window.top = 0;
+
                 if (EqualRect( &window, &update ))
                 {
                     DeleteObject( whole_rgn );
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 45b5222deb..f01314cf51 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -905,6 +905,39 @@ static const struct message WmShowVisiblePopupSeq_2[] = {
     { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE },
     { 0 }
 };
+/* CreateWindow (for a popup window with WS_VISIBLE style set and extreme location)
+ */
+static const struct message WmShowPopupExtremeLocationSeq[] = {
+    { HCBT_CREATEWND, hook },
+    { WM_NCCREATE, sent },
+    { WM_NCCALCSIZE, sent|wparam, 0 },
+    { WM_CREATE, sent },
+    { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
+    { WM_SIZE, sent|wparam, SIZE_RESTORED },
+    { WM_MOVE, sent },
+    { WM_SHOWWINDOW, sent|wparam, 1 },
+    { WM_WINDOWPOSCHANGING, sent },
+    { HCBT_ACTIVATE, hook },
+    { WM_WINDOWPOSCHANGING, sent|optional },
+    { WM_QUERYNEWPALETTE, sent|optional },
+    { WM_ACTIVATEAPP, sent },
+    { WM_NCACTIVATE, sent },
+    { WM_ACTIVATE, sent },
+    { WM_IME_SETCONTEXT, sent|parent|wparam|optional, 0 },
+    { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
+    { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 },
+    { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+    { HCBT_SETFOCUS, hook },
+    { WM_SETFOCUS, sent|defwinproc },
+    { WM_WINDOWPOSCHANGED, sent|optional }, /* optional, wrongly sent in wine */
+    { WM_NCPAINT, sent|wparam, 1 },
+    { WM_ERASEBKGND, sent },
+    { WM_WINDOWPOSCHANGED, sent|optional }, /* optional, correct behavior, we check this in a different test */
+    /* ocasionally received on test machines */
+    { WM_NCPAINT, sent|optional },
+    { WM_ERASEBKGND, sent|optional },
+    { 0 }
+};
 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
  * for a popup window with WS_VISIBLE style set
  */
@@ -4826,6 +4859,15 @@ static void test_messages(void)
     DestroyWindow(hwnd);
     ok_sequence(WmDestroyOverlappedSeq, "DestroyWindow:overlapped", FALSE);
 
+    /* Test message sequence for extreme position and size */
+    flush_sequence();
+    hwnd = CreateWindowExA(0, "TestWindowClass", "Test Popup", WS_POPUP | WS_VISIBLE,
+                             -10, -10, 10000, 10000, NULL, 0, 0, NULL );
+    ok (hwnd != 0, "Failed to create popup window\n");
+    RedrawWindow(hwnd, NULL, 0, RDW_ERASENOW); /* currently needed to avoid another issue */
+    ok_sequence(WmShowPopupExtremeLocationSeq, "RedrawWindow:show_popup_extreme_location", FALSE);
+    DestroyWindow(hwnd);
+
     hparent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                               100, 100, 200, 200, 0, 0, 0, NULL);
     ok (hparent != 0, "Failed to create parent window\n");
-- 
2.11.0




More information about the wine-patches mailing list