/* INCLUDES ******************************************************************/
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
* Initialize windowing implementation.
*/
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitWindowImpl(VOID)
{
return STATUS_SUCCESS;
return TRUE;
}
-PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd)
+PWND FASTCALL IntGetWindowObject(HWND hWnd)
{
- PWINDOW_OBJECT Window;
+ PWND Window;
if (!hWnd) return NULL;
}
/* temp hack */
-PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd)
+PWND FASTCALL UserGetWindowObject(HWND hWnd)
{
PTHREADINFO ti;
- PWINDOW_OBJECT Window;
+ PWND Window;
if (PsGetCurrentProcess() != PsInitialSystemProcess)
{
return NULL;
}
- Window = (PWINDOW_OBJECT)UserGetObject(gHandleTable, hWnd, otWindow);
- if (!Window || 0 != (Window->state & WINDOWSTATUS_DESTROYED))
+ Window = (PWND)UserGetObject(gHandleTable, hWnd, otWindow);
+ if (!Window || 0 != (Window->state & WNDS_DESTROYED))
{
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return NULL;
}
ASSERT(Window->head.cLockObj >= 0);
+
return Window;
}
BOOL FASTCALL
IntIsWindow(HWND hWnd)
{
- PWINDOW_OBJECT Window;
+ PWND Window;
if (!(Window = UserGetWindowObject(hWnd)))
return FALSE;
}
-
-/*
- Caller must NOT dereference retval!
- But if caller want the returned value to persist spanning a co_ call,
- it must reference the value (because the owner is not garanteed to
- exist just because the owned window exist)!
-*/
-PWINDOW_OBJECT FASTCALL
-IntGetParent(PWINDOW_OBJECT Wnd)
+PWND FASTCALL
+IntGetParent(PWND Wnd)
{
- if (!Wnd->Wnd) return NULL;
-
- if (Wnd->Wnd->style & WS_POPUP)
+ if (Wnd->style & WS_POPUP)
{
- return UserGetWindowObject(Wnd->hOwner);
+ return Wnd->spwndOwner;
}
- else if (Wnd->Wnd->style & WS_CHILD)
+ else if (Wnd->style & WS_CHILD)
{
return Wnd->spwndParent;
}
return NULL;
}
-
-/*
- Caller must NOT dereference retval!
- But if caller want the returned value to persist spanning a co_ call,
- it must reference the value (because the owner is not garanteed to
- exist just because the owned window exist)!
-*/
-PWINDOW_OBJECT FASTCALL
-IntGetOwner(PWINDOW_OBJECT Wnd)
-{
- return UserGetWindowObject(Wnd->hOwner);
-}
-
-
-
/*
* IntWinListChildren
*
*/
HWND* FASTCALL
-IntWinListChildren(PWINDOW_OBJECT Window)
+IntWinListChildren(PWND Window)
{
- PWINDOW_OBJECT Child;
+ PWND Child;
HWND *List;
UINT Index, NumChildren = 0;
for (Child = Window->spwndChild, Index = 0;
Child != NULL;
Child = Child->spwndNext, ++Index)
- List[Index] = Child->hSelf;
+ List[Index] = Child->head.h;
List[Index] = NULL;
return List;
static void IntSendDestroyMsg(HWND hWnd)
{
- PWINDOW_OBJECT Window;
+ PWND Window;
#if 0 /* FIXME */
GUITHREADINFO info;
// USER_REFERENCE_ENTRY Ref;
// UserRefObjectCo(Window, &Ref);
- if (!IntGetOwner(Window) && !IntGetParent(Window))
+ if (!Window->spwndOwner && !IntGetParent(Window))
{
co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (LPARAM) hWnd);
}
}
static VOID
-UserFreeWindowInfo(PTHREADINFO ti, PWINDOW_OBJECT WindowObject)
+UserFreeWindowInfo(PTHREADINFO ti, PWND Wnd)
{
PCLIENTINFO ClientInfo = GetWin32ClientInfo();
- PWND Wnd = WindowObject->Wnd;
if (!Wnd) return;
- if (ClientInfo->CallbackWnd.pvWnd == DesktopHeapAddressToUser(WindowObject->Wnd))
+ if (ClientInfo->CallbackWnd.pWnd == DesktopHeapAddressToUser(Wnd))
{
ClientInfo->CallbackWnd.hWnd = NULL;
- ClientInfo->CallbackWnd.pvWnd = NULL;
+ ClientInfo->CallbackWnd.pWnd = NULL;
}
if (Wnd->strName.Buffer != NULL)
Wnd->strName.Buffer = NULL;
}
- DesktopHeapFree(Wnd->head.rpdesk, Wnd);
- WindowObject->Wnd = NULL;
+// DesktopHeapFree(Wnd->head.rpdesk, Wnd);
+// WindowObject->Wnd = NULL;
}
/***********************************************************************
* done in CreateWindow is undone here and not in DestroyWindow:-P
*/
-static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
+static LRESULT co_UserFreeWindow(PWND Window,
PPROCESSINFO ProcessData,
PTHREADINFO ThreadData,
BOOLEAN SendMessages)
{
HWND *Children;
HWND *ChildHandle;
- PWINDOW_OBJECT Child;
+ PWND Child;
PMENU_OBJECT Menu;
BOOLEAN BelongsToThreadData;
- PWND Wnd;
ASSERT(Window);
- Wnd = Window->Wnd;
-
- if(Window->state & WINDOWSTATUS_DESTROYING)
+ if(Window->state2 & WNDS2_INDESTROY)
{
DPRINT("Tried to call IntDestroyWindow() twice\n");
return 0;
}
- Window->state |= WINDOWSTATUS_DESTROYING;
- Wnd->style &= ~WS_VISIBLE;
+ Window->state2 |= WNDS2_INDESTROY;
+ Window->style &= ~WS_VISIBLE;
- IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Wnd, OBJID_WINDOW, 0);
+ IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window, OBJID_WINDOW, CHILDID_SELF, 0);
/* remove the window already at this point from the thread window list so we
don't get into trouble when destroying the thread windows while we're still
BelongsToThreadData = IntWndBelongsToThread(Window, ThreadData);
- IntDeRegisterShellHookWindow(Window->hSelf);
+ IntDeRegisterShellHookWindow(Window->head.h);
if(SendMessages)
{
/* Send destroy messages */
- IntSendDestroyMsg(Window->hSelf);
+ IntSendDestroyMsg(Window->head.h);
}
/* free child windows */
if(!IntWndBelongsToThread(Child, ThreadData))
{
/* send WM_DESTROY messages to windows not belonging to the same thread */
- IntSendDestroyMsg(Child->hSelf);
+ IntSendDestroyMsg(Child->head.h);
}
else
co_UserFreeWindow(Child, ProcessData, ThreadData, SendMessages);
RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE |
RDW_NOINTERNALPAINT | RDW_NOCHILDREN);
if(BelongsToThreadData)
- co_IntSendMessage(Window->hSelf, WM_NCDESTROY, 0, 0);
+ co_IntSendMessage(Window->head.h, WM_NCDESTROY, 0, 0);
}
- MsqRemoveTimersWindow(ThreadData->MessageQueue, Window->hSelf);
- HOOK_DestroyThreadHooks(ThreadData->pEThread); // This is needed here too!
+
+ DestroyTimersForWindow(ThreadData, Window);
/* flush the message queue */
MsqRemoveWindowMessagesFromQueue(Window);
/* from now on no messages can be sent to this window anymore */
- Window->state |= WINDOWSTATUS_DESTROYED;
- Wnd->state |= WNDS_DESTROYED;
- Wnd->fnid |= FNID_FREED;
+ Window->state |= WNDS_DESTROYED;
+ Window->fnid |= FNID_FREED;
/* don't remove the WINDOWSTATUS_DESTROYING bit */
/* reset shell window handles */
if(ThreadData->rpdesk)
{
- if (Window->hSelf == ThreadData->rpdesk->rpwinstaParent->ShellWindow)
+ if (Window->head.h == ThreadData->rpdesk->rpwinstaParent->ShellWindow)
ThreadData->rpdesk->rpwinstaParent->ShellWindow = NULL;
- if (Window->hSelf == ThreadData->rpdesk->rpwinstaParent->ShellListView)
+ if (Window->head.h == ThreadData->rpdesk->rpwinstaParent->ShellListView)
ThreadData->rpdesk->rpwinstaParent->ShellListView = NULL;
}
#if 0 /* FIXME */
- WinPosCheckInternalPos(Window->hSelf);
- if (Window->hSelf == GetCapture())
+ WinPosCheckInternalPos(Window->head.h);
+ if (Window->head.h == GetCapture())
{
ReleaseCapture();
}
/* free resources associated with the window */
- TIMER_RemoveWindowTimers(Window->hSelf);
+ TIMER_RemoveWindowTimers(Window->head.h);
#endif
- if (!(Wnd->style & WS_CHILD) && Wnd->IDMenu
- && (Menu = UserGetMenuObject((HMENU)Wnd->IDMenu)))
+ if (!(Window->style & WS_CHILD) && Window->IDMenu
+ && (Menu = UserGetMenuObject((HMENU)Window->IDMenu)))
{
IntDestroyMenuObject(Menu, TRUE, TRUE);
- Wnd->IDMenu = 0;
+ Window->IDMenu = 0;
}
if(Window->SystemMenu
IntUnlinkWindow(Window);
UserReferenceObject(Window);
- UserDeleteObject(Window->hSelf, otWindow);
+ UserDeleteObject(Window->head.h, otWindow);
IntDestroyScrollBars(Window);
/* dereference the class */
- IntDereferenceClass(Wnd->pcls,
- Window->pti->pDeskInfo,
- Window->pti->ppi);
- Wnd->pcls = NULL;
+ IntDereferenceClass(Window->pcls,
+ Window->head.pti->pDeskInfo,
+ Window->head.pti->ppi);
+ Window->pcls = NULL;
if(Window->hrgnClip)
{
GreDeleteObject(Window->hrgnClip);
}
- ASSERT(Window->Wnd != NULL);
- UserFreeWindowInfo(Window->pti, Window);
+// ASSERT(Window != NULL);
+ UserFreeWindowInfo(Window->head.pti, Window);
UserDereferenceObject(Window);
}
VOID FASTCALL
-IntGetWindowBorderMeasures(PWINDOW_OBJECT Window, UINT *cx, UINT *cy)
+IntGetWindowBorderMeasures(PWND Wnd, UINT *cx, UINT *cy)
{
- PWND Wnd = Window->Wnd;
if(HAS_DLGFRAME(Wnd->style, Wnd->ExStyle) && !(Wnd->style & WS_MINIMIZE))
{
*cx = UserGetSystemMetrics(SM_CXDLGFRAME);
// Move this to user space!
BOOL FASTCALL
-IntGetWindowInfo(PWINDOW_OBJECT Window, PWINDOWINFO pwi)
+IntGetWindowInfo(PWND Wnd, PWINDOWINFO pwi)
{
- PWND Wnd = Window->Wnd;
-
pwi->cbSize = sizeof(WINDOWINFO);
- pwi->rcWindow = Window->Wnd->rcWindow;
- pwi->rcClient = Window->Wnd->rcClient;
+ pwi->rcWindow = Wnd->rcWindow;
+ pwi->rcClient = Wnd->rcClient;
pwi->dwStyle = Wnd->style;
pwi->dwExStyle = Wnd->ExStyle;
- pwi->dwWindowStatus = (UserGetForegroundWindow() == Window->hSelf); /* WS_ACTIVECAPTION */
- IntGetWindowBorderMeasures(Window, &pwi->cxWindowBorders, &pwi->cyWindowBorders);
+ pwi->dwWindowStatus = (UserGetForegroundWindow() == Wnd->head.h); /* WS_ACTIVECAPTION */
+ IntGetWindowBorderMeasures(Wnd, &pwi->cxWindowBorders, &pwi->cyWindowBorders);
pwi->atomWindowType = (Wnd->pcls ? Wnd->pcls->atomClassName : 0);
pwi->wCreatorVersion = 0x400; /* FIXME - return a real version number */
return TRUE;
static BOOL FASTCALL
IntSetMenu(
- PWINDOW_OBJECT Window,
+ PWND Wnd,
HMENU Menu,
BOOL *Changed)
{
PMENU_OBJECT OldMenu, NewMenu = NULL;
- PWND Wnd = Window->Wnd;
if ((Wnd->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
{
if (Wnd->IDMenu)
{
OldMenu = IntGetMenuObject((HMENU) Wnd->IDMenu);
- ASSERT(NULL == OldMenu || OldMenu->MenuInfo.Wnd == Window->hSelf);
+ ASSERT(NULL == OldMenu || OldMenu->MenuInfo.Wnd == Wnd->head.h);
}
else
{
Wnd->IDMenu = (UINT) Menu;
if (NULL != NewMenu)
{
- NewMenu->MenuInfo.Wnd = Window->hSelf;
+ NewMenu->MenuInfo.Wnd = Wnd->head.h;
IntReleaseMenuObject(NewMenu);
}
if (NULL != OldMenu)
{
PTHREADINFO WThread;
PLIST_ENTRY Current;
- PWINDOW_OBJECT Wnd;
+ PWND Wnd;
USER_REFERENCE_ENTRY Ref;
WThread = (PTHREADINFO)Thread->Tcb.Win32Thread;
while (!IsListEmpty(&WThread->WindowListHead))
{
Current = WThread->WindowListHead.Flink;
- Wnd = CONTAINING_RECORD(Current, WINDOW_OBJECT, ThreadListEntry);
+ Wnd = CONTAINING_RECORD(Current, WND, ThreadListEntry);
DPRINT("thread cleanup: while destroy wnds, wnd=0x%x\n",Wnd);
* \note Does not check the validity of the parameters
*/
VOID FASTCALL
-IntGetClientRect(PWINDOW_OBJECT Window, RECTL *Rect)
+IntGetClientRect(PWND Window, RECTL *Rect)
{
ASSERT( Window );
ASSERT( Rect );
Rect->left = Rect->top = 0;
- Rect->right = Window->Wnd->rcClient.right - Window->Wnd->rcClient.left;
- Rect->bottom = Window->Wnd->rcClient.bottom - Window->Wnd->rcClient.top;
+ Rect->right = Window->rcClient.right - Window->rcClient.left;
+ Rect->bottom = Window->rcClient.bottom - Window->rcClient.top;
}
#endif
PMENU_OBJECT FASTCALL
-IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu)
+IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu)
{
PMENU_OBJECT Menu, NewMenu = NULL, SysMenu = NULL, ret = NULL;
PTHREADINFO W32Thread;
{
Window->SystemMenu = NewMenu->MenuInfo.Self;
NewMenu->MenuInfo.Flags |= MF_SYSMENU;
- NewMenu->MenuInfo.Wnd = Window->hSelf;
+ NewMenu->MenuInfo.Wnd = Window->head.h;
ret = NewMenu;
//IntReleaseMenuObject(NewMenu);
}
return NULL;
}
SysMenu->MenuInfo.Flags |= MF_SYSMENU;
- SysMenu->MenuInfo.Wnd = Window->hSelf;
+ SysMenu->MenuInfo.Wnd = Window->head.h;
hNewMenu = co_IntLoadSysMenuTemplate();
if(!hNewMenu)
{
BOOL FASTCALL
-IntIsChildWindow(PWINDOW_OBJECT Parent, PWINDOW_OBJECT BaseWindow)
+IntIsChildWindow(PWND Parent, PWND BaseWindow)
{
- PWINDOW_OBJECT Window;
- PWND Wnd;
+ PWND Window;
Window = BaseWindow;
while (Window)
{
- Wnd = Window->Wnd;
if (Window == Parent)
{
return(TRUE);
}
- if(!(Wnd->style & WS_CHILD))
+ if(!(Window->style & WS_CHILD))
{
break;
}
}
BOOL FASTCALL
-IntIsWindowVisible(PWINDOW_OBJECT BaseWindow)
+IntIsWindowVisible(PWND BaseWindow)
{
- PWINDOW_OBJECT Window;
- PWND Wnd;
+ PWND Window;
Window = BaseWindow;
while(Window)
{
- Wnd = Window->Wnd;
- if(!(Wnd->style & WS_CHILD))
+ if(!(Window->style & WS_CHILD))
{
break;
}
- if(!(Wnd->style & WS_VISIBLE))
+ if(!(Window->style & WS_VISIBLE))
{
return FALSE;
}
Window = Window->spwndParent;
}
- if(Window && Wnd->style & WS_VISIBLE)
+ if(Window && Window->style & WS_VISIBLE)
{
return TRUE;
}
return FALSE;
}
+
+/*
+ link the window into siblings list
+ children and parent are kept in place.
+*/
VOID FASTCALL
-IntLinkWnd(
+IntLinkWindow(
PWND Wnd,
- PWND WndParent,
- PWND WndPrevSibling) /* set to NULL if top sibling */
+ PWND WndInsertAfter /* set to NULL if top sibling */
+)
{
- Wnd->spwndParent = WndParent;
- if ((Wnd->spwndPrev = WndPrevSibling))
+ if ((Wnd->spwndPrev = WndInsertAfter))
{
- /* link after WndPrevSibling */
- if ((Wnd->spwndNext = WndPrevSibling->spwndNext))
+ /* link after WndInsertAfter */
+ if ((Wnd->spwndNext = WndInsertAfter->spwndNext))
Wnd->spwndNext->spwndPrev = Wnd;
Wnd->spwndPrev->spwndNext = Wnd;
else
{
/* link at top */
- if ((Wnd->spwndNext = WndParent->spwndChild))
+ if ((Wnd->spwndNext = Wnd->spwndParent->spwndChild))
Wnd->spwndNext->spwndPrev = Wnd;
-
- WndParent->spwndChild = Wnd;
- }
+ Wnd->spwndParent->spwndChild = Wnd;
+ }
}
-/* link the window into siblings and parent. children are kept in place. */
-VOID FASTCALL
-IntLinkWindow(
- PWINDOW_OBJECT Wnd,
- PWINDOW_OBJECT WndParent,
- PWINDOW_OBJECT WndPrevSibling /* set to NULL if top sibling */
-)
+
+VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
{
- PWINDOW_OBJECT Parent;
+ if (hWndPrev == HWND_NOTOPMOST)
+ {
+ if (!(Wnd->ExStyle & WS_EX_TOPMOST) &&
+ (Wnd->ExStyle2 & WS_EX2_LINKED)) return; /* nothing to do */
+ Wnd->ExStyle &= ~WS_EX_TOPMOST;
+ hWndPrev = HWND_TOP; /* fallback to the HWND_TOP case */
+ }
- IntLinkWnd(Wnd->Wnd,
- WndParent->Wnd,
- WndPrevSibling ? WndPrevSibling->Wnd : NULL);
+ IntUnlinkWindow(Wnd); /* unlink it from the previous location */
+
+ if (hWndPrev == HWND_BOTTOM)
+ {
+ /* Link in the bottom of the list */
+ PWND WndInsertAfter;
- 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 */
- Parent = Wnd->spwndParent;
- if ((Wnd->spwndNext = WndParent->spwndChild))
- Wnd->spwndNext->spwndPrev = Wnd;
- else if (Parent)
- {
- Parent->spwndChild = Wnd;
- return;
- }
- if(Parent)
- {
- Parent->spwndChild = Wnd;
- }
- }
+ WndInsertAfter = Wnd->spwndParent->spwndChild;
+ while( WndInsertAfter && WndInsertAfter->spwndNext)
+ WndInsertAfter = WndInsertAfter->spwndNext;
+
+ IntLinkWindow(Wnd, WndInsertAfter);
+ Wnd->ExStyle &= ~WS_EX_TOPMOST;
+ }
+ else if (hWndPrev == HWND_TOPMOST)
+ {
+ /* Link in the top of the list */
+ IntLinkWindow(Wnd, NULL);
+
+ Wnd->ExStyle |= WS_EX_TOPMOST;
+ }
+ else if (hWndPrev == HWND_TOP)
+ {
+ /* Link it after the last topmost window */
+ PWND WndInsertBefore;
+
+ WndInsertBefore = Wnd->spwndParent->spwndChild;
+
+ if (!(Wnd->ExStyle & WS_EX_TOPMOST)) /* put it above the first non-topmost window */
+ {
+ while (WndInsertBefore != NULL && WndInsertBefore->spwndNext != NULL)
+ {
+ if (!(WndInsertBefore->ExStyle & WS_EX_TOPMOST)) break;
+ if (WndInsertBefore == Wnd->spwndOwner) /* keep it above owner */
+ {
+ Wnd->ExStyle |= WS_EX_TOPMOST;
+ break;
+ }
+ WndInsertBefore = WndInsertBefore->spwndNext;
+ }
+ }
+ IntLinkWindow(Wnd, WndInsertBefore ? WndInsertBefore->spwndPrev : NULL);
+ }
+ else
+ {
+ /* Link it after hWndPrev */
+ PWND 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->ExStyle & WS_EX_TOPMOST))
+ {
+ Wnd->ExStyle &= ~WS_EX_TOPMOST;
+ }
+ else
+ {
+ if(WndInsertAfter->spwndNext &&
+ WndInsertAfter->spwndNext->ExStyle & WS_EX_TOPMOST)
+ {
+ Wnd->ExStyle |= WS_EX_TOPMOST;
+ }
+ }
+ }
}
HWND FASTCALL
IntSetOwner(HWND hWnd, HWND hWndNewOwner)
{
- PWINDOW_OBJECT Wnd, WndOldOwner, WndNewOwner;
+ PWND Wnd, WndOldOwner, WndNewOwner;
HWND ret;
Wnd = IntGetWindowObject(hWnd);
if(!Wnd)
return NULL;
- WndOldOwner = IntGetWindowObject(Wnd->hOwner);
- if (WndOldOwner)
- {
- ret = WndOldOwner->hSelf;
- UserDereferenceObject(WndOldOwner);
- }
- else
- {
- ret = 0;
- }
+ WndOldOwner = Wnd->spwndOwner;
+
+ ret = WndOldOwner ? WndOldOwner->head.h : 0;
if((WndNewOwner = UserGetWindowObject(hWndNewOwner)))
{
- Wnd->hOwner = hWndNewOwner;
- Wnd->Wnd->spwndOwner = WndNewOwner->Wnd;
+ Wnd->spwndOwner= WndNewOwner;
}
else
{
- Wnd->hOwner = NULL;
- Wnd->Wnd->spwndOwner = NULL;
+ Wnd->spwndOwner = NULL;
}
UserDereferenceObject(Wnd);
return ret;
}
-PWINDOW_OBJECT FASTCALL
-co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
+PWND FASTCALL
+co_IntSetParent(PWND Wnd, PWND WndNewParent)
{
- PWINDOW_OBJECT WndOldParent, Sibling, InsertAfter;
-// HWND hWnd, hWndNewParent;
+ PWND WndOldParent;
BOOL WasVisible;
ASSERT(Wnd);
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))
{
*/
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())
+ if (Wnd->head.pti->pEThread->ThreadsProcess != PsGetCurrentProcess())
return NULL;
WndOldParent = Wnd->spwndParent;
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;
+
+ /* Link the window with its new siblings*/
+ IntLinkHwnd(Wnd, HWND_TOP);
+
}
+ IntNotifyWinEvent(EVENT_OBJECT_PARENTCHANGE, Wnd ,OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
/*
* SetParent additionally needs to make hwnd the top window
* in the z-order and send the expected WM_WINDOWPOSCHANGING and
* WM_WINDOWPOSCHANGED notification messages.
*/
- co_WinPosSetWindowPos(Wnd, (0 == (Wnd->Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST),
+ co_WinPosSetWindowPos(Wnd, (0 == (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST),
0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE
| (WasVisible ? SWP_SHOWWINDOW : 0));
* 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
-IntSetSystemMenu(PWINDOW_OBJECT Window, PMENU_OBJECT Menu)
+IntSetSystemMenu(PWND Window, PMENU_OBJECT Menu)
{
PMENU_OBJECT OldMenu;
if(Window->SystemMenu)
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)
+IntUnlinkWindow(PWND Wnd)
{
if (Wnd->spwndNext)
- Wnd->spwndNext->spwndPrev = Wnd->spwndPrev;
-
+ 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 = Wnd->spwndParent = NULL;
-}
+ Wnd->spwndPrev->spwndNext = Wnd->spwndNext;
-
-/* unlink the window from siblings and parent. children 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;
-}
-
-BOOL FASTCALL
-IntAnyPopup(VOID)
-{
- PWINDOW_OBJECT Window, Child;
-
- if(!(Window = UserGetWindowObject(IntGetDesktopWindow())))
- {
- return FALSE;
- }
-
- for(Child = Window->spwndChild; Child; Child = Child->spwndNext)
- {
- if(Child->hOwner && Child->Wnd->style & WS_VISIBLE)
- {
- /*
- * The desktop has a popup window if one of them has
- * an owner window and is visible
- */
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-BOOL FASTCALL
-IntIsWindowInDestroy(PWINDOW_OBJECT Window)
-{
- return ((Window->state & WINDOWSTATUS_DESTROYING) == WINDOWSTATUS_DESTROYING);
+ if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd)
+ Wnd->spwndParent->spwndChild = Wnd->spwndNext;
+
+ Wnd->spwndPrev = Wnd->spwndNext = NULL;
}
-
BOOL
FASTCALL
-IntGetWindowPlacement(PWINDOW_OBJECT Window, WINDOWPLACEMENT *lpwndpl)
+IntGetWindowPlacement(PWND Wnd, WINDOWPLACEMENT *lpwndpl)
{
- PWND Wnd;
POINT Size;
- Wnd = Window->Wnd;
if (!Wnd) return FALSE;
if(lpwndpl->length != sizeof(WINDOWPLACEMENT))
{
lpwndpl->showCmd = SW_HIDE;
}
- else if (0 != (Window->state & WINDOWOBJECT_RESTOREMAX) ||
+ else if (0 != (Wnd->state2 & WNDS2_MAXIMIZEBUTTONDOWN) ||
0 != (Wnd->style & WS_MAXIMIZE))
{
lpwndpl->showCmd = SW_MAXIMIZE;
Size.x = Wnd->rcWindow.left;
Size.y = Wnd->rcWindow.top;
- WinPosInitInternalPos(Window, &Size,
+ WinPosInitInternalPos(Wnd, &Size,
&Wnd->rcWindow);
lpwndpl->rcNormalPosition = Wnd->InternalPos.NormalRect;
if (hwndParent || !dwThreadId)
{
PDESKTOP Desktop;
- PWINDOW_OBJECT Parent, Window;
+ PWND Parent, Window;
if(!hwndParent)
{
_SEH2_TRY
{
ProbeForWrite(pWnd, sizeof(HWND), 1);
- *pWnd = Window->hSelf;
+ *pWnd = Window->head.h;
pWnd++;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
PETHREAD Thread;
PTHREADINFO W32Thread;
PLIST_ENTRY Current;
- PWINDOW_OBJECT Window;
+ PWND Window;
Status = PsLookupThreadByThreadId((HANDLE)dwThreadId, &Thread);
if(!NT_SUCCESS(Status))
Current = W32Thread->WindowListHead.Flink;
while(Current != &(W32Thread->WindowListHead))
{
- Window = CONTAINING_RECORD(Current, WINDOW_OBJECT, ThreadListEntry);
+ Window = CONTAINING_RECORD(Current, WND, ThreadListEntry);
ASSERT(Window);
- if(bChildren || Window->hOwner != NULL)
+ if(bChildren || Window->spwndOwner != NULL)
{
if(dwCount < *pBufSize && pWnd)
{
- Status = MmCopyToCaller(pWnd++, &Window->hSelf, sizeof(HWND));
+ Status = MmCopyToCaller(pWnd++, &Window->head.h, sizeof(HWND));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
LONG y,
UINT uiFlags)
{
- PWINDOW_OBJECT Parent;
+ PWND Parent;
POINTL Pt;
HWND Ret;
HWND *List, *phWnd;
Pt.x = x;
Pt.y = y;
- if(Parent->hSelf != IntGetDesktopWindow())
+ if(Parent->head.h != IntGetDesktopWindow())
{
- Pt.x += Parent->Wnd->rcClient.left;
- Pt.y += Parent->Wnd->rcClient.top;
+ Pt.x += Parent->rcClient.left;
+ Pt.y += Parent->rcClient.top;
}
if(!IntPtInWindow(Parent, Pt.x, Pt.y))
return NULL;
}
- Ret = Parent->hSelf;
+ Ret = Parent->head.h;
if((List = IntWinListChildren(Parent)))
{
for(phWnd = List; *phWnd; phWnd++)
{
- PWINDOW_OBJECT Child;
- PWND ChildWnd;
+ PWND Child;
if((Child = UserGetWindowObject(*phWnd)))
{
- ChildWnd = Child->Wnd;
- if(!(ChildWnd->style & WS_VISIBLE) && (uiFlags & CWP_SKIPINVISIBLE))
+ if(!(Child->style & WS_VISIBLE) && (uiFlags & CWP_SKIPINVISIBLE))
{
continue;
}
- if((ChildWnd->style & WS_DISABLED) && (uiFlags & CWP_SKIPDISABLED))
+ if((Child->style & WS_DISABLED) && (uiFlags & CWP_SKIPDISABLED))
{
continue;
}
- if((ChildWnd->ExStyle & WS_EX_TRANSPARENT) && (uiFlags & CWP_SKIPTRANSPARENT))
+ if((Child->ExStyle & WS_EX_TRANSPARENT) && (uiFlags & CWP_SKIPTRANSPARENT))
{
continue;
}
if(IntPtInWindow(Child, Pt.x, Pt.y))
{
- Ret = Child->hSelf;
+ Ret = Child->head.h;
break;
}
}
return Ret;
}
-
-/*
- * calculates the default position of a window
- */
-BOOL FASTCALL
-IntCalcDefPosSize(PWINDOW_OBJECT Parent, RECTL *rc, BOOL IncPos)
+static void IntSendParentNotify( PWND pWindow, UINT msg )
{
- SIZE Sz;
- PMONITOR pMonitor;
- POINT Pos = {0, 0};
-
- pMonitor = IntGetPrimaryMonitor();
-
- if(Parent != NULL)
- {
- RECTL_bIntersectRect(rc, rc, &pMonitor->rcMonitor);
-
- if(IncPos)
- {
- Pos.x = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CXSIZE) + UserGetSystemMetrics(SM_CXFRAME));
- Pos.y = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CYSIZE) + UserGetSystemMetrics(SM_CYFRAME));
- if (Pos.x > ((rc->right - rc->left) / 4) ||
- Pos.y > ((rc->bottom - rc->top) / 4))
- {
- /* reset counter and position */
- Pos.x = 0;
- Pos.y = 0;
- pMonitor->cWndStack = 0;
- }
- pMonitor->cWndStack++;
- }
- Pos.x += rc->left;
- Pos.y += rc->top;
- }
- else
- {
- Pos.x = rc->left;
- Pos.y = rc->top;
- }
-
- Sz.cx = EngMulDiv(rc->right - rc->left, 3, 4);
- Sz.cy = EngMulDiv(rc->bottom - rc->top, 3, 4);
-
- rc->left = Pos.x;
- rc->top = Pos.y;
- rc->right = rc->left + Sz.cx;
- rc->bottom = rc->top + Sz.cy;
- return TRUE;
+ if ( (pWindow->style & (WS_CHILD | WS_POPUP)) == WS_CHILD &&
+ !(pWindow->style & WS_EX_NOPARENTNOTIFY))
+ {
+ if (pWindow->spwndParent && pWindow->spwndParent != UserGetDesktopWindow())
+ {
+ co_IntSendMessage( pWindow->spwndParent->head.h,
+ WM_PARENTNOTIFY,
+ MAKEWPARAM( msg, pWindow->IDMenu),
+ (LPARAM)pWindow->head.h );
+ }
+ }
}
-
-/*
- * @implemented
- */
-PWND APIENTRY
-co_IntCreateWindowEx(DWORD dwExStyle,
- PUNICODE_STRING ClassName,
- PUNICODE_STRING WindowName,
- DWORD dwStyle,
- LONG x,
- LONG y,
- LONG nWidth,
- LONG nHeight,
- HWND hWndParent,
- HMENU hMenu,
- HINSTANCE hInstance,
- LPVOID lpParam,
- DWORD dwShowMode,
- BOOL bUnicodeWindow)
+void FASTCALL
+IntFixWindowCoordinates(CREATESTRUCTW* Cs, PWND ParentWindow, DWORD* dwShowMode)
{
- PWINSTATION_OBJECT WinSta;
- PWND Wnd = NULL;
- PCLS *ClassLink, Class = NULL;
- RTL_ATOM ClassAtom;
- PWINDOW_OBJECT Window = NULL;
- PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow;
- HWND ParentWindowHandle = NULL;
- HWND OwnerWindowHandle;
- PMENU_OBJECT SystemMenu;
- HWND hWnd;
- POINT Pos;
- SIZE Size;
- PTHREADINFO ti = NULL;
-#if 0
+#define IS_DEFAULT(x) ((x) == CW_USEDEFAULT || (x) == (SHORT)0x8000)
- POINT MaxSize, MaxPos, MinTrack, MaxTrack;
-#else
-
- POINT MaxPos;
-#endif
- CREATESTRUCTW Cs;
- CBT_CREATEWNDW CbtCreate;
- LRESULT Result;
- BOOL MenuChanged;
- DECLARE_RETURN(PWND);
- BOOL HasOwner;
- USER_REFERENCE_ENTRY ParentRef, Ref;
- PTHREADINFO pti;
-
- pti = PsGetCurrentThreadWin32Thread();
-
- if (pti->rpdesk)
+ /* default positioning for overlapped windows */
+ if(!(Cs->style & (WS_POPUP | WS_CHILD)))
{
- ParentWindowHandle = pti->rpdesk->DesktopWindow;
- }
+ PMONITOR pMonitor;
+ PRTL_USER_PROCESS_PARAMETERS ProcessParams;
+ pMonitor = IntGetPrimaryMonitor();
+ ASSERT(pMonitor);
- if ( !(pti->ppi->W32PF_flags & W32PF_CLASSESREGISTERED ))
- {
- UserRegisterSystemClasses();
- }
-
- OwnerWindowHandle = NULL;
+ ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters;
- DPRINT("co_IntCreateWindowEx %wZ\n", ClassName);
+ if (IS_DEFAULT(Cs->x))
+ {
+ if (!IS_DEFAULT(Cs->y)) *dwShowMode = Cs->y;
- if (hWndParent == HWND_MESSAGE)
- {
- /*
- * native ole32.OleInitialize uses HWND_MESSAGE to create the
- * message window (style: WS_POPUP|WS_DISABLED)
- */
- ParentWindowHandle = IntGetMessageWindow();
- DPRINT("Parent is HWND_MESSAGE 0x%x\n", ParentWindowHandle);
- }
- else if (hWndParent)
- {
- if ((dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD)
- { //temp hack
- PWINDOW_OBJECT Par = UserGetWindowObject(hWndParent), Root;
- if (Par && (Root = UserGetAncestor(Par, GA_ROOT)))
- OwnerWindowHandle = Root->hSelf;
+ if(ProcessParams->WindowFlags & STARTF_USEPOSITION)
+ {
+ Cs->x = ProcessParams->StartingX;
+ Cs->y = ProcessParams->StartingY;
+ }
+ else
+ {
+ Cs->x = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CXSIZE) + UserGetSystemMetrics(SM_CXFRAME));
+ Cs->y = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CYSIZE) + UserGetSystemMetrics(SM_CYFRAME));
+ if (Cs->x > ((pMonitor->rcWork.right - pMonitor->rcWork.left) / 4) ||
+ Cs->y > ((pMonitor->rcWork.bottom - pMonitor->rcWork.top) / 4))
+ {
+ /* reset counter and position */
+ Cs->x = 0;
+ Cs->y = 0;
+ pMonitor->cWndStack = 0;
+ }
+ pMonitor->cWndStack++;
+ }
}
- else
- ParentWindowHandle = hWndParent;
- }
- else if ((dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD)
- {
- SetLastWin32Error(ERROR_TLW_WITH_WSCHILD);
- RETURN( (PWND)0); /* WS_CHILD needs a parent, but WS_POPUP doesn't */
- }
-
- if (ParentWindowHandle)
- {
- ParentWindow = UserGetWindowObject(ParentWindowHandle);
- if (ParentWindow) UserRefObjectCo(ParentWindow, &ParentRef);
+ if (IS_DEFAULT(Cs->cx))
+ {
+ if (ProcessParams->WindowFlags & STARTF_USEPOSITION)
+ {
+ Cs->cx = ProcessParams->CountX;
+ Cs->cy = ProcessParams->CountY;
+ }
+ else
+ {
+ Cs->cx = (pMonitor->rcWork.right - pMonitor->rcWork.left) * 3 / 4;
+ Cs->cy = (pMonitor->rcWork.bottom - pMonitor->rcWork.top) * 3 / 4;
+ }
+ }
+ /* neither x nor cx are default. Check the y values .
+ * In the trace we see Outlook and Outlook Express using
+ * cy set to CW_USEDEFAULT when opening the address book.
+ */
+ else if (IS_DEFAULT(Cs->cy))
+ {
+ DPRINT("Strange use of CW_USEDEFAULT in nHeight\n");
+ Cs->cy = (pMonitor->rcWork.bottom - pMonitor->rcWork.top) * 3 / 4;
+ }
}
else
{
- ParentWindow = NULL;
- }
-
- /* FIXME: parent must belong to the current process */
-
- /* Check the window station. */
- ti = GetW32ThreadInfo();
- if (ti == NULL || pti->rpdesk == NULL)
- {
- DPRINT1("Thread is not attached to a desktop! Cannot create window!\n");
- RETURN( (PWND)0);
+ /* if CW_USEDEFAULT is set for non-overlapped windows, both values are set to zero */
+ if(IS_DEFAULT(Cs->x))
+ {
+ Cs->x = 0;
+ Cs->y = 0;
+ }
+ if(IS_DEFAULT(Cs->cx))
+ {
+ Cs->cx = 0;
+ Cs->cy = 0;
+ }
}
- /* Check the class. */
+#undef IS_DEFAULT
+}
- DPRINT("Class %wZ\n", ClassName);
+/* Allocates and initializes a window*/
+PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
+ PLARGE_STRING WindowName,
+ PCLS Class,
+ PWND ParentWindow,
+ PWND OwnerWindow)
+{
+ PWND pWnd = NULL;
+ HWND hWnd;
+ PTHREADINFO pti = NULL;
+ PMENU_OBJECT SystemMenu;
+ BOOL MenuChanged;
+ BOOL bUnicodeWindow;
- ClassAtom = IntGetClassAtom(ClassName,
- hInstance,
- ti->ppi,
- &Class,
- &ClassLink);
+ pti = PsGetCurrentThreadWin32Thread();
- if (ClassAtom == (RTL_ATOM)0)
+ if (!(Cs->dwExStyle & WS_EX_LAYOUTRTL))
{
- if (IS_ATOM(ClassName->Buffer))
+ if (ParentWindow)
{
- DPRINT1("Class 0x%p not found\n", (DWORD_PTR) ClassName->Buffer);
+ if ( (Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD &&
+ ParentWindow->ExStyle & WS_EX_LAYOUTRTL &&
+ !(ParentWindow->ExStyle & WS_EX_NOINHERITLAYOUT) )
+ Cs->dwExStyle |= WS_EX_LAYOUTRTL;
}
else
- {
- DPRINT1("Class \"%wZ\" not found\n", ClassName);
- }
+ {/*
+ Note from MSDN http://msdn.microsoft.com/en-us/library/aa913269.aspx :
- SetLastWin32Error(ERROR_CANNOT_FIND_WND_CLASS);
- RETURN((PWND)0);
- }
- DPRINT("ClassAtom %x\n", ClassAtom);
- Class = IntReferenceClass(Class,
- ClassLink,
- pti->rpdesk);
- if (Class == NULL)
- {
- DPRINT1("Failed to reference window class!\n");
- RETURN(NULL);
+ Dialog boxes and message boxes do not inherit layout, so you must
+ set the layout explicitly.
+ */
+ if ( Class && Class->fnid != FNID_DIALOG)
+ {
+ PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
+ if (ppi->dwLayout & LAYOUT_RTL)
+ {
+ Cs->dwExStyle |= WS_EX_LAYOUTRTL;
+ }
+ }
+ }
}
- WinSta = pti->rpdesk->rpwinstaParent;
+ /* Automatically add WS_EX_WINDOWEDGE */
+ if ((Cs->dwExStyle & WS_EX_DLGMODALFRAME) ||
+ ((!(Cs->dwExStyle & WS_EX_STATICEDGE)) &&
+ (Cs->style & (WS_DLGFRAME | WS_THICKFRAME))))
+ Cs->dwExStyle |= WS_EX_WINDOWEDGE;
+ else
+ Cs->dwExStyle &= ~WS_EX_WINDOWEDGE;
- //FIXME: Reference thread/desktop instead
- ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
+ /* Is it a unicode window? */
+ bUnicodeWindow =!(Cs->dwExStyle & WS_EX_SETANSICREATOR);
+ Cs->dwExStyle &= ~WS_EX_SETANSICREATOR;
- /* Create the window object. */
- Window = (PWINDOW_OBJECT) UserCreateObject( gHandleTable,
- pti->rpdesk,
- (PHANDLE)&hWnd,
- otWindow,
- sizeof(WINDOW_OBJECT));
- if (Window)
- {
- Window->Wnd = DesktopHeapAlloc(pti->rpdesk,
- sizeof(WND) + Class->cbwndExtra);
- if (!Window->Wnd)
- goto AllocErr;
- RtlZeroMemory(Window->Wnd,
- sizeof(WND) + Class->cbwndExtra);
- Window->Wnd->head.h = hWnd;
- Wnd = Window->Wnd;
- Wnd->fnid = 0;
+ /* Allocate the new window */
+ pWnd = (PWND) UserCreateObject( gHandleTable,
+ pti->rpdesk,
+ (PHANDLE)&hWnd,
+ otWindow,
+ sizeof(WND) + Class->cbwndExtra);
- Wnd->head.pti = ti;
- Wnd->head.rpdesk = pti->rpdesk;
- Wnd->hWndLastActive = hWnd;
- Wnd->state2 |= WNDS2_WIN40COMPAT;
- }
-
- DPRINT("Created object with handle %X\n", hWnd);
- if (!Window)
+ if (!pWnd)
{
-AllocErr:
- ObDereferenceObject(WinSta);
- SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
- RETURN( (PWND)0);
+ goto AllocError;
}
- UserRefObjectCo(Window, &Ref);
-
- ObDereferenceObject(WinSta);
+ DPRINT("Created object with handle %X\n", hWnd);
if (NULL == pti->rpdesk->DesktopWindow)
{
/* If there is no desktop window yet, we must be creating it */
pti->rpdesk->DesktopWindow = hWnd;
- pti->rpdesk->pDeskInfo->spwnd = Wnd;
+ pti->rpdesk->pDeskInfo->spwnd = pWnd;
}
/*
* Fill out the structure describing it.
*/
- Window->pti = ti;
- Wnd->pcls = Class;
- Class = NULL;
-
- Window->SystemMenu = (HMENU)0;
- Wnd->IDMenu = 0;
- Wnd->hModule = hInstance;
- Window->hSelf = hWnd;
-
- IntReferenceMessageQueue(Window->pti->MessageQueue);
- Window->spwndParent = ParentWindow;
- Wnd->spwndParent = ParentWindow ? ParentWindow->Wnd : NULL;
- if (Wnd->spwndParent != NULL && hWndParent != 0)
- {
- Wnd->HideFocus = Wnd->spwndParent->HideFocus;
- Wnd->HideAccel = Wnd->spwndParent->HideAccel;
- }
-
- if((OwnerWindow = UserGetWindowObject(OwnerWindowHandle)))
- {
- Window->hOwner = OwnerWindowHandle;
- Wnd->spwndOwner = OwnerWindow->Wnd;
- HasOwner = TRUE;
- }
- else
- {
- Window->hOwner = NULL;
- Wnd->spwndOwner = NULL;
- HasOwner = FALSE;
- }
-
- Wnd->dwUserData = 0;
-
- if (Wnd->pcls->CSF_flags & CSF_SERVERSIDEPROC)
- Wnd->state |= WNDS_SERVERSIDEWINDOWPROC;
+ /* Remember, pWnd->head is setup in object.c ...*/
+ pWnd->spwndParent = ParentWindow;
+ pWnd->spwndOwner = OwnerWindow;
+ pWnd->fnid = 0;
+ pWnd->hWndLastActive = hWnd;
+ pWnd->state2 |= WNDS2_WIN40COMPAT;
+ pWnd->pcls = Class;
+ pWnd->hModule = Cs->hInstance;
+ pWnd->style = Cs->style & ~WS_VISIBLE;
+ pWnd->ExStyle = Cs->dwExStyle;
+ pWnd->cbwndExtra = pWnd->pcls->cbwndExtra;
+
+ IntReferenceMessageQueue(pWnd->head.pti->MessageQueue);
+ if (pWnd->spwndParent != NULL && Cs->hwndParent != 0)
+ {
+ pWnd->HideFocus = pWnd->spwndParent->HideFocus;
+ pWnd->HideAccel = pWnd->spwndParent->HideAccel;
+ }
+
+ if (pWnd->pcls->CSF_flags & CSF_SERVERSIDEPROC)
+ pWnd->state |= WNDS_SERVERSIDEWINDOWPROC;
/* BugBoy Comments: Comment below say that System classes are always created
as UNICODE. In windows, creating a window with the ANSI version of CreateWindow
see what problems this would cause.*/
// Set WndProc from Class.
- Wnd->lpfnWndProc = Wnd->pcls->lpfnWndProc;
+ pWnd->lpfnWndProc = pWnd->pcls->lpfnWndProc;
// GetWindowProc, test for non server side default classes and set WndProc.
- if ( Wnd->pcls->fnid <= FNID_GHOST && Wnd->pcls->fnid >= FNID_BUTTON )
+ if ( pWnd->pcls->fnid <= FNID_GHOST && pWnd->pcls->fnid >= FNID_BUTTON )
{
if (bUnicodeWindow)
{
- if (GETPFNCLIENTA(Wnd->pcls->fnid) == Wnd->lpfnWndProc)
- Wnd->lpfnWndProc = GETPFNCLIENTW(Wnd->pcls->fnid);
+ if (GETPFNCLIENTA(pWnd->pcls->fnid) == pWnd->lpfnWndProc)
+ pWnd->lpfnWndProc = GETPFNCLIENTW(pWnd->pcls->fnid);
}
else
{
- if (GETPFNCLIENTW(Wnd->pcls->fnid) == Wnd->lpfnWndProc)
- Wnd->lpfnWndProc = GETPFNCLIENTA(Wnd->pcls->fnid);
+ if (GETPFNCLIENTW(pWnd->pcls->fnid) == pWnd->lpfnWndProc)
+ pWnd->lpfnWndProc = GETPFNCLIENTA(pWnd->pcls->fnid);
}
}
// If not an Unicode caller, set Ansi creator bit.
- if (!bUnicodeWindow) Wnd->state |= WNDS_ANSICREATOR;
+ if (!bUnicodeWindow) pWnd->state |= WNDS_ANSICREATOR;
// Clone Class Ansi/Unicode proc type.
- if (Wnd->pcls->CSF_flags & CSF_ANSIPROC)
+ if (pWnd->pcls->CSF_flags & CSF_ANSIPROC)
{
- Wnd->state |= WNDS_ANSIWINDOWPROC;
- Wnd->Unicode = FALSE;
+ pWnd->state |= WNDS_ANSIWINDOWPROC;
+ pWnd->Unicode = FALSE;
}
else
{ /*
WndProc, unless the following overriding conditions occur:
*/
if ( !bUnicodeWindow &&
- ( ClassAtom == gpsi->atomSysClass[ICLS_BUTTON] ||
- ClassAtom == gpsi->atomSysClass[ICLS_COMBOBOX] ||
- ClassAtom == gpsi->atomSysClass[ICLS_COMBOLBOX] ||
- ClassAtom == gpsi->atomSysClass[ICLS_DIALOG] ||
- ClassAtom == gpsi->atomSysClass[ICLS_EDIT] ||
- ClassAtom == gpsi->atomSysClass[ICLS_IME] ||
- ClassAtom == gpsi->atomSysClass[ICLS_LISTBOX] ||
- ClassAtom == gpsi->atomSysClass[ICLS_MDICLIENT] ||
- ClassAtom == gpsi->atomSysClass[ICLS_STATIC] ) )
+ ( Class->atomClassName == gpsi->atomSysClass[ICLS_BUTTON] ||
+ Class->atomClassName == gpsi->atomSysClass[ICLS_COMBOBOX] ||
+ Class->atomClassName == gpsi->atomSysClass[ICLS_COMBOLBOX] ||
+ Class->atomClassName == gpsi->atomSysClass[ICLS_DIALOG] ||
+ Class->atomClassName == gpsi->atomSysClass[ICLS_EDIT] ||
+ Class->atomClassName == gpsi->atomSysClass[ICLS_IME] ||
+ Class->atomClassName == gpsi->atomSysClass[ICLS_LISTBOX] ||
+ Class->atomClassName == gpsi->atomSysClass[ICLS_MDICLIENT] ||
+ Class->atomClassName == gpsi->atomSysClass[ICLS_STATIC] ) )
{ // Override Class and set the window Ansi WndProc.
- Wnd->state |= WNDS_ANSIWINDOWPROC;
- Wnd->Unicode = FALSE;
+ pWnd->state |= WNDS_ANSIWINDOWPROC;
+ pWnd->Unicode = FALSE;
}
else
{ // Set the window Unicode WndProc.
- Wnd->state &= ~WNDS_ANSIWINDOWPROC;
- Wnd->Unicode = TRUE;
+ pWnd->state &= ~WNDS_ANSIWINDOWPROC;
+ pWnd->Unicode = TRUE;
}
}
- Window->spwndChild = NULL;
- Window->spwndPrev = NULL;
- Window->spwndNext = NULL;
-
- Wnd->spwndNext = NULL;
- Wnd->spwndPrev = NULL;
- Wnd->spwndChild = NULL;
-
- Wnd->cbwndExtra = Wnd->pcls->cbwndExtra;
-
- InitializeListHead(&Wnd->PropListHead);
-
- if ( NULL != WindowName->Buffer && WindowName->Length > 0 )
+ /* BugBoy Comments: if the window being created is a edit control, ATOM 0xCxxx,
+ then my testing shows that windows (2k and XP) creates a CallProc for it immediately
+ Dont understand why it does this. */
+ if (Class->atomClassName == gpsi->atomSysClass[ICLS_EDIT])
{
- Wnd->strName.Buffer = DesktopHeapAlloc(Wnd->head.rpdesk,
- WindowName->Length + sizeof(UNICODE_NULL));
- if (Wnd->strName.Buffer == NULL)
- {
- SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
- RETURN( (PWND)0);
- }
+ PCALLPROCDATA CallProc;
+ CallProc = CreateCallProc(NULL, pWnd->lpfnWndProc, pWnd->Unicode , pWnd->head.pti->ppi);
- Wnd->strName.Buffer[WindowName->Length / sizeof(WCHAR)] = L'\0';
- _SEH2_TRY
+ if (!CallProc)
{
- RtlCopyMemory(Wnd->strName.Buffer,
- WindowName->Buffer,
- WindowName->Length);
- Wnd->strName.Length = WindowName->Length;
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ DPRINT1("Warning: Unable to create CallProc for edit control. Control may not operate correctly! hwnd %x\n",hWnd);
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ else
{
- WindowName->Length = 0;
- Wnd->strName.Buffer[0] = L'\0';
+ UserAddCallProcToClass(pWnd->pcls, CallProc);
}
- _SEH2_END;
}
- /*
- * This has been tested for WS_CHILD | WS_VISIBLE. It has not been
- * tested for WS_POPUP
- */
- if ((dwExStyle & WS_EX_DLGMODALFRAME) ||
- ((!(dwExStyle & WS_EX_STATICEDGE)) &&
- (dwStyle & (WS_DLGFRAME | WS_THICKFRAME))))
- dwExStyle |= WS_EX_WINDOWEDGE;
- else
- dwExStyle &= ~WS_EX_WINDOWEDGE;
+ InitializeListHead(&pWnd->PropListHead);
+
+ if ( WindowName->Buffer != NULL && WindowName->Length > 0 )
+ {
+ pWnd->strName.Buffer = DesktopHeapAlloc(pWnd->head.rpdesk,
+ WindowName->Length + sizeof(UNICODE_NULL));
+ if (pWnd->strName.Buffer == NULL)
+ {
+ goto AllocError;
+ }
+
+ RtlCopyMemory(pWnd->strName.Buffer, WindowName->Buffer, WindowName->Length);
+ pWnd->strName.Buffer[WindowName->Length / sizeof(WCHAR)] = L'\0';
+ pWnd->strName.Length = WindowName->Length;
+ }
/* Correct the window style. */
- if (!(dwStyle & WS_CHILD))
+ if ((pWnd->style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
{
- dwStyle |= WS_CLIPSIBLINGS;
- DPRINT("3: Style is now %lx\n", dwStyle);
- if (!(dwStyle & WS_POPUP))
+ pWnd->style |= WS_CLIPSIBLINGS;
+ if (!(pWnd->style & WS_POPUP))
{
- dwStyle |= WS_CAPTION;
- Window->state |= WINDOWOBJECT_NEED_SIZE;
- DPRINT("4: Style is now %lx\n", dwStyle);
+ pWnd->style |= WS_CAPTION;
+ pWnd->state |= WNDS_SENDSIZEMOVEMSGS;
}
}
+ if ((pWnd->ExStyle & WS_EX_DLGMODALFRAME) ||
+ (pWnd->style & (WS_DLGFRAME | WS_THICKFRAME)))
+ pWnd->ExStyle |= WS_EX_WINDOWEDGE;
+ else
+ pWnd->ExStyle &= ~WS_EX_WINDOWEDGE;
+
/* create system menu */
- if((dwStyle & WS_SYSMENU) )//&& (dwStyle & WS_CAPTION) == WS_CAPTION)
+ if((Cs->style & WS_SYSMENU) )//&& (dwStyle & WS_CAPTION) == WS_CAPTION)
{
- SystemMenu = IntGetSystemMenu(Window, TRUE, TRUE);
+ SystemMenu = IntGetSystemMenu(pWnd, TRUE, TRUE);
if(SystemMenu)
{
- Window->SystemMenu = SystemMenu->MenuInfo.Self;
+ pWnd->SystemMenu = SystemMenu->MenuInfo.Self;
IntReleaseMenuObject(SystemMenu);
}
}
/* Set the window menu */
- if ((dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD)
+ if ((Cs->style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
{
- if (hMenu)
- IntSetMenu(Window, hMenu, &MenuChanged);
- else if (Wnd->pcls->lpszMenuName) // Take it from the parent.
+ if (Cs->hMenu)
+ IntSetMenu(pWnd, Cs->hMenu, &MenuChanged);
+ else if (pWnd->pcls->lpszMenuName) // Take it from the parent.
{
UNICODE_STRING MenuName;
- if (IS_INTRESOURCE(Wnd->pcls->lpszMenuName))
+ HMENU hMenu;
+
+ if (IS_INTRESOURCE(pWnd->pcls->lpszMenuName))
{
MenuName.Length = 0;
MenuName.MaximumLength = 0;
- MenuName.Buffer = Wnd->pcls->lpszMenuName;
+ MenuName.Buffer = pWnd->pcls->lpszMenuName;
}
else
{
- RtlInitUnicodeString( &MenuName, Wnd->pcls->lpszMenuName);
+ RtlInitUnicodeString( &MenuName, pWnd->pcls->lpszMenuName);
}
- hMenu = co_IntCallLoadMenu( Wnd->pcls->hModule, &MenuName);
- if (hMenu) IntSetMenu(Window, hMenu, &MenuChanged);
+ hMenu = co_IntCallLoadMenu( pWnd->pcls->hModule, &MenuName);
+ if (hMenu) IntSetMenu(pWnd, hMenu, &MenuChanged);
}
}
else // Not a child
- Wnd->IDMenu = (UINT) hMenu;
+ pWnd->IDMenu = (UINT) Cs->hMenu;
/* Insert the window into the thread's window list. */
- InsertTailList (&pti->WindowListHead, &Window->ThreadListEntry);
+ InsertTailList (&pti->WindowListHead, &pWnd->ThreadListEntry);
/* Handle "CS_CLASSDC", it is tested first. */
- if ( (Wnd->pcls->style & CS_CLASSDC) && !(Wnd->pcls->pdce) )
+ if ( (pWnd->pcls->style & CS_CLASSDC) && !(pWnd->pcls->pdce) )
{ /* One DCE per class to have CLASS. */
- Wnd->pcls->pdce = DceAllocDCE( Window, DCE_CLASS_DC );
+ pWnd->pcls->pdce = DceAllocDCE( pWnd, DCE_CLASS_DC );
}
- else if ( Wnd->pcls->style & CS_OWNDC)
+ else if ( pWnd->pcls->style & CS_OWNDC)
{ /* Allocate a DCE for this window. */
- DceAllocDCE(Window, DCE_WINDOW_DC);
- }
-
- Pos.x = x;
- Pos.y = y;
- Size.cx = nWidth;
- Size.cy = nHeight;
-
- Wnd->ExStyle = dwExStyle;
- Wnd->style = dwStyle & ~WS_VISIBLE;
-
- /* call hook */
- Cs.lpCreateParams = lpParam;
- Cs.hInstance = hInstance;
- Cs.hMenu = hMenu;
- Cs.hwndParent = hWndParent; //Pass the original Parent handle!
- Cs.cx = Size.cx;
- Cs.cy = Size.cy;
- Cs.x = Pos.x;
- Cs.y = Pos.y;
- Cs.style = Wnd->style;
-// Cs.lpszName = (LPCWSTR) WindowName->Buffer;
-// Cs.lpszClass = (LPCWSTR) ClassName->Buffer;
- Cs.lpszName = (LPCWSTR) WindowName;
- Cs.lpszClass = (LPCWSTR) ClassName;
- Cs.dwExStyle = dwExStyle;
- CbtCreate.lpcs = &Cs;
- CbtCreate.hwndInsertAfter = HWND_TOP;
- if (ISITHOOKED(WH_CBT))
- {
- if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) &CbtCreate))
- {
- /* FIXME - Delete window object and remove it from the thread windows list */
- /* FIXME - delete allocated DCE */
- DPRINT1("CBT-hook returned !0\n");
- RETURN( (PWND) NULL);
- }
+ DceAllocDCE(pWnd, DCE_WINDOW_DC);
}
- x = Cs.x;
- y = Cs.y;
- nWidth = Cs.cx;
- nHeight = Cs.cy;
-// FIXME: Need to set the Z order in the window link list if the hook callback changed it!
-// hwndInsertAfter = CbtCreate.hwndInsertAfter;
- /* default positioning for overlapped windows */
- if(!(Wnd->style & (WS_POPUP | WS_CHILD)))
+ return pWnd;
+
+AllocError:
+
+ if(pWnd)
+ UserDereferenceObject(pWnd);
+
+ SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
+ return NULL;
+}
+
+/*
+ * @implemented
+ */
+PWND FASTCALL
+co_UserCreateWindowEx(CREATESTRUCTW* Cs,
+ PUNICODE_STRING ClassName,
+ PLARGE_STRING WindowName)
+{
+ PWND Window = NULL, ParentWindow = NULL, OwnerWindow;
+ HWND hWnd, hWndParent, hWndOwner, hwndInsertAfter;
+ DWORD dwStyle;
+ PWINSTATION_OBJECT WinSta;
+ PCLS Class = NULL;
+ SIZE Size;
+ POINT MaxPos;
+ CBT_CREATEWNDW * pCbtCreate;
+ LRESULT Result;
+ USER_REFERENCE_ENTRY ParentRef, Ref;
+ PTHREADINFO pti;
+ DWORD dwShowMode = SW_SHOW;
+ CREATESTRUCTW *pCsw;
+ PVOID pszClass = NULL, pszName = NULL;
+ DECLARE_RETURN(PWND);
+
+ /* Get the current window station and reference it */
+ pti = GetW32ThreadInfo();
+ if (pti == NULL || pti->rpdesk == NULL)
{
- RECTL rc, WorkArea;
- PRTL_USER_PROCESS_PARAMETERS ProcessParams;
- BOOL CalculatedDefPosSize = FALSE;
+ DPRINT1("Thread is not attached to a desktop! Cannot create window!\n");
+ return NULL; //There is nothing to cleanup
+ }
+ WinSta = pti->rpdesk->rpwinstaParent;
+ ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
- IntGetDesktopWorkArea(Window->pti->rpdesk, &WorkArea);
+ pCsw = NULL;
+ pCbtCreate = NULL;
- rc = WorkArea;
- ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters;
+ /* Get the class and reference it*/
+ Class = IntGetAndReferenceClass(ClassName, Cs->hInstance);
+ if(!Class)
+ {
+ DPRINT1("Failed to find class %wZ\n", ClassName);
+ RETURN(NULL);
+ }
- if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
- {
- CalculatedDefPosSize = IntCalcDefPosSize(ParentWindow, &rc, TRUE);
+ /* Now find the parent and the owner window */
+ hWndParent = IntGetDesktopWindow();
+ hWndOwner = NULL;
- if(ProcessParams->WindowFlags & STARTF_USEPOSITION)
- {
- ProcessParams->WindowFlags &= ~STARTF_USEPOSITION;
- Pos.x = WorkArea.left + ProcessParams->StartingX;
- Pos.y = WorkArea.top + ProcessParams->StartingY;
- }
- else
- {
- Pos.x = rc.left;
- Pos.y = rc.top;
- }
+ if (Cs->hwndParent == HWND_MESSAGE)
+ {
+ Cs->hwndParent = hWndParent = IntGetMessageWindow();
+ }
+ else if (Cs->hwndParent)
+ {
+ if ((Cs->style & (WS_CHILD|WS_POPUP)) != WS_CHILD)
+ hWndOwner = Cs->hwndParent;
+ else
+ hWndParent = Cs->hwndParent;
+ }
+ else if ((Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
+ {
+ DPRINT1("Cannot create a child window without a parrent!\n");
+ SetLastWin32Error(ERROR_TLW_WITH_WSCHILD);
+ RETURN(NULL); /* WS_CHILD needs a parent, but WS_POPUP doesn't */
+ }
-/*
- According to wine, the ShowMode is set to y if x == CW_USEDEFAULT(16) and
- y is something else. and Quote!
- */
+ ParentWindow = hWndParent ? UserGetWindowObject(hWndParent): NULL;
+ OwnerWindow = hWndOwner ? UserGetWindowObject(hWndOwner): NULL;
-/* Never believe Microsoft's documentation... CreateWindowEx doc says
- * that if an overlapped window is created with WS_VISIBLE style bit
- * set and the x parameter is set to CW_USEDEFAULT, the system ignores
- * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
- * reveals that
- *
- * 1) not only it checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
- * 2) it does not ignore the y parameter as the docs claim; instead, it
- * uses it as second parameter to ShowWindow() unless y is either
- * CW_USEDEFAULT or CW_USEDEFAULT16.
- *
- * The fact that we didn't do 2) caused bogus windows pop up when wine
- * was running apps that were using this obscure feature. Example -
- * calc.exe that comes with Win98 (only Win98, it's different from
- * the one that comes with Win95 and NT)
- */
- if(y != CW_USEDEFAULT && y != CW_USEDEFAULT16)
- {
- dwShowMode = y;
- }
+ /* FIXME: is this correct?*/
+ if(OwnerWindow)
+ OwnerWindow = UserGetAncestor(OwnerWindow, GA_ROOT);
+
+ /* Fix the position and the size of the window */
+ if (ParentWindow)
+ {
+ UserRefObjectCo(ParentWindow, &ParentRef);
+ IntFixWindowCoordinates(Cs, ParentWindow, &dwShowMode);
+ }
+
+ /* Allocate and initialize the new window */
+ Window = IntCreateWindow(Cs,
+ WindowName,
+ Class,
+ ParentWindow,
+ OwnerWindow);
+ if(!Window)
+ {
+ DPRINT1("IntCreateWindow failed!\n");
+ RETURN(0);
+ }
+
+ hWnd = UserHMGetHandle(Window);
+
+ UserRefObjectCo(Window, &Ref);
+ ObDereferenceObject(WinSta);
+
+ //// Call the WH_CBT hook ////
+
+ // Allocate the calling structures Justin Case this goes Global.
+ pCsw = ExAllocatePoolWithTag(NonPagedPool, sizeof(CREATESTRUCTW), TAG_HOOK);
+ pCbtCreate = ExAllocatePoolWithTag(NonPagedPool, sizeof(CBT_CREATEWNDW), TAG_HOOK);
+
+ /* Fill the new CREATESTRUCTW */
+ pCsw->lpCreateParams = Cs->lpCreateParams;
+ pCsw->hInstance = Cs->hInstance;
+ pCsw->hMenu = Cs->hMenu;
+ pCsw->hwndParent = Cs->hwndParent;
+ pCsw->cx = Cs->cx;
+ pCsw->cy = Cs->cy;
+ pCsw->x = Cs->x;
+ pCsw->y = Cs->y;
+ pCsw->dwExStyle = Cs->dwExStyle;
+ dwStyle = Cs->style; // Save it anyway.
+ pCsw->style = Window->style; /* HCBT_CREATEWND needs the real window style */
+ pCsw->lpszName = Cs->lpszName;
+ pCsw->lpszClass = Cs->lpszClass;
+
+ // Based on the assumption this is from "unicode source" user32, ReactOS, answer is yes.
+ if (!IS_ATOM(ClassName->Buffer))
+ {
+ if (Window->state & WNDS_ANSICREATOR)
+ {
+ ANSI_STRING AnsiString;
+ AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(ClassName)+sizeof(CHAR);
+ pszClass = UserHeapAlloc(AnsiString.MaximumLength);
+ RtlZeroMemory(pszClass, AnsiString.MaximumLength);
+ AnsiString.Buffer = (PCHAR)pszClass;
+ RtlUnicodeStringToAnsiString(&AnsiString, ClassName, FALSE);
}
- if(nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16)
+ else
{
- if(!CalculatedDefPosSize)
- {
- IntCalcDefPosSize(ParentWindow, &rc, FALSE);
- }
- if(ProcessParams->WindowFlags & STARTF_USESIZE)
- {
- ProcessParams->WindowFlags &= ~STARTF_USESIZE;
- Size.cx = ProcessParams->CountX;
- Size.cy = ProcessParams->CountY;
- }
- else
- {
- Size.cx = rc.right - rc.left;
- Size.cy = rc.bottom - rc.top;
- }
-
- /* move the window if necessary */
- if(Pos.x > rc.left)
- Pos.x = max(rc.left, 0);
- if(Pos.y > rc.top)
- Pos.y = max(rc.top, 0);
+ UNICODE_STRING UnicodeString;
+ UnicodeString.MaximumLength = ClassName->Length + sizeof(UNICODE_NULL);
+ pszClass = UserHeapAlloc(UnicodeString.MaximumLength);
+ RtlZeroMemory(pszClass, UnicodeString.MaximumLength);
+ UnicodeString.Buffer = (PWSTR)pszClass;
+ RtlCopyUnicodeString(&UnicodeString, ClassName);
}
+ if (pszClass) pCsw->lpszClass = UserHeapAddressToUser(pszClass);
}
- else
+ if (WindowName->Length)
{
- /* if CW_USEDEFAULT(16) is set for non-overlapped windows, both values are set to zero) */
- if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
+ UNICODE_STRING Name;
+ Name.Buffer = WindowName->Buffer;
+ Name.Length = WindowName->Length;
+ Name.MaximumLength = WindowName->MaximumLength;
+
+ if (Window->state & WNDS_ANSICREATOR)
{
- Pos.x = 0;
- Pos.y = 0;
+ ANSI_STRING AnsiString;
+ AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(&Name)+sizeof(CHAR);
+ pszName = UserHeapAlloc(AnsiString.MaximumLength);
+ RtlZeroMemory(pszName, AnsiString.MaximumLength);
+ AnsiString.Buffer = (PCHAR)pszName;
+ RtlUnicodeStringToAnsiString(&AnsiString, &Name, FALSE);
}
- if(nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16)
+ else
{
- Size.cx = 0;
- Size.cy = 0;
+ UNICODE_STRING UnicodeString;
+ UnicodeString.MaximumLength = Name.Length + sizeof(UNICODE_NULL);
+ pszName = UserHeapAlloc(UnicodeString.MaximumLength);
+ RtlZeroMemory(pszName, UnicodeString.MaximumLength);
+ UnicodeString.Buffer = (PWSTR)pszName;
+ RtlCopyUnicodeString(&UnicodeString, &Name);
}
+ if (pszName) pCsw->lpszName = UserHeapAddressToUser(pszName);
}
- /* Initialize the window dimensions. */
- Wnd->rcWindow.left = Pos.x;
- Wnd->rcWindow.top = Pos.y;
- Wnd->rcWindow.right = Pos.x + Size.cx;
- Wnd->rcWindow.bottom = Pos.y + Size.cy;
- if (0 != (Wnd->style & WS_CHILD) && ParentWindow)
+ pCbtCreate->lpcs = pCsw;
+ pCbtCreate->hwndInsertAfter = HWND_TOP;
+
+ Result = co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) pCbtCreate);
+ if (Result != 0)
{
- RECTL_vOffsetRect(&(Wnd->rcWindow), ParentWindow->Wnd->rcClient.left,
- ParentWindow->Wnd->rcClient.top);
+ DPRINT1("WH_CBT HCBT_CREATEWND hook failed! 0x%x\n", Result);
+ RETURN( (PWND) NULL);
}
- Wnd->rcClient = Wnd->rcWindow;
+ // Write back changes.
+ Cs->cx = pCsw->cx;
+ Cs->cy = pCsw->cy;
+ Cs->x = pCsw->x;
+ Cs->y = pCsw->y;
+ hwndInsertAfter = pCbtCreate->hwndInsertAfter;
+
+ /* NCCREATE and WM_NCCALCSIZE need the original values */
+ Cs->style = dwStyle;
+ Cs->lpszName = (LPCWSTR) WindowName;
+ Cs->lpszClass = (LPCWSTR) ClassName;
+
+ /* Send the WM_GETMINMAXINFO message*/
+ Size.cx = Cs->cx;
+ Size.cy = Cs->cy;
- /*
- * Get the size and position of the window.
- */
if ((dwStyle & WS_THICKFRAME) || !(dwStyle & (WS_POPUP | WS_CHILD)))
{
POINT MaxSize, MaxPos, MinTrack, MaxTrack;
- /* WinPosGetMinMaxInfo sends the WM_GETMINMAXINFO message */
- co_WinPosGetMinMaxInfo(Window, &MaxSize, &MaxPos, &MinTrack,
- &MaxTrack);
- if (MaxSize.x < Size.cx)
- Size.cx = MaxSize.x;
- if (MaxSize.y < Size.cy)
- Size.cy = MaxSize.y;
- if (Size.cx < MinTrack.x )
- Size.cx = MinTrack.x;
- if (Size.cy < MinTrack.y )
- Size.cy = MinTrack.y;
- if (Size.cx < 0)
- Size.cx = 0;
- if (Size.cy < 0)
- Size.cy = 0;
- }
-
- Wnd->rcWindow.left = Pos.x;
- Wnd->rcWindow.top = Pos.y;
- Wnd->rcWindow.right = Pos.x + Size.cx;
- Wnd->rcWindow.bottom = Pos.y + Size.cy;
- if (0 != (Wnd->style & WS_CHILD) && ParentWindow)
- {
- RECTL_vOffsetRect(&(Wnd->rcWindow), ParentWindow->Wnd->rcClient.left,
- ParentWindow->Wnd->rcClient.top);
- }
- Wnd->rcClient = Wnd->rcWindow;
-
- /* FIXME: Initialize the window menu. */
-
- /* Send a NCCREATE message. */
- Cs.cx = Size.cx;
- Cs.cy = Size.cy;
- Cs.x = Pos.x;
- Cs.y = Pos.y;
-
- DPRINT("[win32k.window] IntCreateWindowEx style %d, exstyle %d, parent %d\n", Cs.style, Cs.dwExStyle, Cs.hwndParent);
- DPRINT("IntCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, Size.cx, Size.cy);
- DPRINT("IntCreateWindowEx(): About to send NCCREATE message.\n");
- Result = co_IntSendMessage(Window->hSelf, WM_NCCREATE, 0, (LPARAM) &Cs);
- if (!Result)
- {
- /* FIXME: Cleanup. */
- DPRINT1("IntCreateWindowEx(): NCCREATE message failed. No cleanup performed!\n");
- RETURN((PWND)0);
+ co_WinPosGetMinMaxInfo(Window, &MaxSize, &MaxPos, &MinTrack, &MaxTrack);
+ if (Size.cx > MaxTrack.x) Size.cx = MaxTrack.x;
+ if (Size.cy > MaxTrack.y) Size.cy = MaxTrack.y;
+ if (Size.cx < MinTrack.x) Size.cx = MinTrack.x;
+ if (Size.cy < MinTrack.y) Size.cy = MinTrack.y;
}
- /* Calculate the non-client size. */
- MaxPos.x = Window->Wnd->rcWindow.left;
- MaxPos.y = Window->Wnd->rcWindow.top;
-
-
- DPRINT("IntCreateWindowEx(): About to get non-client size.\n");
- /* WinPosGetNonClientSize SENDS THE WM_NCCALCSIZE message */
- Result = co_WinPosGetNonClientSize(Window,
- &Window->Wnd->rcWindow,
- &Window->Wnd->rcClient);
-
- RECTL_vOffsetRect(&Window->Wnd->rcWindow,
- MaxPos.x - Window->Wnd->rcWindow.left,
- MaxPos.y - Window->Wnd->rcWindow.top);
+ Window->rcWindow.left = Cs->x;
+ Window->rcWindow.top = Cs->y;
+ Window->rcWindow.right = Cs->x + Size.cx;
+ Window->rcWindow.bottom = Cs->y + Size.cy;
+ if (0 != (Window->style & WS_CHILD) && ParentWindow)
+ {
+ RECTL_vOffsetRect(&Window->rcWindow,
+ ParentWindow->rcClient.left,
+ ParentWindow->rcClient.top);
+ }
+ Window->rcClient = Window->rcWindow;
+ /* 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 (!(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 WM_CREATE message. */
- DPRINT("IntCreateWindowEx(): about to send CREATE message.\n");
- Result = co_IntSendMessage(Window->hSelf, WM_CREATE, 0, (LPARAM) &Cs);
-
- if (Result == (LRESULT)-1)
+
+ /* Send the NCCREATE message */
+ Result = co_IntSendMessage(UserHMGetHandle(Window), WM_NCCREATE, 0, (LPARAM) Cs);
+ if (!Result)
{
- /* FIXME: Cleanup. */
- DPRINT1("IntCreateWindowEx(): send CREATE message failed. No cleanup performed!\n");
- IntUnlinkWindow(Window);
+ DPRINT1("co_UserCreateWindowEx(): NCCREATE message failed\n");
RETURN((PWND)0);
}
- IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window->Wnd, OBJID_WINDOW, 0);
+ /* Send the WM_NCCALCSIZE message */
+ MaxPos.x = Window->rcWindow.left;
+ MaxPos.y = Window->rcWindow.top;
- /* Send move and size messages. */
- if (!(Window->state & WINDOWOBJECT_NEED_SIZE))
- {
- LONG lParam;
-
- DPRINT("IntCreateWindow(): About to send WM_SIZE\n");
+ Result = co_WinPosGetNonClientSize(Window, &Window->rcWindow, &Window->rcClient);
- if ((Window->Wnd->rcClient.right - Window->Wnd->rcClient.left) < 0 ||
- (Window->Wnd->rcClient.bottom - Window->Wnd->rcClient.top) < 0)
- {
- DPRINT("Sending bogus WM_SIZE\n");
- }
+ RECTL_vOffsetRect(&Window->rcWindow, MaxPos.x - Window->rcWindow.left,
+ MaxPos.y - Window->rcWindow.top);
- lParam = MAKE_LONG(Window->Wnd->rcClient.right -
- Window->Wnd->rcClient.left,
- Window->Wnd->rcClient.bottom -
- Window->Wnd->rcClient.top);
- co_IntSendMessage(Window->hSelf, WM_SIZE, SIZE_RESTORED,
- lParam);
- DPRINT("IntCreateWindow(): About to send WM_MOVE\n");
+ /* Send the WM_CREATE message. */
+ Result = co_IntSendMessage(UserHMGetHandle(Window), WM_CREATE, 0, (LPARAM) Cs);
+ if (Result == (LRESULT)-1)
+ {
+ DPRINT1("co_UserCreateWindowEx(): WM_CREATE message failed\n");
+ RETURN((PWND)0);
+ }
- if (0 != (Wnd->style & WS_CHILD) && ParentWindow)
- {
- lParam = MAKE_LONG(Wnd->rcClient.left - ParentWindow->Wnd->rcClient.left,
- Wnd->rcClient.top - ParentWindow->Wnd->rcClient.top);
- }
- else
- {
- lParam = MAKE_LONG(Wnd->rcClient.left,
- Wnd->rcClient.top);
- }
+ /* Send the EVENT_OBJECT_CREATE event*/
+ IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_WINDOW, CHILDID_SELF, 0);
- co_IntSendMessage(Window->hSelf, WM_MOVE, 0, lParam);
+ /* By setting the flag below it can be examined to determine if the window
+ was created successfully and a valid pwnd was passed back to caller since
+ from here the function has to succeed. */
+ Window->state2 |= WNDS2_WMCREATEMSGPROCESSED;
- /* Call WNDOBJ change procs */
- IntEngWindowChanged(Window, WOC_RGN_CLIENT);
+ /* Send the WM_SIZE and WM_MOVE messages. */
+ if (!(Window->state & WNDS_SENDSIZEMOVEMSGS))
+ {
+ co_WinPosSendSizeMove(Window);
}
/* Show or maybe minimize or maximize the window. */
- if (Wnd->style & (WS_MINIMIZE | WS_MAXIMIZE))
+ if (Window->style & (WS_MINIMIZE | WS_MAXIMIZE))
{
RECTL NewPos;
UINT16 SwFlag;
- SwFlag = (Wnd->style & WS_MINIMIZE) ? SW_MINIMIZE :
- SW_MAXIMIZE;
+ SwFlag = (Window->style & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
co_WinPosMinMaximize(Window, SwFlag, &NewPos);
- SwFlag = ((Wnd->style & WS_CHILD) || UserGetActiveWindow()) ?
+ SwFlag = ((Window->style & WS_CHILD) || UserGetActiveWindow()) ?
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED :
SWP_NOZORDER | SWP_FRAMECHANGED;
- DPRINT("IntCreateWindow(): About to minimize/maximize\n");
- DPRINT("%d,%d %dx%d\n", NewPos.left, NewPos.top, NewPos.right, NewPos.bottom);
co_WinPosSetWindowPos(Window, 0, NewPos.left, NewPos.top,
NewPos.right, NewPos.bottom, SwFlag);
}
- /* Notify the parent window of a new child. */
- if ((Wnd->style & WS_CHILD) &&
- (!(Wnd->ExStyle & WS_EX_NOPARENTNOTIFY)) && ParentWindow)
- {
- DPRINT("IntCreateWindow(): About to notify parent\n");
- co_IntSendMessage(ParentWindow->hSelf,
- WM_PARENTNOTIFY,
- MAKEWPARAM(WM_CREATE, Wnd->IDMenu),
- (LPARAM)Window->hSelf);
- }
+ /* Send the WM_PARENTNOTIFY message */
+ IntSendParentNotify(Window, WM_CREATE);
- if ((!hWndParent) && (!HasOwner))
+ /* Notify the shell that a new window was created */
+ if ((!hWndParent) && (!hWndOwner))
{
- DPRINT("Sending CREATED notify\n");
co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)hWnd);
}
- else
- {
- DPRINT("Not sending CREATED notify, %x %d\n", ParentWindow, HasOwner);
- }
/* Initialize and show the window's scrollbars */
- if (Wnd->style & WS_VSCROLL)
+ if (Window->style & WS_VSCROLL)
{
co_UserShowScrollBar(Window, SB_VERT, TRUE);
}
- if (Wnd->style & WS_HSCROLL)
+ if (Window->style & WS_HSCROLL)
{
co_UserShowScrollBar(Window, SB_HORZ, TRUE);
}
- if (dwStyle & WS_VISIBLE)
+ /* Show the new window */
+ if (Cs->style & WS_VISIBLE)
{
- if (Wnd->style & WS_MAXIMIZE)
+ if (Window->style & WS_MAXIMIZE)
dwShowMode = SW_SHOW;
- else if (Wnd->style & WS_MINIMIZE)
+ else if (Window->style & WS_MINIMIZE)
dwShowMode = SW_SHOWMINIMIZED;
- DPRINT("IntCreateWindow(): About to show window\n");
co_WinPosShowWindow(Window, dwShowMode);
- if (Wnd->ExStyle & WS_EX_MDICHILD)
+ if (Window->ExStyle & WS_EX_MDICHILD)
{
- co_IntSendMessage(ParentWindow->hSelf, WM_MDIREFRESHMENU, 0, 0);
+ co_IntSendMessage(UserHMGetHandle(ParentWindow), WM_MDIREFRESHMENU, 0, 0);
/* ShowWindow won't activate child windows */
co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
}
}
- /* BugBoy Comments: if the window being created is a edit control, ATOM 0xCxxx,
- then my testing shows that windows (2k and XP) creates a CallProc for it immediately
- Dont understand why it does this. */
- if (ClassAtom == gpsi->atomSysClass[ICLS_EDIT])
- {
- PCALLPROCDATA CallProc;
- //CallProc = CreateCallProc(NULL, Wnd->lpfnWndProc, bUnicodeWindow, Wnd->ti->ppi);
- CallProc = CreateCallProc(NULL, Wnd->lpfnWndProc, Wnd->Unicode , Wnd->head.pti->ppi);
+ DPRINT("co_UserCreateWindowEx(): Created window %X\n", hWnd);
+ RETURN( Window);
- if (!CallProc)
- {
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
- DPRINT1("Warning: Unable to create CallProc for edit control. Control may not operate correctly! hwnd %x\n",hWnd);
- }
- else
- {
- UserAddCallProcToClass(Wnd->pcls, CallProc);
- }
+CLEANUP:
+ if (!_ret_)
+ {
+ /* If the window was created, the class will be dereferenced by co_UserDestroyWindow */
+ if (Window)
+ co_UserDestroyWindow(Window);
+ else if (Class)
+ IntDereferenceClass(Class, pti->pDeskInfo, pti->ppi);
}
- DPRINT("IntCreateWindow(): = %X\n", hWnd);
- DPRINT("WindowObject->SystemMenu = 0x%x\n", Window->SystemMenu);
- RETURN( Wnd);
+ if (pCsw) ExFreePoolWithTag(pCsw, TAG_HOOK);
+ if (pCbtCreate) ExFreePoolWithTag(pCbtCreate, TAG_HOOK);
+ if (pszName) UserHeapFree(pszName);
+ if (pszClass) UserHeapFree(pszClass);
-CLEANUP:
- if (!_ret_ && Window && Window->Wnd && ti)
- co_UserDestroyWindow(Window);
-// UserFreeWindowInfo(ti, Window);
if (Window)
{
UserDerefObjectCo(Window);
UserDereferenceObject(Window);
}
if (ParentWindow) UserDerefObjectCo(ParentWindow);
- if (!_ret_ && ti != NULL)
- {
- if (Class != NULL)
- {
- IntDereferenceClass(Class,
- ti->pDeskInfo,
- ti->ppi);
- }
- }
+
END_CLEANUP;
}
-HWND APIENTRY
-NtUserCreateWindowEx(DWORD dwExStyle,
- PUNICODE_STRING UnsafeClassName,
- PUNICODE_STRING UnsafeWindowName,
- DWORD dwStyle,
- LONG x,
- LONG y,
- LONG nWidth,
- LONG nHeight,
- HWND hWndParent,
- HMENU hMenu,
- HINSTANCE hInstance,
- LPVOID lpParam,
- DWORD dwShowMode,
- BOOL bUnicodeWindow,
- DWORD dwUnknown)
+NTSTATUS
+NTAPI
+ProbeAndCaptureLargeString(
+ OUT PLARGE_STRING plstrSafe,
+ IN PLARGE_STRING plstrUnsafe)
{
- NTSTATUS Status;
- UNICODE_STRING WindowName;
- UNICODE_STRING ClassName;
- HWND NewWindow = NULL;
- PWND pNewWindow;
- DECLARE_RETURN(HWND);
+ LARGE_STRING lstrTemp;
+ PVOID pvBuffer = NULL;
- DPRINT("Enter NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight);
- UserEnterExclusive();
+ _SEH2_TRY
+ {
+ /* Probe and copy the string */
+ ProbeForRead(plstrUnsafe, sizeof(LARGE_STRING), sizeof(ULONG));
+ lstrTemp = *plstrUnsafe;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Fail */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode();)
+ }
+ _SEH2_END
- /* Get the class name (string or atom) */
- Status = MmCopyFromCaller(&ClassName, UnsafeClassName, sizeof(UNICODE_STRING));
- if (! NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( NULL);
- }
- if (ClassName.Length != 0)
- {
- Status = IntSafeCopyUnicodeStringTerminateNULL(&ClassName, UnsafeClassName);
- if (! NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( NULL);
- }
- }
- else if (! IS_ATOM(ClassName.Buffer))
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN(NULL);
- }
+ if (lstrTemp.Length != 0)
+ {
+ /* Allocate a buffer from paged pool */
+ pvBuffer = ExAllocatePoolWithTag(PagedPool, lstrTemp.Length, TAG_STRING);
+ if (!pvBuffer)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ _SEH2_TRY
+ {
+ /* Probe and copy the buffer */
+ ProbeForRead(lstrTemp.Buffer, lstrTemp.Length, sizeof(WCHAR));
+ RtlCopyMemory(pvBuffer, lstrTemp.Buffer, lstrTemp.Length);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Cleanup and fail */
+ ExFreePool(pvBuffer);
+ _SEH2_YIELD(return _SEH2_GetExceptionCode();)
+ }
+ _SEH2_END
+ }
- /* safely copy the window name */
- if (NULL != UnsafeWindowName)
- {
- Status = IntSafeCopyUnicodeString(&WindowName, UnsafeWindowName);
- if (! NT_SUCCESS(Status))
- {
- if (! IS_ATOM(ClassName.Buffer))
- {
- ExFreePoolWithTag(ClassName.Buffer, TAG_STRING);
- }
- SetLastNtError(Status);
- RETURN( NULL);
- }
- }
- else
- {
- RtlInitUnicodeString(&WindowName, NULL);
- }
+ /* Set the output string */
+ plstrSafe->Buffer = pvBuffer;
+ plstrSafe->Length = lstrTemp.Length;
+ plstrSafe->MaximumLength = lstrTemp.Length;
+
+ return STATUS_SUCCESS;
+}
- pNewWindow = co_IntCreateWindowEx( dwExStyle,
- &ClassName,
- &WindowName,
- dwStyle,
- x,
- y,
- nWidth,
- nHeight,
- hWndParent,
- hMenu,
- hInstance,
- lpParam,
- dwShowMode,
- bUnicodeWindow);
+/**
+ * \todo Allow passing plstrClassName as ANSI.
+ */
+HWND
+NTAPI
+NtUserCreateWindowEx(
+ DWORD dwExStyle,
+ PLARGE_STRING plstrClassName,
+ PLARGE_STRING plstrClsVersion,
+ PLARGE_STRING plstrWindowName,
+ DWORD dwStyle,
+ int x,
+ int y,
+ int nWidth,
+ int nHeight,
+ HWND hWndParent,
+ HMENU hMenu,
+ HINSTANCE hInstance,
+ LPVOID lpParam,
+ DWORD dwFlags,
+ PVOID acbiBuffer)
+{
+ NTSTATUS Status;
+ LARGE_STRING lstrWindowName;
+ LARGE_STRING lstrClassName;
+ UNICODE_STRING ustrClassName;
+ CREATESTRUCTW Cs;
+ HWND hwnd = NULL;
+ PWND pwnd;
+
+ lstrWindowName.Buffer = NULL;
+ lstrClassName.Buffer = NULL;
+
+ /* Check if we got a Window name */
+ if (plstrWindowName)
+ {
+ /* Copy the string to kernel mode */
+ Status = ProbeAndCaptureLargeString(&lstrWindowName, plstrWindowName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtUserCreateWindowEx: failed to capture plstrWindowName\n");
+ SetLastNtError(Status);
+ return NULL;
+ }
+ plstrWindowName = &lstrWindowName;
+ }
- if (pNewWindow) NewWindow = UserHMGetHandle(pNewWindow);
+ /* Check if the class is an atom */
+ if (IS_ATOM(plstrClassName))
+ {
+ /* It is, pass the atom in the UNICODE_STRING */
+ ustrClassName.Buffer = (PVOID)plstrClassName;
+ ustrClassName.Length = 0;
+ ustrClassName.MaximumLength = 0;
+ }
+ else
+ {
+ /* It's not, capture the class name */
+ Status = ProbeAndCaptureLargeString(&lstrClassName, plstrClassName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtUserCreateWindowEx: failed to capture plstrClassName\n");
+ /* Set last error, cleanup and return */
+ SetLastNtError(Status);
+ goto cleanup;
+ }
- if (WindowName.Buffer)
- {
- ExFreePoolWithTag(WindowName.Buffer, TAG_STRING);
- }
- if (! IS_ATOM(ClassName.Buffer))
- {
- ExFreePoolWithTag(ClassName.Buffer, TAG_STRING);
- }
+ /* We pass it on as a UNICODE_STRING */
+ ustrClassName.Buffer = lstrClassName.Buffer;
+ ustrClassName.Length = lstrClassName.Length;
+ ustrClassName.MaximumLength = lstrClassName.MaximumLength;
+ }
- RETURN( NewWindow);
+ /* Fill the CREATESTRUCTW */
+ /* we will keep here the original parameters */
+ Cs.style = dwStyle;
+ Cs.lpCreateParams = lpParam;
+ Cs.hInstance = hInstance;
+ Cs.hMenu = hMenu;
+ Cs.hwndParent = hWndParent;
+ Cs.cx = nWidth;
+ Cs.cy = nHeight;
+ Cs.x = x;
+ Cs.y = y;
+ Cs.lpszName = (LPCWSTR) plstrWindowName->Buffer;
+ if (IS_ATOM(plstrClassName))
+ Cs.lpszClass = (LPCWSTR) plstrClassName;
+ else
+ Cs.lpszClass = (LPCWSTR) plstrClassName->Buffer;
+ Cs.dwExStyle = dwExStyle;
+
+ UserEnterExclusive();
+
+ /* Call the internal function */
+ pwnd = co_UserCreateWindowEx(&Cs, &ustrClassName, plstrWindowName);
+
+ if(!pwnd)
+ {
+ DPRINT1("co_UserCreateWindowEx failed!\n");
+ }
+ hwnd = pwnd ? UserHMGetHandle(pwnd) : NULL;
-CLEANUP:
- DPRINT("Leave NtUserCreateWindowEx, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ UserLeave();
+
+cleanup:
+ if (lstrWindowName.Buffer)
+ {
+ ExFreePoolWithTag(lstrWindowName.Buffer, TAG_STRING);
+ }
+ if (lstrClassName.Buffer)
+ {
+ ExFreePoolWithTag(lstrClassName.Buffer, TAG_STRING);
+ }
+
+ return hwnd;
}
/*
}
-BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
+BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
{
- BOOLEAN isChild;
- PWND Wnd;
HWND hWnd;
+ PTHREADINFO ti;
+ MSG msg;
ASSERT_REFS_CO(Window); // FIXME: temp hack?
- hWnd = Window->hSelf;
-
- Wnd = Window->Wnd;
-
- if (!Wnd) return TRUE; // FIXME: Need to finish object rewrite or lock the thread when killing the window!
+ hWnd = Window->head.h;
DPRINT("co_UserDestroyWindow \n");
/* Check for owner thread */
- if ( (Window->pti->pEThread != PsGetCurrentThread()) ||
- Wnd->head.pti != PsGetCurrentThreadWin32Thread() )
+ if ( (Window->head.pti->pEThread != PsGetCurrentThread()) ||
+ Window->head.pti != PsGetCurrentThreadWin32Thread() )
{
SetLastWin32Error(ERROR_ACCESS_DENIED);
return FALSE;
}
- /* Call hooks */
- if (ISITHOOKED(WH_CBT))
+ /* If window was created successfully and it is hooked */
+ if ((Window->state2 & WNDS2_WMCREATEMSGPROCESSED))
+ {
+ if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hWnd, 0))
+ {
+ DPRINT1("Destroy Window WH_CBT Call Hook return!\n");
+ return FALSE;
+ }
+ }
+
+ /* Inform the parent */
+ if (Window->style & WS_CHILD)
{
- if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hWnd, 0)) return FALSE;
+ IntSendParentNotify(Window, WM_DESTROY);
}
/* Look whether the focus is within the tree of windows we will
*/
if (!co_WinPosShowWindow(Window, SW_HIDE))
{
- if (UserGetActiveWindow() == Window->hSelf)
+ if (UserGetActiveWindow() == Window->head.h)
{
co_WinPosActivateOtherWindow(Window);
}
}
- if (Window->pti->MessageQueue->ActiveWindow == Window->hSelf)
- Window->pti->MessageQueue->ActiveWindow = NULL;
- if (Window->pti->MessageQueue->FocusWindow == Window->hSelf)
- Window->pti->MessageQueue->FocusWindow = NULL;
- if (Window->pti->MessageQueue->CaptureWindow == Window->hSelf)
- Window->pti->MessageQueue->CaptureWindow = NULL;
+ if (Window->head.pti->MessageQueue->ActiveWindow == Window->head.h)
+ Window->head.pti->MessageQueue->ActiveWindow = NULL;
+ if (Window->head.pti->MessageQueue->FocusWindow == Window->head.h)
+ Window->head.pti->MessageQueue->FocusWindow = NULL;
+ if (Window->head.pti->MessageQueue->CaptureWindow == Window->head.h)
+ Window->head.pti->MessageQueue->CaptureWindow = NULL;
- IntDereferenceMessageQueue(Window->pti->MessageQueue);
-
- IntEngWindowChanged(Window, WOC_DELETE);
- isChild = (0 != (Wnd->style & WS_CHILD));
+ /*
+ * Check if this window is the Shell's Desktop Window. If so set hShellWindow to NULL
+ */
-#if 0 /* FIXME */
+ ti = PsGetCurrentThreadWin32Thread();
- if (isChild)
+ if ((ti != NULL) & (ti->pDeskInfo != NULL))
{
- if (! USER_IsExitingThread(GetCurrentThreadId()))
+ if (ti->pDeskInfo->hShellWindow == hWnd)
{
- send_parent_notify(hwnd, WM_DESTROY);
+ DPRINT1("Destroying the ShellWindow!\n");
+ ti->pDeskInfo->hShellWindow = NULL;
}
}
- else if (NULL != GetWindow(Wnd, GW_OWNER))
- {
- co_HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWDESTROYED, (WPARAM)hwnd, 0L, TRUE );
- /* FIXME: clean up palette - see "Internals" p.352 */
- }
-#endif
- if (!IntIsWindow(Window->hSelf))
+ IntDereferenceMessageQueue(Window->head.pti->MessageQueue);
+
+ IntEngWindowChanged(Window, WOC_DELETE);
+
+ if (!IntIsWindow(Window->head.h))
{
return TRUE;
}
/* Recursively destroy owned windows */
- if (! isChild)
+
+ if (! (Window->style & WS_CHILD))
{
for (;;)
{
BOOL GotOne = FALSE;
HWND *Children;
HWND *ChildHandle;
- PWINDOW_OBJECT Child, Desktop;
+ PWND Child, Desktop;
Desktop = IntIsDesktopWindow(Window) ? Window :
UserGetWindowObject(IntGetDesktopWindow());
Child = UserGetWindowObject(*ChildHandle);
if (Child == NULL)
continue;
- if (Child->hOwner != Window->hSelf)
+ if (Child->spwndOwner != Window)
{
continue;
}
continue;
}
- if (Child->hOwner != NULL)
+ if (Child->spwndOwner != NULL)
{
- Child->hOwner = NULL;
- Child->Wnd->spwndOwner = NULL;
+ Child->spwndOwner = NULL;
}
}
}
}
- if (!IntIsWindow(Window->hSelf))
+ /* Generate mouse move message for the next window */
+ msg.message = WM_MOUSEMOVE;
+ msg.wParam = IntGetSysCursorInfo()->ButtonsDown;
+ msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y);
+ msg.pt = gpsi->ptCursor;
+ MsqInsertMouseMessage(&msg);
+
+ if (!IntIsWindow(Window->head.h))
{
return TRUE;
}
BOOLEAN APIENTRY
NtUserDestroyWindow(HWND Wnd)
{
- PWINDOW_OBJECT Window;
+ PWND Window;
DECLARE_RETURN(BOOLEAN);
BOOLEAN ret;
USER_REFERENCE_ENTRY Ref;
static HWND FASTCALL
-IntFindWindow(PWINDOW_OBJECT Parent,
- PWINDOW_OBJECT ChildAfter,
+IntFindWindow(PWND Parent,
+ PWND ChildAfter,
RTL_ATOM ClassAtom,
PUNICODE_STRING WindowName)
{
BOOL CheckWindowName;
HWND *List, *phWnd;
HWND Ret = NULL;
+ UNICODE_STRING CurrentWindowName;
ASSERT(Parent);
if(ChildAfter)
{
/* skip handles before and including ChildAfter */
- while(*phWnd && (*(phWnd++) != ChildAfter->hSelf))
+ while(*phWnd && (*(phWnd++) != ChildAfter->head.h))
;
}
/* search children */
while(*phWnd)
{
- PWINDOW_OBJECT Child;
+ PWND Child;
if(!(Child = UserGetWindowObject(*(phWnd++))))
{
continue;
/* Do not send WM_GETTEXT messages in the kernel mode version!
The user mode version however calls GetWindowText() which will
send WM_GETTEXT messages to windows belonging to its processes */
- if((!CheckWindowName || !RtlCompareUnicodeString(WindowName, &(Child->Wnd->strName), TRUE)) &&
- (!ClassAtom || Child->Wnd->pcls->atomClassName == ClassAtom))
+ if (!ClassAtom || Child->pcls->atomClassName == ClassAtom)
{
- Ret = Child->hSelf;
+ // HACK: use UNICODE_STRING instead of LARGE_STRING
+ CurrentWindowName.Buffer = Child->strName.Buffer;
+ CurrentWindowName.Length = Child->strName.Length;
+ CurrentWindowName.MaximumLength = Child->strName.MaximumLength;
+ if(!CheckWindowName ||
+ (Child->strName.Length < 0xFFFF &&
+ !RtlCompareUnicodeString(WindowName, &CurrentWindowName, TRUE)))
+ {
+ Ret = Child->head.h;
break;
}
-
+ }
}
ExFreePool(List);
}
PUNICODE_STRING ucWindowName,
DWORD dwUnknown)
{
- PWINDOW_OBJECT Parent, ChildAfter;
+ PWND Parent, ChildAfter;
UNICODE_STRING ClassName = {0}, WindowName = {0};
HWND Desktop, Ret = NULL;
RTL_ATOM ClassAtom = (RTL_ATOM)0;
_SEH2_TRY
{
- if(Parent->hSelf == Desktop)
+ if(Parent->head.h == Desktop)
{
HWND *List, *phWnd;
- PWINDOW_OBJECT TopLevelWindow;
+ PWND TopLevelWindow;
BOOLEAN CheckWindowName;
BOOLEAN WindowMatches;
BOOLEAN ClassMatches;
if(ChildAfter)
{
/* skip handles before and including ChildAfter */
- while(*phWnd && (*(phWnd++) != ChildAfter->hSelf))
+ while(*phWnd && (*(phWnd++) != ChildAfter->head.h))
;
}
/* search children */
while(*phWnd)
{
+ UNICODE_STRING ustr;
+
if(!(TopLevelWindow = UserGetWindowObject(*(phWnd++))))
{
continue;
/* Do not send WM_GETTEXT messages in the kernel mode version!
The user mode version however calls GetWindowText() which will
send WM_GETTEXT messages to windows belonging to its processes */
- WindowMatches = !CheckWindowName || !RtlCompareUnicodeString(
- &WindowName, &TopLevelWindow->Wnd->strName, TRUE);
+ ustr.Buffer = TopLevelWindow->strName.Buffer;
+ ustr.Length = TopLevelWindow->strName.Length;
+ ustr.MaximumLength = TopLevelWindow->strName.MaximumLength;
+ WindowMatches = !CheckWindowName ||
+ (TopLevelWindow->strName.Length < 0xFFFF &&
+ !RtlCompareUnicodeString(&WindowName, &ustr, TRUE));
ClassMatches = (ClassAtom == (RTL_ATOM)0) ||
- ClassAtom == TopLevelWindow->Wnd->pcls->atomClassName;
+ ClassAtom == TopLevelWindow->pcls->atomClassName;
if (WindowMatches && ClassMatches)
{
- Ret = TopLevelWindow->hSelf;
+ Ret = TopLevelWindow->head.h;
break;
}
{
/* window returns the handle of the top-level window, in case it found
the child window */
- Ret = TopLevelWindow->hSelf;
+ Ret = TopLevelWindow->head.h;
break;
}
/* FIXME - if both hwndParent and hwndChildAfter are NULL, we also should
search the message-only windows. Should this also be done if
Parent is the desktop window??? */
- PWINDOW_OBJECT MsgWindows;
+ PWND MsgWindows;
if((MsgWindows = UserGetWindowObject(IntGetMessageWindow())))
{
/*
* @implemented
*/
-PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
+PWND FASTCALL UserGetAncestor(PWND Wnd, UINT Type)
{
- PWINDOW_OBJECT WndAncestor, Parent;
+ PWND WndAncestor, Parent;
- if (Wnd->hSelf == IntGetDesktopWindow())
+ if (Wnd->head.h == IntGetDesktopWindow())
{
return NULL;
}
for (;;)
{
- PWINDOW_OBJECT Parent, Old;
+ PWND Parent;
- Old = WndAncestor;
Parent = IntGetParent(WndAncestor);
if (!Parent)
break;
}
- //temp hack
-// UserDereferenceObject(Parent);
-
WndAncestor = Parent;
}
break;
HWND APIENTRY
NtUserGetAncestor(HWND hWnd, UINT Type)
{
- PWINDOW_OBJECT Window, Ancestor;
+ PWND Window, Ancestor;
DECLARE_RETURN(HWND);
DPRINT("Enter NtUserGetAncestor\n");
Ancestor = UserGetAncestor(Window, Type);
/* faxme: can UserGetAncestor ever return NULL for a valid window? */
- RETURN(Ancestor ? Ancestor->hSelf : NULL);
+ RETURN(Ancestor ? Ancestor->head.h : NULL);
CLEANUP:
DPRINT("Leave NtUserGetAncestor, ret=%i\n",_ret_);
HWND hWnd,
PCOMBOBOXINFO pcbi)
{
- PWINDOW_OBJECT Wnd;
+ PWND Wnd;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserGetComboBoxInfo\n");
_SEH2_END;
// Pass the user pointer, it was already probed.
- RETURN( (BOOL) co_IntSendMessage( Wnd->hSelf, CB_GETCOMBOBOXINFO, 0, (LPARAM)pcbi));
+ RETURN( (BOOL) co_IntSendMessage( Wnd->head.h, CB_GETCOMBOBOXINFO, 0, (LPARAM)pcbi));
CLEANUP:
DPRINT("Leave NtUserGetComboBoxInfo, ret=%i\n",_ret_);
LPRECT rectWnd,
LPPOINT ptIcon)
{
- PWINDOW_OBJECT Window;
- PWND Wnd;
+ PWND Window;
DWORD Ret = 0;
BOOL Hit = FALSE;
WINDOWPLACEMENT wndpl;
UserEnterShared();
- if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
+ if (!(Window = UserGetWindowObject(hWnd)))
{
Hit = FALSE;
goto Exit;
}
- Wnd = Window->Wnd;
_SEH2_TRY
{
NtUserGetListBoxInfo(
HWND hWnd)
{
- PWINDOW_OBJECT Wnd;
+ PWND Wnd;
DECLARE_RETURN(DWORD);
DPRINT("Enter NtUserGetListBoxInfo\n");
RETURN( 0 );
}
- RETURN( (DWORD) co_IntSendMessage( Wnd->hSelf, LB_GETLISTBOXINFO, 0, 0 ));
+ RETURN( (DWORD) co_IntSendMessage( Wnd->head.h, LB_GETLISTBOXINFO, 0, 0 ));
CLEANUP:
DPRINT("Leave NtUserGetListBoxInfo, ret=%i\n",_ret_);
HWND FASTCALL
co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
{
- PWINDOW_OBJECT Wnd = NULL, WndParent = NULL, WndOldParent;
+ PWND Wnd = NULL, WndParent = NULL, WndOldParent;
HWND hWndOldParent = NULL;
USER_REFERENCE_ENTRY Ref, ParentRef;
if (WndOldParent)
{
- hWndOldParent = WndOldParent->hSelf;
+ hWndOldParent = WndOldParent->head.h;
UserDereferenceObject(WndOldParent);
}
NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
{
PWINSTATION_OBJECT WinStaObject;
- PWINDOW_OBJECT WndShell;
+ PWND WndShell, WndListView;
DECLARE_RETURN(BOOL);
USER_REFERENCE_ENTRY Ref;
NTSTATUS Status;
RETURN(FALSE);
}
+ if(!(WndListView = UserGetWindowObject(hwndListView)))
+ {
+ RETURN(FALSE);
+ }
+
Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
KernelMode,
0,
co_WinPosSetWindowPos(hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
#endif
- if (UserGetWindowLong(hwndListView, GWL_EXSTYLE, FALSE) & WS_EX_TOPMOST)
+ if (WndListView->ExStyle & WS_EX_TOPMOST)
{
ObDereferenceObject(WinStaObject);
RETURN( FALSE);
}
}
- if (UserGetWindowLong(hwndShell, GWL_EXSTYLE, FALSE) & WS_EX_TOPMOST)
+ if (WndShell->ExStyle & WS_EX_TOPMOST)
{
ObDereferenceObject(WinStaObject);
RETURN( FALSE);
HMENU APIENTRY
NtUserGetSystemMenu(HWND hWnd, BOOL bRevert)
{
- PWINDOW_OBJECT Window;
+ PWND Window;
PMENU_OBJECT Menu;
DECLARE_RETURN(HMENU);
NtUserSetSystemMenu(HWND hWnd, HMENU hMenu)
{
BOOL Result = FALSE;
- PWINDOW_OBJECT Window;
+ PWND Window;
PMENU_OBJECT Menu;
DECLARE_RETURN(BOOL);
END_CLEANUP;
}
-HWND FASTCALL
-UserGetWindow(HWND hWnd, UINT Relationship)
-{
- PWINDOW_OBJECT Parent, Window;
- HWND hWndResult = NULL;
-
- if (!(Window = UserGetWindowObject(hWnd)))
- return NULL;
-
- switch (Relationship)
- {
- case GW_HWNDFIRST:
- if((Parent = Window->spwndParent))
- {
- if (Parent->spwndChild)
- hWndResult = Parent->spwndChild->hSelf;
- }
- break;
-
- case GW_HWNDLAST:
- if((Parent = Window->spwndParent))
- {
- if (Parent->spwndChild)
- {
- Window = Parent->spwndChild;
- if(Window)
- {
- while(Window->spwndNext)
- Window = Window->spwndNext;
- }
- hWndResult = Window->hSelf;
- }
- }
- break;
-
- case GW_HWNDNEXT:
- if (Window->spwndNext)
- hWndResult = Window->spwndNext->hSelf;
- break;
-
- case GW_HWNDPREV:
- if (Window->spwndPrev)
- hWndResult = Window->spwndPrev->hSelf;
- break;
-
- case GW_OWNER:
- if((Parent = UserGetWindowObject(Window->hOwner)))
- {
- hWndResult = Parent->hSelf;
- }
- break;
- case GW_CHILD:
- if (Window->spwndChild)
- hWndResult = Window->spwndChild->hSelf;
- break;
- }
-
- return hWndResult;
-}
-
-/*
- * NtUserGetWindowLong
- *
- * The NtUserGetWindowLong function retrieves information about the specified
- * window. The function also retrieves the 32-bit (long) value at the
- * specified offset into the extra window memory.
- *
- * Status
- * @implemented
- */
-
-LONG FASTCALL
-UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
-{
- PWINDOW_OBJECT Window, Parent;
- PWND Wnd;
- LONG Result = 0;
-
- DPRINT("NtUserGetWindowLong(%x,%d,%d)\n", hWnd, (INT)Index, Ansi);
-
- if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
- {
- return 0;
- }
-
- Wnd = Window->Wnd;
-
- /*
- * WndProc is only available to the owner process
- */
- if (GWL_WNDPROC == Index
- && Window->pti->pEThread->ThreadsProcess != PsGetCurrentProcess())
- {
- SetLastWin32Error(ERROR_ACCESS_DENIED);
- return 0;
- }
-
- if ((INT)Index >= 0)
- {
- if ((Index + sizeof(LONG)) > Window->Wnd->cbwndExtra)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
- Result = *((LONG *)((PCHAR)(Window->Wnd + 1) + Index));
- }
- else
- {
- switch (Index)
- {
- case GWL_EXSTYLE:
- Result = Wnd->ExStyle;
- break;
-
- case GWL_STYLE:
- Result = Wnd->style;
- break;
-
- case GWL_WNDPROC:
- Result = (LONG)IntGetWindowProc(Wnd, Ansi);
- break;
-
- case GWL_HINSTANCE:
- Result = (LONG) Wnd->hModule;
- break;
-
- case GWL_HWNDPARENT:
- Parent = Window->spwndParent;
- if(Parent)
- {
- if (Parent && Parent->hSelf == IntGetDesktopWindow())
- Result = (LONG) UserGetWindow(Window->hSelf, GW_OWNER);
- else
- Result = (LONG) Parent->hSelf;
- }
- break;
-
- case GWL_ID:
- Result = (LONG) Wnd->IDMenu;
- break;
-
- case GWL_USERDATA:
- Result = Wnd->dwUserData;
- break;
-
- default:
- DPRINT1("NtUserGetWindowLong(): Unsupported index %d\n", Index);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- Result = 0;
- break;
- }
- }
-
- return Result;
-}
-
LONG FASTCALL
co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
{
- PWINDOW_OBJECT Window, Parent;
- PWND Wnd;
+ PWND Window, Parent;
PWINSTATION_OBJECT WindowStation;
LONG OldValue;
STYLESTRUCT Style;
return( 0);
}
- Wnd = Window->Wnd;
-
- if (!Wnd) return 0; // No go on zero.
-
if ((INT)Index >= 0)
{
- if ((Index + sizeof(LONG)) > Wnd->cbwndExtra)
+ if ((Index + sizeof(LONG)) > Window->cbwndExtra)
{
SetLastWin32Error(ERROR_INVALID_INDEX);
return( 0);
}
- OldValue = *((LONG *)((PCHAR)(Wnd + 1) + Index));
+ OldValue = *((LONG *)((PCHAR)(Window + 1) + Index));
/*
if ( Index == DWLP_DLGPROC && Wnd->state & WNDS_DIALOGWINDOW)
{
if (!OldValue) return 0;
}
*/
- *((LONG *)((PCHAR)(Wnd + 1) + Index)) = NewValue;
+ *((LONG *)((PCHAR)(Window + 1) + Index)) = NewValue;
}
else
{
switch (Index)
{
case GWL_EXSTYLE:
- OldValue = (LONG) Wnd->ExStyle;
+ OldValue = (LONG) Window->ExStyle;
Style.styleOld = OldValue;
Style.styleNew = NewValue;
/*
* Remove extended window style bit WS_EX_TOPMOST for shell windows.
*/
- WindowStation = Window->pti->rpdesk->rpwinstaParent;
+ WindowStation = Window->head.pti->rpdesk->rpwinstaParent;
if(WindowStation)
{
if (hWnd == WindowStation->ShellWindow || hWnd == WindowStation->ShellListView)
}
co_IntSendMessage(hWnd, WM_STYLECHANGING, GWL_EXSTYLE, (LPARAM) &Style);
- Wnd->ExStyle = (DWORD)Style.styleNew;
+ Window->ExStyle = (DWORD)Style.styleNew;
co_IntSendMessage(hWnd, WM_STYLECHANGED, GWL_EXSTYLE, (LPARAM) &Style);
break;
case GWL_STYLE:
- OldValue = (LONG) Wnd->style;
+ OldValue = (LONG) Window->style;
Style.styleOld = OldValue;
Style.styleNew = NewValue;
co_IntSendMessage(hWnd, WM_STYLECHANGING, GWL_STYLE, (LPARAM) &Style);
- Wnd->style = (DWORD)Style.styleNew;
+ Window->style = (DWORD)Style.styleNew;
co_IntSendMessage(hWnd, WM_STYLECHANGED, GWL_STYLE, (LPARAM) &Style);
break;
case GWL_WNDPROC:
{
- if ( Wnd->head.pti->ppi != PsGetCurrentProcessWin32Process() ||
- Wnd->fnid & FNID_FREED)
+ if ( Window->head.pti->ppi != PsGetCurrentProcessWin32Process() ||
+ Window->fnid & FNID_FREED)
{
SetLastWin32Error(ERROR_ACCESS_DENIED);
return( 0);
}
- OldValue = (LONG)IntSetWindowProc(Wnd,
+ OldValue = (LONG)IntSetWindowProc(Window,
(WNDPROC)NewValue,
Ansi);
break;
}
case GWL_HINSTANCE:
- OldValue = (LONG) Wnd->hModule;
- Wnd->hModule = (HINSTANCE) NewValue;
+ OldValue = (LONG) Window->hModule;
+ Window->hModule = (HINSTANCE) NewValue;
break;
case GWL_HWNDPARENT:
Parent = Window->spwndParent;
- if (Parent && (Parent->hSelf == IntGetDesktopWindow()))
- OldValue = (LONG) IntSetOwner(Window->hSelf, (HWND) NewValue);
+ if (Parent && (Parent->head.h == IntGetDesktopWindow()))
+ OldValue = (LONG) IntSetOwner(Window->head.h, (HWND) NewValue);
else
- OldValue = (LONG) co_UserSetParent(Window->hSelf, (HWND) NewValue);
+ OldValue = (LONG) co_UserSetParent(Window->head.h, (HWND) NewValue);
break;
case GWL_ID:
- OldValue = (LONG) Wnd->IDMenu;
- Wnd->IDMenu = (UINT) NewValue;
+ OldValue = (LONG) Window->IDMenu;
+ Window->IDMenu = (UINT) NewValue;
break;
case GWL_USERDATA:
- OldValue = Wnd->dwUserData;
- Wnd->dwUserData = NewValue;
+ OldValue = Window->dwUserData;
+ Window->dwUserData = NewValue;
break;
default:
WORD APIENTRY
NtUserSetWindowWord(HWND hWnd, INT Index, WORD NewValue)
{
- PWINDOW_OBJECT Window;
+ PWND Window;
WORD OldValue;
DECLARE_RETURN(WORD);
case GWL_ID:
case GWL_HINSTANCE:
case GWL_HWNDPARENT:
- RETURN( co_UserSetWindowLong(Window->hSelf, Index, (UINT)NewValue, TRUE));
+ RETURN( co_UserSetWindowLong(Window->head.h, Index, (UINT)NewValue, TRUE));
default:
if (Index < 0)
{
}
}
- if (Index > Window->Wnd->cbwndExtra - sizeof(WORD))
+ if (Index > Window->cbwndExtra - sizeof(WORD))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
RETURN( 0);
}
- OldValue = *((WORD *)((PCHAR)(Window->Wnd + 1) + Index));
- *((WORD *)((PCHAR)(Window->Wnd + 1) + Index)) = NewValue;
+ OldValue = *((WORD *)((PCHAR)(Window + 1) + Index));
+ *((WORD *)((PCHAR)(Window + 1) + Index)) = NewValue;
RETURN( OldValue);
NtUserGetWindowPlacement(HWND hWnd,
WINDOWPLACEMENT *lpwndpl)
{
- PWINDOW_OBJECT Window;
PWND Wnd;
POINT Size;
WINDOWPLACEMENT Safepl;
DPRINT("Enter NtUserGetWindowPlacement\n");
UserEnterShared();
- if (!(Window = UserGetWindowObject(hWnd)))
+ if (!(Wnd = UserGetWindowObject(hWnd)))
{
RETURN( FALSE);
}
- Wnd = Window->Wnd;
Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT));
if(!NT_SUCCESS(Status))
{
Safepl.showCmd = SW_HIDE;
}
- else if ((0 != (Window->state & WINDOWOBJECT_RESTOREMAX) ||
+ else if ((0 != (Wnd->state2 & WNDS2_MAXIMIZEBUTTONDOWN) ||
0 != (Wnd->style & WS_MAXIMIZE)) &&
0 == (Wnd->style & WS_MINIMIZE))
{
Size.x = Wnd->rcWindow.left;
Size.y = Wnd->rcWindow.top;
- WinPosInitInternalPos(Window, &Size,
+ WinPosInitInternalPos(Wnd, &Size,
&Wnd->rcWindow);
Safepl.rcNormalPosition = Wnd->InternalPos.NormalRect;
DWORD APIENTRY
NtUserQueryWindow(HWND hWnd, DWORD Index)
{
- PWINDOW_OBJECT Window;
PWND pWnd;
DWORD Result;
DECLARE_RETURN(UINT);
DPRINT("Enter NtUserQueryWindow\n");
UserEnterShared();
- if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
+ if (!(pWnd = UserGetWindowObject(hWnd)))
{
RETURN( 0);
}
- pWnd = Window->Wnd;
-
switch(Index)
{
case QUERY_WINDOW_UNIQUE_PROCESS_ID:
- Result = (DWORD)IntGetWndProcessId(Window);
+ Result = (DWORD)IntGetWndProcessId(pWnd);
break;
case QUERY_WINDOW_UNIQUE_THREAD_ID:
- Result = (DWORD)IntGetWndThreadId(Window);
+ Result = (DWORD)IntGetWndThreadId(pWnd);
break;
case QUERY_WINDOW_ACTIVE:
break;
case QUERY_WINDOW_ISHUNG:
- Result = (DWORD)MsqIsHung(Window->pti->MessageQueue);
+ Result = (DWORD)MsqIsHung(pWnd->head.pti->MessageQueue);
break;
case QUERY_WINDOW_REAL_ID:
}
Ret = (UINT)IntAddAtom(SafeMessageName.Buffer);
-
- ExFreePoolWithTag(SafeMessageName.Buffer, TAG_STRING);
+ if (SafeMessageName.Buffer)
+ ExFreePoolWithTag(SafeMessageName.Buffer, TAG_STRING);
RETURN( Ret);
CLEANUP:
HMENU Menu,
BOOL Repaint)
{
- PWINDOW_OBJECT Window;
+ PWND Window;
BOOL Changed;
DECLARE_RETURN(BOOL);
NtUserSetWindowFNID(HWND hWnd,
WORD fnID)
{
- PWINDOW_OBJECT Window;
PWND Wnd;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserSetWindowFNID\n");
UserEnterExclusive();
- if (!(Window = UserGetWindowObject(hWnd)))
+ if (!(Wnd = UserGetWindowObject(hWnd)))
{
RETURN( FALSE);
}
- Wnd = Window->Wnd;
if (Wnd->pcls)
{ // From user land we only set these.
NtUserSetWindowPlacement(HWND hWnd,
WINDOWPLACEMENT *lpwndpl)
{
- PWINDOW_OBJECT Window;
PWND Wnd;
WINDOWPLACEMENT Safepl;
NTSTATUS Status;
DPRINT("Enter NtUserSetWindowPlacement\n");
UserEnterExclusive();
- if (!(Window = UserGetWindowObject(hWnd)))
+ if (!(Wnd = UserGetWindowObject(hWnd)))
{
RETURN( FALSE);
}
- Wnd = Window->Wnd;
Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT));
if(!NT_SUCCESS(Status))
RETURN( FALSE);
}
- UserRefObjectCo(Window, &Ref);
+ UserRefObjectCo(Wnd, &Ref);
if ((Wnd->style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0)
{
- co_WinPosSetWindowPos(Window, NULL,
+ co_WinPosSetWindowPos(Wnd, NULL,
Safepl.rcNormalPosition.left, Safepl.rcNormalPosition.top,
Safepl.rcNormalPosition.right - Safepl.rcNormalPosition.left,
Safepl.rcNormalPosition.bottom - Safepl.rcNormalPosition.top,
}
/* FIXME - change window status */
- co_WinPosShowWindow(Window, Safepl.showCmd);
+ co_WinPosShowWindow(Wnd, Safepl.showCmd);
Wnd->InternalPosInitialized = TRUE;
Wnd->InternalPos.NormalRect = Safepl.rcNormalPosition;
Wnd->InternalPos.IconPos = Safepl.ptMinPosition;
Wnd->InternalPos.MaxPos = Safepl.ptMaxPosition;
- UserDerefObjectCo(Window);
+ UserDerefObjectCo(Wnd);
RETURN(TRUE);
CLEANUP:
UINT uFlags)
{
DECLARE_RETURN(BOOL);
- PWINDOW_OBJECT Window;
+ PWND Window;
BOOL ret;
USER_REFERENCE_ENTRY Ref;
INT FASTCALL
-IntGetWindowRgn(PWINDOW_OBJECT Window, HRGN hRgn)
+IntGetWindowRgn(PWND Window, HRGN hRgn)
{
INT Ret;
HRGN VisRgn;
ROSRGNDATA *pRgn;
- PWND Wnd;
if(!Window)
{
return ERROR;
}
- Wnd = Window->Wnd;
-
/* Create a new window region using the window rectangle */
- VisRgn = IntSysCreateRectRgnIndirect(&Window->Wnd->rcWindow);
- NtGdiOffsetRgn(VisRgn, -Window->Wnd->rcWindow.left, -Window->Wnd->rcWindow.top);
+ VisRgn = IntSysCreateRectRgnIndirect(&Window->rcWindow);
+ NtGdiOffsetRgn(VisRgn, -Window->rcWindow.left, -Window->rcWindow.top);
/* if there's a region assigned to the window, combine them both */
- if(Window->hrgnClip && !(Wnd->style & WS_MINIMIZE))
+ if(Window->hrgnClip && !(Window->style & WS_MINIMIZE))
NtGdiCombineRgn(VisRgn, VisRgn, Window->hrgnClip, RGN_AND);
/* Copy the region into hRgn */
NtGdiCombineRgn(hRgn, VisRgn, NULL, RGN_COPY);
if((pRgn = RGNOBJAPI_Lock(hRgn, NULL)))
{
- Ret = pRgn->rdh.iType;
+ Ret = REGION_Complexity(pRgn);
RGNOBJAPI_Unlock(pRgn);
}
else
}
INT FASTCALL
-IntGetWindowRgnBox(PWINDOW_OBJECT Window, RECTL *Rect)
+IntGetWindowRgnBox(PWND Window, RECTL *Rect)
{
INT Ret;
HRGN VisRgn;
ROSRGNDATA *pRgn;
- PWND Wnd;
if(!Window)
{
return ERROR;
}
- Wnd = Window->Wnd;
-
/* Create a new window region using the window rectangle */
- VisRgn = IntSysCreateRectRgnIndirect(&Window->Wnd->rcWindow);
- NtGdiOffsetRgn(VisRgn, -Window->Wnd->rcWindow.left, -Window->Wnd->rcWindow.top);
+ VisRgn = IntSysCreateRectRgnIndirect(&Window->rcWindow);
+ NtGdiOffsetRgn(VisRgn, -Window->rcWindow.left, -Window->rcWindow.top);
/* if there's a region assigned to the window, combine them both */
- if(Window->hrgnClip && !(Wnd->style & WS_MINIMIZE))
+ if(Window->hrgnClip && !(Window->style & WS_MINIMIZE))
NtGdiCombineRgn(VisRgn, VisRgn, Window->hrgnClip, RGN_AND);
if((pRgn = RGNOBJAPI_Lock(VisRgn, NULL)))
{
- Ret = pRgn->rdh.iType;
+ Ret = REGION_Complexity(pRgn);
*Rect = pRgn->rdh.rcBound;
RGNOBJAPI_Unlock(pRgn);
}
BOOL bRedraw)
{
HRGN hrgnCopy;
- PWINDOW_OBJECT Window;
+ PWND Window;
DECLARE_RETURN(INT);
DPRINT("Enter NtUserSetWindowRgn\n");
BOOL APIENTRY
NtUserShowWindow(HWND hWnd, LONG nCmdShow)
{
- PWINDOW_OBJECT Window;
+ PWND Window;
BOOL ret;
DECLARE_RETURN(BOOL);
USER_REFERENCE_ENTRY Ref;
{
POINT pt;
HWND Ret;
- PWINDOW_OBJECT DesktopWindow = NULL, Window = NULL;
+ PWND DesktopWindow = NULL, Window = NULL;
DECLARE_RETURN(HWND);
USER_REFERENCE_ENTRY Ref;
if ((DesktopWindow = UserGetWindowObject(IntGetDesktopWindow())))
{
PTHREADINFO pti;
- USHORT Hit;
pt.x = X;
pt.y = Y;
UserRefObjectCo(DesktopWindow, &Ref);
pti = PsGetCurrentThreadWin32Thread();
- Hit = co_WinPosWindowFromPoint(DesktopWindow, pti->MessageQueue, &pt, &Window);
+ co_WinPosWindowFromPoint(DesktopWindow, pti->MessageQueue, &pt, &Window);
if(Window)
{
- Ret = Window->hSelf;
+ Ret = Window->head.h;
RETURN( Ret);
}
BOOL APIENTRY
NtUserDefSetText(HWND hWnd, PLARGE_STRING WindowText)
{
- PWINDOW_OBJECT Window;
PWND Wnd;
LARGE_STRING SafeText;
UNICODE_STRING UnicodeString;
UserEnterExclusive();
- if(!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
+ if(!(Wnd = UserGetWindowObject(hWnd)))
{
UserLeave();
return FALSE;
}
- Wnd = Window->Wnd;
// ReactOS uses Unicode and not mixed. Up/Down converting will take time.
// Brought to you by: The Wine Project! Dysfunctional Thought Processes!
// In User32, these are called after: NotifyWinEvent EVENT_OBJECT_NAMECHANGE than
// RepaintButton, StaticRepaint, NtUserCallHwndLock HWNDLOCK_ROUTINE_REDRAWFRAMEANDHOOK, etc.
/* Send shell notifications */
- if (!IntGetOwner(Window) && !IntGetParent(Window))
+ if (!Wnd->spwndOwner && !IntGetParent(Wnd))
{
co_IntShellHookNotify(HSHELL_REDRAW, (LPARAM) hWnd);
}
INT APIENTRY
NtUserInternalGetWindowText(HWND hWnd, LPWSTR lpString, INT nMaxCount)
{
- PWINDOW_OBJECT Window;
PWND Wnd;
NTSTATUS Status;
INT Result;
RETURN( 0);
}
- if(!(Window = UserGetWindowObject(hWnd)))
+ if(!(Wnd = UserGetWindowObject(hWnd)))
{
RETURN( 0);
}
- Wnd = Window->Wnd;
Result = Wnd->strName.Length / sizeof(WCHAR);
if(lpString)
BOOL
FASTCALL
-IntShowOwnedPopups(PWINDOW_OBJECT OwnerWnd, BOOL fShow )
+IntShowOwnedPopups(PWND OwnerWnd, BOOL fShow )
{
int count = 0;
- PWINDOW_OBJECT pWnd;
+ PWND pWnd;
HWND *win_array;
// ASSERT(OwnerWnd);
count++;
while (--count >= 0)
{
- if (UserGetWindow( win_array[count], GW_OWNER ) != OwnerWnd->hSelf)
- continue;
if (!(pWnd = UserGetWindowObject( win_array[count] )))
continue;
- // if (pWnd == WND_OTHER_PROCESS) continue;
+ if (pWnd->spwndOwner != OwnerWnd)
+ continue;
if (fShow)
{
- if (pWnd->Wnd->state & WNDS_HIDDENPOPUP)
+ if (pWnd->state & WNDS_HIDDENPOPUP)
{
/* In Windows, ShowOwnedPopups(TRUE) generates
* WM_SHOWWINDOW messages with SW_PARENTOPENING,
}
else
{
- if (pWnd->Wnd->style & WS_VISIBLE)
+ if (pWnd->style & WS_VISIBLE)
{
/* In Windows, ShowOwnedPopups(FALSE) generates
* WM_SHOWWINDOW messages with SW_PARENTCLOSING,
{
case otWindow:
{
- PWINDOW_OBJECT Window;
+ PWND Window;
if ((Window = UserGetWindowObject((HWND) handle))) return TRUE;
return FALSE;
}