Author: gadamopoulos Date: Mon Oct 4 21:44:58 2010 New Revision: 48982
URL: http://svn.reactos.org/svn/reactos?rev=48982&view=rev Log: [win32k] - Reduce duplicated code in co_UserCreateWindowEx, co_IntSetParent and co_WinPosSetWindowPos - based on wine
Modified: trunk/reactos/subsystems/win32/win32k/include/window.h trunk/reactos/subsystems/win32/win32k/ntuser/window.c trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c
Modified: trunk/reactos/subsystems/win32/win32k/include/window.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/window.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/window.h [iso-8859-1] Mon Oct 4 21:44:58 2010 @@ -114,7 +114,10 @@ IntUnlinkWindow(PWINDOW_OBJECT Wnd);
VOID FASTCALL -IntLinkWindow(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndParent, PWINDOW_OBJECT WndPrevSibling); +IntLinkWindow(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndPrevSibling); + +VOID FASTCALL +IntLinkHwnd(PWINDOW_OBJECT Wnd, HWND hWndPrev);
PWINDOW_OBJECT FASTCALL IntGetAncestor(PWINDOW_OBJECT Wnd, UINT Type);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/window.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c [iso-8859-1] Mon Oct 4 21:44:58 2010 @@ -997,17 +997,16 @@ return FALSE; }
-VOID FASTCALL + +static VOID FASTCALL IntLinkWnd( PWND Wnd, - PWND WndParent, - PWND WndPrevSibling) /* set to NULL if top sibling */ -{ - Wnd->spwndParent = WndParent; - if ((Wnd->spwndPrev = WndPrevSibling)) - { - /* link after WndPrevSibling */ - if ((Wnd->spwndNext = WndPrevSibling->spwndNext)) + PWND WndInsertAfter) /* set to NULL if top sibling */ +{ + if ((Wnd->spwndPrev = WndInsertAfter)) + { + /* link after WndInsertAfter */ + if ((Wnd->spwndNext = WndInsertAfter->spwndNext)) Wnd->spwndNext->spwndPrev = Wnd;
Wnd->spwndPrev->spwndNext = Wnd; @@ -1015,53 +1014,129 @@ else { /* link at top */ - if ((Wnd->spwndNext = WndParent->spwndChild)) + if ((Wnd->spwndNext = Wnd->spwndParent->spwndChild)) Wnd->spwndNext->spwndPrev = Wnd; - - WndParent->spwndChild = Wnd; - } - -} - -/* link the window into siblings and parent. children are kept in place. */ + + Wnd->spwndParent->spwndChild = Wnd; + } +} + +/* + link the window into siblings list + children and parent are kept in place. +*/ VOID FASTCALL IntLinkWindow( PWINDOW_OBJECT Wnd, - PWINDOW_OBJECT WndParent, - PWINDOW_OBJECT WndPrevSibling /* set to NULL if top sibling */ + PWINDOW_OBJECT WndInsertAfter /* set to NULL if top sibling */ ) { - PWINDOW_OBJECT Parent; - IntLinkWnd(Wnd->Wnd, - WndParent->Wnd, - WndPrevSibling ? WndPrevSibling->Wnd : NULL); - - Wnd->spwndParent = WndParent; - if ((Wnd->spwndPrev = WndPrevSibling)) - { - /* link after WndPrevSibling */ - if ((Wnd->spwndNext = WndPrevSibling->spwndNext)) + WndInsertAfter ? WndInsertAfter->Wnd : NULL); + + if ((Wnd->spwndPrev = WndInsertAfter)) + { + /* link after WndInsertAfter */ + if ((Wnd->spwndNext = WndInsertAfter->spwndNext)) Wnd->spwndNext->spwndPrev = Wnd; + Wnd->spwndPrev->spwndNext = Wnd; } else { /* link at top */ - Parent = Wnd->spwndParent; - if ((Wnd->spwndNext = WndParent->spwndChild)) + if ((Wnd->spwndNext = Wnd->spwndParent->spwndChild)) Wnd->spwndNext->spwndPrev = Wnd; - else if (Parent) - { - Parent->spwndChild = Wnd; - return; - } - if(Parent) - { - Parent->spwndChild = Wnd; - } - } - + + Wnd->spwndParent->spwndChild = Wnd; + } +} + + +VOID FASTCALL IntLinkHwnd(PWINDOW_OBJECT Wnd, HWND hWndPrev) +{ + if (hWndPrev == HWND_NOTOPMOST) + { + if (!(Wnd->Wnd->ExStyle & WS_EX_TOPMOST) && + (Wnd->Wnd->ExStyle2 & WS_EX2_LINKED)) return; /* nothing to do */ + Wnd->Wnd->ExStyle &= ~WS_EX_TOPMOST; + hWndPrev = HWND_TOP; /* fallback to the HWND_TOP case */ + } + + IntUnlinkWindow(Wnd); /* unlink it from the previous location */ + + if (hWndPrev == HWND_BOTTOM) + { + /* Link in the bottom of the list */ + PWINDOW_OBJECT WndInsertAfter; + + WndInsertAfter = Wnd->spwndParent->spwndChild; + while( WndInsertAfter && WndInsertAfter->spwndNext) + WndInsertAfter = WndInsertAfter->spwndNext; + + IntLinkWindow(Wnd, WndInsertAfter); + Wnd->Wnd->ExStyle &= ~WS_EX_TOPMOST; + } + else if (hWndPrev == HWND_TOPMOST) + { + /* Link in the top of the list */ + IntLinkWindow(Wnd, NULL); + + Wnd->Wnd->ExStyle |= WS_EX_TOPMOST; + } + else if (hWndPrev == HWND_TOP) + { + /* Link it after the last topmost window */ + PWINDOW_OBJECT WndInsertBefore; + + WndInsertBefore = Wnd->spwndParent->spwndChild; + + if (!(Wnd->Wnd->ExStyle & WS_EX_TOPMOST)) /* put it above the first non-topmost window */ + { + while (WndInsertBefore != NULL && WndInsertBefore->spwndNext != NULL) + { + if (!(WndInsertBefore->Wnd->ExStyle & WS_EX_TOPMOST)) break; + if (WndInsertBefore == Wnd->spwndOwner) /* keep it above owner */ + { + Wnd->Wnd->ExStyle |= WS_EX_TOPMOST; + break; + } + WndInsertBefore = WndInsertBefore->spwndNext; + } + } + + IntLinkWindow(Wnd, WndInsertBefore ? WndInsertBefore->spwndPrev : NULL); + } + else + { + /* Link it after hWndPrev */ + PWINDOW_OBJECT WndInsertAfter; + + WndInsertAfter = UserGetWindowObject(hWndPrev); + /* Are we called with an erroneous handle */ + if(WndInsertAfter == NULL) + { + /* Link in a default position */ + IntLinkHwnd(Wnd, HWND_TOP); + return; + } + + IntLinkWindow(Wnd, WndInsertAfter); + + /* Fix the WS_EX_TOPMOST flag */ + if (!(WndInsertAfter->Wnd->ExStyle & WS_EX_TOPMOST)) + { + Wnd->Wnd->ExStyle &= ~WS_EX_TOPMOST; + } + else + { + if(WndInsertAfter->spwndNext && + WndInsertAfter->spwndNext->Wnd->ExStyle & WS_EX_TOPMOST) + { + Wnd->Wnd->ExStyle |= WS_EX_TOPMOST; + } + } + } }
HWND FASTCALL @@ -1096,17 +1171,13 @@ PWINDOW_OBJECT FASTCALL co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent) { - PWINDOW_OBJECT WndOldParent, Sibling, InsertAfter; -// HWND hWnd, hWndNewParent; + PWINDOW_OBJECT WndOldParent; BOOL WasVisible;
ASSERT(Wnd); ASSERT(WndNewParent); ASSERT_REFS_CO(Wnd); ASSERT_REFS_CO(WndNewParent); - -// hWnd = Wnd->hSelf; -// hWndNewParent = WndNewParent->hSelf;
/* Some applications try to set a child as a parent */ if (IntIsChildWindow(Wnd, WndNewParent)) @@ -1121,10 +1192,6 @@ */ WasVisible = co_WinPosShowWindow(Wnd, SW_HIDE);
-// /* Validate that window and parent still exist */ -// if (!IntIsWindow(hWnd) || !IntIsWindow(hWndNewParent)) -// return NULL; - /* Window must belong to current process */ if (Wnd->pti->pEThread->ThreadsProcess != PsGetCurrentProcess()) return NULL; @@ -1135,28 +1202,16 @@
if (WndNewParent != WndOldParent) { + /* Unlink the window from the siblings list */ IntUnlinkWindow(Wnd); - InsertAfter = NULL; - if (0 == (Wnd->Wnd->ExStyle & WS_EX_TOPMOST)) - { - /* Not a TOPMOST window, put after TOPMOSTs of new parent */ - Sibling = WndNewParent->spwndChild; - while (NULL != Sibling && 0 != (Sibling->Wnd->ExStyle & WS_EX_TOPMOST)) - { - InsertAfter = Sibling; - Sibling = Sibling->spwndNext; - } - } - if (NULL == InsertAfter) - { - IntLinkWindow(Wnd, WndNewParent, InsertAfter /*prev sibling*/); - } - else - { -// UserReferenceObject(InsertAfter); - IntLinkWindow(Wnd, WndNewParent, InsertAfter /*prev sibling*/); -// UserDereferenceObject(InsertAfter); - } + + /* Set the new parent */ + Wnd->spwndParent = WndNewParent; + Wnd->Wnd->spwndParent = WndNewParent->Wnd; + + /* Link the window with its new siblings*/ + IntLinkHwnd(Wnd, HWND_TOP); + }
/* @@ -1173,24 +1228,7 @@ * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
- /* - * Validate that the old parent still exist, since it migth have been - * destroyed during the last callbacks to user-mode - */ -// if(WndOldParent) -// { -// if(!IntIsWindow(WndOldParent->hSelf)) -// { -// UserDereferenceObject(WndOldParent); -// return NULL; -// } - - /* don't dereference the window object here, it must be done by the caller - of IntSetParent() */ -// return WndOldParent; -// } - - return WndOldParent;//NULL; + return WndOldParent; }
BOOL FASTCALL @@ -1219,7 +1257,7 @@ return TRUE; }
-/* unlink the window from siblings and parent. children are kept in place. */ +/* unlink the window from siblings. children and parent are kept in place. */ VOID FASTCALL IntUnlinkWnd(PWND Wnd) { @@ -1232,27 +1270,27 @@ if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd) Wnd->spwndParent->spwndChild = Wnd->spwndNext;
- Wnd->spwndPrev = Wnd->spwndNext = Wnd->spwndParent = NULL; -} - - -/* unlink the window from siblings and parent. children are kept in place. */ + Wnd->spwndPrev = Wnd->spwndNext = NULL; +} + + +/* unlink the window from siblings. children and parent are kept in place. */ VOID FASTCALL IntUnlinkWindow(PWINDOW_OBJECT Wnd) { - PWINDOW_OBJECT WndParent = Wnd->spwndParent; - - IntUnlinkWnd(Wnd->Wnd); - - if (Wnd->spwndNext) - Wnd->spwndNext->spwndPrev = Wnd->spwndPrev; - - if (Wnd->spwndPrev) - Wnd->spwndPrev->spwndNext = Wnd->spwndNext; - else if (WndParent && WndParent->spwndChild == Wnd) - WndParent->spwndChild = Wnd->spwndNext; - - Wnd->spwndPrev = Wnd->spwndNext = Wnd->spwndParent = NULL; + + IntUnlinkWnd(Wnd->Wnd); + + if (Wnd->spwndNext) + Wnd->spwndNext->spwndPrev = Wnd->spwndPrev; + + if (Wnd->spwndPrev) + Wnd->spwndPrev->spwndNext = Wnd->spwndNext; + + if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd) + Wnd->spwndParent->spwndChild = Wnd->spwndNext; + + Wnd->spwndPrev = Wnd->spwndNext = NULL; }
BOOL FASTCALL @@ -2037,43 +2075,11 @@ /* Link the window*/ if (NULL != ParentWindow) { - /* link the window into the parent's child list */ + /* link the window into the siblings list */ if ((dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD) - { - PWINDOW_OBJECT PrevSibling; - - PrevSibling = ParentWindow->spwndChild; - - if(PrevSibling) - { - while (PrevSibling->spwndNext) - PrevSibling = PrevSibling->spwndNext; - } - - /* link window as bottom sibling */ - IntLinkWindow(Window, ParentWindow, PrevSibling /*prev sibling*/); - } + IntLinkHwnd(Window, HWND_BOTTOM); else - { - /* link window as top sibling (but after topmost siblings) */ - PWINDOW_OBJECT InsertAfter, Sibling; - if (!(Cs->dwExStyle & WS_EX_TOPMOST)) - { - InsertAfter = NULL; - Sibling = ParentWindow->spwndChild; - while (Sibling && (Sibling->Wnd->ExStyle & WS_EX_TOPMOST)) - { - InsertAfter = Sibling; - Sibling = Sibling->spwndNext; - } - } - else - { - InsertAfter = NULL; - } - - IntLinkWindow(Window, ParentWindow, InsertAfter /* prev sibling */); - } + IntLinkHwnd(Window, HWND_TOP); }
/* Send the NCCREATE message */ @@ -2099,7 +2105,6 @@ if (Result == (LRESULT)-1) { DPRINT1("co_UserCreateWindowEx(): WM_CREATE message failed\n"); - IntUnlinkWindow(Window); RETURN((PWND)0); }
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c [iso-8859-1] Mon Oct 4 21:44:58 2010 @@ -1082,79 +1082,8 @@ /* Relink windows. (also take into account shell window in hwndShellWindow) */ if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwnd != UserGetShellWindow()) { - PWINDOW_OBJECT ParentWindow; - PWINDOW_OBJECT Sibling; - PWINDOW_OBJECT InsertAfterWindow; - - if ((ParentWindow = Window->spwndParent)) - { - if (HWND_TOPMOST == WinPos.hwndInsertAfter) - { - InsertAfterWindow = NULL; - } - else if (HWND_TOP == WinPos.hwndInsertAfter - || HWND_NOTOPMOST == WinPos.hwndInsertAfter) - { - InsertAfterWindow = NULL; - Sibling = ParentWindow->spwndChild; - while ( NULL != Sibling && - 0 != (Sibling->Wnd->ExStyle & WS_EX_TOPMOST) ) - { - InsertAfterWindow = Sibling; - Sibling = Sibling->spwndNext; - } - if (NULL != InsertAfterWindow) - { - UserReferenceObject(InsertAfterWindow); - } - } - else if (WinPos.hwndInsertAfter == HWND_BOTTOM) - { - if(ParentWindow->spwndChild) - { - InsertAfterWindow = ParentWindow->spwndChild; - - if(InsertAfterWindow) - { - while (InsertAfterWindow->spwndNext) - InsertAfterWindow = InsertAfterWindow->spwndNext; - } - - UserReferenceObject(InsertAfterWindow); - } - else - InsertAfterWindow = NULL; - } - else - InsertAfterWindow = IntGetWindowObject(WinPos.hwndInsertAfter); - /* Do nothing if hwndInsertAfter is HWND_BOTTOM and Window is already - the last window */ - if (InsertAfterWindow != Window) - { - IntUnlinkWindow(Window); - IntLinkWindow(Window, ParentWindow, InsertAfterWindow); - } - if (InsertAfterWindow != NULL) - UserDereferenceObject(InsertAfterWindow); - - if ( (HWND_TOPMOST == WinPos.hwndInsertAfter) || - (0 != (Window->Wnd->ExStyle & WS_EX_TOPMOST) && - NULL != Window->spwndPrev && - 0 != (Window->spwndPrev->Wnd->ExStyle & WS_EX_TOPMOST)) || - (NULL != Window->spwndNext && - 0 != (Window->spwndNext->Wnd->ExStyle & WS_EX_TOPMOST)) ) - { - Window->Wnd->ExStyle |= WS_EX_TOPMOST; - } - else - { - Window->Wnd->ExStyle &= ~ WS_EX_TOPMOST; - } - - } - } - - if (!Window->Wnd) return FALSE; + IntLinkHwnd(Window, WndInsertAfter); + }
OldWindowRect = Window->Wnd->rcWindow; OldClientRect = Window->Wnd->rcClient;