diff --git a/dlls/user/painting.c b/dlls/user/painting.c index 5e20162396e..22fb2b3caf2 100644 --- a/dlls/user/painting.c +++ b/dlls/user/painting.c @@ -593,16 +593,33 @@ BOOL WINAPI UpdateWindow( HWND hwnd ) */ BOOL WINAPI InvalidateRgn( HWND hwnd, HRGN hrgn, BOOL erase ) { + if (!hwnd) + { + SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + return FALSE; + } + return RedrawWindow(hwnd, NULL, hrgn, RDW_INVALIDATE | (erase ? RDW_ERASE : 0) ); } /*********************************************************************** * InvalidateRect (USER32.@) + * + * MSDN: if hwnd parameter is NULL, InvalidateRect invalidates and redraws + * all windows and sends WM_ERASEBKGND and WM_NCPAINT. */ BOOL WINAPI InvalidateRect( HWND hwnd, const RECT *rect, BOOL erase ) { - return RedrawWindow( hwnd, rect, 0, RDW_INVALIDATE | (erase ? RDW_ERASE : 0) ); + UINT flags = RDW_INVALIDATE | (erase ? RDW_ERASE : 0); + + if (!hwnd) + { + flags = RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW; + rect = NULL; + } + + return RedrawWindow( hwnd, rect, 0, flags ); } @@ -611,16 +628,33 @@ BOOL WINAPI InvalidateRect( HWND hwnd, const RECT *rect, BOOL erase ) */ BOOL WINAPI ValidateRgn( HWND hwnd, HRGN hrgn ) { + if (!hwnd) + { + SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + return FALSE; + } + return RedrawWindow( hwnd, NULL, hrgn, RDW_VALIDATE ); } /*********************************************************************** * ValidateRect (USER32.@) + * + * MSDN: if hwnd parameter is NULL, ValidateRect invalidates and redraws + * all windows and sends WM_ERASEBKGND and WM_NCPAINT. */ BOOL WINAPI ValidateRect( HWND hwnd, const RECT *rect ) { - return RedrawWindow( hwnd, rect, 0, RDW_VALIDATE ); + UINT flags = RDW_VALIDATE; + + if (!hwnd) + { + flags = RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW; + rect = NULL; + } + + return RedrawWindow( hwnd, rect, 0, flags ); } diff --git a/dlls/user/tests/msg.c b/dlls/user/tests/msg.c index df25053af63..fdbf218bb2d 100644 --- a/dlls/user/tests/msg.c +++ b/dlls/user/tests/msg.c @@ -3697,6 +3697,55 @@ static void test_paint_messages(void) /* validate everything */ RedrawWindow( hwnd, NULL, NULL, RDW_VALIDATE ); check_update_rgn( hwnd, 0 ); + + /* flush pending messages */ + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + flush_sequence(); + + GetClientRect( hwnd, &rect ); + SetRectRgn( hrgn, 0, 0, rect.right - rect.left, rect.bottom - rect.top ); + /* MSDN: if hwnd parameter is NULL, InvalidateRect invalidates and redraws + * all windows and sends WM_ERASEBKGND and WM_NCPAINT. + */ + trace("testing InvalidateRect(0, NULL, FALSE)\n"); + SetRectEmpty( &rect ); + ok(InvalidateRect(0, &rect, FALSE), "InvalidateRect(0, &rc, FALSE) should fail\n"); + check_update_rgn( hwnd, hrgn ); + ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + ok_sequence( WmPaint, "Paint", FALSE ); + RedrawWindow( hwnd, NULL, NULL, RDW_VALIDATE ); + check_update_rgn( hwnd, 0 ); + + /* MSDN: if hwnd parameter is NULL, ValidateRect invalidates and redraws + * all windows and sends WM_ERASEBKGND and WM_NCPAINT. + */ + trace("testing ValidateRect(0, NULL)\n"); + SetRectEmpty( &rect ); + ok(ValidateRect(0, &rect), "ValidateRect(0, &rc) should not fail"); + check_update_rgn( hwnd, hrgn ); + ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + ok_sequence( WmPaint, "Paint", FALSE ); + RedrawWindow( hwnd, NULL, NULL, RDW_VALIDATE ); + check_update_rgn( hwnd, 0 ); + + trace("testing InvalidateRgn(0, NULL, FALSE)\n"); + SetLastError(0xdeadbeef); + ok(!InvalidateRgn(0, NULL, FALSE), "InvalidateRgn(0, NULL, FALSE) should fail\n"); + ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error code %ld\n", GetLastError()); + check_update_rgn( hwnd, 0 ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE ); + + trace("testing ValidateRgn(0, NULL)\n"); + SetLastError(0xdeadbeef); + ok(!ValidateRgn(0, NULL), "ValidateRgn(0, NULL) should fail"); + ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error code %ld\n", GetLastError()); + check_update_rgn( hwnd, 0 ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE ); + /* now with frame */ SetRectRgn( hrgn, -5, -5, 20, 20 );