[PATCH 1/2] user32: Fix WM_NCPAINT for windows crossing screen boarders and add tests
Fabian Maurer
dark.shadow4 at web.de
Thu Dec 22 14:01:16 CST 2016
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