Add the tests for behaviour of [In]validateRect and [In]validateRgn with hwnd set to 0. Take 2

Dmitry Timoshkov dmitry at baikal.ru
Mon Oct 31 05:57:32 CST 2005


Hello,

in order to invalidate all windows [In]validateRect needs to ignore
passed rectangle. This new version of the patch adds a rectangle
to [In]validateRect calls in order to test this. Please use this
version instead of the previous one.
===

Newer PSDK documentation states that if hwnd parameter is set to 0 both
InvalidateRect and ValidateRect invalidate and redraw all windows and
send WM_ERASEBKGND and WM_NCPAINT messages. The tests show that ValidateRgn
and InvalidateRgn don't behave that way.

Changelog:
    Dmitry Timoshkov <dmitry at codeweavers.com>
    Add the tests for behaviour of [In]validateRect and [In]validateRgn
    with hwnd set to 0, make them pass under Wine.

diff -up cvs/hq/wine/dlls/user/painting.c wine/dlls/user/painting.c
--- cvs/hq/wine/dlls/user/painting.c	2005-08-05 15:18:13.000000000 +0900
+++ wine/dlls/user/painting.c	2005-10-31 19:41:36.000000000 +0800
@@ -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, c
  */
 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 -up cvs/hq/wine/dlls/user/tests/msg.c wine/dlls/user/tests/msg.c
--- cvs/hq/wine/dlls/user/tests/msg.c	2005-10-31 15:27:29.000000000 +0800
+++ wine/dlls/user/tests/msg.c	2005-10-31 19:43:09.000000000 +0800
@@ -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 );
 






More information about the wine-patches mailing list