/* INCLUDES ******************************************************************/
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
-
-/* dialog resources appear to pass this in 16 bits, handle them properly */
-#define CW_USEDEFAULT16 (0x8000)
-
#define POINT_IN_RECT(p, r) (((r.bottom >= p.y) && (r.top <= p.y))&&((r.left <= p.x )&&( r.right >= p.x )))
/* PRIVATE FUNCTIONS **********************************************************/
* Initialize windowing implementation.
*/
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitWindowImpl(VOID)
{
return STATUS_SUCCESS;
if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
switch (Action)
{
case UIS_INITIALIZE:
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
case UIS_SET:
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;
-
- if (PsGetCurrentProcess() != PsInitialSystemProcess)
- {
- ti = GetW32ThreadInfo();
- if (ti == NULL)
- {
- SetLastWin32Error(ERROR_ACCESS_DENIED);
- return NULL;
- }
- }
+ PWND Window;
if (!hWnd)
{
- SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
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);
+ EngSetLastError(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)
+BOOL
+FASTCALL
+IntEnableWindow( HWND hWnd, BOOL bEnable )
{
- return UserGetWindowObject(Wnd->hOwner);
-}
+ BOOL Update;
+ PWND pWnd;
+ UINT bIsDisabled;
+
+ if(!(pWnd = UserGetWindowObject(hWnd)))
+ {
+ return FALSE;
+ }
+
+ /* check if updating is needed */
+ bIsDisabled = (pWnd->style & WS_DISABLED);
+ Update = bIsDisabled;
+
+ if (bEnable)
+ {
+ pWnd->style &= ~WS_DISABLED;
+ }
+ else
+ {
+ Update = !bIsDisabled;
+
+ co_IntSendMessage( hWnd, WM_CANCELMODE, 0, 0);
+ /* Remove keyboard focus from that window if it had focus */
+ if (hWnd == IntGetThreadFocusWindow())
+ {
+ co_UserSetFocus(NULL);
+ }
+ pWnd->style |= WS_DISABLED;
+ }
+ if (Update)
+ {
+ IntNotifyWinEvent(EVENT_OBJECT_STATECHANGE, pWnd, OBJID_WINDOW, CHILDID_SELF, 0);
+ co_IntSendMessage(hWnd, WM_ENABLE, (LPARAM)bEnable, 0);
+ }
+ // Return nonzero if it was disabled, or zero if it wasn't:
+ return bIsDisabled;
+}
/*
* 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; Child; Child = Child->spwndNext)
++NumChildren;
- List = ExAllocatePoolWithTag(PagedPool, (NumChildren + 1) * sizeof(HWND), TAG_WINLIST);
+ List = ExAllocatePoolWithTag(PagedPool, (NumChildren + 1) * sizeof(HWND), USERTAG_WINDOWLIST);
if(!List)
{
DPRINT1("Failed to allocate memory for children array\n");
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
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);
+
+ /* Unregister hot keys */
+ UnregisterWindowHotKeys (Window);
/* flush the message queue */
MsqRemoveWindowMessagesFromQueue(Window);
+ IntDereferenceMessageQueue(Window->head.pti->MessageQueue);
+
/* 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;
}
- /* Unregister hot keys */
- UnregisterWindowHotKeys (Window);
-
/* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
#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|WS_POPUP)) != 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)
{
+ IntGdiSetRegionOwner(Window->hrgnClip, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(Window->hrgnClip);
+ Window->hrgnClip = NULL;
}
- 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);
return Ret;
}
-// Move this to user space!
-BOOL FASTCALL
-IntGetWindowInfo(PWINDOW_OBJECT Window, PWINDOWINFO pwi)
-{
- PWND Wnd = Window->Wnd;
-
- pwi->cbSize = sizeof(WINDOWINFO);
- pwi->rcWindow = Window->Wnd->rcWindow;
- pwi->rcClient = Window->Wnd->rcClient;
- pwi->dwStyle = Wnd->style;
- pwi->dwExStyle = Wnd->ExStyle;
- pwi->dwWindowStatus = (UserGetForegroundWindow() == Window->hSelf); /* WS_ACTIVECAPTION */
- IntGetWindowBorderMeasures(Window, &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)
{
- SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
return FALSE;
}
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
{
{
IntReleaseMenuObject(OldMenu);
}
- SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
+ EngSetLastError(ERROR_INVALID_MENU_HANDLE);
return FALSE;
}
if (NULL != NewMenu->MenuInfo.Wnd)
{
IntReleaseMenuObject(OldMenu);
}
- SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
+ EngSetLastError(ERROR_INVALID_MENU_HANDLE);
return FALSE;
}
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;
}
-#if 0
-HWND FASTCALL
-IntGetFocusWindow(VOID)
-{
- PUSER_MESSAGE_QUEUE Queue;
- PDESKTOP pdo = IntGetActiveDesktop();
-
- if( !pdo )
- return NULL;
-
- Queue = (PUSER_MESSAGE_QUEUE)pdo->ActiveMessageQueue;
-
- if (Queue == NULL)
- return(NULL);
- else
- return(Queue->FocusWindow);
-}
-#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)
+ while (Window && ((Window->style & (WS_POPUP|WS_CHILD)) == WS_CHILD))
{
- Wnd = Window->Wnd;
if (Window == Parent)
{
return(TRUE);
}
- if(!(Wnd->style & WS_CHILD))
- {
- break;
- }
Window = Window->spwndParent;
}
}
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 */
- 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;
- }
- }
+ if (hWndPrev == HWND_BOTTOM)
+ {
+ /* Link in the bottom of the list */
+ PWND WndInsertAfter;
+
+ 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, pWndExam;
BOOL WasVisible;
ASSERT(Wnd);
ASSERT_REFS_CO(Wnd);
ASSERT_REFS_CO(WndNewParent);
-// hWnd = Wnd->hSelf;
-// hWndNewParent = WndNewParent->hSelf;
+ if (Wnd == Wnd->head.rpdesk->spwndMessage)
+ {
+ EngSetLastError(ERROR_ACCESS_DENIED);
+ return( NULL);
+ }
/* Some applications try to set a child as a parent */
if (IntIsChildWindow(Wnd, WndNewParent))
{
- SetLastWin32Error( ERROR_INVALID_PARAMETER );
+ EngSetLastError( ERROR_INVALID_PARAMETER );
return NULL;
}
+ pWndExam = WndNewParent; // Load parent Window to examine.
+ // Now test for set parent to parent hit.
+ while (pWndExam)
+ {
+ if (Wnd == pWndExam)
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+ pWndExam = pWndExam->spwndParent;
+ }
+
/*
* Windows hides the window first, then shows it again
* including the WM_SHOWWINDOW messages and all
*/
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;
+}
+
+HWND FASTCALL
+co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
+{
+ PWND Wnd = NULL, WndParent = NULL, WndOldParent;
+ HWND hWndOldParent = NULL;
+ USER_REFERENCE_ENTRY Ref, ParentRef;
+
+ if (IntIsBroadcastHwnd(hWndChild) || IntIsBroadcastHwnd(hWndNewParent))
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return( NULL);
+ }
+
+ if (hWndChild == IntGetDesktopWindow())
+ {
+ EngSetLastError(ERROR_ACCESS_DENIED);
+ return( NULL);
+ }
+
+ if (hWndNewParent)
+ {
+ if (!(WndParent = UserGetWindowObject(hWndNewParent)))
+ {
+ return( NULL);
+ }
+ }
+ else
+ {
+ if (!(WndParent = UserGetWindowObject(IntGetDesktopWindow())))
+ {
+ return( NULL);
+ }
+ }
+
+ if (!(Wnd = UserGetWindowObject(hWndChild)))
+ {
+ return( NULL);
+ }
+
+ UserRefObjectCo(Wnd, &Ref);
+ UserRefObjectCo(WndParent, &ParentRef);
+
+ WndOldParent = co_IntSetParent(Wnd, WndParent);
+
+ UserDerefObjectCo(WndParent);
+ UserDerefObjectCo(Wnd);
+
+ if (WndOldParent)
+ {
+ hWndOldParent = WndOldParent->head.h;
+ UserDereferenceObject(WndOldParent);
+ }
+
+ return( hWndOldParent);
}
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. */
-VOID FASTCALL
-IntUnlinkWnd(PWND Wnd)
-{
- if (Wnd->spwndNext)
- Wnd->spwndNext->spwndPrev = Wnd->spwndPrev;
-
- if (Wnd->spwndPrev)
- Wnd->spwndPrev->spwndNext = Wnd->spwndNext;
-
- if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd)
- Wnd->spwndParent->spwndChild = Wnd->spwndNext;
-
- Wnd->spwndPrev = Wnd->spwndNext = Wnd->spwndParent = NULL;
-}
-
-
-/* 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
-IntUnlinkWindow(PWINDOW_OBJECT Wnd)
+IntUnlinkWindow(PWND Wnd)
{
- PWINDOW_OBJECT WndParent = Wnd->spwndParent;
-
- IntUnlinkWnd(Wnd->Wnd);
-
if (Wnd->spwndNext)
- Wnd->spwndNext->spwndPrev = Wnd->spwndPrev;
+ 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;
- }
- }
+ Wnd->spwndPrev->spwndNext = Wnd->spwndNext;
- return FALSE;
-}
+ if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd)
+ Wnd->spwndParent->spwndChild = Wnd->spwndNext;
-BOOL FASTCALL
-IntIsWindowInDestroy(PWINDOW_OBJECT Window)
-{
- return ((Window->state & WINDOWSTATUS_DESTROYING) == WINDOWSTATUS_DESTROYING);
+ 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;
/* FUNCTIONS *****************************************************************/
-/*
- * @unimplemented
- */
-DWORD APIENTRY
-NtUserAlterWindowStyle(DWORD Unknown0,
- DWORD Unknown1,
- DWORD Unknown2)
-{
- UNIMPLEMENTED
-
- return(0);
-}
-
/*
* As best as I can figure, this function is used by EnumWindows,
* EnumChildWindows, EnumDesktopWindows, & EnumThreadWindows.
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)
ObDereferenceObject(Desktop);
}
}
- else
+ else // Build EnumThreadWindows list!
{
PETHREAD Thread;
PTHREADINFO W32Thread;
PLIST_ENTRY Current;
- PWINDOW_OBJECT Window;
+ PWND Window;
Status = PsLookupThreadByThreadId((HANDLE)dwThreadId, &Thread);
- if(!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
+ DPRINT1("Thread Id is not valid!\n");
return ERROR_INVALID_PARAMETER;
}
- if(!(W32Thread = (PTHREADINFO)Thread->Tcb.Win32Thread))
+ if (!(W32Thread = (PTHREADINFO)Thread->Tcb.Win32Thread))
{
ObDereferenceObject(Thread);
- DPRINT("Thread is not a GUI Thread!\n");
+ DPRINT1("Thread is not initialized!\n");
return ERROR_INVALID_PARAMETER;
}
Current = W32Thread->WindowListHead.Flink;
- while(Current != &(W32Thread->WindowListHead))
+ 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 (dwCount < *pBufSize && pWnd)
{
- if(dwCount < *pBufSize && pWnd)
- {
- Status = MmCopyToCaller(pWnd++, &Window->hSelf, sizeof(HWND));
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- break;
- }
- }
- dwCount++;
+ _SEH2_TRY
+ {
+ ProbeForWrite(pWnd, sizeof(HWND), 1);
+ *pWnd = Window->head.h;
+ pWnd++;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failure to build window list!\n");
+ SetLastNtError(Status);
+ break;
+ }
}
- Current = Current->Flink;
+ dwCount++;
+ Current = Window->ThreadListEntry.Flink;
}
ObDereferenceObject(Thread);
return STATUS_SUCCESS;
}
-
-/*
- * @implemented
- */
-HWND APIENTRY
-NtUserChildWindowFromPointEx(HWND hwndParent,
- LONG x,
- LONG y,
- UINT uiFlags)
+static void IntSendParentNotify( PWND pWindow, UINT msg )
{
- PWINDOW_OBJECT Parent;
- POINTL Pt;
- HWND Ret;
- HWND *List, *phWnd;
-
- if(!(Parent = UserGetWindowObject(hwndParent)))
- {
- return NULL;
- }
+ if ( (pWindow->style & (WS_CHILD | WS_POPUP)) == WS_CHILD &&
+ !(pWindow->style & WS_EX_NOPARENTNOTIFY))
+ {
+ if (pWindow->spwndParent && pWindow->spwndParent != UserGetDesktopWindow())
+ {
+ USER_REFERENCE_ENTRY Ref;
+ UserRefObjectCo(pWindow->spwndParent, &Ref);
+ co_IntSendMessage( pWindow->spwndParent->head.h,
+ WM_PARENTNOTIFY,
+ MAKEWPARAM( msg, pWindow->IDMenu),
+ (LPARAM)pWindow->head.h );
+ UserDerefObjectCo(pWindow->spwndParent);
+ }
+ }
+}
- Pt.x = x;
- Pt.y = y;
+void FASTCALL
+IntFixWindowCoordinates(CREATESTRUCTW* Cs, PWND ParentWindow, DWORD* dwShowMode)
+{
+#define IS_DEFAULT(x) ((x) == CW_USEDEFAULT || (x) == (SHORT)0x8000)
- if(Parent->hSelf != IntGetDesktopWindow())
+ /* default positioning for overlapped windows */
+ if(!(Cs->style & (WS_POPUP | WS_CHILD)))
{
- Pt.x += Parent->Wnd->rcClient.left;
- Pt.y += Parent->Wnd->rcClient.top;
- }
+ PMONITOR pMonitor;
+ PRTL_USER_PROCESS_PARAMETERS ProcessParams;
- if(!IntPtInWindow(Parent, Pt.x, Pt.y))
- {
- return NULL;
- }
+ pMonitor = IntGetPrimaryMonitor();
- Ret = Parent->hSelf;
- if((List = IntWinListChildren(Parent)))
- {
- for(phWnd = List; *phWnd; phWnd++)
+ /* Check if we don't have a monitor attached yet */
+ if(pMonitor == NULL)
{
- PWINDOW_OBJECT Child;
- PWND ChildWnd;
- if((Child = UserGetWindowObject(*phWnd)))
- {
- ChildWnd = Child->Wnd;
- if(!(ChildWnd->style & WS_VISIBLE) && (uiFlags & CWP_SKIPINVISIBLE))
- {
- continue;
- }
- if((ChildWnd->style & WS_DISABLED) && (uiFlags & CWP_SKIPDISABLED))
- {
- continue;
- }
- if((ChildWnd->ExStyle & WS_EX_TRANSPARENT) && (uiFlags & CWP_SKIPTRANSPARENT))
- {
- continue;
- }
- if(IntPtInWindow(Child, Pt.x, Pt.y))
- {
- Ret = Child->hSelf;
- break;
- }
- }
+ Cs->x = Cs->y = 0;
+ Cs->cx = 800;
+ Cs->cy = 600;
+ return;
}
- ExFreePool(List);
- }
-
- return Ret;
-}
+ ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters;
-/*
- * calculates the default position of a window
- */
-BOOL FASTCALL
-IntCalcDefPosSize(PWINDOW_OBJECT Parent, RECTL *rc, BOOL IncPos)
-{
- SIZE Sz;
- PMONITOR pMonitor;
- POINT Pos = {0, 0};
-
- pMonitor = IntGetPrimaryMonitor();
+ if (IS_DEFAULT(Cs->x))
+ {
+ if (!IS_DEFAULT(Cs->y)) *dwShowMode = Cs->y;
- if(Parent != NULL)
- {
- RECTL_bIntersectRect(rc, rc, &pMonitor->rcMonitor);
+ 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++;
+ }
+ }
- if(IncPos)
+ if (IS_DEFAULT(Cs->cx))
{
- 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++;
+ 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;
}
- Pos.x += rc->left;
- Pos.y += rc->top;
}
else
{
- Pos.x = rc->left;
- Pos.y = rc->top;
+ /* 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;
+ }
}
- 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;
+#undef IS_DEFAULT
}
-
-/*
- * @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)
+/* Allocates and initializes a window*/
+PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
+ PLARGE_STRING WindowName,
+ PCLS Class,
+ PWND ParentWindow,
+ PWND OwnerWindow)
{
- 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;
+ PWND pWnd = NULL;
HWND hWnd;
- POINT Pos;
- SIZE Size;
- PTHREADINFO ti = NULL;
-#if 0
-
- POINT MaxSize, MaxPos, MinTrack, MaxTrack;
-#else
-
- POINT MaxPos;
-#endif
- CREATESTRUCTW Cs;
- CBT_CREATEWNDW CbtCreate;
- LRESULT Result;
+ PTHREADINFO pti = NULL;
+ PMENU_OBJECT SystemMenu;
BOOL MenuChanged;
- DECLARE_RETURN(PWND);
- BOOL HasOwner;
- USER_REFERENCE_ENTRY ParentRef, Ref;
- PTHREADINFO pti;
+ BOOL bUnicodeWindow;
pti = PsGetCurrentThreadWin32Thread();
- if (pti->rpdesk)
- {
- ParentWindowHandle = pti->rpdesk->DesktopWindow;
- }
-
-
- if ( !(pti->ppi->W32PF_flags & W32PF_CLASSESREGISTERED ))
+ if (!(Cs->dwExStyle & WS_EX_LAYOUTRTL))
{
- UserRegisterSystemClasses();
- }
-
- OwnerWindowHandle = NULL;
-
- DPRINT("co_IntCreateWindowEx %wZ\n", ClassName);
+ if (ParentWindow)
+ {
+ 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
+ {/*
+ Note from MSDN http://msdn.microsoft.com/en-us/library/aa913269.aspx :
- if (hWndParent == HWND_MESSAGE)
- {
- /*
- * native ole32.OleInitialize uses HWND_MESSAGE to create the
- * message window (style: WS_POPUP|WS_DISABLED)
+ Dialog boxes and message boxes do not inherit layout, so you must
+ set the layout explicitly.
*/
- 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 ( Class && Class->fnid != FNID_DIALOG)
+ {
+ PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
+ if (ppi->dwLayout & LAYOUT_RTL)
+ {
+ Cs->dwExStyle |= WS_EX_LAYOUTRTL;
+ }
+ }
}
- 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);
- }
+ /* 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
- {
- 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);
- }
-
- /* Check the class. */
-
- DPRINT("Class %wZ\n", ClassName);
-
- ClassAtom = IntGetClassAtom(ClassName,
- hInstance,
- ti->ppi,
- &Class,
- &ClassLink);
-
- if (ClassAtom == (RTL_ATOM)0)
- {
- if (IS_ATOM(ClassName->Buffer))
- {
- DPRINT1("Class 0x%p not found\n", (DWORD_PTR) ClassName->Buffer);
- }
- else
- {
- DPRINT1("Class \"%wZ\" not found\n", ClassName);
- }
-
- 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);
- }
+ Cs->dwExStyle &= ~WS_EX_WINDOWEDGE;
- WinSta = pti->rpdesk->rpwinstaParent;
+ /* Is it a unicode window? */
+ bUnicodeWindow =!(Cs->dwExStyle & WS_EX_SETANSICREATOR);
+ Cs->dwExStyle &= ~WS_EX_SETANSICREATOR;
- //FIXME: Reference thread/desktop instead
- ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
+ /* Allocate the new window */
+ pWnd = (PWND) UserCreateObject( gHandleTable,
+ pti->rpdesk,
+ (PHANDLE)&hWnd,
+ otWindow,
+ sizeof(WND) + Class->cbwndExtra);
- /* Create the window object. */
- Window = (PWINDOW_OBJECT) UserCreateObject( gHandleTable,
- pti->rpdesk,
- (PHANDLE)&hWnd,
- otWindow,
- sizeof(WINDOW_OBJECT));
- if (Window)
+ if (!pWnd)
{
- 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;
-
- Wnd->head.pti = ti;
- Wnd->head.rpdesk = pti->rpdesk;
- Wnd->hWndLastActive = hWnd;
- Wnd->state2 |= WNDS2_WIN40COMPAT;
+ goto AllocError;
}
DPRINT("Created object with handle %X\n", hWnd);
- if (!Window)
- {
-AllocErr:
- ObDereferenceObject(WinSta);
- SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
- RETURN( (PWND)0);
- }
-
- UserRefObjectCo(Window, &Ref);
-
- ObDereferenceObject(WinSta);
if (NULL == pti->rpdesk->DesktopWindow)
- {
+ { /*HACK! Helper for win32csr/desktopbg.c */
/* 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;
+ EngSetLastError(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;
+ pWnd->strName.MaximumLength = WindowName->Length + sizeof(UNICODE_NULL);
+ }
/* 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)))
- {
- RECTL rc, WorkArea;
- PRTL_USER_PROCESS_PARAMETERS ProcessParams;
- BOOL CalculatedDefPosSize = FALSE;
-
- IntGetDesktopWorkArea(Window->pti->rpdesk, &WorkArea);
- rc = WorkArea;
- ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters;
+ return pWnd;
- if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
- {
- CalculatedDefPosSize = IntCalcDefPosSize(ParentWindow, &rc, TRUE);
+AllocError:
+ DPRINT1("IntCreateWindow Allocation Error.\n");
+ if(pWnd)
+ UserDereferenceObject(pWnd);
- 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;
- }
+ SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
+ return NULL;
+}
/*
- According to wine, the ShowMode is set to y if x == CW_USEDEFAULT(16) and
- y is something else. and Quote!
- */
-
-/* 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)
+ * @implemented
*/
- if(y != CW_USEDEFAULT && y != CW_USEDEFAULT16)
- {
- dwShowMode = y;
- }
- }
- if(nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16)
- {
- 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);
- }
- }
- else
- {
- /* if CW_USEDEFAULT(16) is set for non-overlapped windows, both values are set to zero) */
- if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
- {
- Pos.x = 0;
- Pos.y = 0;
- }
- if(nWidth == CW_USEDEFAULT || nWidth == CW_USEDEFAULT16)
- {
- Size.cx = 0;
- Size.cy = 0;
- }
- }
+PWND FASTCALL
+co_UserCreateWindowEx(CREATESTRUCTW* Cs,
+ PUNICODE_STRING ClassName,
+ PLARGE_STRING WindowName)
+{
+ PWND Window = NULL, ParentWindow = NULL, OwnerWindow;
+ HWND hWnd, hWndParent, hWndOwner, hwndInsertAfter;
+ 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 = NULL;
+ PVOID pszClass = NULL, pszName = NULL;
+ PWND ret = NULL;
- /* 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)
+ /* Get the current window station and reference it */
+ pti = GetW32ThreadInfo();
+ if (pti == NULL || pti->rpdesk == NULL)
{
- RECTL_vOffsetRect(&(Wnd->rcWindow), ParentWindow->Wnd->rcClient.left,
- ParentWindow->Wnd->rcClient.top);
+ DPRINT1("Thread is not attached to a desktop! Cannot create window!\n");
+ return NULL; //There is nothing to cleanup
}
- Wnd->rcClient = Wnd->rcWindow;
+ WinSta = pti->rpdesk->rpwinstaParent;
+ ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
- /*
- * Get the size and position of the window.
- */
- if ((dwStyle & WS_THICKFRAME) || !(dwStyle & (WS_POPUP | WS_CHILD)))
- {
- POINT MaxSize, MaxPos, MinTrack, MaxTrack;
+ pCsw = NULL;
+ pCbtCreate = NULL;
- /* 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)
+ /* Get the class and reference it*/
+ Class = IntGetAndReferenceClass(ClassName, Cs->hInstance);
+ if(!Class)
{
- /* FIXME: Cleanup. */
- DPRINT1("IntCreateWindowEx(): NCCREATE message failed. No cleanup performed!\n");
- RETURN((PWND)0);
+ DPRINT1("Failed to find class %wZ\n", ClassName);
+ goto cleanup;
}
- /* Calculate the non-client size. */
- MaxPos.x = Window->Wnd->rcWindow.left;
- MaxPos.y = Window->Wnd->rcWindow.top;
-
+ /* Now find the parent and the owner window */
+ hWndParent = IntGetDesktopWindow();
+ hWndOwner = NULL;
- 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);
+ 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");
+ EngSetLastError(ERROR_TLW_WITH_WSCHILD);
+ goto cleanup; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
+ }
- RECTL_vOffsetRect(&Window->Wnd->rcWindow,
- MaxPos.x - Window->Wnd->rcWindow.left,
- MaxPos.y - Window->Wnd->rcWindow.top);
+ ParentWindow = hWndParent ? UserGetWindowObject(hWndParent): NULL;
+ OwnerWindow = hWndOwner ? UserGetWindowObject(hWndOwner): NULL;
+ /* FIXME: is this correct?*/
+ if(OwnerWindow)
+ OwnerWindow = UserGetAncestor(OwnerWindow, GA_ROOT);
- if (NULL != ParentWindow)
+ /* Fix the position and the size of the window */
+ if (ParentWindow)
{
- /* link the window into the parent's child list */
- if ((dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
- {
- PWINDOW_OBJECT PrevSibling;
-
- PrevSibling = ParentWindow->spwndChild;
+ UserRefObjectCo(ParentWindow, &ParentRef);
+ IntFixWindowCoordinates(Cs, ParentWindow, &dwShowMode);
+ }
- if(PrevSibling)
+ /* Allocate and initialize the new window */
+ Window = IntCreateWindow(Cs,
+ WindowName,
+ Class,
+ ParentWindow,
+ OwnerWindow);
+ if(!Window)
+ {
+ DPRINT1("IntCreateWindow failed!\n");
+ goto cleanup;
+ }
+
+ hWnd = UserHMGetHandle(Window);
+ hwndInsertAfter = HWND_TOP;
+
+ UserRefObjectCo(Window, &Ref);
+ UserDereferenceObject(Window);
+ ObDereferenceObject(WinSta);
+
+ //// Check for a hook to eliminate overhead. ////
+ if ( ISITHOOKED(WH_CBT) || (pti->rpdesk->pDeskInfo->fsHooks & HOOKID_TO_FLAG(WH_CBT)) )
+ {
+ // Allocate the calling structures Justin Case this goes Global.
+ pCsw = ExAllocatePoolWithTag(NonPagedPool, sizeof(CREATESTRUCTW), TAG_HOOK);
+ pCbtCreate = ExAllocatePoolWithTag(NonPagedPool, sizeof(CBT_CREATEWNDW), TAG_HOOK);
+ if (!pCsw || !pCbtCreate)
+ {
+ DPRINT1("UserHeapAlloc() failed!\n");
+ goto cleanup;
+ }
+
+ /* Fill the new CREATESTRUCTW */
+ RtlCopyMemory(pCsw, Cs, sizeof(CREATESTRUCTW));
+ pCsw->style = Window->style; /* HCBT_CREATEWND needs the real window style */
+
+ // 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);
+ if (!pszClass)
+ {
+ DPRINT1("UserHeapAlloc() failed!\n");
+ goto cleanup;
+ }
+ RtlZeroMemory(pszClass, AnsiString.MaximumLength);
+ AnsiString.Buffer = (PCHAR)pszClass;
+ RtlUnicodeStringToAnsiString(&AnsiString, ClassName, FALSE);
+ }
+ else
{
- while (PrevSibling->spwndNext)
- PrevSibling = PrevSibling->spwndNext;
+ UNICODE_STRING UnicodeString;
+ UnicodeString.MaximumLength = ClassName->Length + sizeof(UNICODE_NULL);
+ pszClass = UserHeapAlloc(UnicodeString.MaximumLength);
+ if (!pszClass)
+ {
+ DPRINT1("UserHeapAlloc() failed!\n");
+ goto cleanup;
+ }
+ RtlZeroMemory(pszClass, UnicodeString.MaximumLength);
+ UnicodeString.Buffer = (PWSTR)pszClass;
+ RtlCopyUnicodeString(&UnicodeString, ClassName);
}
-
- /* link window as bottom sibling */
- IntLinkWindow(Window, ParentWindow, PrevSibling /*prev sibling*/);
+ pCsw->lpszClass = UserHeapAddressToUser(pszClass);
}
- else
+ if (WindowName->Length)
{
- /* link window as top sibling (but after topmost siblings) */
- PWINDOW_OBJECT InsertAfter, Sibling;
- if (!(dwExStyle & WS_EX_TOPMOST))
+ UNICODE_STRING Name;
+ Name.Buffer = WindowName->Buffer;
+ Name.Length = WindowName->Length;
+ Name.MaximumLength = WindowName->MaximumLength;
+
+ if (Window->state & WNDS_ANSICREATOR)
{
- InsertAfter = NULL;
- Sibling = ParentWindow->spwndChild;
- while (Sibling && (Sibling->Wnd->ExStyle & WS_EX_TOPMOST))
+ ANSI_STRING AnsiString;
+ AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(&Name) + sizeof(CHAR);
+ pszName = UserHeapAlloc(AnsiString.MaximumLength);
+ if (!pszName)
{
- InsertAfter = Sibling;
- Sibling = Sibling->spwndNext;
+ DPRINT1("UserHeapAlloc() failed!\n");
+ goto cleanup;
}
+ RtlZeroMemory(pszName, AnsiString.MaximumLength);
+ AnsiString.Buffer = (PCHAR)pszName;
+ RtlUnicodeStringToAnsiString(&AnsiString, &Name, FALSE);
}
else
{
- InsertAfter = NULL;
+ UNICODE_STRING UnicodeString;
+ UnicodeString.MaximumLength = Name.Length + sizeof(UNICODE_NULL);
+ pszName = UserHeapAlloc(UnicodeString.MaximumLength);
+ if (!pszName)
+ {
+ DPRINT1("UserHeapAlloc() failed!\n");
+ goto cleanup;
+ }
+ RtlZeroMemory(pszName, UnicodeString.MaximumLength);
+ UnicodeString.Buffer = (PWSTR)pszName;
+ RtlCopyUnicodeString(&UnicodeString, &Name);
}
+ pCsw->lpszName = UserHeapAddressToUser(pszName);
+ }
- IntLinkWindow(Window, ParentWindow, InsertAfter /* prev sibling */);
+ pCbtCreate->lpcs = pCsw;
+ pCbtCreate->hwndInsertAfter = hwndInsertAfter;
+
+ //// Call the WH_CBT hook ////
+ Result = co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) pCbtCreate);
+ if (Result != 0)
+ {
+ DPRINT1("WH_CBT HCBT_CREATEWND hook failed! 0x%x\n", Result);
+ goto cleanup;
}
+ // Write back changes.
+ Cs->cx = pCsw->cx;
+ Cs->cy = pCsw->cy;
+ Cs->x = pCsw->x;
+ Cs->y = pCsw->y;
+ hwndInsertAfter = pCbtCreate->hwndInsertAfter;
}
- /* Send the WM_CREATE message. */
- DPRINT("IntCreateWindowEx(): about to send CREATE message.\n");
- Result = co_IntSendMessage(Window->hSelf, WM_CREATE, 0, (LPARAM) &Cs);
+ /* NCCREATE and WM_NCCALCSIZE need the original values */
+ Cs->lpszName = (LPCWSTR) WindowName;
+ Cs->lpszClass = (LPCWSTR) ClassName;
- if (Result == (LRESULT)-1)
+ /* Send the WM_GETMINMAXINFO message*/
+ Size.cx = Cs->cx;
+ Size.cy = Cs->cy;
+
+ if ((Cs->style & WS_THICKFRAME) || !(Cs->style & (WS_POPUP | WS_CHILD)))
{
- /* FIXME: Cleanup. */
- DPRINT1("IntCreateWindowEx(): send CREATE message failed. No cleanup performed!\n");
- IntUnlinkWindow(Window);
- RETURN((PWND)0);
+ POINT MaxSize, MaxPos, MinTrack, MaxTrack;
+
+ 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;
}
- IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window->Wnd, OBJID_WINDOW, 0);
+ 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;
- /* Send move and size messages. */
- if (!(Window->state & WINDOWOBJECT_NEED_SIZE))
+ /* Link the window*/
+ if (NULL != ParentWindow)
{
- LONG lParam;
+ /* link the window into the siblings list */
+ if ((Cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
+ IntLinkHwnd(Window, HWND_BOTTOM);
+ else
+ IntLinkHwnd(Window, hwndInsertAfter);
+ }
- DPRINT("IntCreateWindow(): About to send WM_SIZE\n");
+ /* Send the NCCREATE message */
+ Result = co_IntSendMessage(UserHMGetHandle(Window), WM_NCCREATE, 0, (LPARAM) Cs);
+ if (!Result)
+ {
+ DPRINT1("co_UserCreateWindowEx(): NCCREATE message failed\n");
+ goto cleanup;
+ }
- 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");
- }
+ /* Send the WM_NCCALCSIZE message */
+ 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);
+ Result = co_WinPosGetNonClientSize(Window, &Window->rcWindow, &Window->rcClient);
- DPRINT("IntCreateWindow(): About to send WM_MOVE\n");
+ RECTL_vOffsetRect(&Window->rcWindow, MaxPos.x - Window->rcWindow.left,
+ MaxPos.y - Window->rcWindow.top);
- 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);
- }
- co_IntSendMessage(Window->hSelf, WM_MOVE, 0, lParam);
+ /* 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");
+ goto cleanup;
+ }
+
+ /* Send the EVENT_OBJECT_CREATE event*/
+ IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_WINDOW, CHILDID_SELF, 0);
+
+ /* 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);
+ ret = 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)
+ {
+ DPRINT("co_UserCreateWindowEx(): Error Created window!\n");
+ /* 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;
+
+ return ret;
}
-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;
- pNewWindow = co_IntCreateWindowEx( dwExStyle,
- &ClassName,
- &WindowName,
- dwStyle,
- x,
- y,
- nWidth,
- nHeight,
- hWndParent,
- hMenu,
- hInstance,
- lpParam,
- dwShowMode,
- bUnicodeWindow);
+ return STATUS_SUCCESS;
+}
- if (pNewWindow) NewWindow = UserHMGetHandle(pNewWindow);
+/**
+ * \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 (WindowName.Buffer)
- {
- ExFreePoolWithTag(WindowName.Buffer, TAG_STRING);
- }
- if (! IS_ATOM(ClassName.Buffer))
- {
- ExFreePoolWithTag(ClassName.Buffer, TAG_STRING);
- }
+ /* 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;
+ }
- RETURN( NewWindow);
+ /* We pass it on as a UNICODE_STRING */
+ ustrClassName.Buffer = lstrClassName.Buffer;
+ ustrClassName.Length = lstrClassName.Length;
+ ustrClassName.MaximumLength = lstrClassName.MaximumLength;
+ }
-CLEANUP:
- DPRINT("Leave NtUserCreateWindowEx, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
+ /* 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;
-/*
- * @unimplemented
- */
-HDWP APIENTRY
-NtUserDeferWindowPos(HDWP WinPosInfo,
- HWND Wnd,
- HWND WndInsertAfter,
- int x,
- int y,
- int cx,
- int cy,
- UINT Flags)
-{
- UNIMPLEMENTED
+ UserLeave();
- return 0;
+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);
+ EngSetLastError(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;
-
- IntDereferenceMessageQueue(Window->pti->MessageQueue);
+ 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;
- 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))
+ 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;
+ co_MsqInsertMouseMessage(&msg, 0, 0, TRUE);
+
+ 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;
}
-
-/*
- * @unimplemented
- */
-DWORD
-APIENTRY
-NtUserDrawMenuBarTemp(
- HWND hWnd,
- HDC hDC,
- PRECT hRect,
- HMENU hMenu,
- HFONT hFont)
-{
- /* we'll use this function just for caching the menu bar */
- UNIMPLEMENTED
- return 0;
-}
-
-
-/*
- * @unimplemented
- */
-DWORD APIENTRY
-NtUserEndDeferWindowPosEx(DWORD Unknown0,
- DWORD Unknown1)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
-/*
- * FillWindow: Called from User; Dialog, Edit and ListBox procs during a WM_ERASEBKGND.
- */
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserFillWindow(HWND hWndPaint,
- HWND hWndPaint1,
- HDC hDC,
- HBRUSH hBrush)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
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;
}
else if (!IS_ATOM(ClassName.Buffer))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
_SEH2_LEAVE;
}
if (ClassName.Length == 0 && ClassName.Buffer != NULL &&
!IS_ATOM(ClassName.Buffer))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
RETURN(NULL);
}
else if (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())))
{
}
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserFlashWindowEx(IN PFLASHWINFO pfwi)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
/*
* @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
{
sizeof(POINT),
1);
}
-
+
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
- wndpl.length = sizeof(WINDOWPLACEMENT);
+ wndpl.length = sizeof(WINDOWPLACEMENT);
if (IntGetWindowPlacement(Window, &wndpl) && !Hit)
{
{
RtlCopyMemory(ptIcon, &wndpl.ptMinPosition, sizeof(POINT));
}
-
+
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
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_);
END_CLEANUP;
}
+/*
+ * NtUserSetParent
+ *
+ * The NtUserSetParent function changes the parent window of the specified
+ * child window.
+ *
+ * Remarks
+ * The new parent window and the child window must belong to the same
+ * application. If the window identified by the hWndChild parameter is
+ * visible, the system performs the appropriate redrawing and repainting.
+ * For compatibility reasons, NtUserSetParent does not modify the WS_CHILD
+ * or WS_POPUP window styles of the window whose parent is being changed.
+ *
+ * Status
+ * @implemented
+ */
-HWND FASTCALL
-co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
+HWND APIENTRY
+NtUserSetParent(HWND hWndChild, HWND hWndNewParent)
{
- PWINDOW_OBJECT Wnd = NULL, WndParent = NULL, WndOldParent;
- HWND hWndOldParent = NULL;
- USER_REFERENCE_ENTRY Ref, ParentRef;
+ DECLARE_RETURN(HWND);
- if (IntIsBroadcastHwnd(hWndChild) || IntIsBroadcastHwnd(hWndNewParent))
+ DPRINT("Enter NtUserSetParent\n");
+ UserEnterExclusive();
+
+ /*
+ Check Parent first from user space, set it here.
+ */
+ if (!hWndNewParent)
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return( NULL);
+ hWndNewParent = IntGetDesktopWindow();
}
-
- if (hWndChild == IntGetDesktopWindow())
+ else if (hWndNewParent == HWND_MESSAGE)
{
- SetLastWin32Error(ERROR_ACCESS_DENIED);
- return( NULL);
- }
-
- if (hWndNewParent)
- {
- if (!(WndParent = UserGetWindowObject(hWndNewParent)))
- {
- return( NULL);
- }
- }
- else
- {
- if (!(WndParent = UserGetWindowObject(IntGetDesktopWindow())))
- {
- return( NULL);
- }
- }
-
- if (!(Wnd = UserGetWindowObject(hWndChild)))
- {
- return( NULL);
- }
-
- UserRefObjectCo(Wnd, &Ref);
- UserRefObjectCo(WndParent, &ParentRef);
-
- WndOldParent = co_IntSetParent(Wnd, WndParent);
-
- UserDerefObjectCo(WndParent);
- UserDerefObjectCo(Wnd);
-
- if (WndOldParent)
- {
- hWndOldParent = WndOldParent->hSelf;
- UserDereferenceObject(WndOldParent);
- }
-
- return( hWndOldParent);
-}
-
-/*
- * NtUserSetParent
- *
- * The NtUserSetParent function changes the parent window of the specified
- * child window.
- *
- * Remarks
- * The new parent window and the child window must belong to the same
- * application. If the window identified by the hWndChild parameter is
- * visible, the system performs the appropriate redrawing and repainting.
- * For compatibility reasons, NtUserSetParent does not modify the WS_CHILD
- * or WS_POPUP window styles of the window whose parent is being changed.
- *
- * Status
- * @implemented
- */
-
-HWND APIENTRY
-NtUserSetParent(HWND hWndChild, HWND hWndNewParent)
-{
- DECLARE_RETURN(HWND);
-
- DPRINT("Enter NtUserSetParent\n");
- UserEnterExclusive();
-
- /*
- Check Parent first from user space, set it here.
- */
- if (!hWndNewParent)
- {
- hWndNewParent = IntGetDesktopWindow();
- }
- else if (hWndNewParent == HWND_MESSAGE)
- {
- hWndNewParent = IntGetMessageWindow();
+ hWndNewParent = IntGetMessageWindow();
}
RETURN( co_UserSetParent(hWndChild, hWndNewParent));
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);
WinStaObject->ShellListView = hwndListView;
ti = GetW32ThreadInfo();
- if (ti->pDeskInfo) ti->pDeskInfo->hShellWindow = hwndShell;
+ if (ti->pDeskInfo)
+ {
+ ti->pDeskInfo->hShellWindow = hwndShell;
+ ti->pDeskInfo->ppiShellProcess = ti->ppi;
+ }
UserDerefObjectCo(WndShell);
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;
if (hWnd == IntGetDesktopWindow())
{
- SetLastWin32Error(STATUS_ACCESS_DENIED);
+ EngSetLastError(STATUS_ACCESS_DENIED);
return( 0);
}
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);
+ EngSetLastError(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);
+ EngSetLastError(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:
DPRINT1("NtUserSetWindowLong(): Unsupported index %d\n", Index);
- SetLastWin32Error(ERROR_INVALID_INDEX);
+ EngSetLastError(ERROR_INVALID_INDEX);
OldValue = 0;
break;
}
WORD APIENTRY
NtUserSetWindowWord(HWND hWnd, INT Index, WORD NewValue)
{
- PWINDOW_OBJECT Window;
+ PWND Window;
WORD OldValue;
DECLARE_RETURN(WORD);
if (!(Window = UserGetWindowObject(hWnd)))
{
- RETURN( 0);
- }
-
- switch (Index)
- {
- case GWL_ID:
- case GWL_HINSTANCE:
- case GWL_HWNDPARENT:
- RETURN( co_UserSetWindowLong(Window->hSelf, Index, (UINT)NewValue, TRUE));
- default:
- if (Index < 0)
- {
- SetLastWin32Error(ERROR_INVALID_INDEX);
- RETURN( 0);
- }
- }
-
- if (Index > Window->Wnd->cbwndExtra - sizeof(WORD))
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN( 0);
- }
-
- OldValue = *((WORD *)((PCHAR)(Window->Wnd + 1) + Index));
- *((WORD *)((PCHAR)(Window->Wnd + 1) + Index)) = NewValue;
-
- RETURN( OldValue);
-
-CLEANUP:
- DPRINT("Leave NtUserSetWindowWord, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
-
-/*
- * @implemented
- */
-BOOL APIENTRY
-NtUserGetWindowPlacement(HWND hWnd,
- WINDOWPLACEMENT *lpwndpl)
-{
- PWINDOW_OBJECT Window;
- PWND Wnd;
- POINT Size;
- WINDOWPLACEMENT Safepl;
- NTSTATUS Status;
- DECLARE_RETURN(BOOL);
-
- DPRINT("Enter NtUserGetWindowPlacement\n");
- UserEnterShared();
-
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- RETURN( FALSE);
- }
- Wnd = Window->Wnd;
-
- Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT));
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( FALSE);
- }
- if(Safepl.length != sizeof(WINDOWPLACEMENT))
- {
- RETURN( FALSE);
- }
-
- Safepl.flags = 0;
- if (0 == (Wnd->style & WS_VISIBLE))
- {
- Safepl.showCmd = SW_HIDE;
- }
- else if ((0 != (Window->state & WINDOWOBJECT_RESTOREMAX) ||
- 0 != (Wnd->style & WS_MAXIMIZE)) &&
- 0 == (Wnd->style & WS_MINIMIZE))
- {
- Safepl.showCmd = SW_SHOWMAXIMIZED;
- }
- else if (0 != (Wnd->style & WS_MINIMIZE))
- {
- Safepl.showCmd = SW_SHOWMINIMIZED;
- }
- else if (0 != (Wnd->style & WS_VISIBLE))
- {
- Safepl.showCmd = SW_SHOWNORMAL;
- }
-
- Size.x = Wnd->rcWindow.left;
- Size.y = Wnd->rcWindow.top;
- WinPosInitInternalPos(Window, &Size,
- &Wnd->rcWindow);
-
- Safepl.rcNormalPosition = Wnd->InternalPos.NormalRect;
- Safepl.ptMinPosition = Wnd->InternalPos.IconPos;
- Safepl.ptMaxPosition = Wnd->InternalPos.MaxPos;
-
- Status = MmCopyToCaller(lpwndpl, &Safepl, sizeof(WINDOWPLACEMENT));
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( FALSE);
- }
-
- RETURN( TRUE);
-
-CLEANUP:
- DPRINT("Leave NtUserGetWindowPlacement, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
-
-
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserLockWindowUpdate(HWND hWnd)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
-/*
- * @implemented
- */
-BOOL APIENTRY
-NtUserMoveWindow(
- HWND hWnd,
- int X,
- int Y,
- int nWidth,
- int nHeight,
- BOOL bRepaint)
-{
- return NtUserSetWindowPos(hWnd, 0, X, Y, nWidth, nHeight,
- (bRepaint ? SWP_NOZORDER | SWP_NOACTIVATE :
- SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW));
-}
-
-/*
- QueryWindow based on KJK::Hyperion and James Tabor.
-
- 0 = QWUniqueProcessId
- 1 = QWUniqueThreadId
- 2 = QWActiveWindow
- 3 = QWFocusWindow
- 4 = QWIsHung Implements IsHungAppWindow found
- by KJK::Hyperion.
-
- 9 = QWKillWindow When I called this with hWnd ==
- DesktopWindow, it shutdown the system
- and rebooted.
-*/
-/*
- * @implemented
- */
-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)
- {
- RETURN( 0);
- }
-
- pWnd = Window->Wnd;
-
- switch(Index)
- {
- case QUERY_WINDOW_UNIQUE_PROCESS_ID:
- Result = (DWORD)IntGetWndProcessId(Window);
- break;
-
- case QUERY_WINDOW_UNIQUE_THREAD_ID:
- Result = (DWORD)IntGetWndThreadId(Window);
- break;
-
- case QUERY_WINDOW_ACTIVE:
- Result = (DWORD)UserGetActiveWindow();
- break;
-
- case QUERY_WINDOW_FOCUS:
- Result = (DWORD)IntGetFocusWindow();
- break;
-
- case QUERY_WINDOW_ISHUNG:
- Result = (DWORD)MsqIsHung(Window->pti->MessageQueue);
- break;
-
- case QUERY_WINDOW_REAL_ID:
- Result = (DWORD)pWnd->head.pti->pEThread->Cid.UniqueProcess;
-
- default:
- Result = (DWORD)NULL;
- break;
- }
-
- RETURN( Result);
-
-CLEANUP:
- DPRINT("Leave NtUserQueryWindow, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
-
-
-/*
- * @unimplemented
- */
-DWORD APIENTRY
-NtUserRealChildWindowFromPoint(DWORD Unknown0,
- DWORD Unknown1,
- DWORD Unknown2)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
-/*
- * @implemented
- */
-UINT APIENTRY
-NtUserRegisterWindowMessage(PUNICODE_STRING MessageNameUnsafe)
-{
- UNICODE_STRING SafeMessageName;
- NTSTATUS Status;
- UINT Ret;
- DECLARE_RETURN(UINT);
-
- DPRINT("Enter NtUserRegisterWindowMessage\n");
- UserEnterExclusive();
-
- if(MessageNameUnsafe == NULL)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN( 0);
- }
-
- Status = IntSafeCopyUnicodeStringTerminateNULL(&SafeMessageName, MessageNameUnsafe);
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( 0);
- }
-
- Ret = (UINT)IntAddAtom(SafeMessageName.Buffer);
-
- ExFreePoolWithTag(SafeMessageName.Buffer, TAG_STRING);
- RETURN( Ret);
-
-CLEANUP:
- DPRINT("Leave NtUserRegisterWindowMessage, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
-
-
-/*
- * @unimplemented
- */
-DWORD APIENTRY
-NtUserSetImeOwnerWindow(DWORD Unknown0,
- DWORD Unknown1)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
-/*
- * @unimplemented
- */
-DWORD APIENTRY
-NtUserSetInternalWindowPos(
- HWND hwnd,
- UINT showCmd,
- LPRECT rect,
- LPPOINT pt)
-{
- UNIMPLEMENTED
-
- return 0;
-
-}
-
-
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserSetLayeredWindowAttributes(HWND hwnd,
- COLORREF crKey,
- BYTE bAlpha,
- DWORD dwFlags)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
-
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserSetLogonNotifyWindow(HWND hWnd)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
-/*
- * @implemented
- */
-BOOL APIENTRY
-NtUserSetMenu(
- HWND hWnd,
- HMENU Menu,
- BOOL Repaint)
-{
- PWINDOW_OBJECT Window;
- BOOL Changed;
- DECLARE_RETURN(BOOL);
-
- DPRINT("Enter NtUserSetMenu\n");
- UserEnterExclusive();
-
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- RETURN( FALSE);
- }
-
- if (! IntSetMenu(Window, Menu, &Changed))
- {
- RETURN( FALSE);
- }
-
- if (Changed && Repaint)
- {
- USER_REFERENCE_ENTRY Ref;
-
- UserRefObjectCo(Window, &Ref);
- co_WinPosSetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
- SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
-
- UserDerefObjectCo(Window);
- }
-
- RETURN( TRUE);
-
-CLEANUP:
- DPRINT("Leave NtUserSetMenu, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
-
-
-/*
- * @implemented
- */
-BOOL APIENTRY
-NtUserSetWindowFNID(HWND hWnd,
- WORD fnID)
-{
- PWINDOW_OBJECT Window;
- PWND Wnd;
- DECLARE_RETURN(BOOL);
-
- DPRINT("Enter NtUserSetWindowFNID\n");
- UserEnterExclusive();
-
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- RETURN( FALSE);
+ RETURN( 0);
}
- Wnd = Window->Wnd;
- if (Wnd->pcls)
- { // From user land we only set these.
- if ((fnID != FNID_DESTROY) || ((fnID < FNID_BUTTON) && (fnID > FNID_IME)) )
- {
- RETURN( FALSE);
- }
- else
- Wnd->pcls->fnid |= fnID;
+ switch (Index)
+ {
+ case GWL_ID:
+ case GWL_HINSTANCE:
+ case GWL_HWNDPARENT:
+ RETURN( co_UserSetWindowLong(Window->head.h, Index, (UINT)NewValue, TRUE));
+ default:
+ if (Index < 0)
+ {
+ EngSetLastError(ERROR_INVALID_INDEX);
+ RETURN( 0);
+ }
}
- RETURN( TRUE);
+
+ if (Index > Window->cbwndExtra - sizeof(WORD))
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ RETURN( 0);
+ }
+
+ OldValue = *((WORD *)((PCHAR)(Window + 1) + Index));
+ *((WORD *)((PCHAR)(Window + 1) + Index)) = NewValue;
+
+ RETURN( OldValue);
CLEANUP:
- DPRINT("Leave NtUserSetWindowFNID\n");
+ DPRINT("Leave NtUserSetWindowWord, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
-
/*
* @implemented
*/
BOOL APIENTRY
-NtUserSetWindowPlacement(HWND hWnd,
+NtUserGetWindowPlacement(HWND hWnd,
WINDOWPLACEMENT *lpwndpl)
{
- PWINDOW_OBJECT Window;
PWND Wnd;
+ POINT Size;
WINDOWPLACEMENT Safepl;
NTSTATUS Status;
DECLARE_RETURN(BOOL);
- USER_REFERENCE_ENTRY Ref;
- DPRINT("Enter NtUserSetWindowPlacement\n");
- UserEnterExclusive();
+ 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))
RETURN( FALSE);
}
- UserRefObjectCo(Window, &Ref);
-
- if ((Wnd->style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0)
+ Safepl.flags = 0;
+ if (0 == (Wnd->style & WS_VISIBLE))
+ {
+ Safepl.showCmd = SW_HIDE;
+ }
+ else if ((0 != (Wnd->state2 & WNDS2_MAXIMIZEBUTTONDOWN) ||
+ 0 != (Wnd->style & WS_MAXIMIZE)) &&
+ 0 == (Wnd->style & WS_MINIMIZE))
+ {
+ Safepl.showCmd = SW_SHOWMAXIMIZED;
+ }
+ else if (0 != (Wnd->style & WS_MINIMIZE))
{
- co_WinPosSetWindowPos(Window, NULL,
- Safepl.rcNormalPosition.left, Safepl.rcNormalPosition.top,
- Safepl.rcNormalPosition.right - Safepl.rcNormalPosition.left,
- Safepl.rcNormalPosition.bottom - Safepl.rcNormalPosition.top,
- SWP_NOZORDER | SWP_NOACTIVATE);
+ Safepl.showCmd = SW_SHOWMINIMIZED;
+ }
+ else if (0 != (Wnd->style & WS_VISIBLE))
+ {
+ Safepl.showCmd = SW_SHOWNORMAL;
}
- /* FIXME - change window status */
- co_WinPosShowWindow(Window, Safepl.showCmd);
+ Size.x = Wnd->rcWindow.left;
+ Size.y = Wnd->rcWindow.top;
+ WinPosInitInternalPos(Wnd, &Size,
+ &Wnd->rcWindow);
+
+ Safepl.rcNormalPosition = Wnd->InternalPos.NormalRect;
+ Safepl.ptMinPosition = Wnd->InternalPos.IconPos;
+ Safepl.ptMaxPosition = Wnd->InternalPos.MaxPos;
- Wnd->InternalPosInitialized = TRUE;
- Wnd->InternalPos.NormalRect = Safepl.rcNormalPosition;
- Wnd->InternalPos.IconPos = Safepl.ptMinPosition;
- Wnd->InternalPos.MaxPos = Safepl.ptMaxPosition;
+ Status = MmCopyToCaller(lpwndpl, &Safepl, sizeof(WINDOWPLACEMENT));
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ RETURN( FALSE);
+ }
- UserDerefObjectCo(Window);
- RETURN(TRUE);
+ RETURN( TRUE);
CLEANUP:
- DPRINT("Leave NtUserSetWindowPlacement, ret=%i\n",_ret_);
+ DPRINT("Leave NtUserGetWindowPlacement, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
+/*
+ QueryWindow based on KJK::Hyperion and James Tabor.
+
+ 0 = QWUniqueProcessId
+ 1 = QWUniqueThreadId
+ 2 = QWActiveWindow
+ 3 = QWFocusWindow
+ 4 = QWIsHung Implements IsHungAppWindow found
+ by KJK::Hyperion.
+ 9 = QWKillWindow When I called this with hWnd ==
+ DesktopWindow, it shutdown the system
+ and rebooted.
+*/
/*
* @implemented
*/
-BOOL APIENTRY
-NtUserSetWindowPos(
- HWND hWnd,
- HWND hWndInsertAfter,
- int X,
- int Y,
- int cx,
- int cy,
- UINT uFlags)
+DWORD APIENTRY
+NtUserQueryWindow(HWND hWnd, DWORD Index)
{
- DECLARE_RETURN(BOOL);
- PWINDOW_OBJECT Window;
- BOOL ret;
- USER_REFERENCE_ENTRY Ref;
+ PWND pWnd;
+ DWORD Result;
+ DECLARE_RETURN(UINT);
- DPRINT("Enter NtUserSetWindowPos\n");
- UserEnterExclusive();
+ DPRINT("Enter NtUserQueryWindow\n");
+ UserEnterShared();
- if (!(Window = UserGetWindowObject(hWnd)))
+ if (!(pWnd = UserGetWindowObject(hWnd)))
{
- RETURN(FALSE);
+ RETURN( 0);
}
- /* First make sure that coordinates are valid for WM_WINDOWPOSCHANGING */
- if (!(uFlags & SWP_NOMOVE))
- {
- if (X < -32768) X = -32768;
- else if (X > 32767) X = 32767;
- if (Y < -32768) Y = -32768;
- else if (Y > 32767) Y = 32767;
- }
- if (!(uFlags & SWP_NOSIZE))
+ switch(Index)
{
- if (cx < 0) cx = 0;
- else if (cx > 32767) cx = 32767;
- if (cy < 0) cy = 0;
- else if (cy > 32767) cy = 32767;
- }
-
- UserRefObjectCo(Window, &Ref);
- ret = co_WinPosSetWindowPos(Window, hWndInsertAfter, X, Y, cx, cy, uFlags);
- UserDerefObjectCo(Window);
-
- RETURN(ret);
-
-CLEANUP:
- DPRINT("Leave NtUserSetWindowPos, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
+ case QUERY_WINDOW_UNIQUE_PROCESS_ID:
+ Result = (DWORD)IntGetWndProcessId(pWnd);
+ break;
+ case QUERY_WINDOW_UNIQUE_THREAD_ID:
+ Result = (DWORD)IntGetWndThreadId(pWnd);
+ break;
-INT FASTCALL
-IntGetWindowRgn(PWINDOW_OBJECT Window, HRGN hRgn)
-{
- INT Ret;
- HRGN VisRgn;
- ROSRGNDATA *pRgn;
- PWND Wnd;
+ case QUERY_WINDOW_ACTIVE:
+ Result = (DWORD)UserGetActiveWindow();
+ break;
- if(!Window)
- {
- return ERROR;
- }
- if(!hRgn)
- {
- return ERROR;
- }
+ case QUERY_WINDOW_FOCUS:
+ Result = (DWORD)IntGetFocusWindow();
+ break;
- Wnd = Window->Wnd;
+ case QUERY_WINDOW_ISHUNG:
+ Result = (DWORD)MsqIsHung(pWnd->head.pti->MessageQueue);
+ break;
- /* Create a new window region using the window rectangle */
- VisRgn = IntSysCreateRectRgnIndirect(&Window->Wnd->rcWindow);
- NtGdiOffsetRgn(VisRgn, -Window->Wnd->rcWindow.left, -Window->Wnd->rcWindow.top);
- /* if there's a region assigned to the window, combine them both */
- if(Window->hrgnClip && !(Wnd->style & WS_MINIMIZE))
- NtGdiCombineRgn(VisRgn, VisRgn, Window->hrgnClip, RGN_AND);
- /* Copy the region into hRgn */
- NtGdiCombineRgn(hRgn, VisRgn, NULL, RGN_COPY);
+ case QUERY_WINDOW_REAL_ID:
+ Result = (DWORD)pWnd->head.pti->pEThread->Cid.UniqueProcess;
- if((pRgn = RGNOBJAPI_Lock(hRgn, NULL)))
- {
- Ret = pRgn->rdh.iType;
- RGNOBJAPI_Unlock(pRgn);
+ default:
+ Result = (DWORD)NULL;
+ break;
}
- else
- Ret = ERROR;
- REGION_FreeRgnByHandle(VisRgn);
+ RETURN( Result);
- return Ret;
+CLEANUP:
+ DPRINT("Leave NtUserQueryWindow, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
}
-INT FASTCALL
-IntGetWindowRgnBox(PWINDOW_OBJECT Window, RECTL *Rect)
+
+/*
+ * @implemented
+ */
+UINT APIENTRY
+NtUserRegisterWindowMessage(PUNICODE_STRING MessageNameUnsafe)
{
- INT Ret;
- HRGN VisRgn;
- ROSRGNDATA *pRgn;
- PWND Wnd;
+ UNICODE_STRING SafeMessageName;
+ NTSTATUS Status;
+ UINT Ret;
+ DECLARE_RETURN(UINT);
- if(!Window)
- {
- return ERROR;
- }
- if(!Rect)
+ DPRINT("Enter NtUserRegisterWindowMessage\n");
+ UserEnterExclusive();
+
+ if(MessageNameUnsafe == NULL)
{
- return ERROR;
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ RETURN( 0);
}
- 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);
- /* if there's a region assigned to the window, combine them both */
- if(Window->hrgnClip && !(Wnd->style & WS_MINIMIZE))
- NtGdiCombineRgn(VisRgn, VisRgn, Window->hrgnClip, RGN_AND);
-
- if((pRgn = RGNOBJAPI_Lock(VisRgn, NULL)))
+ Status = IntSafeCopyUnicodeStringTerminateNULL(&SafeMessageName, MessageNameUnsafe);
+ if(!NT_SUCCESS(Status))
{
- Ret = pRgn->rdh.iType;
- *Rect = pRgn->rdh.rcBound;
- RGNOBJAPI_Unlock(pRgn);
+ SetLastNtError(Status);
+ RETURN( 0);
}
- else
- Ret = ERROR;
- REGION_FreeRgnByHandle(VisRgn);
+ Ret = (UINT)IntAddAtom(SafeMessageName.Buffer);
+ if (SafeMessageName.Buffer)
+ ExFreePoolWithTag(SafeMessageName.Buffer, TAG_STRING);
+ RETURN( Ret);
- return Ret;
+CLEANUP:
+ DPRINT("Leave NtUserRegisterWindowMessage, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
}
/*
* @implemented
*/
-INT APIENTRY
-NtUserSetWindowRgn(
+BOOL APIENTRY
+NtUserSetMenu(
HWND hWnd,
- HRGN hRgn,
- BOOL bRedraw)
+ HMENU Menu,
+ BOOL Repaint)
{
- HRGN hrgnCopy;
- PWINDOW_OBJECT Window;
- DECLARE_RETURN(INT);
+ PWND Window;
+ BOOL Changed;
+ DECLARE_RETURN(BOOL);
- DPRINT("Enter NtUserSetWindowRgn\n");
+ DPRINT("Enter NtUserSetMenu\n");
UserEnterExclusive();
if (!(Window = UserGetWindowObject(hWnd)))
{
- RETURN( 0);
- }
-
- if (hRgn) // The region will be deleted in user32.
- {
- if (GDIOBJ_ValidateHandle(hRgn, GDI_OBJECT_TYPE_REGION))
- {
- hrgnCopy = IntSysCreateRectRgn(0, 0, 0, 0);
- NtGdiCombineRgn(hrgnCopy, hRgn, 0, RGN_COPY);
- }
- else
- RETURN( 0);
+ RETURN( FALSE);
}
- else
- hrgnCopy = (HRGN) 1;
- if (Window->hrgnClip)
+ if (! IntSetMenu(Window, Menu, &Changed))
{
- /* Delete no longer needed region handle */
- GreDeleteObject(Window->hrgnClip);
+ RETURN( FALSE);
}
- Window->hrgnClip = hrgnCopy;
- /* FIXME - send WM_WINDOWPOSCHANGING and WM_WINDOWPOSCHANGED messages to the window */
-
- if(bRedraw)
+ if (Changed && Repaint)
{
USER_REFERENCE_ENTRY Ref;
+
UserRefObjectCo(Window, &Ref);
- co_UserRedrawWindow(Window, NULL, NULL, RDW_INVALIDATE);
+ co_WinPosSetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
+ SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
+
UserDerefObjectCo(Window);
}
- RETURN( (INT)hRgn);
+ RETURN( TRUE);
CLEANUP:
- DPRINT("Leave NtUserSetWindowRgn, ret=%i\n",_ret_);
+ DPRINT("Leave NtUserSetMenu, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
* @implemented
*/
BOOL APIENTRY
-NtUserShowWindow(HWND hWnd, LONG nCmdShow)
+NtUserSetWindowFNID(HWND hWnd,
+ WORD fnID)
{
- PWINDOW_OBJECT Window;
- BOOL ret;
+ PWND Wnd;
DECLARE_RETURN(BOOL);
- USER_REFERENCE_ENTRY Ref;
- DPRINT("Enter NtUserShowWindow\n");
+ DPRINT("Enter NtUserSetWindowFNID\n");
UserEnterExclusive();
- if (!(Window = UserGetWindowObject(hWnd)))
+ if (!(Wnd = UserGetWindowObject(hWnd)))
{
- RETURN(FALSE);
+ RETURN( FALSE);
}
- UserRefObjectCo(Window, &Ref);
- ret = co_WinPosShowWindow(Window, nCmdShow);
- UserDerefObjectCo(Window);
+ if (Wnd->head.pti->ppi != PsGetCurrentProcessWin32Process())
+ {
+ EngSetLastError(ERROR_ACCESS_DENIED);
+ RETURN( FALSE);
+ }
- RETURN(ret);
+ // From user land we only set these.
+ if (fnID != FNID_DESTROY)
+ { // Hacked so we can mark desktop~!
+ if ( (/*(fnID < FNID_BUTTON)*/ (fnID < FNID_FIRST) && (fnID > FNID_GHOST)) ||
+ Wnd->fnid != 0 )
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ RETURN( FALSE);
+ }
+ }
+
+ Wnd->fnid |= fnID;
+ RETURN( TRUE);
CLEANUP:
- DPRINT("Leave NtUserShowWindow, ret=%i\n",_ret_);
+ DPRINT("Leave NtUserSetWindowFNID\n");
UserLeave();
END_CLEANUP;
}
-
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserShowWindowAsync(HWND hWnd, LONG nCmdShow)
-{
-#if 0
- UNIMPLEMENTED
- return 0;
-#else
- return NtUserShowWindow(hWnd, nCmdShow);
-#endif
-}
-
-
-/*
- * @unimplemented
- */
-BOOL
-APIENTRY
-NtUserUpdateLayeredWindow(
- HWND hwnd,
- HDC hdcDst,
- POINT *pptDst,
- SIZE *psize,
- HDC hdcSrc,
- POINT *pptSrc,
- COLORREF crKey,
- BLENDFUNCTION *pblend,
- DWORD dwFlags,
- RECT *prcDirty)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-/*
- * @unimplemented
- */
-HWND APIENTRY
-NtUserWindowFromPhysicalPoint(POINT Point)
-{
- UNIMPLEMENTED
-
- return NULL;
-}
-
/*
* @implemented
*/
{
POINT pt;
HWND Ret;
- PWINDOW_OBJECT DesktopWindow = NULL, Window = NULL;
+ PWND DesktopWindow = NULL, Window = NULL;
+ USHORT hittest;
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);
+ Window = co_WinPosWindowFromPoint(DesktopWindow, &pt, &hittest);
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!
}
else
{
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
Ret = FALSE;
goto Exit;
}
// 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;
if(lpString && (nMaxCount <= 1))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
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,
PUSER_HANDLE_ENTRY entry;
if (!(entry = handle_to_entry(gHandleTable, handle )))
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
uType = entry->type;
{
case otWindow:
{
- PWINDOW_OBJECT Window;
+ PWND Window;
if ((Window = UserGetWindowObject((HWND) handle))) return TRUE;
return FALSE;
}
return UserGetCallProcInfo( handle, &Proc );
}
default:
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
}
}
else