+/*
+ * ReactOS W32 Subsystem
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
#include <include/callback.h>
#include <include/msgqueue.h>
#include <include/rect.h>
+#include <include/dce.h>
+#include <include/paint.h>
+#include <include/painting.h>
+#include <include/scroll.h>
+#include <include/vis.h>
+#include <include/menu.h>
#define NDEBUG
#include <win32k/debug1.h>
#define TAG_WNAM TAG('W', 'N', 'A', 'M')
-/* FUNCTIONS *****************************************************************/
-
-HWND STDCALL
-NtUserGetAncestor(HWND hWnd, UINT Flags)
+typedef struct _REGISTERED_MESSAGE
{
- if (W32kIsDesktopWindow(hWnd))
- {
- return(NULL);
- }
- if (Flags & GA_PARENT)
- {
- PWINDOW_OBJECT Window;
- HWND hParent;
+ LIST_ENTRY ListEntry;
+ WCHAR MessageName[1];
+} REGISTERED_MESSAGE, *PREGISTERED_MESSAGE;
- Window = W32kGetWindowObject(hWnd);
- if (Window == NULL)
- {
- return(NULL);
- }
+static LIST_ENTRY RegisteredMessageListHead;
- if (Window->Parent == NULL)
- {
- W32kReleaseWindowObject(Window);
- }
+#define REGISTERED_MESSAGE_MIN 0xc000
+#define REGISTERED_MESSAGE_MAX 0xffff
- hParent = Window->Parent->Self;
- W32kReleaseWindowObject(Window);
+ /* globally stored handles to the shell windows */
+HWND hwndShellWindow = 0;
+HWND hwndShellListView = 0;
+DWORD pidShellWindow = 0;
- return(hParent);
- }
- else
- {
- UNIMPLEMENTED;
- return(NULL);
- }
-}
-VOID
-W32kSetFocusWindow(HWND hWnd)
+NTSTATUS FASTCALL
+InitWindowImpl(VOID)
{
-}
+ InitializeListHead(&RegisteredMessageListHead);
-BOOL
-W32kIsChildWindow(HWND Parent, HWND Child)
-{
- PWINDOW_OBJECT BaseWindow = W32kGetWindowObject(Child);
- PWINDOW_OBJECT Window = BaseWindow;
- while (Window != NULL && Window->Style & WS_CHILD)
- {
- if (Window->Self == Parent)
- {
- W32kReleaseWindowObject(BaseWindow);
- return(TRUE);
- }
- Window = Window->Parent;
- }
- W32kReleaseWindowObject(BaseWindow);
- return(FALSE);
+ return(STATUS_SUCCESS);
}
-BOOL
-W32kIsWindowVisible(HWND Wnd)
+NTSTATUS FASTCALL
+CleanupWindowImpl(VOID)
{
- PWINDOW_OBJECT BaseWindow = W32kGetWindowObject(Wnd);
- PWINDOW_OBJECT Window = BaseWindow;
- BOOLEAN Result = FALSE;
- while (Window != NULL && Window->Style & WS_CHILD)
- {
- if (!(Window->Style & WS_VISIBLE))
- {
- W32kReleaseWindowObject(BaseWindow);
- return(FALSE);
- }
- Window = Window->Parent;
- }
- if (Window != NULL && Window->Style & WS_VISIBLE)
- {
- Result = TRUE;
- }
- W32kReleaseWindowObject(BaseWindow);
- return(Result);
+ return(STATUS_SUCCESS);
}
-BOOL
-W32kIsDesktopWindow(HWND hWnd)
-{
- PWINDOW_OBJECT WindowObject;
- BOOL IsDesktop;
- WindowObject = W32kGetWindowObject(hWnd);
- IsDesktop = WindowObject->Parent == NULL;
- W32kReleaseWindowObject(WindowObject);
- return(IsDesktop);
-}
-HWND W32kGetDesktopWindow()
-{
- return W32kGetActiveDesktop()->DesktopWindow;
-}
+/* HELPER FUNCTIONS ***********************************************************/
-HWND W32kGetParentWindow(HWND hWnd)
+/* check if hwnd is a broadcast magic handle */
+inline BOOL IntIsBroadcastHwnd( HWND hwnd )
{
- return W32kGetWindowObject(hWnd)->ParentHandle;
+ return (hwnd == HWND_BROADCAST || hwnd == HWND_TOPMOST);
}
-PWINDOW_OBJECT
-W32kGetWindowObject(HWND hWnd)
-{
- PWINDOW_OBJECT WindowObject;
- NTSTATUS Status;
- Status =
- ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->
- HandleTable,
- hWnd,
- otWindow,
- (PVOID*)&WindowObject);
- if (!NT_SUCCESS(Status))
- {
- return(NULL);
- }
- return(WindowObject);
-}
-VOID
-W32kReleaseWindowObject(PWINDOW_OBJECT Window)
+inline BOOL IntIsDesktopWindow(PWINDOW_OBJECT Wnd)
{
- ObmDereferenceObject(Window);
+ return Wnd->Parent == NULL;
}
-/*!
- * Internal function.
- * Returns client window rectangle relative to the upper-left corner of client area.
- *
- * \note Does not check the validity of the parameters
-*/
-VOID
-W32kGetClientRect(PWINDOW_OBJECT WindowObject, PRECT Rect)
-{
- ASSERT( WindowObject );
- ASSERT( Rect );
-
- Rect->left = Rect->top = 0;
- Rect->right = WindowObject->ClientRect.right - WindowObject->ClientRect.left;
- Rect->bottom =
- WindowObject->ClientRect.bottom - WindowObject->ClientRect.top;
-}
-/*!
- * Internal Function.
- * Return the dimension of the window in the screen coordinates.
-*/
-BOOL STDCALL
-W32kGetWindowRect(HWND hWnd, LPRECT Rect)
+static BOOL BuildChildWindowArray(PWINDOW_OBJECT Window, HWND **Children, unsigned *NumChildren)
{
- PWINDOW_OBJECT WindowObject;
-
- ASSERT( Rect );
-
- WindowObject = W32kGetWindowObject(hWnd);
- if (WindowObject == NULL)
+ unsigned Index;
+ PWINDOW_OBJECT Child;
+
+ *Children = NULL;
+ *NumChildren = 0;
+
+ ExAcquireFastMutexUnsafe(&Window->ChildrenListLock);
+ Child = Window->FirstChild;
+ while (Child)
+ {
+ (*NumChildren)++;
+ Child = Child->NextSibling;
+ }
+
+ if (0 != *NumChildren)
+ {
+ *Children = ExAllocatePoolWithTag(PagedPool, *NumChildren * sizeof(HWND), TAG_WNAM);
+ if (NULL != *Children)
{
- return(FALSE);
+ Child = Window->FirstChild;
+ Index = 0;
+ while (Child)
+ {
+ (*Children)[Index] = Child->Self;
+ Child = Child->NextSibling;
+ Index++;
+ }
+ assert(Index == *NumChildren);
}
- *Rect = WindowObject->WindowRect;
- if (WindowObject->Style & WS_CHILD)
+ else
{
- DbgBreakPoint();
+ DPRINT1("Failed to allocate memory for children array\n");
}
- W32kReleaseWindowObject(WindowObject);
- return(TRUE);
-}
+ }
+ ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
-/*!
- * Return the dimension of the window in the screen coordinates.
- * \param hWnd window handle.
- * \param Rect pointer to the buffer where the coordinates are returned.
-*/
-BOOL STDCALL
-NtUserGetWindowRect(HWND hWnd, LPRECT Rect)
-{
- RECT SafeRect;
- BOOL bRet;
- bRet = W32kGetWindowRect(hWnd, &SafeRect);
- if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT)))){
- return(FALSE);
- }
- return( bRet );
+ return 0 == *NumChildren || NULL != *Children;
}
-/*!
- * Returns client window rectangle relative to the upper-left corner of client area.
- *
- * \param hWnd window handle.
- * \param Rect pointer to the buffer where the coordinates are returned.
+
+/***********************************************************************
+ * IntDestroyWindow
*
-*/
-BOOL STDCALL
-NtUserGetClientRect(HWND hWnd, LPRECT Rect)
+ * Destroy storage associated to a window. "Internals" p.358
+ */
+static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
+ PW32PROCESS ProcessData,
+ PW32THREAD ThreadData,
+ BOOLEAN SendMessages)
{
- PWINDOW_OBJECT WindowObject;
- RECT SafeRect;
+ HWND *Children;
+ unsigned NumChildren;
+ unsigned Index;
+ PWINDOW_OBJECT Child;
- WindowObject = W32kGetWindowObject(hWnd);
- if (WindowObject == NULL)
+ if (! IntWndBelongsToThread(Window, ThreadData))
{
- return(FALSE);
+ DPRINT1("Window doesn't belong to current thread\n");
+ return 0;
}
- W32kGetClientRect(WindowObject, &SafeRect);
- if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT))))
+
+ /* free child windows */
+ if (! BuildChildWindowArray(Window, &Children, &NumChildren))
{
- return(FALSE);
+ return 0;
}
-
- W32kReleaseWindowObject(WindowObject);
- return(TRUE);
-}
-
-HWND
-W32kGetActiveWindow(VOID)
-{
- PUSER_MESSAGE_QUEUE Queue;
- Queue = (PUSER_MESSAGE_QUEUE)W32kGetActiveDesktop()->ActiveMessageQueue;
- if (Queue == NULL)
+ for (Index = NumChildren; 0 < Index; Index--)
{
- return(NULL);
+ Child = IntGetWindowObject(Children[Index - 1]);
+ if (NULL != Child)
+ {
+ if (IntWndBelongsToThread(Child, ThreadData))
+ {
+ IntDestroyWindow(Child, ProcessData, ThreadData, SendMessages);
+ }
+#if 0 /* FIXME */
+ else
+ {
+ SendMessageW( list[i], WM_WINE_DESTROYWINDOW, 0, 0 );
+ }
+#endif
+ }
}
- else
+ if (0 != NumChildren)
{
- return(Queue->ActiveWindow);
+ ExFreePool(Children);
}
-}
-HWND
-W32kGetFocusWindow(VOID)
-{
- PUSER_MESSAGE_QUEUE Queue;
- PDESKTOP_OBJECT pdo = W32kGetActiveDesktop();
+ if (SendMessages)
+ {
+ /*
+ * Clear the update region to make sure no WM_PAINT messages will be
+ * generated for this window while processing the WM_NCDESTROY.
+ */
+ PaintRedrawWindow(Window, NULL, 0,
+ RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_NOCHILDREN,
+ 0);
+
+ /*
+ * Send the WM_NCDESTROY to the window being destroyed.
+ */
+ NtUserSendMessage(Window->Self, WM_NCDESTROY, 0, 0);
+ }
- if( !pdo )
- return NULL;
+ /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
- Queue = (PUSER_MESSAGE_QUEUE)pdo->ActiveMessageQueue;
+#if 0 /* FIXME */
+ WinPosCheckInternalPos(Window->Self);
+ if (Window->Self == GetCapture())
+ {
+ ReleaseCapture();
+ }
- if (Queue == NULL)
- return(NULL);
- else
- return(Queue->FocusWindow);
-}
+ /* free resources associated with the window */
+ TIMER_RemoveWindowTimers(Window->Self);
+#endif
+#if 0 /* FIXME */
+ if (0 == (Window->Style & WS_CHILD))
+ {
+ HMENU Menu = (HMENU) NtUserSetWindowLongW(Window->Self, GWL_ID, 0);
+ if (NULL != Menu)
+ {
+ DestroyMenu(Menu);
+ }
+ }
+ if (Window->hSysMenu)
+ {
+ DestroyMenu(Window->hSysMenu);
+ Window->hSysMenu = 0;
+ }
+ DCE_FreeWindowDCE(Window->Self); /* Always do this to catch orphaned DCs */
+ WINPROC_FreeProc(Window->winproc, WIN_PROC_WINDOW);
+ CLASS_RemoveWindow(Window->Class);
+#endif
-WNDPROC
-W32kGetWindowProc(HWND Wnd)
-{
- PWINDOW_OBJECT WindowObject;
- WNDPROC WndProc;
+ ExAcquireFastMutexUnsafe(&Window->Parent->ChildrenListLock);
+ IntUnlinkWindow(Window);
+ ExReleaseFastMutexUnsafe(&Window->Parent->ChildrenListLock);
- WindowObject = W32kGetWindowObject(Wnd);
- if( !WindowObject )
- return NULL;
+ ExAcquireFastMutexUnsafe (&ThreadData->WindowListLock);
+ RemoveEntryList(&Window->ThreadListEntry);
+ ExReleaseFastMutexUnsafe (&ThreadData->WindowListLock);
+
+ IntDestroyScrollBar(Window, SB_VERT);
+ IntDestroyScrollBar(Window, SB_HORZ);
- WndProc = WindowObject->Class->Class.lpfnWndProc;
- W32kReleaseWindowObject(Wnd);
- return(WndProc);
-}
+ Window->Class = NULL;
+ ObmCloseHandle(ProcessData->WindowStation->HandleTable, Window->Self);
-NTSTATUS
-InitWindowImpl(VOID)
-{
- return(STATUS_SUCCESS);
-}
+ IntGraphicsCheck(FALSE);
-NTSTATUS
-CleanupWindowImpl(VOID)
-{
- return(STATUS_SUCCESS);
+ return 0;
}
-DWORD STDCALL
-NtUserAlterWindowStyle(DWORD Unknown0,
- DWORD Unknown1,
- DWORD Unknown2)
-{
- UNIMPLEMENTED
+/* INTERNAL ******************************************************************/
- return(0);
-}
-DWORD STDCALL
-NtUserChildWindowFromPointEx(HWND Parent,
- LONG x,
- LONG y,
- UINT Flags)
+VOID FASTCALL
+DestroyThreadWindows(struct _ETHREAD *Thread)
{
- UNIMPLEMENTED
-
- return(0);
+ PLIST_ENTRY LastHead;
+ PW32PROCESS Win32Process;
+ PW32THREAD Win32Thread;
+ PWINDOW_OBJECT Window;
+
+ Win32Thread = Thread->Win32Thread;
+ Win32Process = Thread->ThreadsProcess->Win32Process;
+ ExAcquireFastMutexUnsafe(&Win32Thread->WindowListLock);
+ LastHead = NULL;
+ while (Win32Thread->WindowListHead.Flink != &(Win32Thread->WindowListHead) &&
+ Win32Thread->WindowListHead.Flink != LastHead)
+ {
+ LastHead = Win32Thread->WindowListHead.Flink;
+ Window = CONTAINING_RECORD(Win32Thread->WindowListHead.Flink, WINDOW_OBJECT, ThreadListEntry);
+ ExReleaseFastMutexUnsafe(&Win32Thread->WindowListLock);
+ IntDestroyWindow(Window, Win32Process, Win32Thread, FALSE);
+ ExAcquireFastMutexUnsafe(&Win32Thread->WindowListLock);
+ }
+ if (Win32Thread->WindowListHead.Flink == LastHead)
+ {
+ /* Window at head of list was not removed, should never happen, infinite loop */
+ KEBUGCHECK(0);
+ }
+ ExReleaseFastMutexUnsafe(&Win32Thread->WindowListLock);
}
+
HWND STDCALL
-W32kCreateDesktopWindow(PWINSTATION_OBJECT WindowStation,
+IntCreateDesktopWindow(PWINSTATION_OBJECT WindowStation,
PWNDCLASS_OBJECT DesktopClass,
ULONG Width, ULONG Height)
{
WindowObject->Height = Height;
WindowObject->ParentHandle = NULL;
WindowObject->Parent = NULL;
- WindowObject->Menu = NULL;
+ WindowObject->IDMenu = 0;
WindowObject->Instance = NULL;
WindowObject->Parameters = NULL;
WindowObject->Self = Handle;
WindowObject->WindowRect.right = Width;
WindowObject->WindowRect.bottom = Height;
WindowObject->ClientRect = WindowObject->WindowRect;
- InitializeListHead(&WindowObject->ChildrenListHead);
+ WindowObject->UserData = 0;
+ /*FIXME: figure out what the correct strange value is and what to do with it (and how to set the wndproc values correctly) */
+ WindowObject->WndProcA = DesktopClass->lpfnWndProcA;
+ WindowObject->WndProcW = DesktopClass->lpfnWndProcW;
+ WindowObject->OwnerThread = PsGetCurrentThread();
+ WindowObject->FirstChild = NULL;
+ WindowObject->LastChild = NULL;
+ WindowObject->PrevSibling = NULL;
+ WindowObject->NextSibling = NULL;
+
+ ExInitializeFastMutex(&WindowObject->ChildrenListLock);
WindowName = ExAllocatePool(NonPagedPool, sizeof(L"DESKTOP"));
wcscpy(WindowName, L"DESKTOP");
return(Handle);
}
-HWND STDCALL
-NtUserCreateWindowEx(DWORD dwExStyle,
- PUNICODE_STRING lpClassName,
- PUNICODE_STRING lpWindowName,
- DWORD dwStyle,
- LONG x,
- LONG y,
- LONG nWidth,
- LONG nHeight,
- HWND hWndParent,
- HMENU hMenu,
- HINSTANCE hInstance,
- LPVOID lpParam,
- DWORD dwShowMode)
-{
- PWINSTATION_OBJECT WinStaObject;
- PWNDCLASS_OBJECT ClassObject;
- PWINDOW_OBJECT WindowObject;
- PWINDOW_OBJECT ParentWindow;
- UNICODE_STRING WindowName;
- NTSTATUS Status;
- HANDLE Handle;
- POINT MaxSize, MaxPos, MinTrack, MaxTrack;
- CREATESTRUCTW Cs;
- LRESULT Result;
- DPRINT("NtUserCreateWindowEx\n");
-
- /* Initialize gui state if necessary. */
- W32kGuiCheck();
- W32kGraphicsCheck(TRUE);
-
- if (!RtlCreateUnicodeString(&WindowName, lpWindowName->Buffer))
- {
- SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
- return((HWND)0);
- }
- if (hWndParent != NULL)
+HWND FASTCALL
+IntGetActiveWindow(VOID)
+{
+ PUSER_MESSAGE_QUEUE Queue;
+ Queue = (PUSER_MESSAGE_QUEUE)IntGetActiveDesktop()->ActiveMessageQueue;
+ if (Queue == NULL)
{
- ParentWindow = W32kGetWindowObject(hWndParent);
+ return(NULL);
}
else
{
- hWndParent = PsGetWin32Thread()->Desktop->DesktopWindow;
- ParentWindow = W32kGetWindowObject(hWndParent);
+ return(Queue->ActiveWindow);
}
+}
- /* Check the class. */
- Status = ClassReferenceClassByNameOrAtom(&ClassObject, lpClassName->Buffer);
- if (!NT_SUCCESS(Status))
- {
- RtlFreeUnicodeString(&WindowName);
- return((HWND)0);
- }
- /* Check the window station. */
- DPRINT("IoGetCurrentProcess() %X\n", IoGetCurrentProcess());
- DPRINT("PROCESS_WINDOW_STATION %X\n", PROCESS_WINDOW_STATION());
+PWINDOW_OBJECT FASTCALL
+IntGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
+{
+ if (IntIsDesktopWindow(Wnd)) return NULL;
+
+ switch (Type)
+ {
+ case GA_PARENT:
+ return Wnd->Parent;
+
+ case GA_ROOT:
+ while(!IntIsDesktopWindow(Wnd->Parent))
+ {
+ Wnd = Wnd->Parent;
+ }
+ return Wnd;
+
+ case GA_ROOTOWNER:
+ while ((Wnd = IntGetParent(Wnd)));
+ return Wnd;
+ }
+
+ return NULL;
+}
+
+
+/*!
+ * Internal function.
+ * Returns client window rectangle relative to the upper-left corner of client area.
+ *
+ * \note Does not check the validity of the parameters
+*/
+VOID FASTCALL
+IntGetClientRect(PWINDOW_OBJECT WindowObject, PRECT Rect)
+{
+ ASSERT( WindowObject );
+ ASSERT( Rect );
+
+ Rect->left = Rect->top = 0;
+ Rect->right = WindowObject->ClientRect.right - WindowObject->ClientRect.left;
+ Rect->bottom =
+ WindowObject->ClientRect.bottom - WindowObject->ClientRect.top;
+}
+
+
+HWND FASTCALL IntGetDesktopWindow(VOID)
+{
+ return IntGetActiveDesktop()->DesktopWindow;
+}
+
+
+HWND FASTCALL
+IntGetFocusWindow(VOID)
+{
+ PUSER_MESSAGE_QUEUE Queue;
+ PDESKTOP_OBJECT pdo = IntGetActiveDesktop();
+
+ if( !pdo )
+ return NULL;
+
+ Queue = (PUSER_MESSAGE_QUEUE)pdo->ActiveMessageQueue;
+
+ if (Queue == NULL)
+ return(NULL);
+ else
+ return(Queue->FocusWindow);
+}
+
+
+PWINDOW_OBJECT FASTCALL
+IntGetParent(PWINDOW_OBJECT Wnd)
+{
+ if (Wnd->Style & WS_POPUP)
+ {
+ return IntGetWindowObject(Wnd->ParentHandle); /* wine use HWND for owner window (unknown reason) */
+ }
+ else if (Wnd->Style & WS_CHILD)
+ {
+ return Wnd->Parent;
+ }
+
+ return NULL;
+}
+
+
+HMENU FASTCALL
+IntGetSystemMenu(PWINDOW_OBJECT WindowObject, BOOL bRevert, BOOL RetMenu)
+{
+ PMENU_OBJECT MenuObject, NewMenuObject;
+ PW32PROCESS W32Process;
+ HMENU NewMenu, ret = (HMENU)0;
+
+ if(bRevert)
+ {
+ W32Process = PsGetWin32Process();
+
+ if(!W32Process->WindowStation)
+ return (HMENU)0;
+
+ if(WindowObject->SystemMenu)
+ {
+ MenuObject = IntGetMenuObject(WindowObject->SystemMenu);
+ if(MenuObject)
+ {
+ IntDestroyMenuObject(MenuObject, FALSE, TRUE);
+ }
+ }
+
+ if(W32Process->WindowStation->SystemMenuTemplate)
+ {
+ /* clone system menu */
+ MenuObject = IntGetMenuObject(W32Process->WindowStation->SystemMenuTemplate);
+ if(!MenuObject)
+ return (HMENU)0;
+
+ NewMenuObject = IntCloneMenu(MenuObject);
+ if(NewMenuObject)
+ {
+ WindowObject->SystemMenu = NewMenuObject->Self;
+ NewMenuObject->IsSystemMenu = TRUE;
+ ret = NewMenuObject->Self;
+ IntReleaseMenuObject(NewMenuObject);
+ }
+ IntReleaseMenuObject(MenuObject);
+ }
+ else
+ {
+ NewMenu = IntLoadSysMenuTemplate();
+ if(!NewMenu)
+ return (HMENU)0;
+ MenuObject = IntGetMenuObject(NewMenu);
+ if(!MenuObject)
+ return (HMENU)0;
+
+ NewMenuObject = IntCloneMenu(MenuObject);
+ if(NewMenuObject)
+ {
+ WindowObject->SystemMenu = NewMenuObject->Self;
+ NewMenuObject->IsSystemMenu = TRUE;
+ ret = NewMenuObject->Self;
+ IntReleaseMenuObject(NewMenuObject);
+ }
+ IntDestroyMenuObject(MenuObject, FALSE, TRUE);
+ }
+ if(RetMenu)
+ return ret;
+ else
+ return (HMENU)0;
+ }
+ else
+ {
+ return WindowObject->SystemMenu;
+ }
+}
+
+
+PWINDOW_OBJECT FASTCALL
+IntGetWindowObject(HWND hWnd)
+{
+ PWINDOW_OBJECT WindowObject;
+ NTSTATUS Status;
+ Status =
+ ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->
+ HandleTable,
+ hWnd,
+ otWindow,
+ (PVOID*)&WindowObject);
+ if (!NT_SUCCESS(Status))
+ {
+ return(NULL);
+ }
+ return(WindowObject);
+}
+
+
+DWORD FASTCALL
+IntGetWindowThreadProcessId(PWINDOW_OBJECT Wnd, PDWORD pid)
+{
+ if (pid) *pid = (DWORD) Wnd->OwnerThread->ThreadsProcess->UniqueProcessId;
+ return (DWORD) Wnd->OwnerThread->Cid.UniqueThread;
+}
+
+
+VOID FASTCALL
+IntInitDesktopWindow(ULONG Width, ULONG Height)
+{
+ PWINDOW_OBJECT DesktopWindow;
+ HRGN DesktopRgn;
+
+ DesktopWindow = IntGetWindowObject(PsGetWin32Thread()->Desktop->DesktopWindow);
+ if (NULL == DesktopWindow)
+ {
+ return;
+ }
+ DesktopWindow->WindowRect.right = Width;
+ DesktopWindow->WindowRect.bottom = Height;
+ DesktopWindow->ClientRect = DesktopWindow->WindowRect;
+
+ DesktopRgn = UnsafeIntCreateRectRgnIndirect(&(DesktopWindow->WindowRect));
+ VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, DesktopWindow, DesktopRgn);
+ NtGdiDeleteObject(DesktopRgn);
+ IntReleaseWindowObject(DesktopWindow);
+}
+
+
+BOOL FASTCALL
+IntIsChildWindow(HWND Parent, HWND Child)
+{
+ PWINDOW_OBJECT BaseWindow = IntGetWindowObject(Child);
+ PWINDOW_OBJECT Window = BaseWindow;
+ while (Window != NULL && Window->Style & WS_CHILD)
+ {
+ if (Window->Self == Parent)
+ {
+ IntReleaseWindowObject(BaseWindow);
+ return(TRUE);
+ }
+ Window = Window->Parent;
+ }
+ IntReleaseWindowObject(BaseWindow);
+ return(FALSE);
+}
+
+
+BOOL FASTCALL
+IntIsWindowVisible(HWND Wnd)
+{
+ PWINDOW_OBJECT BaseWindow = IntGetWindowObject(Wnd);
+ PWINDOW_OBJECT Window = BaseWindow;
+ BOOLEAN Result = FALSE;
+ while (Window != NULL && Window->Style & WS_CHILD)
+ {
+ if (!(Window->Style & WS_VISIBLE))
+ {
+ IntReleaseWindowObject(BaseWindow);
+ return(FALSE);
+ }
+ Window = Window->Parent;
+ }
+ if (Window != NULL && Window->Style & WS_VISIBLE)
+ {
+ Result = TRUE;
+ }
+ IntReleaseWindowObject(BaseWindow);
+ return(Result);
+}
+
+
+/* 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 */
+ )
+{
+ Wnd->Parent = WndParent;
+
+ if ((Wnd->PrevSibling = WndPrevSibling))
+ {
+ /* link after WndPrevSibling */
+ if ((Wnd->NextSibling = WndPrevSibling->NextSibling)) Wnd->NextSibling->PrevSibling = Wnd;
+ else if (Wnd->Parent->LastChild == WndPrevSibling) Wnd->Parent->LastChild = Wnd;
+ Wnd->PrevSibling->NextSibling = Wnd;
+ }
+ else
+ {
+ /* link at top */
+ if ((Wnd->NextSibling = WndParent->FirstChild)) Wnd->NextSibling->PrevSibling = Wnd;
+ else Wnd->Parent->LastChild = Wnd;
+ WndParent->FirstChild = Wnd;
+ }
+
+}
+
+
+HWND FASTCALL
+IntSetFocusWindow(HWND hWnd)
+{
+ PUSER_MESSAGE_QUEUE OldMessageQueue;
+ PDESKTOP_OBJECT DesktopObject;
+ PWINDOW_OBJECT WindowObject;
+ HWND hWndOldFocus;
+
+ DPRINT("IntSetFocusWindow(hWnd 0x%x)\n", hWnd);
+
+ if (hWnd != (HWND)0)
+ {
+ WindowObject = IntGetWindowObject(hWnd);
+ if (!WindowObject)
+ {
+ DPRINT("Bad window handle 0x%x\n", hWnd);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return (HWND)0;
+ }
+ }
+ else
+ {
+ WindowObject = NULL;
+ }
+
+ DesktopObject = IntGetActiveDesktop();
+ if (!DesktopObject)
+ {
+ DPRINT("No active desktop\n");
+ if (WindowObject != NULL)
+ {
+ IntReleaseWindowObject(WindowObject);
+ }
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return (HWND)0;
+ }
+
+ hWndOldFocus = (HWND)0;
+ OldMessageQueue = (PUSER_MESSAGE_QUEUE)DesktopObject->ActiveMessageQueue;
+ if (OldMessageQueue != NULL)
+ {
+ hWndOldFocus = OldMessageQueue->FocusWindow;
+ }
+
+ if (WindowObject != NULL)
+ {
+ WindowObject->MessageQueue->FocusWindow = hWnd;
+ (PUSER_MESSAGE_QUEUE)DesktopObject->ActiveMessageQueue =
+ WindowObject->MessageQueue;
+ IntReleaseWindowObject(WindowObject);
+ }
+ else
+ {
+ (PUSER_MESSAGE_QUEUE)DesktopObject->ActiveMessageQueue = NULL;
+ }
+
+ DPRINT("hWndOldFocus = 0x%x\n", hWndOldFocus);
+
+ return hWndOldFocus;
+}
+
+
+PWINDOW_OBJECT FASTCALL
+IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
+{
+ PWINDOW_OBJECT WndOldParent;
+ BOOL was_visible;
+ HWND hWnd, hWndNewParent, hWndOldParent;
+
+ if (!WndNewParent) WndNewParent = IntGetWindowObject(IntGetDesktopWindow());
+
+ hWnd = Wnd;
+ hWndNewParent = WndNewParent;
+
+#if 0
+ if (!(full_handle = WIN_IsCurrentThread( hwnd )))
+ return (HWND)SendMessageW( hwnd, WM_WINE_SETPARENT, (WPARAM)parent, 0 );
+
+ if (USER_Driver.pSetParent)
+ return USER_Driver.pSetParent( hwnd, parent );
+#endif
+
+ /* Windows hides the window first, then shows it again
+ * including the WM_SHOWWINDOW messages and all */
+ was_visible = WinPosShowWindow( hWnd, SW_HIDE );
+
+ /* validate that window and parent still exist */
+ if (!IntGetWindowObject(hWnd) || !IntGetWindowObject(hWndNewParent)) return NULL;
+
+ /* window must belong to current process */
+ if (Wnd->OwnerThread->ThreadsProcess != PsGetCurrentProcess()) return NULL;
+
+ WndOldParent = Wnd->Parent;
+ hWndOldParent = WndOldParent->Self;
+
+ if (WndNewParent != WndOldParent)
+ {
+ IntUnlinkWindow(Wnd);
+ IntLinkWindow(Wnd, WndNewParent, NULL /*prev sibling*/);
+
+ if (WndNewParent->Self != IntGetDesktopWindow()) /* a child window */
+ {
+ if (!(Wnd->Style & WS_CHILD))
+ {
+ //if ( Wnd->Menu ) DestroyMenu ( Wnd->menu );
+ Wnd->IDMenu = 0;
+ }
+ }
+ }
+
+ /* SetParent additionally needs to make hwnd the topmost window
+ in the x-order and send the expected WM_WINDOWPOSCHANGING and
+ WM_WINDOWPOSCHANGED notification messages.
+ */
+ WinPosSetWindowPos( hWnd, HWND_TOPMOST, 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | (was_visible ? SWP_SHOWWINDOW : 0) );
+ /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
+ * 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
+ */
+ return (IntGetWindowObject(hWndOldParent) ? WndOldParent : NULL);
+}
+
+
+VOID FASTCALL
+IntReleaseWindowObject(PWINDOW_OBJECT Window)
+{
+ ObmDereferenceObject(Window);
+}
+
+
+/***********************************************************************
+ * IntSendDestroyMsg
+ */
+static void IntSendDestroyMsg(HWND Wnd)
+{
+#if 0 /* FIXME */
+ GUITHREADINFO info;
+
+ if (GetGUIThreadInfo(GetCurrentThreadId(), &info))
+ {
+ if (Wnd == info.hwndCaret)
+ {
+ DestroyCaret();
+ }
+ }
+#endif
+
+ /*
+ * Send the WM_DESTROY to the window.
+ */
+ NtUserSendMessage(Wnd, WM_DESTROY, 0, 0);
+
+ /*
+ * This WM_DESTROY message can trigger re-entrant calls to DestroyWindow
+ * make sure that the window still exists when we come back.
+ */
+#if 0 /* FIXME */
+ if (IsWindow(Wnd))
+ {
+ HWND* pWndArray;
+ int i;
+
+ if (!(pWndArray = WIN_ListChildren( hwnd ))) return;
+
+ /* start from the end (FIXME: is this needed?) */
+ for (i = 0; pWndArray[i]; i++) ;
+
+ while (--i >= 0)
+ {
+ if (IsWindow( pWndArray[i] )) WIN_SendDestroyMsg( pWndArray[i] );
+ }
+ HeapFree(GetProcessHeap(), 0, pWndArray);
+ }
+ else
+ {
+ DPRINT("destroyed itself while in WM_DESTROY!\n");
+ }
+#endif
+}
+
+
+BOOL FASTCALL
+IntSetSystemMenu(PWINDOW_OBJECT WindowObject, PMENU_OBJECT MenuObject)
+{
+ PMENU_OBJECT OldMenuObject;
+ if(WindowObject->SystemMenu)
+ {
+ OldMenuObject = IntGetMenuObject(WindowObject->SystemMenu);
+ if(OldMenuObject)
+ {
+ OldMenuObject->IsSystemMenu = FALSE;
+ IntReleaseMenuObject(OldMenuObject);
+ }
+ }
+
+ WindowObject->SystemMenu = MenuObject->Self;
+ if(MenuObject) /* FIXME check window style, propably return FALSE ? */
+ MenuObject->IsSystemMenu = TRUE;
+
+ return TRUE;
+}
+
+
+/* unlink the window from siblings and parent. children are kept in place. */
+VOID FASTCALL
+IntUnlinkWindow(PWINDOW_OBJECT Wnd)
+{
+ PWINDOW_OBJECT WndParent = Wnd->Parent;
+
+ if (Wnd->NextSibling) Wnd->NextSibling->PrevSibling = Wnd->PrevSibling;
+ else if (WndParent->LastChild == Wnd) WndParent->LastChild = Wnd->PrevSibling;
+
+ if (Wnd->PrevSibling) Wnd->PrevSibling->NextSibling = Wnd->NextSibling;
+ else if (WndParent->FirstChild == Wnd) WndParent->FirstChild = Wnd->NextSibling;
+ //else if (parent->first_unlinked == win) parent->first_unlinked = Wnd->NextSibling;
+}
+
+
+BOOLEAN FASTCALL
+IntWndBelongsToThread(PWINDOW_OBJECT Window, PW32THREAD ThreadData)
+{
+ if (Window->OwnerThread && Window->OwnerThread->Win32Thread)
+ {
+ return (Window->OwnerThread->Win32Thread == ThreadData);
+ }
+
+ return FALSE;
+}
+
+
+/* FUNCTIONS *****************************************************************/
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+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.
+ *
+ * It's supposed to build a list of HWNDs to return to the caller.
+ * We can figure out what kind of list by what parameters are
+ * passed to us.
+ */
+/*
+ * @implemented
+ */
+ULONG
+STDCALL
+NtUserBuildHwndList(
+ HDESK hDesktop,
+ HWND hwndParent,
+ BOOLEAN bChildren,
+ ULONG dwThreadId,
+ ULONG lParam,
+ HWND* pWnd,
+ ULONG nBufSize)
+{
+ ULONG dwCount = 0;
+
+ /* FIXME handle bChildren */
+ if ( hwndParent )
+ {
+ PWINDOW_OBJECT WindowObject = NULL;
+ PWINDOW_OBJECT Child;
+
+ WindowObject = IntGetWindowObject ( hwndParent );
+ if ( !WindowObject )
+ {
+ DPRINT("Bad window handle 0x%x\n", hwndParent);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+
+ ExAcquireFastMutex ( &WindowObject->ChildrenListLock );
+ Child = WindowObject->FirstChild;
+ while (Child)
+ {
+ if ( pWnd && dwCount < nBufSize )
+ pWnd[dwCount] = Child->Self;
+ dwCount++;
+ Child = Child->NextSibling;
+ }
+ ExReleaseFastMutex ( &WindowObject->ChildrenListLock );
+ IntReleaseWindowObject ( WindowObject );
+ }
+ else if ( dwThreadId )
+ {
+ NTSTATUS Status;
+ struct _ETHREAD* Thread;
+ struct _EPROCESS* ThreadsProcess;
+ struct _W32PROCESS* Win32Process;
+ struct _WINSTATION_OBJECT* WindowStation;
+ PUSER_HANDLE_TABLE HandleTable;
+ PLIST_ENTRY Current;
+ PUSER_HANDLE_BLOCK Block = NULL;
+ ULONG i;
+
+ Status = PsLookupThreadByThreadId ( (PVOID)dwThreadId, &Thread );
+ if ( !NT_SUCCESS(Status) || !Thread )
+ {
+ DPRINT("Bad ThreadId 0x%x\n", dwThreadId );
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+ ThreadsProcess = Thread->ThreadsProcess;
+ ASSERT(ThreadsProcess);
+ Win32Process = ThreadsProcess->Win32Process;
+ ASSERT(Win32Process);
+ WindowStation = Win32Process->WindowStation;
+ ASSERT(WindowStation);
+ HandleTable = (PUSER_HANDLE_TABLE)(WindowStation->HandleTable);
+ ASSERT(HandleTable);
+
+ ExAcquireFastMutex(&HandleTable->ListLock);
+
+ Current = HandleTable->ListHead.Flink;
+ while ( Current != &HandleTable->ListHead )
+ {
+ Block = CONTAINING_RECORD(Current, USER_HANDLE_BLOCK, ListEntry);
+ for ( i = 0; i < HANDLE_BLOCK_ENTRIES; i++ )
+ {
+ PVOID ObjectBody = Block->Handles[i].ObjectBody;
+ if ( ObjectBody )
+ {
+ if ( pWnd && dwCount < nBufSize )
+ {
+ pWnd[dwCount] =
+ (HWND)ObmReferenceObjectByPointer ( ObjectBody, otWindow );
+ }
+ dwCount++;
+ }
+ }
+ Current = Current->Flink;
+ }
+
+ ExReleaseFastMutex(&HandleTable->ListLock);
+ }
+ else
+ {
+ PDESKTOP_OBJECT DesktopObject = NULL;
+ KIRQL OldIrql;
+ PWINDOW_OBJECT Child, WndDesktop;
+
+ if ( hDesktop )
+ DesktopObject = IntGetDesktopObject ( hDesktop );
+ else
+ DesktopObject = IntGetActiveDesktop();
+ if (!DesktopObject)
+ {
+ DPRINT("Bad desktop handle 0x%x\n", hDesktop );
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+
+ KeAcquireSpinLock ( &DesktopObject->Lock, &OldIrql );
+
+ WndDesktop = IntGetWindowObject(DesktopObject->DesktopWindow);
+ Child = (WndDesktop ? WndDesktop->FirstChild : NULL);
+ while (Child)
+ {
+ if ( pWnd && dwCount < nBufSize )
+ pWnd[dwCount] = Child->Self;
+ dwCount++;
+ Child = Child->NextSibling;
+ }
+ KeReleaseSpinLock ( &DesktopObject->Lock, OldIrql );
+ }
+
+ return dwCount;
+}
+
+
+/*
+ * @unimplemented
+ */
+BOOL
+STDCALL
+NtUserCallHwndLock(
+ HWND hWnd,
+ DWORD Unknown1)
+{
+ UNIMPLEMENTED
+ /* DrawMenuBar() calls it with Unknown1==0x55 */
+ return 0;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+NtUserChildWindowFromPointEx(HWND Parent,
+ LONG x,
+ LONG y,
+ UINT Flags)
+{
+ UNIMPLEMENTED
+
+ return(0);
+}
+
+
+/*
+ * @implemented
+ */
+HWND STDCALL
+NtUserCreateWindowEx(DWORD dwExStyle,
+ PUNICODE_STRING lpClassName,
+ PUNICODE_STRING lpWindowName,
+ DWORD dwStyle,
+ LONG x,
+ LONG y,
+ LONG nWidth,
+ LONG nHeight,
+ HWND hWndParent,
+ HMENU hMenu,
+ HINSTANCE hInstance,
+ LPVOID lpParam,
+ DWORD dwShowMode)
+{
+ PWINSTATION_OBJECT WinStaObject;
+ PWNDCLASS_OBJECT ClassObject;
+ PWINDOW_OBJECT WindowObject;
+ PWINDOW_OBJECT ParentWindow;
+ PMENU_OBJECT SystemMenu;
+ UNICODE_STRING WindowName;
+ NTSTATUS Status;
+ HANDLE Handle;
+ POINT MaxSize, MaxPos, MinTrack, MaxTrack;
+ CREATESTRUCTW Cs;
+ LRESULT Result;
+ DPRINT("NtUserCreateWindowEx\n");
+
+ /* Initialize gui state if necessary. */
+ IntGraphicsCheck(TRUE);
+
+ if (!RtlCreateUnicodeString(&WindowName,
+ NULL == lpWindowName->Buffer ?
+ L"" : lpWindowName->Buffer))
+ {
+ SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
+ return((HWND)0);
+ }
+
+ /* FIXME: parent must belong to the current process */
+
+ if (hWndParent != NULL)
+ {
+ ParentWindow = IntGetWindowObject(hWndParent);
+ }
+ else
+ {
+ hWndParent = PsGetWin32Thread()->Desktop->DesktopWindow;
+ ParentWindow = IntGetWindowObject(hWndParent);
+ }
+
+ /* Check the class. */
+ Status = ClassReferenceClassByNameOrAtom(&ClassObject, lpClassName->Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeUnicodeString(&WindowName);
+ IntReleaseWindowObject(ParentWindow);
+ return((HWND)0);
+ }
+
+ /* Check the window station. */
+ DPRINT("IoGetCurrentProcess() %X\n", IoGetCurrentProcess());
+ DPRINT("PROCESS_WINDOW_STATION %X\n", PROCESS_WINDOW_STATION());
Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
KernelMode,
0,
{
RtlFreeUnicodeString(&WindowName);
ObmDereferenceObject(ClassObject);
+ IntReleaseWindowObject(ParentWindow);
DPRINT("Validation of window station handle (0x%X) failed\n",
PROCESS_WINDOW_STATION());
return (HWND)0;
/* Create the window object. */
WindowObject = (PWINDOW_OBJECT)
ObmCreateObject(PsGetWin32Process()->WindowStation->HandleTable, &Handle,
- otWindow, sizeof(WINDOW_OBJECT));
+ otWindow, sizeof(WINDOW_OBJECT) + ClassObject->cbWndExtra
+ );
+
DPRINT("Created object with handle %X\n", Handle);
if (!WindowObject)
{
ObDereferenceObject(WinStaObject);
ObmDereferenceObject(ClassObject);
RtlFreeUnicodeString(&WindowName);
+ IntReleaseWindowObject(ParentWindow);
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
return (HWND)0;
}
*/
WindowObject->Class = ClassObject;
WindowObject->ExStyle = dwExStyle;
- WindowObject->Style = dwStyle | WIN_NCACTIVATED;
+ WindowObject->Style = dwStyle & ~WS_VISIBLE;
+ DPRINT("1: Style is now %d\n", WindowObject->Style);
+
+ SystemMenu = IntGetSystemMenu(WindowObject, TRUE, TRUE);
+
WindowObject->x = x;
WindowObject->y = y;
WindowObject->Width = nWidth;
WindowObject->Height = nHeight;
+ WindowObject->ContextHelpId = 0;
WindowObject->ParentHandle = hWndParent;
- WindowObject->Menu = hMenu;
+ WindowObject->IDMenu = (UINT)hMenu;
+ if(SystemMenu)
+ WindowObject->SystemMenu = SystemMenu->Self;
+ else
+ WindowObject->SystemMenu = (HMENU)0;
WindowObject->Instance = hInstance;
WindowObject->Parameters = lpParam;
WindowObject->Self = Handle;
WindowObject->MessageQueue = PsGetWin32Thread()->MessageQueue;
WindowObject->Parent = ParentWindow;
- InsertHeadList(&ParentWindow->ChildrenListHead,
- &WindowObject->SiblingListEntry);
- InitializeListHead(&WindowObject->ChildrenListHead);
- InitializeListHead(&WindowObject->PropListHead);
- ExInitializeFastMutex(&WindowObject->ChildrenListLock);
-
- RtlInitUnicodeString(&WindowObject->WindowName, WindowName.Buffer);
- RtlFreeUnicodeString(&WindowName);
-
- if (ClassObject->Class.cbWndExtra != 0)
+ WindowObject->UserData = 0;
+ WindowObject->Unicode = ClassObject->Unicode;
+ WindowObject->WndProcA = ClassObject->lpfnWndProcA;
+ WindowObject->WndProcW = ClassObject->lpfnWndProcW;
+ WindowObject->OwnerThread = PsGetCurrentThread();
+ WindowObject->FirstChild = NULL;
+ WindowObject->LastChild = NULL;
+ WindowObject->PrevSibling = NULL;
+ WindowObject->NextSibling = NULL;
+
+ /* extra window data */
+ if (ClassObject->cbWndExtra != 0)
{
- WindowObject->ExtraData =
- ExAllocatePool(PagedPool,
- ClassObject->Class.cbWndExtra * sizeof(DWORD));
- WindowObject->ExtraDataSize = ClassObject->Class.cbWndExtra;
+ WindowObject->ExtraData = (PULONG)(WindowObject + 1);
+ WindowObject->ExtraDataSize = ClassObject->cbWndExtra;
+ RtlZeroMemory(WindowObject->ExtraData, WindowObject->ExtraDataSize);
}
else
{
WindowObject->ExtraDataSize = 0;
}
+ InitializeListHead(&WindowObject->PropListHead);
+ ExInitializeFastMutex(&WindowObject->ChildrenListLock);
+
+ RtlInitUnicodeString(&WindowObject->WindowName, WindowName.Buffer);
+ RtlFreeUnicodeString(&WindowName);
+
+
/* Correct the window style. */
if (!(dwStyle & WS_CHILD))
{
WindowObject->Style |= WS_CLIPSIBLINGS;
+ DPRINT("3: Style is now %d\n", WindowObject->Style);
if (!(dwStyle & WS_POPUP))
{
WindowObject->Style |= WS_CAPTION;
+ WindowObject->Flags |= WINDOWOBJECT_NEED_SIZE;
+ DPRINT("4: Style is now %d\n", WindowObject->Style);
/* FIXME: Note the window needs a size. */
}
}
- /* Insert the window into the process's window list. */
+ /* Insert the window into the thread's window list. */
ExAcquireFastMutexUnsafe (&PsGetWin32Thread()->WindowListLock);
InsertTailList (&PsGetWin32Thread()->WindowListHead,
&WindowObject->ThreadListEntry);
ExReleaseFastMutexUnsafe (&PsGetWin32Thread()->WindowListLock);
- /*
- * Insert the window into the list of windows associated with the thread's
- * desktop.
- */
- InsertTailList(&PsGetWin32Thread()->Desktop->WindowListHead,
- &WindowObject->DesktopListEntry);
/* Allocate a DCE for this window. */
if (dwStyle & CS_OWNDC) WindowObject->Dce = DceAllocDCE(WindowObject->Self,DCE_WINDOW_DC);
/* FIXME: Handle "CS_CLASSDC" */
*/
if ((dwStyle & WS_THICKFRAME) || !(dwStyle & (WS_POPUP | WS_CHILD)))
{
+ /* WinPosGetMinMaxInfo sends the WM_GETMINMAXINFO message */
WinPosGetMinMaxInfo(WindowObject, &MaxSize, &MaxPos, &MinTrack,
&MaxTrack);
x = min(MaxSize.x, y);
/* Initialize the window's scrollbars */
if (dwStyle & WS_VSCROLL)
- SCROLL_CreateScrollBar(WindowObject, SB_VERT);
+ IntCreateScrollBar(WindowObject, SB_VERT);
if (dwStyle & WS_HSCROLL)
- SCROLL_CreateScrollBar(WindowObject, SB_HORZ);
+ IntCreateScrollBar(WindowObject, SB_HORZ);
/* Send a NCCREATE message. */
Cs.lpCreateParams = lpParam;
Cs.lpszName = lpWindowName->Buffer;
Cs.lpszClass = lpClassName->Buffer;
Cs.dwExStyle = dwExStyle;
+
+ // AG: For some reason these don't get set already. This might need moving
+ // elsewhere... What is actually done with WindowObject anyway, to retain
+ // its data?
+ DPRINT("[win32k.window] NtUserCreateWindowEx style %d, exstyle %d, parent %d\n", Cs.style, Cs.dwExStyle, Cs.hwndParent);
+// NtUserSetWindowLong(Handle, GWL_STYLE, WindowObject->Style, TRUE);
+// NtUserSetWindowLong(Handle, GWL_EXSTYLE, WindowObject->ExStyle, TRUE);
+ // Any more?
+
DPRINT("NtUserCreateWindowEx(): About to send NCCREATE message.\n");
- Result = W32kSendNCCREATEMessage(WindowObject->Self, &Cs);
+ Result = IntSendNCCREATEMessage(WindowObject->Self, &Cs);
if (!Result)
{
/* FIXME: Cleanup. */
+ IntReleaseWindowObject(ParentWindow);
DPRINT("NtUserCreateWindowEx(): NCCREATE message failed.\n");
- return(NULL);
+ return((HWND)0);
}
/* Calculate the non-client size. */
MaxPos.x = WindowObject->WindowRect.left;
MaxPos.y = WindowObject->WindowRect.top;
DPRINT("NtUserCreateWindowEx(): About to get non-client size.\n");
+ /* WinPosGetNonClientSize SENDS THE WM_NCCALCSIZE message */
Result = WinPosGetNonClientSize(WindowObject->Self,
&WindowObject->WindowRect,
&WindowObject->ClientRect);
- W32kOffsetRect(&WindowObject->WindowRect,
+ NtGdiOffsetRect(&WindowObject->WindowRect,
MaxPos.x - WindowObject->WindowRect.left,
MaxPos.y - WindowObject->WindowRect.top);
- /* Send the CREATE message. */
+
+ /* link the window into the parent's child list */
+ ExAcquireFastMutexUnsafe(&ParentWindow->ChildrenListLock);
+ if ((dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
+ {
+ /* link window as bottom sibling */
+ IntLinkWindow(WindowObject, ParentWindow, ParentWindow->LastChild /*prev sibling*/);
+ }
+ else
+ {
+ /* link window as top sibling */
+ IntLinkWindow(WindowObject, ParentWindow, NULL /*prev sibling*/);
+ }
+ ExReleaseFastMutexUnsafe(&ParentWindow->ChildrenListLock);
+
+ /* Send the WM_CREATE message. */
DPRINT("NtUserCreateWindowEx(): about to send CREATE message.\n");
- Result = W32kSendCREATEMessage(WindowObject->Self, &Cs);
+ Result = IntSendCREATEMessage(WindowObject->Self, &Cs);
if (Result == (LRESULT)-1)
{
/* FIXME: Cleanup. */
+ IntReleaseWindowObject(ParentWindow);
DPRINT("NtUserCreateWindowEx(): send CREATE message failed.\n");
- return(NULL);
+ return((HWND)0);
}
-
+
/* Send move and size messages. */
if (!(WindowObject->Flags & WINDOWOBJECT_NEED_SIZE))
{
LONG lParam;
+
+ DPRINT("NtUserCreateWindow(): About to send WM_SIZE\n");
+
+ if ((WindowObject->ClientRect.right - WindowObject->ClientRect.left) < 0 ||
+ (WindowObject->ClientRect.bottom - WindowObject->ClientRect.top) < 0)
+ DPRINT("Sending bogus WM_SIZE\n");
- lParam =
- MAKE_LONG(WindowObject->ClientRect.right -
+ lParam = MAKE_LONG(WindowObject->ClientRect.right -
WindowObject->ClientRect.left,
WindowObject->ClientRect.bottom -
WindowObject->ClientRect.top);
-
- DPRINT("NtUserCreateWindow(): About to send WM_SIZE\n");
- W32kCallWindowProc(NULL, WindowObject->Self, WM_SIZE, SIZE_RESTORED,
- lParam);
- lParam =
- MAKE_LONG(WindowObject->ClientRect.left,
- WindowObject->ClientRect.top);
+ IntCallWindowProc(NULL, WindowObject->Self, WM_SIZE, SIZE_RESTORED,
+ lParam);
+
DPRINT("NtUserCreateWindow(): About to send WM_MOVE\n");
- W32kCallWindowProc(NULL, WindowObject->Self, WM_MOVE, 0, lParam);
+
+ lParam = MAKE_LONG(WindowObject->ClientRect.left,
+ WindowObject->ClientRect.top);
+ IntCallWindowProc(NULL, WindowObject->Self, WM_MOVE, 0, lParam);
+ }
+
+ /* Move from parent-client to screen coordinates */
+ if (0 != (WindowObject->Style & WS_CHILD))
+ {
+ NtGdiOffsetRect(&WindowObject->WindowRect,
+ ParentWindow->ClientRect.left,
+ ParentWindow->ClientRect.top);
+ NtGdiOffsetRect(&WindowObject->ClientRect,
+ ParentWindow->ClientRect.left,
+ ParentWindow->ClientRect.top);
}
/* Show or maybe minimize or maximize the window. */
SW_MAXIMIZE;
WinPosMinMaximize(WindowObject, SwFlag, &NewPos);
SwFlag =
- ((WindowObject->Style & WS_CHILD) || W32kGetActiveWindow()) ?
+ ((WindowObject->Style & WS_CHILD) || IntGetActiveWindow()) ?
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED :
SWP_NOZORDER | SWP_FRAMECHANGED;
DPRINT("NtUserCreateWindow(): About to minimize/maximize\n");
NewPos.right, NewPos.bottom, SwFlag);
}
- /* Notify the parent window of a new child. */
- if ((WindowObject->Style & WS_CHILD) ||
- (!(WindowObject->ExStyle & WS_EX_NOPARENTNOTIFY)))
+ /* Notify the parent window of a new child. */
+ if ((WindowObject->Style & WS_CHILD) ||
+ (!(WindowObject->ExStyle & WS_EX_NOPARENTNOTIFY)))
+ {
+ DPRINT("NtUserCreateWindow(): About to notify parent\n");
+ IntCallWindowProc(NULL, WindowObject->Parent->Self,
+ WM_PARENTNOTIFY,
+ MAKEWPARAM(WM_CREATE, WindowObject->IDMenu),
+ (LPARAM)WindowObject->Self);
+ }
+
+ if (dwStyle & WS_VISIBLE)
+ {
+ DPRINT("NtUserCreateWindow(): About to show window\n");
+ WinPosShowWindow(WindowObject->Self, dwShowMode);
+ }
+ /* FIXME: Should code be reworked to accomodate the following line? */
+ DPRINT("Setting Active Window to %d\n\n\n",WindowObject->Self);
+ NtUserSetActiveWindow(WindowObject->Self);
+ DPRINT("NtUserCreateWindow(): = %X\n", Handle);
+ DPRINT("WindowObject->SystemMenu = 0x%x\n", WindowObject->SystemMenu);
+ return((HWND)Handle);
+}
+
+
+/*
+ * @unimplemented
+ */
+HDWP STDCALL
+NtUserDeferWindowPos(HDWP WinPosInfo,
+ HWND Wnd,
+ HWND WndInsertAfter,
+ int x,
+ int y,
+ int cx,
+ int cy,
+ UINT Flags)
+{
+ UNIMPLEMENTED
+
+ return 0;
+}
+
+
+/*
+ * @implemented
+ */
+BOOLEAN STDCALL
+NtUserDestroyWindow(HWND Wnd)
+{
+ PWINDOW_OBJECT Window;
+ BOOLEAN isChild;
+ HWND hWndFocus;
+
+ Window = IntGetWindowObject(Wnd);
+ if (Window == NULL)
+ {
+ return FALSE;
+ }
+
+ /* Check for desktop window (has NULL parent) */
+ if (NULL == Window->Parent)
+ {
+ IntReleaseWindowObject(Window);
+ SetLastWin32Error(ERROR_ACCESS_DENIED);
+ return FALSE;
+ }
+
+ /* Look whether the focus is within the tree of windows we will
+ * be destroying.
+ */
+ hWndFocus = IntGetFocusWindow();
+ if (hWndFocus == Wnd || IntIsChildWindow(Wnd, hWndFocus))
+ {
+ HWND Parent = NtUserGetAncestor(Wnd, GA_PARENT);
+ if (Parent == IntGetDesktopWindow())
+ {
+ Parent = NULL;
+ }
+ IntSetFocusWindow(Parent);
+ }
+
+ /* Call hooks */
+#if 0 /* FIXME */
+ if (HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hwnd, 0, TRUE))
+ {
+ return FALSE;
+ }
+#endif
+
+ isChild = (0 != (Window->Style & WS_CHILD));
+
+#if 0 /* FIXME */
+ if (isChild)
+ {
+ if (! USER_IsExitingThread(GetCurrentThreadId()))
+ {
+ send_parent_notify(hwnd, WM_DESTROY);
+ }
+ }
+ else if (NULL != GetWindow(Wnd, GW_OWNER))
+ {
+ HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWDESTROYED, (WPARAM)hwnd, 0L, TRUE );
+ /* FIXME: clean up palette - see "Internals" p.352 */
+ }
+
+ if (! IsWindow(Wnd))
+ {
+ return TRUE;
+ }
+#endif
+
+ /* Hide the window */
+ if (! WinPosShowWindow(Wnd, SW_HIDE ))
+ {
+#if 0 /* FIXME */
+ if (hwnd == GetActiveWindow())
+ {
+ WINPOS_ActivateOtherWindow( hwnd );
+ }
+#endif
+ }
+
+#if 0 /* FIXME */
+ if (! IsWindow(Wnd))
{
- DPRINT("NtUserCreateWindow(): About to notify parent\n");
- W32kCallWindowProc(NULL, WindowObject->Parent->Self,
- WM_PARENTNOTIFY,
- MAKEWPARAM(WM_CREATE, WindowObject->IDMenu),
- (LPARAM)WindowObject->Self);
+ return TRUE;
}
+#endif
- if (dwStyle & WS_VISIBLE)
+ /* Recursively destroy owned windows */
+#if 0 /* FIXME */
+ if (! isChild)
{
- DPRINT("NtUserCreateWindow(): About to show window\n");
- WinPosShowWindow(WindowObject->Self, dwShowMode);
+ for (;;)
+ {
+ int i;
+ BOOL GotOne = FALSE;
+ HWND *list = WIN_ListChildren(GetDesktopWindow());
+ if (list)
+ {
+ for (i = 0; list[i]; i++)
+ {
+ if (GetWindow(list[i], GW_OWNER) != Wnd)
+ {
+ continue;
+ }
+ if (WIN_IsCurrentThread(list[i]))
+ {
+ DestroyWindow(list[i]);
+ GotOne = TRUE;
+ continue;
+ }
+ WIN_SetOwner(list[i], NULL);
+ }
+ HeapFree(GetProcessHeap(), 0, list);
+ }
+ if (! GotOne)
+ {
+ break;
+ }
+ }
}
+#endif
- DPRINT("NtUserCreateWindow(): = %X\n", Handle);
- return((HWND)Handle);
-}
+ /* Send destroy messages */
+ IntSendDestroyMsg(Wnd);
-DWORD STDCALL
-NtUserDeferWindowPos(HDWP WinPosInfo,
- HWND Wnd,
- HWND WndInsertAfter,
- LONG x,
- LONG y,
- LONG cx,
- LONG cy,
- UINT Flags)
-{
- UNIMPLEMENTED
+#if 0 /* FIXME */
+ if (!IsWindow(Wnd))
+ {
+ return TRUE;
+ }
+#endif
- return 0;
+ /* Unlink now so we won't bother with the children later on */
+#if 0 /* FIXME */
+ WIN_UnlinkWindow( hwnd );
+#endif
+
+ /* Destroy the window storage */
+ IntDestroyWindow(Window, PsGetWin32Process(), PsGetWin32Thread(), TRUE);
+
+ return TRUE;
}
-BOOLEAN STDCALL
-NtUserDestroyWindow(HWND Wnd)
-{
- W32kGraphicsCheck(FALSE);
+/*
+ * @unimplemented
+ */
+DWORD
+STDCALL
+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 STDCALL
NtUserEndDeferWindowPosEx(DWORD Unknown0,
DWORD Unknown1)
return 0;
}
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserFillWindow(DWORD Unknown0,
DWORD Unknown1,
return 0;
}
+
+/*
+ * FUNCTION:
+ * Searches a window's children for a window with the specified
+ * class and name
+ * ARGUMENTS:
+ * hwndParent = The window whose childs are to be searched.
+ * NULL = desktop
+ *
+ * hwndChildAfter = Search starts after this child window.
+ * NULL = start from beginning
+ *
+ * ucClassName = Class name to search for
+ * Reguired parameter.
+ *
+ * ucWindowName = Window name
+ * ->Buffer == NULL = don't care
+ *
+ * RETURNS:
+ * The HWND of the window if it was found, otherwise NULL
+ *
+ * FIXME:
+ * Should use MmCopyFromCaller, we don't want an access violation in here
+ *
+ */
+/*
+ * @implemented
+ */
HWND STDCALL
NtUserFindWindowEx(HWND hwndParent,
HWND hwndChildAfter,
PUNICODE_STRING ucClassName,
- PUNICODE_STRING ucWindowName,
- DWORD Unknown4)
+ PUNICODE_STRING ucWindowName)
{
-#if 0
NTSTATUS status;
HWND windowHandle;
- PWINDOW_OBJECT windowObject;
- PLIST_ENTRY currentEntry;
+ PWINDOW_OBJECT ParentWindow, WndChildAfter, WndChild;
PWNDCLASS_OBJECT classObject;
- W32kGuiCheck();
-
+ // Get a pointer to the class
status = ClassReferenceClassByNameOrAtom(&classObject, ucClassName->Buffer);
if (!NT_SUCCESS(status))
{
- return (HWND)0;
+ return NULL;
}
+
+ // If hwndParent==NULL use the desktop window instead
+ if(!hwndParent)
+ hwndParent = PsGetWin32Thread()->Desktop->DesktopWindow;
- ExAcquireFastMutexUnsafe (&PsGetWin32Process()->WindowListLock);
- currentEntry = PsGetWin32Process()->WindowListHead.Flink;
- while (currentEntry != &PsGetWin32Process()->WindowListHead)
+ // Get the object
+ ParentWindow = IntGetWindowObject(hwndParent);
+
+ if(!ParentWindow)
{
- windowObject = CONTAINING_RECORD (currentEntry, WINDOW_OBJECT,
- ListEntry);
+ ObmDereferenceObject(classObject);
+ return NULL;
+ }
- if (classObject == windowObject->Class &&
- RtlCompareUnicodeString (ucWindowName, &windowObject->WindowName,
- TRUE) == 0)
- {
- ObmCreateHandle(PsGetWin32Process()->HandleTable,
- windowObject,
- &windowHandle);
- ExReleaseFastMutexUnsafe (&PsGetWin32Process()->WindowListLock);
- ObmDereferenceObject (classObject);
+ ExAcquireFastMutexUnsafe (&ParentWindow->ChildrenListLock);
+
+ if(hwndChildAfter)
+ {
+ if (!(WndChildAfter = IntGetWindowObject(hwndChildAfter)))
+ {
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return NULL;
+ }
+
+ /* must be a direct child (not a decendant child)*/
+ if (WndChildAfter->Parent != ParentWindow)
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ WndChild = WndChildAfter->NextSibling;
+ }
+ else
+ {
+ WndChild = ParentWindow->FirstChild;
+ }
+
+ while (WndChild)
+ {
+ if (classObject == WndChild->Class && (ucWindowName->Buffer==NULL ||
+ RtlCompareUnicodeString (ucWindowName, &WndChild->WindowName, TRUE) == 0))
+ {
+ windowHandle = WndChild->Self;
+
+ ExReleaseFastMutexUnsafe (&ParentWindow->ChildrenListLock);
+ IntReleaseWindowObject(ParentWindow);
+ ObmDereferenceObject (classObject);
- return windowHandle;
- }
- currentEntry = currentEntry->Flink;
+ return windowHandle;
+ }
+
+ WndChild = WndChild->NextSibling;
}
- ExReleaseFastMutexUnsafe (&PsGetWin32Process()->WindowListLock);
-
+
+ ExReleaseFastMutexUnsafe (&ParentWindow->ChildrenListLock);
+
+ IntReleaseWindowObject(ParentWindow);
ObmDereferenceObject (classObject);
- return (HWND)0;
-#endif
+ return NULL;
}
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserFlashWindowEx(DWORD Unknown0)
{
return 0;
}
+
+/*
+ * @implemented
+ */
+HWND STDCALL
+NtUserGetAncestor(HWND hWnd, UINT Type)
+{
+ PWINDOW_OBJECT Wnd, WndAncestor;
+ HWND hWndAncestor = NULL;
+
+ IntAcquireWinLockShared();
+
+ if (!(Wnd = IntGetWindowObject(hWnd)))
+ {
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return NULL;
+ }
+
+ WndAncestor = IntGetAncestor(Wnd, Type);
+ if (WndAncestor) hWndAncestor = WndAncestor->Self;
+
+ IntReleaseWinLock();
+
+ return hWndAncestor;
+}
+
+
+/*
+ * @implemented
+ */
+HWND
+STDCALL
+NtUserGetCapture(VOID)
+{
+ PWINDOW_OBJECT Window;
+ Window = IntGetCaptureWindow();
+ if (Window != NULL)
+ {
+ return(Window->Self);
+ }
+ else
+ {
+ return(NULL);
+ }
+}
+
+
+/*!
+ * Returns client window rectangle relative to the upper-left corner of client area.
+ *
+ * \param hWnd window handle.
+ * \param Rect pointer to the buffer where the coordinates are returned.
+ *
+*/
+/*
+ * @implemented
+ */
+BOOL STDCALL
+NtUserGetClientRect(HWND hWnd, LPRECT Rect)
+{
+ PWINDOW_OBJECT WindowObject;
+ RECT SafeRect;
+
+ IntAcquireWinLockShared();
+ if (!(WindowObject = IntGetWindowObject(hWnd)))
+ {
+ IntReleaseWinLock();
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return FALSE;
+ }
+
+ IntGetClientRect(WindowObject, &SafeRect);
+ IntReleaseWinLock();
+
+ if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT))))
+ {
+ return(FALSE);
+ }
+
+ return(TRUE);
+}
+
+
+/*
+ * @implemented
+ */
+HWND
+STDCALL
+NtUserGetDesktopWindow()
+{
+ return IntGetDesktopWindow();
+}
+
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserGetForegroundWindow(VOID)
{
return 0;
}
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserGetInternalWindowPos(DWORD Unknown0,
DWORD Unknown1,
return 0;
}
+
+/*
+ * @implemented
+ */
+HWND
+STDCALL
+NtUserGetLastActivePopup(HWND hWnd)
+{
+ PWINDOW_OBJECT Wnd;
+ HWND hWndLastPopup;
+
+ IntAcquireWinLockShared();
+
+ if (!(Wnd = IntGetWindowObject(hWnd)))
+ {
+ IntReleaseWinLock();
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return NULL;
+ }
+
+ hWndLastPopup = Wnd->hWndLastPopup;
+
+ IntReleaseWinLock();
+
+ return hWndLastPopup;
+}
+
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserGetOpenClipboardWindow(VOID)
{
return 0;
}
-DWORD STDCALL
-NtUserGetWindowDC(HWND hWnd)
+
+/*
+ * @implemented
+ */
+HWND STDCALL
+NtUserGetParent(HWND hWnd)
+{
+ PWINDOW_OBJECT Wnd, WndParent;
+ HWND hWndParent = NULL;
+
+ IntAcquireWinLockShared();
+
+ if (!(Wnd = IntGetWindowObject(hWnd)))
+ {
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return NULL;
+ }
+
+ WndParent = IntGetParent(Wnd);
+ if (WndParent) hWndParent = WndParent->Self;
+
+ IntReleaseWinLock();
+
+ return hWndParent;
+}
+
+
+/*
+ * @implemented
+ */
+HWND STDCALL
+NtUserGetShellWindow()
+{
+ return hwndShellWindow;
+}
+
+
+/*
+ * @implemented
+ */
+HMENU
+STDCALL
+NtUserGetSystemMenu(
+ HWND hWnd,
+ BOOL bRevert)
+{
+ HMENU res = (HMENU)0;
+ PWINDOW_OBJECT WindowObject;
+ WindowObject = IntGetWindowObject((HWND)hWnd);
+ if(!WindowObject)
+ {
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return (HMENU)0;
+ }
+
+ res = IntGetSystemMenu(WindowObject, bRevert, FALSE);
+
+ IntReleaseWindowObject(WindowObject);
+ return res;
+}
+
+
+/*
+ * @implemented
+ */
+HWND
+STDCALL
+NtUserGetWindow(HWND hWnd, UINT Relationship)
+{
+ PWINDOW_OBJECT Wnd;
+ HWND hWndResult = NULL;
+
+ IntAcquireWinLockShared();
+
+ if (!(Wnd = IntGetWindowObject(hWnd)))
+ {
+ IntReleaseWinLock();
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return NULL;
+ }
+
+ switch (Relationship)
+ {
+ case GW_HWNDFIRST:
+ if (Wnd->Parent && Wnd->Parent->FirstChild)
+ {
+ hWndResult = Wnd->Parent->FirstChild->Self;
+ }
+ break;
+ case GW_HWNDLAST:
+ if (Wnd->Parent && Wnd->Parent->LastChild)
+ {
+ hWndResult = Wnd->Parent->LastChild->Self;
+ }
+ break;
+ case GW_HWNDNEXT:
+ if (Wnd->Parent && Wnd->NextSibling)
+ {
+ hWndResult = Wnd->NextSibling->Self;
+ }
+ break;
+ case GW_HWNDPREV:
+ if (Wnd->Parent && Wnd->PrevSibling)
+ {
+ hWndResult = Wnd->PrevSibling->Self;
+ }
+ break;
+ case GW_OWNER:
+ if (Wnd->Parent)
+ {
+ hWndResult = Wnd->hWndOwner;
+ }
+ break;
+ case GW_CHILD:
+ if (Wnd->FirstChild)
+ {
+ hWndResult = Wnd->FirstChild->Self;
+ }
+ break;
+ }
+
+ IntReleaseWinLock();
+
+ return hWndResult;
+}
+
+
+/*
+ * @implemented
+ */
+DWORD STDCALL
+NtUserGetWindowDC(HWND hWnd)
+{
+ return (DWORD) NtUserGetDCEx( hWnd, 0, DCX_USESTYLE | DCX_WINDOW );
+}
+
+
+/*
+ * @implemented
+ */
+LONG STDCALL
+NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
+{
+ PWINDOW_OBJECT WindowObject;
+ NTSTATUS Status;
+ LONG Result;
+
+ Status =
+ ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable,
+ hWnd,
+ otWindow,
+ (PVOID*)&WindowObject);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+
+ if (0 <= (int) Index)
+ {
+ if (WindowObject->ExtraDataSize - sizeof(LONG) < Index ||
+ 0 != Index % sizeof(LONG))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+ Result = WindowObject->ExtraData[Index / sizeof(LONG)];
+ }
+ else
+ {
+ switch (Index)
+ {
+ case GWL_EXSTYLE:
+ Result = WindowObject->ExStyle;
+ break;
+
+ case GWL_STYLE:
+ Result = WindowObject->Style;
+ break;
+ case GWL_WNDPROC:
+ if (Ansi)
+ {
+ Result = (LONG) WindowObject->WndProcA;
+ }
+ else
+ {
+ Result = (LONG) WindowObject->WndProcW;
+ }
+ break;
+
+ case GWL_HINSTANCE:
+ Result = (LONG) WindowObject->Instance;
+ break;
+
+ case GWL_HWNDPARENT:
+ Result = (LONG) WindowObject->ParentHandle;
+ break;
+
+ case GWL_ID:
+ Result = (LONG) WindowObject->IDMenu;
+ break;
+
+ case GWL_USERDATA:
+ Result = WindowObject->UserData;
+ break;
+
+ default:
+ DPRINT1("NtUserGetWindowLong(): Unsupported index %d\n", Index);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ Result = 0;
+ break;
+ }
+ }
+
+ ObmDereferenceObject(WindowObject);
+
+ return Result;
+}
+
+
+/*
+ * @unimplemented
+ */
+DWORD STDCALL
+NtUserGetWindowPlacement(DWORD Unknown0,
+ DWORD Unknown1)
+{
+ UNIMPLEMENTED
+
+ return 0;
+}
+
+
+/*!
+ * Return the dimension of the window in the screen coordinates.
+ * \param hWnd window handle.
+ * \param Rect pointer to the buffer where the coordinates are returned.
+*/
+/*
+ * @implemented
+ */
+BOOL STDCALL
+NtUserGetWindowRect(HWND hWnd, LPRECT Rect)
{
- return NtUserGetDCEx( hWnd, 0, DCX_USESTYLE | DCX_WINDOW );
+ PWINDOW_OBJECT Wnd;
+ RECT SafeRect;
+
+ IntAcquireWinLockShared();
+ if (!(Wnd = IntGetWindowObject(hWnd)))
+ {
+ IntReleaseWinLock();
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return FALSE;
+ }
+
+ SafeRect = Wnd->WindowRect;
+ IntReleaseWinLock();
+
+ if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT))))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
}
+
+/*
+ * @implemented
+ */
DWORD STDCALL
-NtUserGetWindowPlacement(DWORD Unknown0,
- DWORD Unknown1)
+NtUserGetWindowThreadProcessId(HWND hWnd, LPDWORD UnsafePid)
{
- UNIMPLEMENTED
-
- return 0;
+ PWINDOW_OBJECT Wnd;
+ DWORD tid, pid;
+
+ IntAcquireWinLockShared();
+
+ if (!(Wnd = IntGetWindowObject(hWnd)))
+ {
+ IntReleaseWinLock();
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return 0;
+ }
+
+ tid = IntGetWindowThreadProcessId(Wnd, &pid);
+ IntReleaseWinLock();
+
+ if (UnsafePid) MmCopyToCaller(UnsafePid, &pid, sizeof(DWORD));
+
+ return tid;
}
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
-NtUserInternalGetWindowText(DWORD Unknown0,
- DWORD Unknown1,
- DWORD Unknown2)
+NtUserInternalGetWindowText(HWND hWnd,
+ LPWSTR lpString,
+ int nMaxCount)
{
- UNIMPLEMENTED
-
- return 0;
+ DWORD res = 0;
+ PWINDOW_OBJECT WindowObject;
+
+ IntAcquireWinLockShared(); /* ??? */
+ WindowObject = IntGetWindowObject(hWnd);
+ if(!WindowObject)
+ {
+ IntReleaseWinLock(); /* ??? */
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return 0;
+ }
+
+ if(lpString)
+ {
+ /* FIXME - Window text is currently stored
+ in the Atom 'USER32!WindowTextAtomA' */
+
+ }
+ else
+ {
+ /* FIXME - return length of window text */
+ }
+
+ IntReleaseWindowObject(WindowObject);
+
+ IntReleaseWinLock(); /* ??? */
+ return res;
}
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserLockWindowUpdate(DWORD Unknown0)
{
return 0;
}
+
+/*
+ * @implemented
+ */
BOOL STDCALL
NtUserMoveWindow(
HWND hWnd,
int nHeight,
BOOL bRepaint)
{
- PWINDOW_OBJECT Window = W32kGetWindowObject(hWnd);
- ULONG uStyle, uExStyle;
- WINDOWPOS pWinPos;
+ UINT flags = SWP_NOZORDER | SWP_NOACTIVATE;
- if (!Window) return FALSE;
-
- uStyle = Window->Style;
- uExStyle = Window->ExStyle;
- pWinPos.hwnd = hWnd;
-
- pWinPos.x = X;
- pWinPos.y = Y;
- if (nWidth > NtUserGetSystemMetrics(SM_CXMIN))
- pWinPos.cx = pWinPos.x + nWidth;
- else
- pWinPos.cx = pWinPos.x + NtUserGetSystemMetrics(SM_CXMIN);
-
- if (nHeight > NtUserGetSystemMetrics(SM_CYMIN))
- pWinPos.cy = pWinPos.x + nHeight;
- else
- pWinPos.cy = pWinPos.y + NtUserGetSystemMetrics(SM_CYMIN);
- NtUserSendMessage(hWnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)&pWinPos);
-
- Window->WindowRect.top = Window->ClientRect.top = pWinPos.y;
- Window->WindowRect.left = Window->ClientRect.left = pWinPos.x;
- Window->WindowRect.bottom = Window->ClientRect.bottom = pWinPos.cy;
- Window->WindowRect.right = Window->ClientRect.right = pWinPos.cx;
-
- if (!(uStyle & WS_THICKFRAME))
- {
- Window->ClientRect.top += NtUserGetSystemMetrics(SM_CYFIXEDFRAME);
- Window->ClientRect.bottom -= NtUserGetSystemMetrics(SM_CYFIXEDFRAME);
- Window->ClientRect.left += NtUserGetSystemMetrics(SM_CXFIXEDFRAME);
- Window->ClientRect.right -= NtUserGetSystemMetrics(SM_CXFIXEDFRAME);
- }
- else
- {
- Window->ClientRect.top += NtUserGetSystemMetrics(SM_CYSIZEFRAME);
- Window->ClientRect.bottom -= NtUserGetSystemMetrics(SM_CYSIZEFRAME);
- Window->ClientRect.left += NtUserGetSystemMetrics(SM_CXSIZEFRAME);
- Window->ClientRect.right -= NtUserGetSystemMetrics(SM_CXSIZEFRAME);
- }
+ if(!bRepaint)
+ flags |= SWP_NOREDRAW;
+ return NtUserSetWindowPos(hWnd, 0, X, Y, nWidth, nHeight, flags);
+}
- if (uStyle & WS_CAPTION)
- Window->ClientRect.top += NtUserGetSystemMetrics(SM_CYCAPTION);
- if ( Window->Class->Class.lpszMenuName)
- {
- Window->ClientRect.top += NtUserGetSystemMetrics(SM_CYMENU);
- }
+/*
+ QueryWindow based on KJK::Hyperion and James Tabor.
- NtUserSendMessage(hWnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&pWinPos);
-
- NtUserSendMessage(hWnd, WM_MOVE, 0, MAKEWORD(Window->ClientRect.left,
- Window->ClientRect.top));
-
- NtUserSendMessage(hWnd, WM_SIZE, 0, MAKEWORD(Window->ClientRect.right -
- Window->ClientRect.left,
- Window->ClientRect.bottom -
- Window->ClientRect.top));
-
- /* FIXME: Send WM_NCCALCSIZE */
- W32kReleaseWindowObject(Window);
- if (bRepaint) NtUserSendMessage(hWnd, WM_PAINT, 0, 0);
- return TRUE;
-}
+ 0 = QWUniqueProcessId
+ 1 = QWUniqueThreadId
+ 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 STDCALL
-NtUserQueryWindow(DWORD Unknown0,
- DWORD Unknown1)
+NtUserQueryWindow(HWND hWnd, DWORD Index)
{
- UNIMPLEMENTED
- return 0;
+PWINDOW_OBJECT Window = IntGetWindowObject(hWnd);
+
+ if(Window == NULL) return((DWORD)NULL);
+
+ IntReleaseWindowObject(Window);
+
+ switch(Index)
+ {
+ case 0x00:
+ return((DWORD)Window->OwnerThread->ThreadsProcess->UniqueProcessId);
+
+ case 0x01:
+ return((DWORD)Window->OwnerThread->Cid.UniqueThread);
+
+ default:
+ return((DWORD)NULL);
+ }
+
}
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserRealChildWindowFromPoint(DWORD Unknown0,
DWORD Unknown1,
return 0;
}
-NTSTATUS STDCALL
-NtUserRedrawWindow(HWND hWnd, CONST RECT *lprcUpdate, HRGN hrgnUpdate, UINT flags)
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+NtUserRedrawWindow
+(
+ HWND hWnd,
+ CONST RECT *lprcUpdate,
+ HRGN hrgnUpdate,
+ UINT flags
+)
+{
+ RECT SafeUpdateRect;
+ NTSTATUS Status;
+ PWINDOW_OBJECT Wnd;
+
+ if (!(Wnd = IntGetWindowObject(hWnd)))
+ {
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return FALSE;
+ }
+
+ if(NULL != lprcUpdate)
+ {
+ Status = MmCopyFromCaller(&SafeUpdateRect, (PRECT)lprcUpdate, sizeof(RECT));
+
+ if(!NT_SUCCESS(Status))
+ {
+ /* FIXME: set last error */
+ return FALSE;
+ }
+ }
+
+
+ Status = PaintRedrawWindow
+ (
+ Wnd,
+ NULL == lprcUpdate ? NULL : &SafeUpdateRect,
+ hrgnUpdate,
+ flags,
+ 0
+ );
+
+
+ if(!NT_SUCCESS(Status))
+ {
+ /* FIXME: set last error */
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * @implemented
+ */
+UINT STDCALL
+NtUserRegisterWindowMessage(PUNICODE_STRING MessageNameUnsafe)
{
- RECT SafeUpdateRect;
+ PLIST_ENTRY Current;
+ PREGISTERED_MESSAGE NewMsg, RegMsg;
+ UINT Msg = REGISTERED_MESSAGE_MIN;
+ UNICODE_STRING MessageName;
NTSTATUS Status;
- if (NULL != lprcUpdate)
+ Status = MmCopyFromCaller(&MessageName, MessageNameUnsafe, sizeof(UNICODE_STRING));
+ if (! NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return 0;
+ }
+
+ NewMsg = ExAllocatePoolWithTag(PagedPool,
+ sizeof(REGISTERED_MESSAGE) +
+ MessageName.Length,
+ TAG_WNAM);
+ if (NULL == NewMsg)
+ {
+ SetLastNtError(STATUS_NO_MEMORY);
+ return 0;
+ }
+
+ Status = MmCopyFromCaller(NewMsg->MessageName, MessageName.Buffer, MessageName.Length);
+ if (! NT_SUCCESS(Status))
+ {
+ ExFreePool(NewMsg);
+ SetLastNtError(Status);
+ return 0;
+ }
+ NewMsg->MessageName[MessageName.Length / sizeof(WCHAR)] = L'\0';
+ if (wcslen(NewMsg->MessageName) != MessageName.Length / sizeof(WCHAR))
+ {
+ ExFreePool(NewMsg);
+ SetLastNtError(STATUS_INVALID_PARAMETER);
+ return 0;
+ }
+
+ Current = RegisteredMessageListHead.Flink;
+ while (Current != &RegisteredMessageListHead)
{
- Status = MmCopyFromCaller(&SafeUpdateRect, lprcUpdate, sizeof(RECT));
- if (! NT_SUCCESS(Status))
+ RegMsg = CONTAINING_RECORD(Current, REGISTERED_MESSAGE, ListEntry);
+ if (0 == wcscmp(NewMsg->MessageName, RegMsg->MessageName))
{
- return Status;
+ ExFreePool(NewMsg);
+ return Msg;
}
+ Msg++;
+ Current = Current->Flink;
}
- return PaintRedrawWindow(hWnd, NULL == lprcUpdate ? NULL : &SafeUpdateRect, hrgnUpdate,
- flags, 0) ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER;
-;
-}
+ if (REGISTERED_MESSAGE_MAX < Msg)
+ {
+ ExFreePool(NewMsg);
+ SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
+ return 0;
+ }
-UINT STDCALL
-NtUserRegisterWindowMessage(LPCWSTR MessageName)
-{
- UNIMPLEMENTED
+ InsertTailList(&RegisteredMessageListHead, &(NewMsg->ListEntry));
- return(0);
+ return Msg;
}
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserScrollWindowEx(DWORD Unknown0,
DWORD Unknown1,
return 0;
}
-DWORD STDCALL
-NtUserSetActiveWindow(DWORD Unknown0)
+
+/*
+ * @implemented
+ */
+HWND STDCALL
+NtUserSetCapture(HWND Wnd)
{
- UNIMPLEMENTED
+ PWINDOW_OBJECT Window;
+ PWINDOW_OBJECT Prev;
- return 0;
+ Prev = IntGetCaptureWindow();
+
+ if (Prev != NULL)
+ {
+ IntSendMessage(Prev->Self, WM_CAPTURECHANGED, 0L, (LPARAM)Wnd, FALSE);
+ }
+
+ if (Wnd == NULL)
+ {
+ IntSetCaptureWindow(NULL);
+ }
+ else
+ {
+ Window = IntGetWindowObject(Wnd);
+ IntSetCaptureWindow(Window);
+ IntReleaseWindowObject(Window);
+ }
+ if (Prev != NULL)
+ {
+ return(Prev->Self);
+ }
+ else
+ {
+ return(NULL);
+ }
}
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserSetImeOwnerWindow(DWORD Unknown0,
DWORD Unknown1)
return 0;
}
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserSetInternalWindowPos(DWORD Unknown0,
DWORD Unknown1,
}
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserSetLayeredWindowAttributes(DWORD Unknown0,
DWORD Unknown1,
return 0;
}
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserSetLogonNotifyWindow(DWORD Unknown0)
{
return 0;
}
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+NtUserSetMenu(
+ HWND hWnd,
+ HMENU hMenu,
+ BOOL bRepaint)
+{
+ PWINDOW_OBJECT WindowObject;
+ PMENU_OBJECT MenuObject;
+ WindowObject = IntGetWindowObject((HWND)hWnd);
+ if(!WindowObject)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if(hMenu)
+ {
+ /* assign new menu handle */
+ MenuObject = IntGetMenuObject((HWND)hMenu);
+ if(!MenuObject)
+ {
+ IntReleaseWindowObject(WindowObject);
+ SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
+ return FALSE;
+ }
+
+ WindowObject->IDMenu = (UINT)hMenu;
+
+ IntReleaseMenuObject(MenuObject);
+ }
+ else
+ {
+ /* remove the menu handle */
+ WindowObject->IDMenu = 0;
+ }
+
+ IntReleaseWindowObject(WindowObject);
+
+ /* FIXME (from wine)
+ if(bRepaint)
+ {
+ if (IsWindowVisible(hWnd))
+ SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
+ SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
+ }
+ */
+
+ return TRUE;
+}
+
+
+/*
+ * @implemented
+ */
+HWND
+STDCALL
+NtUserSetParent(HWND hWndChild, HWND hWndNewParent)
+{
+ PWINDOW_OBJECT Wnd = NULL, WndParent = NULL, WndOldParent;
+ HWND hWndOldParent;
+
+ if (IntIsBroadcastHwnd(hWndChild) || IntIsBroadcastHwnd(hWndNewParent))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ IntAcquireWinLockExclusive();
+ if (hWndNewParent)
+ {
+ if (!(WndParent = IntGetWindowObject(hWndNewParent)))
+ {
+ IntReleaseWinLock();
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return NULL;
+ }
+ }
+
+ if (!(Wnd = IntGetWindowObject(hWndNewParent)))
+ {
+ IntReleaseWinLock();
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return NULL;
+ }
+
+ WndOldParent = IntSetParent(Wnd, WndParent);
+ if (WndOldParent) hWndOldParent = WndOldParent->Self;
+
+ IntReleaseWinLock();
+
+ return hWndOldParent;
+}
+
+
+/*
+ * @implemented
+ */
DWORD STDCALL
-NtUserSetShellWindowEx(DWORD Unknown0,
- DWORD Unknown1)
+NtUserSetShellWindowEx(HWND hwndShell, HWND hwndShellListView)
{
- UNIMPLEMENTED
+ PEPROCESS my_current = IoGetCurrentProcess();
- return 0;
+ /* test if we are permitted to change the shell window */
+ if (pidShellWindow && my_current->UniqueProcessId!=pidShellWindow)
+ return FALSE;
+
+ hwndShellWindow = hwndShell;
+ hwndShellListView = hwndShellListView;
+
+ if (hwndShell)
+ pidShellWindow = my_current->UniqueProcessId; /* request shell window for the calling process */
+ else
+ pidShellWindow = 0; /* shell window is now free for other processes. */
+
+ return TRUE;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+NtUserSetSystemMenu(
+ HWND hWnd,
+ HMENU hMenu)
+{
+ BOOL res = FALSE;
+ PWINDOW_OBJECT WindowObject;
+ PMENU_OBJECT MenuObject;
+ WindowObject = IntGetWindowObject((HWND)hWnd);
+ if(!WindowObject)
+ {
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return FALSE;
+ }
+
+ if(hMenu)
+ {
+ /* assign new menu handle */
+ MenuObject = IntGetMenuObject(hMenu);
+ if(!MenuObject)
+ {
+ IntReleaseWindowObject(WindowObject);
+ SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
+ return FALSE;
+ }
+
+ res = IntSetSystemMenu(WindowObject, MenuObject);
+
+ IntReleaseMenuObject(MenuObject);
+ }
+
+ IntReleaseWindowObject(WindowObject);
+ return res;
}
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserSetWindowFNID(DWORD Unknown0,
DWORD Unknown1)
return 0;
}
-DWORD STDCALL
-NtUserGetWindowLong(HWND hWnd, DWORD Index)
+
+/*
+ * @implemented
+ */
+LONG STDCALL
+NtUserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
{
PWINDOW_OBJECT WindowObject;
NTSTATUS Status;
- DWORD Result;
-
- W32kGuiCheck();
+ LONG OldValue;
+ STYLESTRUCT Style;
Status =
ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable,
(PVOID*)&WindowObject);
if (!NT_SUCCESS(Status))
{
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
return(0);
}
- switch (Index)
+ if (0 <= (int) Index)
{
- case GWL_EXSTYLE:
- {
- Result = (DWORD)WindowObject->ExStyle;
- break;
- }
-
- case GWL_STYLE:
- {
- Result = (DWORD)WindowObject->Style;
- break;
- }
-
- case GWL_WNDPROC:
- {
- Result = (DWORD)WindowObject->Class->Class.lpfnWndProc;
- break;
- }
- case GWL_ID:
- break;
+ if (WindowObject->ExtraDataSize - sizeof(LONG) < Index ||
+ 0 != Index % sizeof(LONG))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+ OldValue = WindowObject->ExtraData[Index / sizeof(LONG)];
+ WindowObject->ExtraData[Index / sizeof(LONG)] = NewValue;
+ }
+ else
+ {
+ switch (Index)
+ {
+ case GWL_EXSTYLE:
+ OldValue = (LONG) WindowObject->ExStyle;
+ Style.styleOld = OldValue;
+ Style.styleNew = NewValue;
+ IntSendSTYLECHANGINGMessage(hWnd, GWL_EXSTYLE, &Style);
+ WindowObject->ExStyle = (DWORD)Style.styleNew;
+ IntSendSTYLECHANGEDMessage(hWnd, GWL_EXSTYLE, &Style);
+ break;
+
+ case GWL_STYLE:
+ OldValue = (LONG) WindowObject->Style;
+ Style.styleOld = OldValue;
+ Style.styleNew = NewValue;
+ IntSendSTYLECHANGINGMessage(hWnd, GWL_STYLE, &Style);
+ WindowObject->Style = (DWORD)Style.styleNew;
+ IntSendSTYLECHANGEDMessage(hWnd, GWL_STYLE, &Style);
+ break;
+
+ case GWL_WNDPROC:
+ /* FIXME: should check if window belongs to current process */
+ if (Ansi)
+ {
+ OldValue = (LONG) WindowObject->WndProcA;
+ WindowObject->WndProcA = (WNDPROC) NewValue;
+ WindowObject->WndProcW = (WNDPROC) NewValue+0x80000000;
+ WindowObject->Unicode = FALSE;
+ }
+ else
+ {
+ OldValue = (LONG) WindowObject->WndProcW;
+ WindowObject->WndProcW = (WNDPROC) NewValue;
+ WindowObject->WndProcA = (WNDPROC) NewValue+0x80000000;
+ WindowObject->Unicode = TRUE;
+ }
+ break;
+
+ case GWL_HINSTANCE:
+ OldValue = (LONG) WindowObject->Instance;
+ WindowObject->Instance = (HINSTANCE) NewValue;
+ break;
+
+ case GWL_HWNDPARENT:
+ OldValue = (LONG) WindowObject->ParentHandle;
+ WindowObject->ParentHandle = (HWND) NewValue;
+ /* FIXME: Need to update window lists of old and new parent */
+ UNIMPLEMENTED;
+ break;
+
+ case GWL_ID:
+ OldValue = (LONG) WindowObject->IDMenu;
+ WindowObject->IDMenu = (UINT) NewValue;
+ break;
+
+ case GWL_USERDATA:
+ OldValue = WindowObject->UserData;
+ WindowObject->UserData = NewValue;
+ break;
- default:
- {
- DPRINT1("NtUserGetWindowLong(): Unsupported index %d\n", Index);
- Result = 0;
- break;
- }
+ default:
+ DPRINT1("NtUserSetWindowLong(): Unsupported index %d\n", Index);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ OldValue = 0;
+ break;
+ }
}
ObmDereferenceObject(WindowObject);
- return(Result);
+ return(OldValue);
}
-DWORD STDCALL
-NtUserSetWindowLong(DWORD Unknown0,
- DWORD Unknown1,
- DWORD Unknown2,
- DWORD Unknown3)
-{
- UNIMPLEMENTED
-
- return 0;
-}
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserSetWindowPlacement(DWORD Unknown0,
DWORD Unknown1)
return 0;
}
-BOOL
-STDCALL NtUserSetWindowPos(
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+NtUserSetWindowPos(
HWND hWnd,
HWND hWndInsertAfter,
int X,
return WinPosSetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags);
}
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserSetWindowRgn(DWORD Unknown0,
DWORD Unknown1,
return 0;
}
-DWORD STDCALL
-NtUserSetWindowWord(DWORD Unknown0,
- DWORD Unknown1,
- DWORD Unknown2)
+
+/*
+ * @unimplemented
+ */
+WORD STDCALL
+NtUserSetWindowWord(HWND hWnd, INT Index, WORD NewVal)
{
UNIMPLEMENTED
-
return 0;
}
+
+/*
+ * @implemented
+ */
BOOL STDCALL
NtUserShowWindow(HWND hWnd,
LONG nCmdShow)
{
- W32kGuiCheck();
-
return(WinPosShowWindow(hWnd, nCmdShow));
}
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserShowWindowAsync(DWORD Unknown0,
DWORD Unknown1)
return 0;
}
-BOOL STDCALL NtUserUpdateWindow( HWND hWnd )
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+NtUserUpdateWindow(HWND hWnd)
{
- PWINDOW_OBJECT pWindow = W32kGetWindowObject( hWnd);
+ PWINDOW_OBJECT pWindow = IntGetWindowObject( hWnd);
if (!pWindow)
return FALSE;
if (pWindow->UpdateRegion)
NtUserSendMessage( hWnd, WM_PAINT,0,0);
- W32kReleaseWindowObject(pWindow);
+ IntReleaseWindowObject(pWindow);
return TRUE;
}
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserUpdateLayeredWindow(DWORD Unknown0,
DWORD Unknown1,
return 0;
}
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+NtUserValidateRect(HWND hWnd, const RECT* Rect)
+{
+ return (VOID)NtUserRedrawWindow(hWnd, Rect, 0, RDW_VALIDATE | RDW_NOCHILDREN);
+}
+
+
+/*
+ * @unimplemented
+ */
DWORD STDCALL
NtUserWindowFromPoint(DWORD Unknown0,
DWORD Unknown1)