FoundWnd = DesktopPtrToUser(Wnd->spwndOwner);
break;
+ case GW_HWNDFIRST:
+ if(Wnd->spwndParent != NULL)
+ {
+ FoundWnd = DesktopPtrToUser(Wnd->spwndParent);
+ if (FoundWnd->spwndChild != NULL)
+ FoundWnd = DesktopPtrToUser(FoundWnd->spwndChild);
+ }
+ break;
+ case GW_HWNDNEXT:
+ if (Wnd->spwndNext != NULL)
+ FoundWnd = DesktopPtrToUser(Wnd->spwndNext);
+ break;
+
+ case GW_HWNDPREV:
+ if (Wnd->spwndPrev != NULL)
+ FoundWnd = DesktopPtrToUser(Wnd->spwndPrev);
+ break;
+
+ case GW_CHILD:
+ if (Wnd->spwndChild != NULL)
+ FoundWnd = DesktopPtrToUser(Wnd->spwndChild);
+ break;
+
+ case GW_HWNDLAST:
+ FoundWnd = Wnd;
+ while ( FoundWnd->spwndNext != NULL)
+ FoundWnd = DesktopPtrToUser(FoundWnd->spwndNext);
+ break;
+
default:
- /* FIXME: Optimize! Fall back to NtUserGetWindow for now... */
Wnd = NULL;
break;
}
}
_SEH2_END;
- if (!Wnd) /* Fall back to win32k... */
- Ret = NtUserGetWindow(hWnd, uCmd);
-
return Ret;
}
return FALSE;
}
+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))
+ Wnd->spwndNext->spwndPrev = Wnd;
+
+ Wnd->spwndPrev->spwndNext = Wnd;
+ }
+ else
+ {
+ /* link at top */
+ if ((Wnd->spwndNext = WndParent->spwndChild))
+ Wnd->spwndNext->spwndPrev = Wnd;
+
+ WndParent->spwndChild = Wnd;
+ }
+
+}
/* link the window into siblings and parent. children are kept in place. */
VOID FASTCALL
{
PWINDOW_OBJECT Parent;
+ IntLinkWnd(Wnd->Wnd,
+ WndParent->Wnd,
+ WndPrevSibling ? WndPrevSibling->Wnd : NULL);
+
Wnd->Parent = WndParent;
- Wnd->Wnd->spwndParent = WndParent ? WndParent->Wnd : NULL;
if ((Wnd->PrevSibling = WndPrevSibling))
{
/* link after WndPrevSibling */
return TRUE;
}
+/* unlink the window from siblings and parent. children are kept in place. */
+VOID FASTCALL
+IntUnlinkWnd(PWND 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->spwndParent = Wnd->spwndPrev = Wnd->spwndNext = Wnd->spwndParent = NULL;
+}
+
/* unlink the window from siblings and parent. children are kept in place. */
VOID FASTCALL
{
PWINDOW_OBJECT WndParent = Wnd->Parent;
+ IntUnlinkWnd(Wnd->Wnd);
+
if (Wnd->NextSibling)
Wnd->NextSibling->PrevSibling = Wnd->PrevSibling;
else if (WndParent && WndParent->LastChild == Wnd)
WndParent->FirstChild = Wnd->NextSibling;
Wnd->PrevSibling = Wnd->NextSibling = Wnd->Parent = NULL;
- if (Wnd->Wnd)
- Wnd->Wnd->spwndParent = NULL;
}
BOOL FASTCALL
Window->LastChild = NULL;
Window->PrevSibling = NULL;
Window->NextSibling = NULL;
+
+ Wnd->spwndNext = NULL;
+ Wnd->spwndPrev = NULL;
+ Wnd->spwndChild = NULL;
+
Wnd->cbwndExtra = Wnd->pcls->cbwndExtra;
InitializeListHead(&Wnd->PropListHead);
return hWndResult;
}
-/*
- * NtUserGetWindow
- *
- * The NtUserGetWindow function retrieves a handle to a window that has the
- * specified relationship (Z order or owner) to the specified window.
- *
- * Status
- * @implemented
- */
-
-HWND APIENTRY
-NtUserGetWindow(HWND hWnd, UINT Relationship)
-{
- DECLARE_RETURN(HWND);
-
- DPRINT("Enter NtUserGetWindow\n");
- UserEnterShared();
-
- RETURN(UserGetWindow(hWnd, Relationship));
-
-CLEANUP:
- DPRINT("Leave NtUserGetWindow, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
-
/*
* NtUserGetWindowLong
*