Some additions to the USER code; nothing is working yet.
authorDavid Welch <welch@cwcom.net>
Mon, 6 May 2002 22:20:32 +0000 (22:20 +0000)
committerDavid Welch <welch@cwcom.net>
Mon, 6 May 2002 22:20:32 +0000 (22:20 +0000)
svn path=/trunk/; revision=2915

16 files changed:
reactos/include/user32/callback.h
reactos/include/win32k/ntuser.h
reactos/lib/user32/misc/dllmain.c
reactos/lib/user32/misc/stubs.c
reactos/lib/user32/windows/message.c
reactos/lib/user32/windows/window.c
reactos/subsys/win32k/include/callback.h
reactos/subsys/win32k/include/msgqueue.h
reactos/subsys/win32k/include/window.h
reactos/subsys/win32k/include/winpos.h [new file with mode: 0644]
reactos/subsys/win32k/makefile
reactos/subsys/win32k/ntuser/callback.c
reactos/subsys/win32k/ntuser/message.c
reactos/subsys/win32k/ntuser/msgqueue.c
reactos/subsys/win32k/ntuser/window.c
reactos/subsys/win32k/ntuser/winpos.c [new file with mode: 0644]

index 5a9d7b4..3e30731 100644 (file)
@@ -2,7 +2,10 @@
 #define __INCLUDE_USER32_CALLBACK_H
 
 #define USER32_CALLBACK_WINDOWPROC          (0)
-#define USER32_CALLBACK_MAXIMUM             (1)
+#define USER32_CALLBACK_SENDASYNCPROC       (1)
+#define USER32_CALLBACK_SENDNCCREATE        (2)
+#define USER32_C
+#define USER32_CALLBACK_MAXIMUM             (3)
 
 typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS
 {
@@ -13,7 +16,27 @@ typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS
   LPARAM lParam;
 } WINDOWPROC_CALLBACK_ARGUMENTS, *PWINDOWPROC_CALLBACK_ARGUMENTS;
 
+typedef struct _SENDASYNCPROC_CALLBACK_ARGUMENTS
+{
+  SENDASYNCPROC Proc;
+  HWND Wnd;
+  UINT Msg;
+  ULONG Data;
+  LRESULT Result;
+} SENDASYNCPROC_CALLBACK_ARGUMENTS, *PSENDASYNCPROC_CALLBACK_ARGUMENTS;
+
+typedef struct _SENDNCREATEMESSAGE_CALLBACK_ARGUMENTS
+{
+  HWND Wnd;
+  CREATESTRUCT CreateStruct;
+} SENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS, 
+  *PSENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS;
+
 NTSTATUS STDCALL
 User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength);
+NTSTATUS STDCALL
+User32CallSendAsyncProcForKernel(PVOID Arguments, ULONG ArgumentLength);
+NTSTATUS STDCALL
+User32SendNCCREATEMessageForKernel(PVOID Arguments, ULONG ArgumentLength);
 
 #endif /* __INCLUDE_USER32_CALLBACK_H */
index 73655d3..78c0a56 100644 (file)
@@ -162,13 +162,11 @@ NtUserCheckMenuItem(
   DWORD Unknown1,
   DWORD Unknown2);
 
-DWORD
-STDCALL
-NtUserChildWindowFromPointEx(
-  DWORD Unknown0,
-  DWORD Unknown1,
-  DWORD Unknown2,
-  DWORD Unknown3);
+DWORD STDCALL
+NtUserChildWindowFromPointEx(HWND Parent,
+                            LONG x,
+                            LONG y,
+                            UINT Flags);
 
 DWORD
 STDCALL
@@ -287,18 +285,15 @@ NtUserDdeSetQualityOfService(
   DWORD Unknown1,
   DWORD Unknown2);
 
-DWORD
-STDCALL
-NtUserDeferWindowPos(
-  DWORD Unknown0,
-  DWORD Unknown1,
-  DWORD Unknown2,
-  DWORD Unknown3,
-  DWORD Unknown4,
-  DWORD Unknown5,
-  DWORD Unknown6,
-  DWORD Unknown7);
-
+DWORD STDCALL
+NtUserDeferWindowPos(HDWP WinPosInfo,
+                    HWND Wnd,
+                    HWND WndInsertAfter,
+                    LONG x,
+                    LONG y,
+                    LONG cx,
+                    LONG cy,
+                    UINT Flags);
 DWORD
 STDCALL
 NtUserDefSetText(
@@ -328,10 +323,8 @@ STDCALL
 NtUserDestroyMenu(
   DWORD Unknown0);
 
-DWORD
-STDCALL
-NtUserDestroyWindow(
-  DWORD Unknown0);
+BOOLEAN STDCALL
+NtUserDestroyWindow(HWND Wnd);
 
 LRESULT
 STDCALL
@@ -1126,10 +1119,8 @@ STDCALL
 NtUserRegisterTasklist(
   DWORD Unknown0);
 
-DWORD
-STDCALL
-NtUserRegisterWindowMessage(
-  DWORD Unknown0);
+UINT STDCALL
+NtUserRegisterWindowMessage(LPCWSTR MessageName);
 
 DWORD
 STDCALL
index 8e72095..7ebb88c 100644 (file)
@@ -25,6 +25,10 @@ Init(VOID)
   /* Set up the kernel callbacks. */
   NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_WINDOWPROC] =
     (PVOID)User32CallWindowProcFromKernel;
+  NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_SENDASYNCPROC] =
+    (PVOID)User32CallSendAsyncProcForKernel;
+  NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_SENDNCCREATE] =
+    (PVOID)User32SendNCCREATEMessageForKernel;
 
   //ProcessWindowStation = CreateWindowStationW(L"WinStaName",0,GENERIC_ALL,NULL);
   //Desktop = CreateDesktopA(NULL,NULL,NULL,0,0,NULL);
