user32.dll Add redraw and WM_WINDOWPOS* notifications to SetActiveWindow [1]

Vitaliy Margolen wine-patch at kievinfo.com
Wed May 11 10:27:41 CDT 2005


According to native messages sent to app we should redraw window
inside SetActiveWindow.

Vitaliy Margolen

changelog:
  dlls/user/focus.c
  Add redraw and WM_WINDOWPOS* notifications to SetActiveWindow
-------------- next part --------------
Index: dlls/user/focus.c
===================================================================
RCS file: /home/wine/wine/dlls/user/focus.c,v
retrieving revision 1.14
diff -u -p -r1.14 focus.c
--- dlls/user/focus.c	1 Feb 2005 18:53:59 -0000	1.14
+++ dlls/user/focus.c	11 May 2005 15:18:04 -0000
@@ -30,6 +30,7 @@
 #include "winuser.h"
 #include "winerror.h"
 #include "win.h"
+#include "winpos.h"
 #include "user_private.h"
 #include "wine/server.h"
 #include "wine/debug.h"
@@ -69,6 +70,67 @@ static HWND set_focus_window( HWND hwnd 
     return previous;
 }
 
+inline static HWND get_root_owner ( HWND hwnd )
+{
+    HWND owner = hwnd;
+    HWND tmp;
+    while ((tmp = GetWindow(owner, GW_OWNER)) != NULL)
+        owner = tmp;
+    return owner;
+}
+
+struct notify_owned_info
+{
+    HWND owner;
+    HWND self;
+    UINT uMsg;
+    WINDOWPOS wndpos;
+};
+
+static BOOL CALLBACK notify_owned_window( HWND hwnd, LPARAM lparam )
+{
+    struct notify_owned_info *info = (struct notify_owned_info *)lparam;
+    RECT rect;
+
+    if (get_root_owner(hwnd) == info->owner)
+    {
+        info->wndpos.hwnd = hwnd;
+        info->wndpos.hwndInsertAfter = GetNextWindow(hwnd, GW_HWNDPREV);
+        switch (info->uMsg)
+        {
+        case WM_WINDOWPOSCHANGING:
+            info->wndpos.x = info->wndpos.y = info->wndpos.cx = info->wndpos.cy = 0;
+            break;
+
+        case WM_WINDOWPOSCHANGED:
+            GetWindowRect(hwnd, &rect);
+            info->wndpos.x = rect.left;
+            info->wndpos.y = rect.top;
+            info->wndpos.cx = rect.right - rect.left;
+            info->wndpos.cy = rect.bottom - rect.top;
+            info->wndpos.flags |= (IsWindowVisible(hwnd)) ? 0 : SWP_NOREDRAW;
+            break;
+        }
+        if (hwnd == info->self)
+            info->wndpos.flags &= ~SWP_NOACTIVATE;
+        else
+            info->wndpos.flags |= SWP_NOACTIVATE;
+
+        SendMessageW( hwnd, info->uMsg, 0, (LPARAM)&info->wndpos );
+    }
+
+    return TRUE;
+}
+
+static BOOL CALLBACK redraw_owned( HWND hwnd, LPARAM lparam )
+{
+    HWND owner = (HWND)lparam;
+
+    if (get_root_owner(hwnd) == owner)
+        RedrawWindow( hwnd, NULL, 0, RDW_ERASENOW | RDW_ERASE | RDW_NOCHILDREN | RDW_INVALIDATE | RDW_FRAME );
+
+    return TRUE;
+}
 
 /*******************************************************************
  *		set_active_window
@@ -79,6 +141,9 @@ static BOOL set_active_window( HWND hwnd
     BOOL ret;
     DWORD old_thread, new_thread;
     CBTACTIVATESTRUCT cbt;
+    struct notify_owned_info info;
+
+    TRACE("hwnd=%p prev*=%p mouse=%i focus=%i\n", hwnd, prev, mouse, focus);
 
     if (previous == hwnd)
     {
@@ -119,8 +184,23 @@ static BOOL set_active_window( HWND hwnd
             SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
 
         if (!IsWindow(hwnd)) return FALSE;
-    }
 
+        info.owner = get_root_owner(hwnd);
+        info.self = hwnd;
+        info.uMsg = WM_WINDOWPOSCHANGING;
+        info.wndpos.flags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE;
+        EnumWindows(notify_owned_window, (LPARAM)&info);
+
+        if (get_root_owner(previous) != get_root_owner(hwnd))
+        {
+            EnumWindows(redraw_owned, (LPARAM)get_root_owner(hwnd));
+
+            info.uMsg = WM_WINDOWPOSCHANGED;
+            info.wndpos.flags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE;
+            EnumWindows(notify_owned_window, (LPARAM)&info);
+        }
+    }
+    
     old_thread = previous ? GetWindowThreadProcessId( previous, NULL ) : 0;
     new_thread = hwnd ? GetWindowThreadProcessId( hwnd, NULL ) : 0;
 
@@ -152,7 +232,7 @@ static BOOL set_active_window( HWND hwnd
 
     if (IsWindow(hwnd))
     {
-        SendMessageW( hwnd, WM_NCACTIVATE, (hwnd == GetForegroundWindow()), (LPARAM)previous );
+        SendMessageW( hwnd, WM_NCACTIVATE, TRUE, (LPARAM)previous );
         SendMessageW( hwnd, WM_ACTIVATE,
                       MAKEWPARAM( mouse ? WA_CLICKACTIVE : WA_ACTIVE, IsIconic(hwnd) ),
                       (LPARAM)previous );


More information about the wine-patches mailing list