At 09:16 AM 6/28/00 -0400, you wrote:

<snip>
>I think a better approach to avoid the extra repaint (and possibly remove
>some flickers) will be to use WM_SYNCPAINT message.
>
>On an ExposeEvent:
>a. Service thread invalidate the expose event.
>b. Send a WM_SYNCPAINT message to the application. lParam is pointing on the
>expose rectangle.
>
>On reception of an WM_SYNCPAINT in def window proc:
>a. Check if the rectangle pointed by lParam is still part of the invalid
>region (or update region)
>b. If so, erase the background (WM_ERASEBKGND) and repaint the non client
>area (WM_NCPAINT)
>
>With this solution, the WM_ERASEBKGND and WM_NCPAINT, will always be sent by
>the application thread, and we should avoid the race condition.

Thanks for your explanation.
I'm a bit late in replying <g>, but I wanted to test your idea.

I have tried a quick and dirty implementation of WM_SYNCPAINT and it seems
to work as you intend. I have not seen any nasty side-effect on any program I use.
Some paintings have a different order, it seems  that a few splash screen are not
painted as fast as before, but no crash or obvious mis-paintings.

There is certainly still work to do, but I think that you are right and the
result will be worth the bother.

>I must admit, because of the lack of documentation on WM_SYNCPAINT, I'm not
>quite sure it's exactly the way this message should be used.

As all this is undocumented, the exact way Windows is passing the update
rectangle is maybe not very important. I have done it in a childishly simple
way, I wonder if it's worth much trouble to emulate the thing exactly here...

Gerard


Index: windows/defwnd.c
===================================================================
RCS file: /home/wine/wine/windows/defwnd.c,v
retrieving revision 1.30
diff -u -r1.30 defwnd.c
--- windows/defwnd.c    2000/07/10 12:09:31     1.30
+++ windows/defwnd.c    2000/07/13 18:31:11
@@ -227,6 +227,17 @@
     case WM_NCPAINT:
        return NC_HandleNCPaint( wndPtr->hwndSelf, (HRGN)wParam );
 
+    case WM_SYNCPAINT:
+        {
+        RECT r;
+        GetRgnBox( (HRGN) wParam, &r);
+        RedrawWindow( wndPtr->hwndSelf,  &r, 0,
+                          RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE |
+                          (lParam ? 0 : RDW_ERASENOW) );  
+        DeleteObject( (HRGN) wParam);
+        }
+        break;
+
     case WM_NCHITTEST:
         return NC_HandleNCHitTest( wndPtr->hwndSelf, MAKEPOINT16(lParam) );
 
Index: windows/x11drv/event.c
===================================================================
RCS file: /home/wine/wine/windows/x11drv/event.c,v
retrieving revision 1.70
diff -u -r1.70 event.c
--- windows/x11drv/event.c      2000/06/08 19:21:06     1.70
+++ windows/x11drv/event.c      2000/07/13 18:31:14
@@ -637,10 +637,8 @@
   rect.right  = rect.left + event->width;
   rect.bottom = rect.top + event->height;
   WIN_ReleaseWndPtr(pWnd);
- 
-  Callout.RedrawWindow( hWnd, &rect, 0,
-                          RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE |
-                          (event->count ? 0 : RDW_ERASENOW) );
+
+  PostMessageA( hWnd, WM_SYNCPAINT, CreateRectRgnIndirect(&rect), event->count );
 }
 
 



Reply via email to