user32: Windows adds SWP_NOREDRAW if a window is being just moved

Dmitry Timoshkov dmitry at codeweavers.com
Tue Apr 24 04:35:00 CDT 2007


Hello,

this patch fixes repainting in an application I'm working on. I've analyzed
a lot of message logs, and got some ideas how to solve the problem from very
old Wine code. The message sequences in dlls/user32/tests/msg.c show that
Windows doesn't repaint non-client window areas before WM_WINDOWPOSCHANGED
is sent if SWP_NOREDRAW is present in the flags.

'make test' in dlls/user32/tests still passes with this patch applied.

Changelog:
    user32: Windows adds SWP_NOREDRAW if a window is being just moved.

---
 dlls/user32/winpos.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c
index 1bfd16b..fc62ef7 100644
--- a/dlls/user32/winpos.c
+++ b/dlls/user32/winpos.c
@@ -40,6 +40,8 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(win);
 
+#define SWP_AGG_NOGEOMETRYCHANGE \
+    (SWP_NOSIZE | SWP_NOCLIENTSIZE | SWP_NOZORDER)
 #define SWP_AGG_NOPOSCHANGE \
     (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE | SWP_NOZORDER)
 #define SWP_AGG_STATUSFLAGS \
@@ -1467,6 +1469,7 @@ static UINT SWP_DoNCCalcSize( WINDOWPOS* pWinpos, const RECT* pNewWindowRect, RE
 /* fix redundant flags and values in the WINDOWPOS structure */
 static BOOL fixup_flags( WINDOWPOS *winpos )
 {
+    UINT flags;
     HWND parent;
     WND *wndPtr = WIN_GetPtr( winpos->hwnd );
     BOOL ret = TRUE;
@@ -1515,6 +1518,11 @@ static BOOL fixup_flags( WINDOWPOS *winpos )
         }
     }
 
+    /* Windows adds SWP_NOREDRAW if a window is being just moved */
+    flags = winpos->flags & ~SWP_NOCLIENTMOVE;
+    if ((flags & SWP_AGG_STATUSFLAGS) == SWP_AGG_NOGEOMETRYCHANGE)
+        winpos->flags |= SWP_NOREDRAW;
+
     /* Check hwndInsertAfter */
     if (winpos->flags & SWP_NOZORDER) goto done;
 
@@ -1602,7 +1610,7 @@ BOOL USER_SetWindowPos( WINDOWPOS * winpos )
                             &newWindowRect, &newClientRect, orig_flags, valid_rects ))
         return FALSE;
 
-    if (!(orig_flags & SWP_SHOWWINDOW))
+    if (!(orig_flags & SWP_SHOWWINDOW) && !(winpos->flags & SWP_NOREDRAW))
     {
         UINT rdw_flags = RDW_FRAME | RDW_ERASE;
         if ( !(orig_flags & SWP_DEFERERASE) ) rdw_flags |= RDW_ERASENOW;
-- 
1.5.1.1






More information about the wine-patches mailing list