index 932262f..2cc394b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: stubs.c,v 1.6 2001/11/03 16:48:06 chorns Exp $
+/* $Id: stubs.c,v 1.7 2002/05/06 22:20:31 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS user32.dll
@@ -3358,21 +3358,6 @@ RegisterHotKey(
   return FALSE;
 }
 
-UINT
-STDCALL
-RegisterWindowMessageA(
-  LPCSTR lpString)
-{
-  return 0;
-}
-
-UINT
-STDCALL
-RegisterWindowMessageW(
-  LPCWSTR lpString)
-{
-  return 0;
-}
 
 WINBOOL
 STDCALL
index 918dcc5..26b950d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: message.c,v 1.4 2001/06/12 17:50:27 chorns Exp $
+/* $Id: message.c,v 1.5 2002/05/06 22:20:31 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS user32.dll
@@ -266,4 +266,28 @@ WaitMessage(VOID)
   return FALSE;
 }
 
+UINT STDCALL
+RegisterWindowMessageA(LPCSTR lpString)
+{
+  UNICODE_STRING String;
+  BOOLEAN Result;
+  UINT Atom;
+
+  Result = RtlCreateUnicodeStringFromAsciiz(&String, lpString);
+  if (!Result)
+    {
+      return(0);
+    }
+  Atom = RegisterWindowMessageW(String.Buffer);
+  RtlFreeUnicodeString(&String);
+  return(Atom);
+}
+
+UINT STDCALL
+RegisterWindowMessageW(LPCWSTR lpString)
+{
+  return(NtUserRegisterWindowMessage(lpString));
+}
+
+
 /* EOF */
index c37ae11..14b3e09 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: window.c,v 1.4 2002/01/27 01:11:23 dwelch Exp $
+/* $Id: window.c,v 1.5 2002/05/06 22:20:31 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS user32.dll
 
 /* FUNCTIONS *****************************************************************/
 
+NTSTATUS STDCALL
+User32SendNCCREATEMessageForKernel(PVOID Arguments, ULONG ArgumentLength)
+{
+  PSENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS CallbackArgs;
+  WNDPROC Proc;
+  LRESULT Result;
+
+  CallbackArgs = (PSENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS)Arguments;
+  if (ArgumentLength != sizeof(SENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS))
+    {
+      return(STATUS_INFO_LENGTH_MISMATCH);
+    }
+  Proc = (WNDPROC)GetWindowLong(CallbackArgs->Wnd, GWL_WNDPROC);
+  Result = CallWindowProc(Proc, CallbackArgs->Wnd, WM_NCCREATE, 0, 
+                         (LPARAM)&CallbackArgs->CreateStruct);
+  ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS);
+  /* Doesn't return. */
+}
+
+NTSTATUS STDCALL
+User32CallSendAsyncProcForKernel(PVOID Arguments, ULONG ArgumentLength)
+{
+  PSENDASYNCPROC_CALLBACK_ARGUMENTS CallbackArgs;
+  
+  CallbackArgs = (PSENDASYNCPROC_CALLBACK_ARGUMENTS)Arguments;
+  if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS))
+    {
+      return(STATUS_INFO_LENGTH_MISMATCH);
+    }
+  CallbackArgs->Proc(CallbackArgs->Wnd, CallbackArgs->Msg,
+                    CallbackArgs->Data, CallbackArgs->Result);
+  return(STATUS_SUCCESS);
+}
+
 NTSTATUS STDCALL
 User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
 {
@@ -30,8 +64,14 @@ User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
     {
       return(STATUS_INFO_LENGTH_MISMATCH);
     }
-  Result = CallbackArgs->Proc(CallbackArgs->Wnd, CallbackArgs->Msg,
-                             CallbackArgs->wParam, CallbackArgs->lParam);
+  if (CallbackArgs->Proc == NULL)
+    {
+      CallbackArgs->Proc = (WNDPROC)GetWindowLong(CallbackArgs->Wnd, 
+                                                 GWL_WNDPROC);
+    }
+  Result = CallWindowProc(CallbackArgs->Proc, CallbackArgs->Wnd, 
+                         CallbackArgs->Msg, CallbackArgs->wParam, 
+                         CallbackArgs->lParam);
   ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS);
   /* Doesn't return. */
 }
