[PATCH] Restore visible region in EndPaint

Gerard Patel gerard.patel at nerim.net
Wed Dec 19 20:47:38 CST 2001

Looking at the painting problems of a popular application under Wine 
I have found that they come from the use of the CS_OWNDC style in
its (custom) editing window.

The following description shows what the app is essentially doing.
Recreating the problem with a test app is easy.

- it has a permanently allocated DC that stays used all the time while 
the editing is done; in my test I used a simple GetDC(hwnd).
- it calls BeginPaint (outside of any WM_PAINT message)
- Wine reuses then the same DC and set the visible region 
to nil because the update region is empty. At this point 
everything performs similarly to Windows.
- when EndPaint is called, Wine releases the DC, and restores
the clipping region, but not the visible region. This is what differs
from Windows.
- after that when the app calls GetClipBox on the DC, under Wine 
the result is then an empty rectangle, under Windows (NT4 SP6)
it's the normal window rectangle.

My first try was to add this code in ReleaseDC, but I've failed to
reproduce the same behaviour under Windows by calling GetDCEX
with the same parameters as Wine in BeginPaint. : in this case the
visible region is not restored under Windows - so I think that either
something like that is really done in EndPaint, or (more probably) the
whole BeginPaint/EndPaint is  designed differently.


	* dlls/user/painting.c
               Restore visible region in EndPaint for CS_OWNDC windows
-------------- next part --------------
Index: dlls/user/painting.c
RCS file: /home/wine/wine/dlls/user/painting.c,v
retrieving revision 1.1
diff -u -r1.1 painting.c
--- dlls/user/painting.c	2001/12/13 01:03:30	1.1
+++ dlls/user/painting.c	2001/12/19 21:10:56
@@ -12,6 +12,7 @@
 #include "wine/server.h"
 #include "win.h"
 #include "dce.h"
+#include "gdi.h"
 #include "debugtools.h"
@@ -225,6 +226,19 @@
 BOOL WINAPI EndPaint( HWND hwnd, const PAINTSTRUCT *lps )
+    WND *wnd;
+    if (hwnd && (wnd = WIN_FindWndPtr(hwnd)))
+    { /* FIXME : is this appropriate here !? */
+        DWORD clsStyle = wnd->clsStyle;
+        WIN_ReleaseWndPtr(wnd);
+        if (clsStyle & CS_OWNDC) /* the dc has been reused */
+        {   /* restore visible region */
+            HRGN hrgn=CreateRectRgn(0,0,0,0);
+            SetHookFlags16( lps->hdc, DCHF_INVALIDATEVISRGN );
+            USER_Driver.pGetDC( hwnd, lps->hdc, hrgn, DCX_EXCLUDERGN );
+            DeleteObject(hrgn);
+         }
+    }
     ReleaseDC( hwnd, lps->hdc );
     ShowCaret( hwnd );
     return TRUE;
-------------- next part --------------

More information about the wine-patches mailing list