From 28a8cacaf510033c3ebc1e720bf03516ad8c59c5 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 2 Sep 2004 20:13:19 +0000 Subject: [PATCH] GetUpdateRect should return TRUE even if only the non-client area is invalid (reported by Rein Klazes). --- dlls/user/painting.c | 17 ++++++++++++++-- dlls/user/tests/msg.c | 45 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/dlls/user/painting.c b/dlls/user/painting.c index 694ad9fb552..e038c4f254c 100644 --- a/dlls/user/painting.c +++ b/dlls/user/painting.c @@ -314,8 +314,15 @@ INT WINAPI GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase ) */ BOOL WINAPI GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase ) { + WND *wndPtr; + BOOL ret = FALSE; HRGN update_rgn = CreateRectRgn( 0, 0, 0, 0 ); - INT retval = GetUpdateRgn( hwnd, update_rgn, erase ); + + if (GetUpdateRgn( hwnd, update_rgn, erase ) == ERROR) + { + DeleteObject( update_rgn ); + return FALSE; + } if (rect) { @@ -332,7 +339,13 @@ BOOL WINAPI GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase ) } DeleteObject( update_rgn ); - return (retval != ERROR && retval != NULLREGION); + wndPtr = WIN_GetPtr( hwnd ); + if (wndPtr && wndPtr != WND_OTHER_PROCESS) + { + ret = (wndPtr->hrgnUpdate != 0); + WIN_ReleasePtr( wndPtr ); + } + return ret; } diff --git a/dlls/user/tests/msg.c b/dlls/user/tests/msg.c index 1b4c4816146..661f493135f 100644 --- a/dlls/user/tests/msg.c +++ b/dlls/user/tests/msg.c @@ -1899,6 +1899,7 @@ static const struct message WmPaint[] = { static void test_paint_messages(void) { RECT rect; + MSG msg; HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 ); HRGN hrgn2 = CreateRectRgn( 0, 0, 0, 0 ); HWND hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW, @@ -1981,6 +1982,50 @@ static void test_paint_messages(void) RedrawWindow( hwnd, NULL, hrgn, RDW_VALIDATE | RDW_NOERASE | RDW_UPDATENOW ); ok_sequence( WmPaint, "Paint", FALSE ); + flush_sequence(); + SetRectRgn( hrgn, -4, -4, -2, -2 ); + RedrawWindow( hwnd, NULL, hrgn, RDW_INVALIDATE | RDW_FRAME ); + SetRectRgn( hrgn, -4, -4, -3, -3 ); + RedrawWindow( hwnd, NULL, hrgn, RDW_VALIDATE | RDW_NOFRAME | RDW_ERASENOW ); + ok_sequence( WmEmptySeq, "EmptySeq", FALSE ); + + flush_sequence(); + SetRectRgn( hrgn, -4, -4, -2, -2 ); + RedrawWindow( hwnd, NULL, hrgn, RDW_INVALIDATE | RDW_FRAME ); + SetRectRgn( hrgn, -4, -4, -3, -3 ); + RedrawWindow( hwnd, NULL, hrgn, RDW_VALIDATE | RDW_NOFRAME ); + SetRectRgn( hrgn, 0, 0, 1, 1 ); + RedrawWindow( hwnd, NULL, hrgn, RDW_INVALIDATE | RDW_UPDATENOW ); + ok_sequence( WmPaint, "Paint", TRUE ); + + flush_sequence(); + SetRectRgn( hrgn, -4, -4, -1, -1 ); + RedrawWindow( hwnd, NULL, hrgn, RDW_INVALIDATE | RDW_FRAME ); + RedrawWindow( hwnd, NULL, 0, RDW_ERASENOW ); + /* make sure no WM_PAINT was generated */ + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + ok_sequence( WmInvalidateRgn, "InvalidateRgn", FALSE ); + + flush_sequence(); + SetRectRgn( hrgn, -4, -4, -1, -1 ); + RedrawWindow( hwnd, NULL, hrgn, RDW_INVALIDATE | RDW_FRAME ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) + { + if (msg.hwnd == hwnd && msg.message == WM_PAINT) + { + /* GetUpdateRgn must return empty region since only nonclient area is invalidated */ + INT ret = GetUpdateRgn( hwnd, hrgn, FALSE ); + ok( ret == NULLREGION, "Invalid GetUpdateRgn result %d\n", ret ); + ret = GetUpdateRect( hwnd, &rect, FALSE ); + ok( ret, "Invalid GetUpdateRect result %d\n", ret ); + /* this will send WM_NCPAINT and validate the non client area */ + ret = GetUpdateRect( hwnd, &rect, TRUE ); + ok( !ret, "Invalid GetUpdateRect result %d\n", ret ); + } + else DispatchMessage( &msg ); + } + ok_sequence( WmInvalidateRgn, "InvalidateRgn", FALSE ); + DeleteObject( hrgn ); DeleteObject( hrgn2 ); DestroyWindow( hwnd );