@@ -133,6 +173,7 @@ CreateWindowExA(DWORD dwExStyle,
   UNICODE_STRING WindowName;
   UNICODE_STRING ClassName;
   HWND Handle;
+  INT sw;
   
   if (IS_ATOM(lpClassName)) 
     {
@@ -158,6 +199,56 @@ CreateWindowExA(DWORD dwExStyle,
       return (HWND)0;
     }
 
+  /* Fixup default coordinates. */
+  sw = SW_SHOW;
+  if (x == CW_USEDEFAULT || nWidth == CW_USEDEFAULT)
+    {
+      if (dwStyle & (WS_CHILD | WS_POPUP))
+       {
+         if (x == CW_USEDEFAULT)
+           {
+             x = y = 0;
+           }
+         if (nWidth == CW_USEDEFAULT)
+           {
+             nWidth = nHeight = 0;
+           }
+       }
+      else
+       {
+         STARTUPINFOA info;
+
+         GetStartupInfoA(&info);
+
+         if (x == CW_USEDEFAULT)
+           {
+             if (y != CW_USEDEFAULT)
+               {
+                 sw = y;
+               }
+             x = (info.dwFlags & STARTF_USEPOSITION) ? info.dwX : 0;
+             y = (info.dwFlags & STARTF_USEPOSITION) ? info.dwY : 0;
+           }
+         
+         if (nWidth == CW_USEDEFAULT)
+           {
+             if (info.dwFlags & STARTF_USESIZE)
+               {
+                 nWidth = info.dwXSize;
+                 nHeight = info.dwYSize;
+               }
+             else
+               {
+                 RECT r;
+
+                 SystemParametersInfoA(SPI_GETWORKAREA, 0, &r, 0);
+                 nWidth = (((r.right - r.left) * 3) / 4) - x;
+                 nHeight = (((r.bottom - r.top) * 3) / 4) - y;
+               }
+           }
+       }
+    }
+
   Handle = NtUserCreateWindowEx(dwExStyle,
                                &ClassName,
                                &WindowName,
@@ -170,7 +261,7 @@ CreateWindowExA(DWORD dwExStyle,
                                hMenu,
                                hInstance,
                                lpParam,
-                               0);
+                               sw);
 
   RtlFreeUnicodeString(&WindowName);
 
@@ -199,6 +290,7 @@ CreateWindowExW(DWORD dwExStyle,
   UNICODE_STRING WindowName;
   UNICODE_STRING ClassName;
   HANDLE Handle;
+  UINT sw;
 
   if (IS_ATOM(lpClassName)) 
     {
@@ -212,6 +304,56 @@ CreateWindowExW(DWORD dwExStyle,
 
   RtlInitUnicodeString(&WindowName, lpWindowName);
 
+  /* Fixup default coordinates. */
+  sw = SW_SHOW;
+  if (x == CW_USEDEFAULT || nWidth == CW_USEDEFAULT)
+    {
+      if (dwStyle & (WS_CHILD | WS_POPUP))
+       {
+         if (x == CW_USEDEFAULT)
+           {
+             x = y = 0;
+           }
+         if (nWidth == CW_USEDEFAULT)
+           {
+             nWidth = nHeight = 0;
+           }
+       }
+      else
+       {
+         STARTUPINFOW info;
+
+         GetStartupInfoW(&info);
+
+         if (x == CW_USEDEFAULT)
+           {
+             if (y != CW_USEDEFAULT)
+               {
+                 sw = y;
+               }
+             x = (info.dwFlags & STARTF_USEPOSITION) ? info.dwX : 0;
+             y = (info.dwFlags & STARTF_USEPOSITION) ? info.dwY : 0;
+           }
+         
+         if (nWidth == CW_USEDEFAULT)
+           {
+             if (info.dwFlags & STARTF_USESIZE)
+               {
+                 nWidth = info.dwXSize;
+                 nHeight = info.dwYSize;
+               }
+             else
+               {
+                 RECT r;
+
+                 SystemParametersInfoW(SPI_GETWORKAREA, 0, &r, 0);
+                 nWidth = (((r.right - r.left) * 3) / 4) - x;
+                 nHeight = (((r.bottom - r.top) * 3) / 4) - y;
+               }
+           }
+       }
+    }
+
   Handle = NtUserCreateWindowEx(dwExStyle,
                                &ClassName,
                                &WindowName,
index 7ccdb4f..db404b8 100644 (file)
@@ -7,5 +7,9 @@ W32kCallWindowProc(WNDPROC Proc,
                   UINT Message,
                   WPARAM wParam,
                   LPARAM lParam);
+LRESULT STDCALL
+W32kSendNCCREATEMessage(HWND Wnd, CREATESTRUCT* CreateStruct);
+LRESULT STDCALL
+W32kSendCREATEMessage(HWND Wnd, CREATESTRUCT* CreateStruct);
 
 #endif /* __SUBSYS_WIN32K_INCLUDE_CALLBACK_H */
index 474d21e..a090974 100644 (file)
@@ -9,11 +9,35 @@ typedef struct _USER_MESSAGE
   MSG Msg;
 } USER_MESSAGE, *PUSER_MESSAGE;
 
+struct _USER_MESSAGE_QUEUE;
+
+typedef struct _USER_SENT_MESSAGE
+{
+  LIST_ENTRY ListEntry;
+  MSG Msg;
+  PKEVENT CompletionEvent;
+  LRESULT* Result;
+  struct _USER_MESSAGE_QUEUE* CompletionQueue;
+  SENDASYNCPROC CompletionCallback;
+  ULONG_PTR CompletionCallbackContext;
+} USER_SENT_MESSAGE, *PUSER_SENT_MESSAGE;
+
+typedef struct _USER_SENT_MESSAGE_NOTIFY
+{
+  SENDASYNCPROC CompletionCallback;
+  ULONG_PTR CompletionCallbackContext;
+  LRESULT Result;
+  HWND hWnd;
+  UINT Msg;
+  LIST_ENTRY ListEntry;
+} USER_SENT_MESSAGE_NOTIFY, *PUSER_SENT_MESSAGE_NOTIFY;
+
 typedef struct _USER_MESSAGE_QUEUE
 {
   LIST_ENTRY SentMessagesListHead;
   LIST_ENTRY PostedMessagesListHead;
   LIST_ENTRY HardwareMessagesListHead;
+  LIST_ENTRY NotifyMessagesListHead;
   FAST_MUTEX Lock;
   BOOLEAN QuitPosted;
   ULONG QuitExitCode;
@@ -22,7 +46,9 @@ typedef struct _USER_MESSAGE_QUEUE
   HWND FocusWindow;
 } USER_MESSAGE_QUEUE, *PUSER_MESSAGE_QUEUE;
 
-
+VOID
+MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
+              PUSER_SENT_MESSAGE Message);
 VOID
 MsqInitializeMessage(PUSER_MESSAGE Message,
                     LPMSG Msg);
@@ -57,6 +83,8 @@ MsqWaitForNewMessage(PUSER_MESSAGE_QUEUE MessageQueue);
 NTSTATUS
 MsqInitializeImpl(VOID);
 
+#define MAKE_LONG(x, y) ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF))
+
 #endif /* __WIN32K_MSGQUEUE_H */
 
 /* EOF */
index 96d09ad..90b43ed 100644 (file)
@@ -7,21 +7,46 @@
 
 typedef struct _WINDOW_OBJECT
 {
+  /* Pointer to the window class. */
   PWNDCLASS_OBJECT Class;
+  /* Extended style. */
   DWORD ExStyle;
+  /* Window name. */
   UNICODE_STRING WindowName;
+  /* Style. */
   DWORD Style;
-  int x;
-  int y;
-  int Width;
-  int Height;
-  HWND Parent;
+  /* Initial window position. */
+  INT x;
+  INT y;
+  INT Width;
+  INT Height;
+  /* Parent window handle. */
+  HWND ParentHandle;
+  struct _WINDOW_OBJECT* Parent;
+  /* Window menu handle. */
   HMENU Menu;
+  /* Handle of the module that created the window. */
   HINSTANCE Instance;
+  /* Unknown. */
   LPVOID Parameters;
+  /* Entry in the thread's list of windows. */
   LIST_ENTRY ListEntry;
+  /* Pointer to the extra data associated with the window. */
+  PULONG ExtraData;
+  /* Size of the extra data associated with the window. */
+  ULONG ExtraDataSize;
+  /* Position of the window. */
+  RECT WindowRect;
+  /* Position of the window's client area. */
+  RECT ClientRect;
+  /* Handle for the window. */
+  HANDLE Self;
+  /* Window flags. */
+  ULONG Flags;
+  UINT IDMenu;
 } WINDOW_OBJECT, *PWINDOW_OBJECT;
 
+#define WINDOWOBJECT_NEED_SIZE            (0x00000001)
 
 NTSTATUS
 InitWindowImpl(VOID);
diff --git a/reactos/subsys/win32k/include/winpos.h b/reactos/subsys/win32k/include/winpos.h
new file mode 100644 (file)
index 0000000..6593019
--- /dev/null
@@ -0,0 +1,12 @@
+LRESULT
+WinPosGetNonClientSize(HWND Wnd, RECT* WindowRect, RECT* ClientRect);
+VOID
+WinPosGetMinMaxInfo(PWINDOW_OBJECT Window, POINT* MaxSize, POINT* MaxPos,
+                   POINT* MinTrack, POINT* MaxTrack);
+VOID
+WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos);
+BOOLEAN
+WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
+                  INT cy, UINT flags);
+BOOLEAN
+WinPosShowWindow(HWND Wnd, INT Cmd);
index 747e99b..fbc1b86 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.42 2002/01/27 01:11:24 dwelch Exp $
+# $Id: makefile,v 1.43 2002/05/06 22:20:32 dwelch Exp $
 
 PATH_TO_TOP = ../..
 
@@ -24,7 +24,8 @@ LDR_OBJECTS = ldr/loader.o
 NTUSER_OBJECTS = ntuser/class.o ntuser/guicheck.o ntuser/hook.o \
                  ntuser/message.o ntuser/msgqueue.o ntuser/stubs.o \
                  ntuser/userobj.o ntuser/window.o ntuser/winsta.o \
-                ntuser/input.o ntuser/keyboard.o ntuser/callback.o
+                ntuser/input.o ntuser/keyboard.o ntuser/callback.o \
+                ntuser/winpos.o
 OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o  \
                   objects/color.o objects/coord.o objects/dc.o  \
                   objects/fillshap.o objects/gdiobj.o objects/icm.o  \
index bea5098..db5561b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: callback.c,v 1.1 2002/01/27 14:47:44 dwelch Exp $
+/* $Id: callback.c,v 1.2 2002/05/06 22:20:32 dwelch Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
 
 /* FUNCTIONS *****************************************************************/
 
+VOID STDCALL
+W32kCallSentMessageCallback(SENDASYNCPROC CompletionCallback,
+                           HWND hWnd,
+                           UINT Msg,
+                           ULONG_PTR CompletionCallbackContext,
+                           LRESULT Result)
+{
+}
+
+LRESULT STDCALL
+W32kSendNCCALCSIZEMessage(HWND Wnd, BOOL Validate, RECT Rect1,
+                         RECT Rect2, RECT Rect3, PWINDOWPOS Pos)
+{
+}
+
+LRESULT STDCALL
+W32kSendCREATEMessage(HWND Wnd, CREATESTRUCT* CreateStruct)
+{
+}
+
+LRESULT STDCALL
+W32kSendNCCREATEMessage(HWND Wnd, CREATESTRUCT* CreateStruct)
+{
+  SENDNCCREATEMESSAGE_CALLBACK_ARGUMENTS Arguments;
+  LRESULT Result;
+  NTSTATUS Status;
+  PVOID ResultPointer;
+  DWORD ResultLength;
+
+  Arguments.Wnd = Wnd;
+  Arguments.CreateStruct = *CreateStruct;
+  ResultPointer = &Result;
+  ResultLength = sizeof(LRESULT);
+  Status = NtW32Call(USER32_CALLBACK_WINDOWPROC,
+                    &Arguments,
+                    sizeof(WINDOWPROC_CALLBACK_ARGUMENTS),
+                    &ResultPointer,
+                    &ResultLength);
+  if (!NT_SUCCESS(Status))
+    {
+      return(0);
+    }
+  return(Result);
+}                              
+
 LRESULT STDCALL
 W32kCallWindowProc(WNDPROC Proc,
                   HWND Wnd,
index 245c005..240d972 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: message.c,v 1.4 2002/01/27 01:11:24 dwelch Exp $
+/* $Id: message.c,v 1.5 2002/05/06 22:20:32 dwelch Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -221,6 +221,14 @@ NtUserQuerySendMessage(DWORD Unknown0)
   return 0;
 }
 
+BOOL STDCALL
+NtUserSendMessage(HWND hWnd,
+                 UINT Msg,
+                 WPARAM Wparam,
+                 LPARAM lParam)
+{
+}
+
 BOOL STDCALL
 NtUserSendMessageCallback(HWND hWnd,
                          UINT Msg,
index 6e3defb..451c055 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: msgqueue.c,v 1.2 2002/01/13 22:52:08 dwelch Exp $
+/* $Id: msgqueue.c,v 1.3 2002/05/06 22:20:32 dwelch Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -76,6 +76,103 @@ MsqDestroyMessage(PUSER_MESSAGE Message)
   ExFreePool(Message);
 }
 
+VOID
+MsqDispatchSentNotifyMessages(PUSER_MESSAGE_QUEUE MessageQueue)
+{
+  PLIST_ENTRY ListEntry;
+  PUSER_SENT_MESSAGE_NOTIFY Message;
+
+  while (!IsListEmpty(&MessageQueue->SentMessagesListHead))
+  {
+    ExAcquireFastMutex(&MessageQueue->Lock);
+    ListEntry = RemoveHeadList(&MessageQueue->SentMessagesListHead);
+    Message = CONTAINING_RECORD(ListEntry, USER_SENT_MESSAGE_NOTIFY, 
+                               ListEntry);
+    ExReleaseFastMutex(&MessageQueue->Lock);
+
+    W32kCallSentMessageCallback(Message->CompletionCallback,
+                               Message->hWnd,
+                               Message->Msg,
+                               Message->CompletionCallbackContext,
+                               Message->Result);
+  }
+}
+
+BOOLEAN
+MsqPeekSentMessages(PUSER_MESSAGE_QUEUE MessageQueue)
+{
+  return(!IsListEmpty(&MessageQueue->SentMessagesListHead));
+}
+
+VOID
+MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
+{
+  PUSER_SENT_MESSAGE Message;
+  PLIST_ENTRY Entry;
+  LRESULT Result;
+  PUSER_SENT_MESSAGE_NOTIFY NotifyMessage;
+
+  ExAcquireFastMutex(&MessageQueue->Lock);
+  Entry = RemoveHeadList(&MessageQueue->SentMessagesListHead);
+  Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
+  ExReleaseFastMutex(&MessageQueue->Lock);
+
+  /* Call the window procedure. */
+  Result = W32kCallWindowProc(W32kGetWindowProc(Message->Msg.hwnd),
+                             Message->Msg.hwnd,
+                             Message->Msg.message,
+                             Message->Msg.wParam,
+                             Message->Msg.lParam);
+
+  /* Let the sender know the result. */
+  if (Message->Result != NULL)
+    {
+      *Message->Result = Result;
+    }
+
+  /* Notify the sender. */
+  if (Message->CompletionEvent != NULL)
+    {
+      KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE);
+    }
+
+  /* Notify the sender if they specified a callback. */
+  if (Message->CompletionCallback != NULL)
+    {
+      NotifyMessage = ExAllocatePool(NonPagedPool, 
+                                    sizeof(USER_SENT_MESSAGE_NOTIFY));
+      NotifyMessage->CompletionCallback = 
+       Message->CompletionCallback;
+      NotifyMessage->CompletionCallbackContext =
+       Message->CompletionCallbackContext;
+      NotifyMessage->Result = Result;
+      NotifyMessage->hWnd = Message->Msg.hwnd;
+      NotifyMessage->Msg = Message->Msg.message;
+      MsqSendNotifyMessage(Message->CompletionQueue);
+    }
+
+  ExFreePool(Message);
+}
+
+VOID
+MsqSendNotifyMessage(PUSER_MESSAGE_QUEUE MessageQueue,
+                    PUSER_SENT_MESSAGE_NOTIFY NotifyMessage)
+{
+  ExAcquireFastMutex(&MessageQueue->Lock);
+  InsertTailList(&MessageQueue->NotifyMessagesListHead, 
+                &NotifyMessage->ListEntry);
+  ExReleaseFastMutex(&MessageQueue->Lock);
+}
+
+VOID
+MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
+              PUSER_SENT_MESSAGE Message)
+{
+  ExAcquireFastMutex(&MessageQueue->Lock);
+  InsertTailList(&MessageQueue->SentMessagesListHead, &Message->ListEntry);
+  ExReleaseFastMutex(&MessageQueue->Lock);
+}
+
 VOID
 MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue,
               PUSER_MESSAGE Message,
