From a8a999793fa8697268b55f9224174b3b3d5ccc77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Tue, 30 Mar 2004 20:50:16 +0000 Subject: [PATCH] Implement TOPMOST windows svn path=/trunk/; revision=8928 --- reactos/subsys/win32k/ntuser/window.c | 66 +++++++++++++++++++++++---- reactos/subsys/win32k/ntuser/winpos.c | 51 +++++++++++++++++---- 2 files changed, 100 insertions(+), 17 deletions(-) diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index 6592b00d3cf..7ab8fd7e563 100644 --- a/reactos/subsys/win32k/ntuser/window.c +++ b/reactos/subsys/win32k/ntuser/window.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: window.c,v 1.202 2004/03/28 21:46:26 weiden Exp $ +/* $Id: window.c,v 1.203 2004/03/30 20:50:15 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -873,7 +873,7 @@ IntSetOwner(HWND hWnd, HWND hWndNewOwner) PWINDOW_OBJECT FASTCALL IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent) { - PWINDOW_OBJECT WndOldParent; + PWINDOW_OBJECT WndOldParent, Sibling, InsertAfter; HWND hWnd, hWndNewParent, hWndOldParent; BOOL WasVisible; BOOL MenuChanged; @@ -904,7 +904,29 @@ IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent) if (WndNewParent != WndOldParent) { IntUnlinkWindow(Wnd); - IntLinkWindow(Wnd, WndNewParent, NULL /*prev sibling*/); + InsertAfter = NULL; + if (0 == (Wnd->ExStyle & WS_EX_TOPMOST)) + { + /* Not a TOPMOST window, put after TOPMOSTs of new parent */ + IntLockRelatives(WndNewParent); + Sibling = WndNewParent->FirstChild; + while (NULL != Sibling && 0 != (Sibling->ExStyle & WS_EX_TOPMOST)) + { + InsertAfter = Sibling; + Sibling = Sibling->NextSibling; + } + IntUnLockRelatives(WndNewParent); + } + if (NULL == InsertAfter) + { + IntLinkWindow(Wnd, WndNewParent, InsertAfter /*prev sibling*/); + } + else + { + IntReferenceWindowObject(InsertAfter); + IntLinkWindow(Wnd, WndNewParent, InsertAfter /*prev sibling*/); + IntReleaseWindowObject(InsertAfter); + } if (WndNewParent->Self != IntGetDesktopWindow()) /* a child window */ { @@ -917,12 +939,13 @@ IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent) } /* - * SetParent additionally needs to make hwnd the topmost window - * in the x-order and send the expected WM_WINDOWPOSCHANGING and + * SetParent additionally needs to make hwnd the top window + * in the z-order and send the expected WM_WINDOWPOSCHANGING and * WM_WINDOWPOSCHANGED notification messages. */ - WinPosSetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | (WasVisible ? SWP_SHOWWINDOW : 0)); + WinPosSetWindowPos(hWnd, (0 == (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST), + 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE + | (WasVisible ? SWP_SHOWWINDOW : 0)); /* * FIXME: a WM_MOVE is also generated (in the DefWindowProc handler @@ -1613,8 +1636,33 @@ NtUserCreateWindowEx(DWORD dwExStyle, } else { - /* link window as top sibling */ - IntLinkWindow(WindowObject, ParentWindow, NULL /*prev sibling*/); + /* link window as top sibling (but after topmost siblings) */ + PWINDOW_OBJECT InsertAfter, Sibling; + if (0 == (dwExStyle & WS_EX_TOPMOST)) + { + IntLockRelatives(ParentWindow); + InsertAfter = NULL; + Sibling = ParentWindow->FirstChild; + while (NULL != Sibling && 0 != (Sibling->ExStyle & WS_EX_TOPMOST)) + { + InsertAfter = Sibling; + Sibling = Sibling->NextSibling; + } + IntUnLockRelatives(ParentWindow); + } + else + { + InsertAfter = NULL; + } + if (NULL != InsertAfter) + { + IntReferenceWindowObject(InsertAfter); + } + IntLinkWindow(WindowObject, ParentWindow, InsertAfter /* prev sibling */); + if (NULL != InsertAfter) + { + IntReleaseWindowObject(InsertAfter); + } } } diff --git a/reactos/subsys/win32k/ntuser/winpos.c b/reactos/subsys/win32k/ntuser/winpos.c index 942494a0104..d2a300a0e69 100644 --- a/reactos/subsys/win32k/ntuser/winpos.c +++ b/reactos/subsys/win32k/ntuser/winpos.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: winpos.c,v 1.105 2004/03/23 21:30:18 gvg Exp $ +/* $Id: winpos.c,v 1.106 2004/03/30 20:50:16 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -745,7 +745,8 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWINDOW_OBJECT Window) if (!(WinPos->flags & SWP_NOACTIVATE)) { WinPos->flags &= ~SWP_NOZORDER; - WinPos->hwndInsertAfter = HWND_TOP; + WinPos->hwndInsertAfter = (0 != (Window->ExStyle & WS_EX_TOPMOST) ? + HWND_TOPMOST : HWND_TOP); return TRUE; } } @@ -763,16 +764,22 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWINDOW_OBJECT Window) WinPos->hwndInsertAfter = HWND_NOTOPMOST; } - /* FIXME: TOPMOST not supported yet */ - if ((WinPos->hwndInsertAfter == HWND_TOPMOST) || - (WinPos->hwndInsertAfter == HWND_NOTOPMOST)) + if (WinPos->hwndInsertAfter == HWND_NOTOPMOST) { WinPos->hwndInsertAfter = HWND_TOP; } + else if (HWND_TOP == WinPos->hwndInsertAfter + && 0 != (Window->ExStyle & WS_EX_TOPMOST)) + { + /* Keep it topmost when it's already topmost */ + WinPos->hwndInsertAfter = HWND_TOPMOST; + } /* hwndInsertAfter must be a sibling of the window */ - if ((WinPos->hwndInsertAfter != HWND_TOP) && - (WinPos->hwndInsertAfter != HWND_BOTTOM)) + if (HWND_TOPMOST != WinPos->hwndInsertAfter + && HWND_TOP != WinPos->hwndInsertAfter + && HWND_NOTOPMOST != WinPos->hwndInsertAfter + && HWND_BOTTOM != WinPos->hwndInsertAfter) { PWINDOW_OBJECT Parent = IntGetParentObject(Window); if (NtUserGetAncestor(WinPos->hwndInsertAfter, GA_PARENT) != @@ -905,12 +912,32 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx, if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwnd != NtUserGetShellWindow()) { PWINDOW_OBJECT ParentWindow; + PWINDOW_OBJECT Sibling; PWINDOW_OBJECT InsertAfterWindow; if ((ParentWindow = IntGetParentObject(Window))) { - if (WinPos.hwndInsertAfter == HWND_TOP) + if (HWND_TOPMOST == WinPos.hwndInsertAfter) + { InsertAfterWindow = NULL; + } + else if (HWND_TOP == WinPos.hwndInsertAfter + || HWND_NOTOPMOST == WinPos.hwndInsertAfter) + { + InsertAfterWindow = NULL; + IntLockRelatives(ParentWindow); + Sibling = ParentWindow->FirstChild; + while (NULL != Sibling && 0 != (Sibling->ExStyle & WS_EX_TOPMOST)) + { + InsertAfterWindow = Sibling; + Sibling = Sibling->NextSibling; + } + if (NULL != InsertAfterWindow) + { + IntReferenceWindowObject(InsertAfterWindow); + } + IntUnLockRelatives(ParentWindow); + } else if (WinPos.hwndInsertAfter == HWND_BOTTOM) { IntLockRelatives(ParentWindow); @@ -934,6 +961,14 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx, } if (InsertAfterWindow != NULL) IntReleaseWindowObject(InsertAfterWindow); + if (HWND_TOPMOST == WinPos.hwndInsertAfter) + { + Window->ExStyle |= WS_EX_TOPMOST; + } + else + { + Window->ExStyle &= ~ WS_EX_TOPMOST; + } IntReleaseWindowObject(ParentWindow); }