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