index 98ef5b6..7396689 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: window.c,v 1.5 2002/01/27 01:11:24 dwelch Exp $
+/* $Id: window.c,v 1.6 2002/05/06 22:20:32 dwelch Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
 #include <include/class.h>
 #include <include/error.h>
 #include <include/winsta.h>
+#include <include/winpos.h>
+#include <include/callback.h>
+#include <include/msgqueue.h>
 
 #define NDEBUG
 #include <debug.h>
 
 /* FUNCTIONS *****************************************************************/
 
+BOOL
+W32kOffsetRect(LPRECT Rect, INT x, INT y)
+{
+  Rect->left += x;
+  Rect->right += x;
+  Rect->top += y;
+  Rect->bottom += y;
+  return(TRUE);
+}
+
+HWND
+W32kGetActiveWindow(VOID)
+{
+}
+
+WNDPROC
+W32kGetWindowProc(HWND Wnd)
+{
+}
+
 NTSTATUS
 InitWindowImpl(VOID)
 {
@@ -48,10 +71,10 @@ NtUserAlterWindowStyle(DWORD Unknown0,
 }
 
 DWORD STDCALL
-NtUserChildWindowFromPointEx(DWORD Unknown0,
-                            DWORD Unknown1,
-                            DWORD Unknown2,
-                            DWORD Unknown3)
+NtUserChildWindowFromPointEx(HWND Parent,
+                            LONG x,
+                            LONG y,
+                            UINT Flags)
 {
   UNIMPLEMENTED
 
@@ -71,7 +94,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
                     HMENU hMenu,
                     HINSTANCE hInstance,
                     LPVOID lpParam,
-                    DWORD Unknown12)
+                    DWORD dwShowMode)
 {
   PWINSTATION_OBJECT WinStaObject;
   PWNDCLASS_OBJECT ClassObject;
@@ -79,22 +102,29 @@ NtUserCreateWindowEx(DWORD dwExStyle,
   UNICODE_STRING WindowName;
   NTSTATUS Status;
   HANDLE Handle;
+  POINT MaxSize, MaxPos, MinTrack, MaxTrack;
+  CREATESTRUCT Cs;
+  LRESULT Result;
 
   W32kGuiCheck();
 
-  Status = ClassReferenceClassByNameOrAtom(&ClassObject, lpClassName->Buffer);
-  if (!NT_SUCCESS(Status))
-    {
-      return (HWND)0;
-    }
-  
   if (!RtlCreateUnicodeString(&WindowName, lpWindowName->Buffer))
     {
-      ObmDereferenceObject(ClassObject);
       SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
-      return (HWND)0;
+      return((HWND)0);
     }
 
+  /* FIXME: Validate the parent window. */
+
+  /* Check the class. */
+  Status = ClassReferenceClassByNameOrAtom(&ClassObject, lpClassName->Buffer);
+  if (!NT_SUCCESS(Status))
+    {
+      RtlFreeUnicodeString(&WindowName);
+      return((HWND)0);
+    }
+
+  /* Check the window station. */
   Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
                                       KernelMode,
                                       0,
@@ -108,6 +138,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
       return (HWND)0;
     }
 
+  /* Create the window object. */
   WindowObject = (PWINDOW_OBJECT) 
     ObmCreateObject(PsGetWin32Process()->HandleTable, &Handle, otWindow, 
                    sizeof(WINDOW_OBJECT));
@@ -119,9 +150,11 @@ NtUserCreateWindowEx(DWORD dwExStyle,
       SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
       return (HWND)0;
     }
-
   ObDereferenceObject(WinStaObject);
-  
+
+  /*
+   * Fill out the structure describing it.
+   */
   WindowObject->Class = ClassObject;
   WindowObject->ExStyle = dwExStyle;
   WindowObject->Style = dwStyle;
@@ -133,34 +166,181 @@ NtUserCreateWindowEx(DWORD dwExStyle,
   WindowObject->Menu = hMenu;
   WindowObject->Instance = hInstance;
   WindowObject->Parameters = lpParam;
+  WindowObject->Self = Handle;
+
+  /* FIXME: Add the window parent. */
 
   RtlInitUnicodeString(&WindowObject->WindowName, WindowName.Buffer);
+  RtlFreeUnicodeString(&WindowName);
+  
+  if (ClassObject->Class.cbWndExtra != 0)
+    {
+      WindowObject->ExtraData = 
+       ExAllocatePool(PagedPool, 
+                      ClassObject->Class.cbWndExtra * sizeof(DWORD));
+      WindowObject->ExtraDataSize = ClassObject->Class.cbWndExtra;
+    }
+  else
+    {
+      WindowObject->ExtraData = NULL;
+      WindowObject->ExtraDataSize = 0;
+    }
 
+  /* Correct the window style. */
+  if (!(dwStyle & WS_CHILD))
+    {
+      WindowObject->Style |= WS_CLIPSIBLINGS;
+      if (!(dwStyle & WS_POPUP))
+       {
+         WindowObject->Style |= WS_CAPTION;
+         /* FIXME: Note the window needs a size. */ 
+       }
+    }
+
+  /* Insert the window into the process's window list. */
   ExAcquireFastMutexUnsafe (&PsGetWin32Process()->WindowListLock);
   InsertTailList (&PsGetWin32Process()->WindowListHead, 
                  &WindowObject->ListEntry);
   ExReleaseFastMutexUnsafe (&PsGetWin32Process()->WindowListLock);
 
-  return (HWND)Handle;
+  /* FIXME: Maybe allocate a DCE for this window. */
+
+  /* Initialize the window dimensions. */
+  WindowObject->WindowRect.left = x;
+  WindowObject->WindowRect.top = y;
+  WindowObject->WindowRect.right = x + nWidth;
+  WindowObject->WindowRect.bottom = y + nHeight;
+  WindowObject->ClientRect = WindowObject->WindowRect;
+
+  /*
+   * Get the size and position of the window.
+   */
+  if ((dwStyle & WS_THICKFRAME) || !(dwStyle & (WS_POPUP | WS_CHILD)))
+    {
+      WinPosGetMinMaxInfo(WindowObject, &MaxSize, &MaxPos, &MinTrack,
+                         &MaxTrack);
+      x = min(MaxSize.x, y);
+      y = min(MaxSize.y, y);
+      x = max(MinTrack.x, x);
+      y = max(MinTrack.y, y);
+    }
+
+  WindowObject->WindowRect.left = x;
+  WindowObject->WindowRect.top = y;
+  WindowObject->WindowRect.right = x + nWidth;
+  WindowObject->WindowRect.bottom = y + nHeight;
+  WindowObject->ClientRect = WindowObject->WindowRect;
+
+  /* FIXME: Initialize the window menu. */
+
+  /* Send a NCCREATE message. */
+  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.style = dwStyle;
+  Cs.lpszName = lpWindowName->Buffer;
+  Cs.lpszClass = lpClassName->Buffer;
+  Cs.dwExStyle = dwExStyle;
+  Result = W32kSendNCCREATEMessage(WindowObject->Self, &Cs);
+  if (!Result)
+    {
+      /* FIXME: Cleanup. */
+      return(NULL);
+    }
+  /* Calculate the non-client size. */
+  MaxPos.x = WindowObject->WindowRect.left;
+  MaxPos.y = WindowObject->WindowRect.top;
+  Result = WinPosGetNonClientSize(WindowObject->Self, 
+                                 &WindowObject->WindowRect,
+                                 &WindowObject->ClientRect);
+  W32kOffsetRect(&WindowObject->WindowRect, 
+                MaxPos.x - WindowObject->WindowRect.left,
+                MaxPos.y - WindowObject->WindowRect.top);
+
+  /* Send the CREATE message. */
+  Result = W32kSendCREATEMessage(WindowObject->Self, &Cs);
+  if (!Result)
+    {
+      /* FIXME: Cleanup. */
+      return(NULL);
+    } 
+
+  /* Send move and size messages. */
+  if (!(WindowObject->Flags & WINDOWOBJECT_NEED_SIZE))
+    {
+      LONG lParam;
+      
+      lParam = 
+       MAKE_LONG(WindowObject->ClientRect.right - 
+                 WindowObject->ClientRect.left,
+                 WindowObject->ClientRect.bottom - 
+                 WindowObject->ClientRect.top);
+      W32kCallWindowProc(NULL, WindowObject->Self, WM_SIZE, SIZE_RESTORED, 
+                        lParam);
+      lParam = 
+       MAKE_LONG(WindowObject->ClientRect.left,
+                 WindowObject->ClientRect.top);
+      W32kCallWindowProc(NULL, WindowObject->Self, WM_MOVE, 0, lParam);
+    }
+
+  /* Show or maybe minimize or maximize the window. */
+  if (WindowObject->Style & (WS_MINIMIZE | WS_MAXIMIZE))
+    {
+      RECT NewPos;
+      UINT16 SwFlag;
+
+      SwFlag = (WindowObject->Style & WS_MINIMIZE) ? SW_MINIMIZE : 
+       SW_MAXIMIZE;
+      WinPosMinMaximize(WindowObject, SwFlag, &NewPos);
+      SwFlag = 
+       ((WindowObject->Style & WS_CHILD) || W32kGetActiveWindow()) ?
+       SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED :
+       SWP_NOZORDER | SWP_FRAMECHANGED;
+      WinPosSetWindowPos(WindowObject->Self, 0, NewPos.left, NewPos.top,
+                        NewPos.right, NewPos.bottom, SwFlag);
+    }
+
+  /* Notify the parent window of a new child. */
+  if ((WindowObject->Style & WS_CHILD) ||
+      (!(WindowObject->ExStyle & WS_EX_NOPARENTNOTIFY)))
+    {
+      W32kCallWindowProc(NULL, WindowObject->Parent->Self,
+                        WM_PARENTNOTIFY, 
+                        MAKEWPARAM(WM_CREATE, WindowObject->IDMenu),
+                        (LPARAM)WindowObject->Self);
+    }
+
+  if (dwStyle & WS_VISIBLE)
+    {
+      WinPosShowWindow(WindowObject->Self, dwShowMode);
+    }
+
+  return((HWND)Handle);
 }
 
 DWORD STDCALL
-NtUserDeferWindowPos(DWORD Unknown0,
-                    DWORD Unknown1,
-                    DWORD Unknown2,
-                    DWORD Unknown3,
-                    DWORD Unknown4,
-                    DWORD Unknown5,
-                    DWORD Unknown6,
-                    DWORD Unknown7)
+NtUserDeferWindowPos(HDWP WinPosInfo,
+                    HWND Wnd,
+                    HWND WndInsertAfter,
+                    LONG x,
+                    LONG y,
+                    LONG cx,
+                    LONG cy,
+                    UINT Flags)
 {
   UNIMPLEMENTED
 
   return 0;
 }
 
-DWORD STDCALL
-NtUserDestroyWindow(DWORD Unknown0)
+BOOLEAN STDCALL
+NtUserDestroyWindow(HWND Wnd)
 {
   UNIMPLEMENTED
 
@@ -348,12 +528,12 @@ NtUserRedrawWindow(DWORD Unknown0,
   return 0;
 }
 
-DWORD STDCALL
-NtUserRegisterWindowMessage(DWORD Unknown0)
+UINT STDCALL
+NtUserRegisterWindowMessage(LPCWSTR MessageName)
 {
   UNIMPLEMENTED
 
-  return 0;
+  return(0);
 }
 
 DWORD STDCALL
diff --git a/reactos/subsys/win32k/ntuser/winpos.c b/reactos/subsys/win32k/ntuser/winpos.c
new file mode 100644 (file)
index 0000000..9751f25
--- /dev/null
@@ -0,0 +1,263 @@
+/* $Id: winpos.c,v 1.1 2002/05/06 22:20:32 dwelch Exp $
+ *
+ * COPYRIGHT:        See COPYING in the top level directory
+ * PROJECT:          ReactOS kernel
+ * PURPOSE:          Windows
+ * FILE:             subsys/win32k/ntuser/window.c
+ * PROGRAMER:        Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * REVISION HISTORY:
+ *       06-06-2001  CSH  Created
+ */
+/* INCLUDES ******************************************************************/
+
+#include <ddk/ntddk.h>
+#include <win32k/win32k.h>
+#include <include/object.h>
+#include <include/guicheck.h>
+#include <include/window.h>
+#include <include/class.h>
+#include <include/error.h>
+#include <include/winsta.h>
+#include <windows.h>
+
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS *******************************************************************/
+
+#define MINMAX_NOSWP  (0x00010000)
+
+/* FUNCTIONS *****************************************************************/
+
+UINT
+WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos)
+{
+}
+
+UINT
+WinPosGetMinMaxInfo(PWINDOW_OBJECT Window, POINT* MaxSize, POINT* MaxPos,
+                   POINT* MaxTrack)
+{
+}
+
+BOOLEAN
+WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
+                  INT cy, UINT flags)
+{
+  PWINDOW_OBJECT Window;
+  NTSTATUS Status;
+
+  /* FIXME: Get current active window from active queue. */
+
+  /* FIXME: Check if the window is for a desktop. */
+
+  Status = ObmReferenceObjectByHandle(PsGetWin32Process()->HandleTable,
+                                     Wnd,
+                                     otWindow,
+                                     (PVOID*)&Window);
+  if (!NT_SUCCESS(Status))
+    {
+      return(FALSE);
+    }
+  
+  /* Fix up the flags. */
+  if (Window->Style & WS_VISIBLE)
+    {
+      flags &= ~SWP_SHOWWINDOW;
+    }
+  else 
+    {
+      if (!(flags & SWP_SHOWWINDOW))
+       {
+         flags |= SWP_NOREDRAW;
+       }
+      flags &= ~SWP_HIDEWINDOW;
+    }
+
+  if (cx < 0)
+    {
+      cx = 0;
+    }
+  if (cy < 0)
+    {
+      cy = 0;
+    }
+
+  
+}
+
+LRESULT
+WinPosGetNonClientSize(HWND Wnd, RECT* WindowRect, RECT* ClientRect)
+{
+  LRESULT Result;
+
+  Result = 
+    W32kSendNCCALCSIZEMessage(Wnd, FALSE, WindowRect, NULL,
+                             NULL, NULL, ClientRect);
+  return(Result);
+}
+
+BOOLEAN
+WinPosShowWindow(HWND Wnd, INT Cmd)
+{
+  BOOLEAN WasVisible;
+  PWINDOW_OBJECT Window;
+  NTSTATUS Status;
+  UINT Swp = 0;
+  RECT NewPos;
+  BOOLEAN ShowFlag;
+
+  Status = ObmReferenceObjectByHandle(PsGetWin32Process()->HandleTable,
+                                     Wnd,
+                                     otWindow,
+                                     (PVOID*)&Window);
+  if (!NT_SUCCESS(Status))
+    {
+      return(FALSE);
+    }
+  
+  WasVisible = (Window->Style & WS_VISIBLE) != 0;
+
+  switch (Cmd)
+    {
+    case SW_HIDE:
+      {
+       if (!WasVisible)
+         {
+           ObmDereferenceObject(Window);
+           return(FALSE);
+         }
+       Swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE |
+         SWP_NOZORDER;
+       break;
+      }
+
+    case SW_SHOWMINNOACTIVE:
+      Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+      /* Fall through. */
+    case SW_SHOWMINIMIZED:
+      Swp |= SWP_SHOWWINDOW;
+      /* Fall through. */
+    case SW_MINIMIZE:
+      {
+       Swp |= SWP_FRAMECHANGED;
+       if (!(Window->Style & WS_MINIMIZE))
+         {
+           Swp |= WinPosMinMaximize(Window, SW_MINIMIZE, &NewPos);
+         }
+       else
+         {
+           Swp |= SWP_NOSIZE | SWP_NOMOVE;
+         }
+       break;
+      }
+
+    case SW_SHOWMAXIMIZED:
+      {
+       Swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
+       if (!(Window->Style & WS_MAXIMIZE))
+         {
+           Swp |= WinPosMinMaximize(Window, SW_MAXIMIZE, &NewPos);
+         }
+       else
+         {
+           Swp |= SWP_NOSIZE | SWP_NOMOVE;
+         }
+       break;
+      }
+
+    case SW_SHOWNA:
+      Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+      /* Fall through. */
+    case SW_SHOW:
+      Swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
+      /* Don't activate the topmost window. */
+      break;
+
+    case SW_SHOWNOACTIVATE:
+      Swp |= SWP_NOZORDER;
+      /* Fall through. */
+    case SW_SHOWNORMAL:
+    case SW_SHOWDEFAULT:
+    case SW_RESTORE:
+      Swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
+      if (Window->Style & (WS_MINIMIZE | WS_MAXIMIZE))
+       {
+         Swp |= WinPosMinMaximize(Window, SW_RESTORE, &NewPos);         
+       }
+      else
+       {
+         Swp |= SWP_NOSIZE | SWP_NOMOVE;
+       }
+      break;
+    }
+
+  ShowFlag = (Cmd != SW_HIDE);
+  if (ShowFlag != WasVisible)
+    {
+      NtUserSendMessage(Wnd, WM_SHOWWINDOW, ShowFlag, 0);
+      /* 
+       * FIXME: Need to check the window wasn't destroyed during the 
+       * window procedure. 
+       */
+    }
+
+  if (Window->Style & WS_CHILD &&
+      /* !IsWindowVisible(WindowObject->Parent->Self) && */
+      (Swp & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE))
+    {
+      if (Cmd == SW_HIDE)
+       {
+         Window->Style &= ~WS_VISIBLE;
+       }
+      else
+       {
+         Window->Style |= WS_VISIBLE;
+       }
+    }
+  else
+    {
+      if (Window->Style & WS_CHILD &&
+         !(Window->ExStyle & WS_EX_MDICHILD))
+       {
+         Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+       }
+      if (!(Swp & MINMAX_NOSWP))
+       {
+         WinPosSetWindowPos(Wnd, HWND_TOP, NewPos.left, NewPos.top,
+                            NewPos.right, NewPos.bottom, LOWORD(Swp));
+         if (Cmd == SW_HIDE)
+           {
+             /* Hide the window. */
+           }
+       }
+      /* FIXME: Check for window destruction. */
+      /* FIXME: Show title for minimized windows. */
+    }
+
+  if (Window->Flags & WINDOWOBJECT_NEED_SIZE)
+    {
+      WPARAM wParam = SIZE_RESTORED;
+
+      Window->Flags &= ~WINDOWOBJECT_NEED_SIZE;
+      if (Window->Style & WS_MAXIMIZE)
+       {
+         wParam = SIZE_MAXIMIZED;
+       }
+      else if (Window->Style & WS_MINIMIZE)
+       {
+         wParam = SIZE_MINIMIZED;
+       }
+
+      NtUserSendMessage(Wnd, WM_SIZE, wParam,
+                       MAKELONG(Window->ClientRect.right - 
+                                Window->ClientRect.left,
+                                Window->ClientRect.bottom -
+                                Window->ClientRect.top));
+      NtUserSendMessage(Wnd, WM_MOVE, 0,
+                       MAKELONG(Window->ClientRect.left,
+                                Window->ClientRect.top));
+    }
+  ObmDereferenceObject(Window);
+  return(WasVisible);
+}