2003-05-18 17:16:18 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2003-07-25 19:36:26 +00:00
|
|
|
/* $Id: window.c,v 1.67 2003/07/25 19:35:51 gdalsnes Exp $
|
2001-06-12 17:51:51 +00:00
|
|
|
*
|
|
|
|
* 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
|
|
|
|
*/
|
2002-01-27 01:11:24 +00:00
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
#include <ddk/ntddk.h>
|
2003-03-06 21:03:49 +00:00
|
|
|
#include <internal/safe.h>
|
2001-06-12 17:51:51 +00:00
|
|
|
#include <win32k/win32k.h>
|
2002-01-27 01:11:24 +00:00
|
|
|
#include <include/object.h>
|
2001-06-12 17:51:51 +00:00
|
|
|
#include <include/guicheck.h>
|
|
|
|
#include <include/window.h>
|
|
|
|
#include <include/class.h>
|
|
|
|
#include <include/error.h>
|
|
|
|
#include <include/winsta.h>
|
2002-05-06 22:20:32 +00:00
|
|
|
#include <include/winpos.h>
|
|
|
|
#include <include/callback.h>
|
|
|
|
#include <include/msgqueue.h>
|
2002-07-17 21:04:57 +00:00
|
|
|
#include <include/rect.h>
|
2003-05-18 17:16:18 +00:00
|
|
|
#include <include/dce.h>
|
|
|
|
#include <include/paint.h>
|
|
|
|
#include <include/painting.h>
|
|
|
|
#include <include/scroll.h>
|
2003-07-17 07:49:15 +00:00
|
|
|
#include <include/vis.h>
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2003-03-18 09:16:44 +00:00
|
|
|
#define NDEBUG
|
2003-03-14 22:48:32 +00:00
|
|
|
#include <win32k/debug1.h>
|
2001-06-12 17:51:51 +00:00
|
|
|
#include <debug.h>
|
|
|
|
|
2003-03-14 22:48:32 +00:00
|
|
|
#define TAG_WNAM TAG('W', 'N', 'A', 'M')
|
|
|
|
|
2003-05-02 07:52:33 +00:00
|
|
|
typedef struct _REGISTERED_MESSAGE
|
|
|
|
{
|
|
|
|
LIST_ENTRY ListEntry;
|
|
|
|
WCHAR MessageName[1];
|
|
|
|
} REGISTERED_MESSAGE, *PREGISTERED_MESSAGE;
|
|
|
|
|
|
|
|
static LIST_ENTRY RegisteredMessageListHead;
|
|
|
|
|
|
|
|
#define REGISTERED_MESSAGE_MIN 0xc000
|
|
|
|
#define REGISTERED_MESSAGE_MAX 0xffff
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2002-08-30 02:47:37 +00:00
|
|
|
HWND STDCALL
|
|
|
|
NtUserGetAncestor(HWND hWnd, UINT Flags)
|
|
|
|
{
|
|
|
|
if (W32kIsDesktopWindow(hWnd))
|
|
|
|
{
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
if (Flags & GA_PARENT)
|
|
|
|
{
|
|
|
|
PWINDOW_OBJECT Window;
|
|
|
|
HWND hParent;
|
|
|
|
|
|
|
|
Window = W32kGetWindowObject(hWnd);
|
|
|
|
if (Window == NULL)
|
|
|
|
{
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Window->Parent == NULL)
|
|
|
|
{
|
|
|
|
W32kReleaseWindowObject(Window);
|
|
|
|
}
|
|
|
|
|
|
|
|
hParent = Window->Parent->Self;
|
|
|
|
|
|
|
|
W32kReleaseWindowObject(Window);
|
|
|
|
|
|
|
|
return(hParent);
|
|
|
|
}
|
2003-06-03 15:43:57 +00:00
|
|
|
else if (Flags & GA_ROOT)
|
|
|
|
{
|
|
|
|
PWINDOW_OBJECT Window;
|
|
|
|
PWINDOW_OBJECT pChainEnumerator;
|
|
|
|
HWND hRoot;
|
|
|
|
|
|
|
|
Window = W32kGetWindowObject(hWnd);
|
|
|
|
if(Window == NULL)
|
|
|
|
{
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
pChainEnumerator = Window;
|
|
|
|
while(pChainEnumerator->Parent != NULL)
|
|
|
|
{
|
|
|
|
pChainEnumerator = pChainEnumerator->Parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
hRoot = pChainEnumerator->Self;
|
|
|
|
W32kReleaseWindowObject(Window);
|
|
|
|
|
|
|
|
return(hRoot);
|
|
|
|
}
|
2002-08-30 02:47:37 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED;
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-07-05 16:04:01 +00:00
|
|
|
HWND FASTCALL
|
2002-07-17 21:04:57 +00:00
|
|
|
W32kSetFocusWindow(HWND hWnd)
|
|
|
|
{
|
2003-07-05 16:04:01 +00:00
|
|
|
PUSER_MESSAGE_QUEUE OldMessageQueue;
|
|
|
|
PDESKTOP_OBJECT DesktopObject;
|
|
|
|
PWINDOW_OBJECT WindowObject;
|
|
|
|
HWND hWndOldFocus;
|
|
|
|
|
|
|
|
DPRINT("W32kSetFocusWindow(hWnd 0x%x)\n", hWnd);
|
|
|
|
|
|
|
|
if (hWnd != (HWND)0)
|
|
|
|
{
|
|
|
|
WindowObject = W32kGetWindowObject(hWnd);
|
|
|
|
if (!WindowObject)
|
|
|
|
{
|
|
|
|
DPRINT("Bad window handle 0x%x\n", hWnd);
|
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
|
|
|
return (HWND)0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
WindowObject = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
DesktopObject = W32kGetActiveDesktop();
|
|
|
|
if (!DesktopObject)
|
|
|
|
{
|
|
|
|
DPRINT("No active desktop\n");
|
|
|
|
if (WindowObject != NULL)
|
|
|
|
{
|
|
|
|
W32kReleaseWindowObject(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;
|
|
|
|
W32kReleaseWindowObject(WindowObject);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
(PUSER_MESSAGE_QUEUE)DesktopObject->ActiveMessageQueue = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT("hWndOldFocus = 0x%x\n", hWndOldFocus);
|
|
|
|
|
|
|
|
return hWndOldFocus;
|
2002-07-17 21:04:57 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
BOOL FASTCALL
|
2002-07-17 21:04:57 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
BOOL FASTCALL
|
2002-07-17 21:04:57 +00:00
|
|
|
W32kIsWindowVisible(HWND Wnd)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
BOOL FASTCALL
|
2002-07-17 21:04:57 +00:00
|
|
|
W32kIsDesktopWindow(HWND hWnd)
|
|
|
|
{
|
|
|
|
PWINDOW_OBJECT WindowObject;
|
|
|
|
BOOL IsDesktop;
|
|
|
|
WindowObject = W32kGetWindowObject(hWnd);
|
|
|
|
IsDesktop = WindowObject->Parent == NULL;
|
|
|
|
W32kReleaseWindowObject(WindowObject);
|
|
|
|
return(IsDesktop);
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
HWND FASTCALL W32kGetDesktopWindow(VOID)
|
2002-08-24 11:09:17 +00:00
|
|
|
{
|
|
|
|
return W32kGetActiveDesktop()->DesktopWindow;
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
HWND FASTCALL W32kGetParentWindow(HWND hWnd)
|
2002-08-24 11:09:17 +00:00
|
|
|
{
|
|
|
|
return W32kGetWindowObject(hWnd)->ParentHandle;
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
PWINDOW_OBJECT FASTCALL
|
2002-07-04 19:56:38 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
VOID FASTCALL
|
2002-07-04 19:56:38 +00:00
|
|
|
W32kReleaseWindowObject(PWINDOW_OBJECT Window)
|
|
|
|
{
|
|
|
|
ObmDereferenceObject(Window);
|
|
|
|
}
|
|
|
|
|
2003-03-14 22:48:32 +00:00
|
|
|
/*!
|
|
|
|
* Internal function.
|
|
|
|
* Returns client window rectangle relative to the upper-left corner of client area.
|
|
|
|
*
|
|
|
|
* \note Does not check the validity of the parameters
|
|
|
|
*/
|
2003-05-18 17:16:18 +00:00
|
|
|
VOID FASTCALL
|
2002-07-04 19:56:38 +00:00
|
|
|
W32kGetClientRect(PWINDOW_OBJECT WindowObject, PRECT Rect)
|
2002-05-06 22:20:32 +00:00
|
|
|
{
|
2003-03-14 22:48:32 +00:00
|
|
|
ASSERT( WindowObject );
|
|
|
|
ASSERT( Rect );
|
|
|
|
|
2002-09-01 20:39:56 +00:00
|
|
|
Rect->left = Rect->top = 0;
|
2002-07-17 21:04:57 +00:00
|
|
|
Rect->right = WindowObject->ClientRect.right - WindowObject->ClientRect.left;
|
2002-09-01 20:39:56 +00:00
|
|
|
Rect->bottom =
|
|
|
|
WindowObject->ClientRect.bottom - WindowObject->ClientRect.top;
|
2002-05-06 22:20:32 +00:00
|
|
|
}
|
|
|
|
|
2003-03-14 22:48:32 +00:00
|
|
|
/*!
|
|
|
|
* Internal Function.
|
|
|
|
* Return the dimension of the window in the screen coordinates.
|
|
|
|
*/
|
2002-08-31 23:18:47 +00:00
|
|
|
BOOL STDCALL
|
|
|
|
W32kGetWindowRect(HWND hWnd, LPRECT Rect)
|
|
|
|
{
|
|
|
|
PWINDOW_OBJECT WindowObject;
|
|
|
|
|
2003-07-17 07:49:15 +00:00
|
|
|
ASSERT(NULL != Rect);
|
2003-03-14 22:48:32 +00:00
|
|
|
|
2002-08-31 23:18:47 +00:00
|
|
|
WindowObject = W32kGetWindowObject(hWnd);
|
|
|
|
if (WindowObject == NULL)
|
|
|
|
{
|
2003-07-17 07:49:15 +00:00
|
|
|
return FALSE;
|
2002-08-31 23:18:47 +00:00
|
|
|
}
|
|
|
|
*Rect = WindowObject->WindowRect;
|
|
|
|
W32kReleaseWindowObject(WindowObject);
|
2003-07-17 07:49:15 +00:00
|
|
|
|
|
|
|
return TRUE;
|
2002-08-31 23:18:47 +00:00
|
|
|
}
|
|
|
|
|
2003-03-14 22:48:32 +00:00
|
|
|
/*!
|
|
|
|
* 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.
|
|
|
|
*/
|
2002-08-31 23:18:47 +00:00
|
|
|
BOOL STDCALL
|
|
|
|
NtUserGetWindowRect(HWND hWnd, LPRECT Rect)
|
|
|
|
{
|
2003-03-14 22:48:32 +00:00
|
|
|
RECT SafeRect;
|
|
|
|
BOOL bRet;
|
|
|
|
|
|
|
|
bRet = W32kGetWindowRect(hWnd, &SafeRect);
|
2003-07-17 07:49:15 +00:00
|
|
|
if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT))))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return bRet;
|
2002-08-31 23:18:47 +00:00
|
|
|
}
|
|
|
|
|
2003-03-14 22:48:32 +00:00
|
|
|
/*!
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
*/
|
2003-03-06 21:03:49 +00:00
|
|
|
BOOL STDCALL
|
|
|
|
NtUserGetClientRect(HWND hWnd, LPRECT Rect)
|
|
|
|
{
|
|
|
|
PWINDOW_OBJECT WindowObject;
|
|
|
|
RECT SafeRect;
|
|
|
|
|
|
|
|
WindowObject = W32kGetWindowObject(hWnd);
|
|
|
|
if (WindowObject == NULL)
|
|
|
|
{
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
W32kGetClientRect(WindowObject, &SafeRect);
|
|
|
|
if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT))))
|
|
|
|
{
|
2003-07-05 16:04:01 +00:00
|
|
|
W32kReleaseWindowObject(WindowObject);
|
2003-03-06 21:03:49 +00:00
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
W32kReleaseWindowObject(WindowObject);
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
HWND FASTCALL
|
2002-05-06 22:20:32 +00:00
|
|
|
W32kGetActiveWindow(VOID)
|
|
|
|
{
|
2002-07-17 21:04:57 +00:00
|
|
|
PUSER_MESSAGE_QUEUE Queue;
|
|
|
|
Queue = (PUSER_MESSAGE_QUEUE)W32kGetActiveDesktop()->ActiveMessageQueue;
|
|
|
|
if (Queue == NULL)
|
|
|
|
{
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return(Queue->ActiveWindow);
|
|
|
|
}
|
2002-05-06 22:20:32 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
HWND FASTCALL
|
2002-07-17 21:04:57 +00:00
|
|
|
W32kGetFocusWindow(VOID)
|
|
|
|
{
|
|
|
|
PUSER_MESSAGE_QUEUE Queue;
|
2003-03-14 22:48:32 +00:00
|
|
|
PDESKTOP_OBJECT pdo = W32kGetActiveDesktop();
|
|
|
|
|
|
|
|
if( !pdo )
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
Queue = (PUSER_MESSAGE_QUEUE)pdo->ActiveMessageQueue;
|
|
|
|
|
2002-07-17 21:04:57 +00:00
|
|
|
if (Queue == NULL)
|
|
|
|
return(NULL);
|
|
|
|
else
|
|
|
|
return(Queue->FocusWindow);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
WNDPROC FASTCALL
|
2002-05-06 22:20:32 +00:00
|
|
|
W32kGetWindowProc(HWND Wnd)
|
|
|
|
{
|
2002-07-17 21:04:57 +00:00
|
|
|
PWINDOW_OBJECT WindowObject;
|
|
|
|
WNDPROC WndProc;
|
|
|
|
|
|
|
|
WindowObject = W32kGetWindowObject(Wnd);
|
2003-03-14 22:48:32 +00:00
|
|
|
if( !WindowObject )
|
|
|
|
return NULL;
|
|
|
|
|
2003-05-17 09:20:23 +00:00
|
|
|
WndProc = WindowObject->WndProc;
|
2003-07-05 16:04:01 +00:00
|
|
|
W32kReleaseWindowObject(WindowObject);
|
2002-07-17 21:04:57 +00:00
|
|
|
return(WndProc);
|
2002-05-06 22:20:32 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
NTSTATUS FASTCALL
|
2001-06-12 17:51:51 +00:00
|
|
|
InitWindowImpl(VOID)
|
|
|
|
{
|
2003-05-02 07:52:33 +00:00
|
|
|
InitializeListHead(&RegisteredMessageListHead);
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
return(STATUS_SUCCESS);
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
NTSTATUS FASTCALL
|
2001-06-12 17:51:51 +00:00
|
|
|
CleanupWindowImpl(VOID)
|
|
|
|
{
|
2002-01-27 01:11:24 +00:00
|
|
|
return(STATUS_SUCCESS);
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserAlterWindowStyle(DWORD Unknown0,
|
|
|
|
DWORD Unknown1,
|
|
|
|
DWORD Unknown2)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
return(0);
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
2002-05-06 22:20:32 +00:00
|
|
|
NtUserChildWindowFromPointEx(HWND Parent,
|
|
|
|
LONG x,
|
|
|
|
LONG y,
|
|
|
|
UINT Flags)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
return(0);
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2002-07-17 21:04:57 +00:00
|
|
|
HWND STDCALL
|
|
|
|
W32kCreateDesktopWindow(PWINSTATION_OBJECT WindowStation,
|
|
|
|
PWNDCLASS_OBJECT DesktopClass,
|
|
|
|
ULONG Width, ULONG Height)
|
|
|
|
{
|
|
|
|
PWSTR WindowName;
|
|
|
|
HWND Handle;
|
|
|
|
PWINDOW_OBJECT WindowObject;
|
|
|
|
|
|
|
|
/* Create the window object. */
|
|
|
|
WindowObject = (PWINDOW_OBJECT)ObmCreateObject(WindowStation->HandleTable,
|
|
|
|
&Handle,
|
2003-01-24 22:42:15 +00:00
|
|
|
otWindow,
|
2002-07-17 21:04:57 +00:00
|
|
|
sizeof(WINDOW_OBJECT));
|
|
|
|
if (!WindowObject)
|
|
|
|
{
|
|
|
|
return((HWND)0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Fill out the structure describing it.
|
|
|
|
*/
|
|
|
|
WindowObject->Class = DesktopClass;
|
|
|
|
WindowObject->ExStyle = 0;
|
|
|
|
WindowObject->Style = WS_VISIBLE;
|
|
|
|
WindowObject->x = 0;
|
|
|
|
WindowObject->y = 0;
|
|
|
|
WindowObject->Width = Width;
|
|
|
|
WindowObject->Height = Height;
|
|
|
|
WindowObject->ParentHandle = NULL;
|
|
|
|
WindowObject->Parent = NULL;
|
|
|
|
WindowObject->Menu = NULL;
|
|
|
|
WindowObject->Instance = NULL;
|
|
|
|
WindowObject->Parameters = NULL;
|
|
|
|
WindowObject->Self = Handle;
|
|
|
|
WindowObject->MessageQueue = NULL;
|
|
|
|
WindowObject->ExtraData = NULL;
|
|
|
|
WindowObject->ExtraDataSize = 0;
|
|
|
|
WindowObject->WindowRect.left = 0;
|
|
|
|
WindowObject->WindowRect.top = 0;
|
|
|
|
WindowObject->WindowRect.right = Width;
|
|
|
|
WindowObject->WindowRect.bottom = Height;
|
|
|
|
WindowObject->ClientRect = WindowObject->WindowRect;
|
2003-05-17 09:20:23 +00:00
|
|
|
WindowObject->UserData = 0;
|
|
|
|
WindowObject->WndProc = DesktopClass->Class.lpfnWndProc;
|
2003-07-25 19:36:26 +00:00
|
|
|
WindowObject->OwnerThread = PsGetCurrentThread();
|
2003-07-10 00:24:04 +00:00
|
|
|
|
2002-08-26 23:20:54 +00:00
|
|
|
InitializeListHead(&WindowObject->ChildrenListHead);
|
2003-07-10 00:24:04 +00:00
|
|
|
ExInitializeFastMutex(&WindowObject->ChildrenListLock);
|
2002-07-17 21:04:57 +00:00
|
|
|
|
|
|
|
WindowName = ExAllocatePool(NonPagedPool, sizeof(L"DESKTOP"));
|
|
|
|
wcscpy(WindowName, L"DESKTOP");
|
|
|
|
RtlInitUnicodeString(&WindowObject->WindowName, WindowName);
|
|
|
|
|
|
|
|
return(Handle);
|
|
|
|
}
|
|
|
|
|
2003-07-17 07:49:15 +00:00
|
|
|
VOID FASTCALL
|
|
|
|
W32kInitDesktopWindow(ULONG Width, ULONG Height)
|
|
|
|
{
|
|
|
|
PWINDOW_OBJECT DesktopWindow;
|
|
|
|
HRGN DesktopRgn;
|
|
|
|
|
|
|
|
DesktopWindow = W32kGetWindowObject(PsGetWin32Thread()->Desktop->DesktopWindow);
|
|
|
|
if (NULL == DesktopWindow)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
DesktopWindow->WindowRect.right = Width;
|
|
|
|
DesktopWindow->WindowRect.bottom = Height;
|
|
|
|
DesktopWindow->ClientRect = DesktopWindow->WindowRect;
|
|
|
|
|
|
|
|
DesktopRgn = UnsafeW32kCreateRectRgnIndirect(&(DesktopWindow->WindowRect));
|
|
|
|
VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, DesktopWindow, DesktopRgn);
|
|
|
|
W32kDeleteObject(DesktopRgn);
|
|
|
|
W32kReleaseWindowObject(DesktopWindow);
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
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,
|
2002-05-06 22:20:32 +00:00
|
|
|
DWORD dwShowMode)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
PWINSTATION_OBJECT WinStaObject;
|
|
|
|
PWNDCLASS_OBJECT ClassObject;
|
|
|
|
PWINDOW_OBJECT WindowObject;
|
2002-07-17 21:04:57 +00:00
|
|
|
PWINDOW_OBJECT ParentWindow;
|
2001-06-12 17:51:51 +00:00
|
|
|
UNICODE_STRING WindowName;
|
|
|
|
NTSTATUS Status;
|
|
|
|
HANDLE Handle;
|
2002-05-06 22:20:32 +00:00
|
|
|
POINT MaxSize, MaxPos, MinTrack, MaxTrack;
|
2002-07-17 21:04:57 +00:00
|
|
|
CREATESTRUCTW Cs;
|
2002-05-06 22:20:32 +00:00
|
|
|
LRESULT Result;
|
2002-06-18 21:51:11 +00:00
|
|
|
DPRINT("NtUserCreateWindowEx\n");
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2002-06-18 21:51:11 +00:00
|
|
|
/* Initialize gui state if necessary. */
|
2003-03-06 23:57:03 +00:00
|
|
|
W32kGraphicsCheck(TRUE);
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2003-06-16 13:43:16 +00:00
|
|
|
if (!RtlCreateUnicodeString(&WindowName,
|
|
|
|
NULL == lpWindowName->Buffer ?
|
|
|
|
L"" : lpWindowName->Buffer))
|
2002-01-27 01:11:24 +00:00
|
|
|
{
|
|
|
|
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
|
2002-05-06 22:20:32 +00:00
|
|
|
return((HWND)0);
|
2002-01-27 01:11:24 +00:00
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2002-07-17 21:04:57 +00:00
|
|
|
if (hWndParent != NULL)
|
|
|
|
{
|
|
|
|
ParentWindow = W32kGetWindowObject(hWndParent);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hWndParent = PsGetWin32Thread()->Desktop->DesktopWindow;
|
|
|
|
ParentWindow = W32kGetWindowObject(hWndParent);
|
|
|
|
}
|
2002-05-06 22:20:32 +00:00
|
|
|
|
|
|
|
/* Check the class. */
|
|
|
|
Status = ClassReferenceClassByNameOrAtom(&ClassObject, lpClassName->Buffer);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
RtlFreeUnicodeString(&WindowName);
|
2003-07-05 16:04:01 +00:00
|
|
|
W32kReleaseWindowObject(ParentWindow);
|
2002-05-06 22:20:32 +00:00
|
|
|
return((HWND)0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check the window station. */
|
2002-07-04 19:56:38 +00:00
|
|
|
DPRINT("IoGetCurrentProcess() %X\n", IoGetCurrentProcess());
|
|
|
|
DPRINT("PROCESS_WINDOW_STATION %X\n", PROCESS_WINDOW_STATION());
|
2002-01-27 01:11:24 +00:00
|
|
|
Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
|
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&WinStaObject);
|
2001-06-12 17:51:51 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2002-01-27 01:11:24 +00:00
|
|
|
{
|
|
|
|
RtlFreeUnicodeString(&WindowName);
|
|
|
|
ObmDereferenceObject(ClassObject);
|
2003-07-05 16:04:01 +00:00
|
|
|
W32kReleaseWindowObject(ParentWindow);
|
2002-01-27 01:11:24 +00:00
|
|
|
DPRINT("Validation of window station handle (0x%X) failed\n",
|
|
|
|
PROCESS_WINDOW_STATION());
|
|
|
|
return (HWND)0;
|
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2002-05-06 22:20:32 +00:00
|
|
|
/* Create the window object. */
|
2003-01-24 22:42:15 +00:00
|
|
|
WindowObject = (PWINDOW_OBJECT)
|
|
|
|
ObmCreateObject(PsGetWin32Process()->WindowStation->HandleTable, &Handle,
|
2002-07-04 19:56:38 +00:00
|
|
|
otWindow, sizeof(WINDOW_OBJECT));
|
2002-06-18 21:51:11 +00:00
|
|
|
DPRINT("Created object with handle %X\n", Handle);
|
2003-01-24 22:42:15 +00:00
|
|
|
if (!WindowObject)
|
2002-01-27 01:11:24 +00:00
|
|
|
{
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
ObmDereferenceObject(ClassObject);
|
|
|
|
RtlFreeUnicodeString(&WindowName);
|
2003-07-05 16:04:01 +00:00
|
|
|
W32kReleaseWindowObject(ParentWindow);
|
2002-01-27 01:11:24 +00:00
|
|
|
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
|
|
|
|
return (HWND)0;
|
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
ObDereferenceObject(WinStaObject);
|
2002-05-06 22:20:32 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Fill out the structure describing it.
|
|
|
|
*/
|
2001-06-12 17:51:51 +00:00
|
|
|
WindowObject->Class = ClassObject;
|
|
|
|
WindowObject->ExStyle = dwExStyle;
|
2003-03-12 08:26:54 +00:00
|
|
|
WindowObject->Style = dwStyle | WIN_NCACTIVATED;
|
2001-06-12 17:51:51 +00:00
|
|
|
WindowObject->x = x;
|
|
|
|
WindowObject->y = y;
|
|
|
|
WindowObject->Width = nWidth;
|
|
|
|
WindowObject->Height = nHeight;
|
2002-07-17 21:04:57 +00:00
|
|
|
WindowObject->ParentHandle = hWndParent;
|
2001-06-12 17:51:51 +00:00
|
|
|
WindowObject->Menu = hMenu;
|
|
|
|
WindowObject->Instance = hInstance;
|
|
|
|
WindowObject->Parameters = lpParam;
|
2002-05-06 22:20:32 +00:00
|
|
|
WindowObject->Self = Handle;
|
2002-07-04 19:56:38 +00:00
|
|
|
WindowObject->MessageQueue = PsGetWin32Thread()->MessageQueue;
|
2002-07-17 21:04:57 +00:00
|
|
|
WindowObject->Parent = ParentWindow;
|
2003-05-17 09:20:23 +00:00
|
|
|
WindowObject->UserData = 0;
|
|
|
|
WindowObject->WndProc = ClassObject->Class.lpfnWndProc;
|
2003-07-25 19:36:26 +00:00
|
|
|
WindowObject->OwnerThread = PsGetCurrentThread();
|
2003-07-10 00:24:04 +00:00
|
|
|
|
|
|
|
ExAcquireFastMutexUnsafe(&ParentWindow->ChildrenListLock);
|
2003-01-24 22:42:15 +00:00
|
|
|
InsertHeadList(&ParentWindow->ChildrenListHead,
|
2002-08-26 23:20:54 +00:00
|
|
|
&WindowObject->SiblingListEntry);
|
2003-07-10 00:24:04 +00:00
|
|
|
ExReleaseFastMutexUnsafe(&ParentWindow->ChildrenListLock);
|
|
|
|
|
2002-08-26 23:20:54 +00:00
|
|
|
InitializeListHead(&WindowObject->ChildrenListHead);
|
2002-09-03 22:44:21 +00:00
|
|
|
InitializeListHead(&WindowObject->PropListHead);
|
2003-03-20 10:09:24 +00:00
|
|
|
ExInitializeFastMutex(&WindowObject->ChildrenListLock);
|
2001-06-12 17:51:51 +00:00
|
|
|
|
|
|
|
RtlInitUnicodeString(&WindowObject->WindowName, WindowName.Buffer);
|
2002-05-06 22:20:32 +00:00
|
|
|
RtlFreeUnicodeString(&WindowName);
|
2003-01-24 22:42:15 +00:00
|
|
|
|
2002-05-06 22:20:32 +00:00
|
|
|
if (ClassObject->Class.cbWndExtra != 0)
|
|
|
|
{
|
2003-01-24 22:42:15 +00:00
|
|
|
WindowObject->ExtraData =
|
|
|
|
ExAllocatePool(PagedPool,
|
2003-05-17 09:20:23 +00:00
|
|
|
ClassObject->Class.cbWndExtra);
|
2002-05-06 22:20:32 +00:00
|
|
|
WindowObject->ExtraDataSize = ClassObject->Class.cbWndExtra;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
WindowObject->ExtraData = NULL;
|
|
|
|
WindowObject->ExtraDataSize = 0;
|
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2002-05-06 22:20:32 +00:00
|
|
|
/* 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. */
|
2002-07-04 19:56:38 +00:00
|
|
|
ExAcquireFastMutexUnsafe (&PsGetWin32Thread()->WindowListLock);
|
|
|
|
InsertTailList (&PsGetWin32Thread()->WindowListHead,
|
2002-08-26 23:20:54 +00:00
|
|
|
&WindowObject->ThreadListEntry);
|
2002-07-04 19:56:38 +00:00
|
|
|
ExReleaseFastMutexUnsafe (&PsGetWin32Thread()->WindowListLock);
|
|
|
|
|
2003-01-24 22:42:15 +00:00
|
|
|
/*
|
2002-07-17 21:04:57 +00:00
|
|
|
* Insert the window into the list of windows associated with the thread's
|
|
|
|
* desktop.
|
|
|
|
*/
|
|
|
|
InsertTailList(&PsGetWin32Thread()->Desktop->WindowListHead,
|
|
|
|
&WindowObject->DesktopListEntry);
|
2003-03-16 23:01:08 +00:00
|
|
|
/* Allocate a DCE for this window. */
|
|
|
|
if (dwStyle & CS_OWNDC) WindowObject->Dce = DceAllocDCE(WindowObject->Self,DCE_WINDOW_DC);
|
|
|
|
/* FIXME: Handle "CS_CLASSDC" */
|
2002-05-06 22:20:32 +00:00
|
|
|
|
|
|
|
/* 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. */
|
2003-03-22 04:53:01 +00:00
|
|
|
|
2002-12-21 19:25:41 +00:00
|
|
|
/* Initialize the window's scrollbars */
|
|
|
|
if (dwStyle & WS_VSCROLL)
|
|
|
|
SCROLL_CreateScrollBar(WindowObject, SB_VERT);
|
|
|
|
if (dwStyle & WS_HSCROLL)
|
|
|
|
SCROLL_CreateScrollBar(WindowObject, SB_HORZ);
|
|
|
|
|
2002-05-06 22:20:32 +00:00
|
|
|
/* 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;
|
2002-06-18 21:51:11 +00:00
|
|
|
DPRINT("NtUserCreateWindowEx(): About to send NCCREATE message.\n");
|
2002-05-06 22:20:32 +00:00
|
|
|
Result = W32kSendNCCREATEMessage(WindowObject->Self, &Cs);
|
|
|
|
if (!Result)
|
|
|
|
{
|
|
|
|
/* FIXME: Cleanup. */
|
2003-07-05 16:04:01 +00:00
|
|
|
W32kReleaseWindowObject(ParentWindow);
|
2002-06-18 21:51:11 +00:00
|
|
|
DPRINT("NtUserCreateWindowEx(): NCCREATE message failed.\n");
|
2003-07-05 16:04:01 +00:00
|
|
|
return((HWND)0);
|
2002-05-06 22:20:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculate the non-client size. */
|
|
|
|
MaxPos.x = WindowObject->WindowRect.left;
|
|
|
|
MaxPos.y = WindowObject->WindowRect.top;
|
2002-06-18 21:51:11 +00:00
|
|
|
DPRINT("NtUserCreateWindowEx(): About to get non-client size.\n");
|
2002-05-06 22:20:32 +00:00
|
|
|
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. */
|
2002-06-18 21:51:11 +00:00
|
|
|
DPRINT("NtUserCreateWindowEx(): about to send CREATE message.\n");
|
2002-05-06 22:20:32 +00:00
|
|
|
Result = W32kSendCREATEMessage(WindowObject->Self, &Cs);
|
2002-06-18 21:51:11 +00:00
|
|
|
if (Result == (LRESULT)-1)
|
2002-05-06 22:20:32 +00:00
|
|
|
{
|
|
|
|
/* FIXME: Cleanup. */
|
2003-07-05 16:04:01 +00:00
|
|
|
W32kReleaseWindowObject(ParentWindow);
|
2002-06-18 21:51:11 +00:00
|
|
|
DPRINT("NtUserCreateWindowEx(): send CREATE message failed.\n");
|
2003-07-05 16:04:01 +00:00
|
|
|
return((HWND)0);
|
2002-05-06 22:20:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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);
|
2003-03-22 04:53:01 +00:00
|
|
|
|
2002-06-18 21:51:11 +00:00
|
|
|
DPRINT("NtUserCreateWindow(): About to send WM_SIZE\n");
|
2002-05-06 22:20:32 +00:00
|
|
|
W32kCallWindowProc(NULL, WindowObject->Self, WM_SIZE, SIZE_RESTORED,
|
|
|
|
lParam);
|
|
|
|
lParam =
|
|
|
|
MAKE_LONG(WindowObject->ClientRect.left,
|
|
|
|
WindowObject->ClientRect.top);
|
2002-07-04 19:56:38 +00:00
|
|
|
DPRINT("NtUserCreateWindow(): About to send WM_MOVE\n");
|
2002-05-06 22:20:32 +00:00
|
|
|
W32kCallWindowProc(NULL, WindowObject->Self, WM_MOVE, 0, lParam);
|
|
|
|
}
|
|
|
|
|
2003-05-31 08:51:58 +00:00
|
|
|
/* Move from parent-client to screen coordinates */
|
|
|
|
if (0 != (WindowObject->Style & WS_CHILD))
|
|
|
|
{
|
|
|
|
W32kOffsetRect(&WindowObject->WindowRect,
|
|
|
|
ParentWindow->ClientRect.left,
|
|
|
|
ParentWindow->ClientRect.top);
|
|
|
|
W32kOffsetRect(&WindowObject->ClientRect,
|
|
|
|
ParentWindow->ClientRect.left,
|
|
|
|
ParentWindow->ClientRect.top);
|
|
|
|
}
|
|
|
|
|
2002-05-06 22:20:32 +00:00
|
|
|
/* Show or maybe minimize or maximize the window. */
|
|
|
|
if (WindowObject->Style & (WS_MINIMIZE | WS_MAXIMIZE))
|
|
|
|
{
|
|
|
|
RECT NewPos;
|
2002-09-08 10:23:54 +00:00
|
|
|
UINT16 SwFlag;
|
2002-05-06 22:20:32 +00:00
|
|
|
|
|
|
|
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;
|
2002-06-18 21:51:11 +00:00
|
|
|
DPRINT("NtUserCreateWindow(): About to minimize/maximize\n");
|
2002-05-06 22:20:32 +00:00
|
|
|
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)))
|
|
|
|
{
|
2002-06-18 21:51:11 +00:00
|
|
|
DPRINT("NtUserCreateWindow(): About to notify parent\n");
|
2002-05-06 22:20:32 +00:00
|
|
|
W32kCallWindowProc(NULL, WindowObject->Parent->Self,
|
|
|
|
WM_PARENTNOTIFY,
|
|
|
|
MAKEWPARAM(WM_CREATE, WindowObject->IDMenu),
|
|
|
|
(LPARAM)WindowObject->Self);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dwStyle & WS_VISIBLE)
|
|
|
|
{
|
2002-06-18 21:51:11 +00:00
|
|
|
DPRINT("NtUserCreateWindow(): About to show window\n");
|
2002-05-06 22:20:32 +00:00
|
|
|
WinPosShowWindow(WindowObject->Self, dwShowMode);
|
|
|
|
}
|
|
|
|
|
2002-06-18 21:51:11 +00:00
|
|
|
DPRINT("NtUserCreateWindow(): = %X\n", Handle);
|
2002-05-06 22:20:32 +00:00
|
|
|
return((HWND)Handle);
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
2002-05-06 22:20:32 +00:00
|
|
|
NtUserDeferWindowPos(HDWP WinPosInfo,
|
|
|
|
HWND Wnd,
|
|
|
|
HWND WndInsertAfter,
|
|
|
|
LONG x,
|
|
|
|
LONG y,
|
|
|
|
LONG cx,
|
|
|
|
LONG cy,
|
|
|
|
UINT Flags)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-06-14 10:00:58 +00:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* W32kSendDestroyMsg
|
|
|
|
*/
|
|
|
|
static void W32kSendDestroyMsg(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
|
|
|
|
}
|
|
|
|
|
2003-06-25 22:37:07 +00:00
|
|
|
static BOOLEAN W32kWndBelongsToThread(PWINDOW_OBJECT Window, PW32THREAD ThreadData)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-06-14 10:00:58 +00:00
|
|
|
PLIST_ENTRY Current;
|
|
|
|
PWINDOW_OBJECT ThreadWindow;
|
2003-06-25 22:37:07 +00:00
|
|
|
BOOLEAN Belongs = FALSE;
|
2003-06-14 10:00:58 +00:00
|
|
|
|
|
|
|
ExAcquireFastMutexUnsafe(&ThreadData->WindowListLock);
|
|
|
|
/* If there's no win32k thread data then this thread hasn't created any windows */
|
|
|
|
if (NULL != ThreadData)
|
|
|
|
{
|
|
|
|
Current = ThreadData->WindowListHead.Flink;
|
|
|
|
while (! Belongs && Current != &ThreadData->WindowListHead)
|
|
|
|
{
|
|
|
|
ThreadWindow = CONTAINING_RECORD(Current, WINDOW_OBJECT, ThreadListEntry);
|
|
|
|
Belongs = (Window == ThreadWindow);
|
|
|
|
Current = Current->Flink;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ExReleaseFastMutexUnsafe(&ThreadData->WindowListLock);
|
|
|
|
|
|
|
|
return Belongs;
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL BuildChildWindowArray(PWINDOW_OBJECT Window, HWND **Children, unsigned *NumChildren)
|
|
|
|
{
|
|
|
|
PLIST_ENTRY Current;
|
|
|
|
unsigned Index;
|
|
|
|
PWINDOW_OBJECT Child;
|
|
|
|
|
|
|
|
*Children = NULL;
|
|
|
|
*NumChildren = 0;
|
|
|
|
ExAcquireFastMutexUnsafe(&Window->ChildrenListLock);
|
|
|
|
Current = Window->ChildrenListHead.Flink;
|
|
|
|
while (Current != &Window->ChildrenListHead)
|
|
|
|
{
|
|
|
|
(*NumChildren)++;
|
|
|
|
Current = Current->Flink;
|
|
|
|
}
|
|
|
|
if (0 != *NumChildren)
|
|
|
|
{
|
|
|
|
*Children = ExAllocatePoolWithTag(PagedPool, *NumChildren * sizeof(HWND), TAG_WNAM);
|
|
|
|
if (NULL != *Children)
|
|
|
|
{
|
|
|
|
Current = Window->ChildrenListHead.Flink;
|
|
|
|
Index = 0;
|
|
|
|
while (Current != &Window->ChildrenListHead)
|
|
|
|
{
|
|
|
|
Child = CONTAINING_RECORD(Current, WINDOW_OBJECT, SiblingListEntry);
|
|
|
|
(*Children)[Index] = Child->Self;
|
|
|
|
Current = Current->Flink;
|
|
|
|
Index++;
|
|
|
|
}
|
|
|
|
assert(Index == *NumChildren);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPRINT1("Failed to allocate memory for children array\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
|
|
|
|
|
|
|
|
return 0 == *NumChildren || NULL != *Children;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* W32kDestroyWindow
|
|
|
|
*
|
|
|
|
* Destroy storage associated to a window. "Internals" p.358
|
|
|
|
*/
|
2003-06-25 22:37:07 +00:00
|
|
|
static LRESULT W32kDestroyWindow(PWINDOW_OBJECT Window,
|
|
|
|
PW32PROCESS ProcessData,
|
|
|
|
PW32THREAD ThreadData,
|
|
|
|
BOOLEAN SendMessages)
|
2003-06-14 10:00:58 +00:00
|
|
|
{
|
|
|
|
HWND *Children;
|
|
|
|
unsigned NumChildren;
|
|
|
|
unsigned Index;
|
|
|
|
PWINDOW_OBJECT Child;
|
|
|
|
|
2003-06-25 22:37:07 +00:00
|
|
|
if (! W32kWndBelongsToThread(Window, ThreadData))
|
2003-06-14 10:00:58 +00:00
|
|
|
{
|
|
|
|
DPRINT1("Window doesn't belong to current thread\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* free child windows */
|
|
|
|
if (! BuildChildWindowArray(Window, &Children, &NumChildren))
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
for (Index = NumChildren; 0 < Index; Index--)
|
|
|
|
{
|
|
|
|
Child = W32kGetWindowObject(Children[Index - 1]);
|
|
|
|
if (NULL != Child)
|
|
|
|
{
|
2003-06-25 22:37:07 +00:00
|
|
|
if (W32kWndBelongsToThread(Child, ThreadData))
|
2003-06-14 10:00:58 +00:00
|
|
|
{
|
2003-06-25 22:37:07 +00:00
|
|
|
W32kDestroyWindow(Child, ProcessData, ThreadData, SendMessages);
|
2003-06-14 10:00:58 +00:00
|
|
|
}
|
|
|
|
#if 0 /* FIXME */
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SendMessageW( list[i], WM_WINE_DESTROYWINDOW, 0, 0 );
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (0 != NumChildren)
|
|
|
|
{
|
|
|
|
ExFreePool(Children);
|
|
|
|
}
|
|
|
|
|
2003-06-25 22:37:07 +00:00
|
|
|
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->Self, 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);
|
|
|
|
}
|
2003-06-14 10:00:58 +00:00
|
|
|
|
|
|
|
/* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
|
|
|
|
|
|
|
|
#if 0 /* FIXME */
|
|
|
|
WinPosCheckInternalPos(Window->Self);
|
|
|
|
if (Window->Self == GetCapture())
|
|
|
|
{
|
|
|
|
ReleaseCapture();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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
|
2003-07-10 00:24:04 +00:00
|
|
|
|
|
|
|
ExAcquireFastMutexUnsafe(&Window->Parent->ChildrenListLock);
|
2003-06-14 10:00:58 +00:00
|
|
|
RemoveEntryList(&Window->SiblingListEntry);
|
2003-07-10 00:24:04 +00:00
|
|
|
ExReleaseFastMutexUnsafe(&Window->Parent->ChildrenListLock);
|
|
|
|
|
2003-06-14 10:00:58 +00:00
|
|
|
RemoveEntryList(&Window->DesktopListEntry);
|
2003-07-10 00:24:04 +00:00
|
|
|
|
|
|
|
ExAcquireFastMutexUnsafe (&ThreadData->WindowListLock);
|
2003-06-14 10:00:58 +00:00
|
|
|
RemoveEntryList(&Window->ThreadListEntry);
|
2003-07-10 00:24:04 +00:00
|
|
|
ExReleaseFastMutexUnsafe (&ThreadData->WindowListLock);
|
|
|
|
|
2003-06-14 10:00:58 +00:00
|
|
|
Window->Class = NULL;
|
2003-06-25 22:37:07 +00:00
|
|
|
ObmCloseHandle(ProcessData->WindowStation->HandleTable, Window->Self);
|
2003-06-14 10:00:58 +00:00
|
|
|
|
2003-03-06 23:57:03 +00:00
|
|
|
W32kGraphicsCheck(FALSE);
|
2001-06-12 17:51:51 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-06-14 10:00:58 +00:00
|
|
|
BOOLEAN STDCALL
|
|
|
|
NtUserDestroyWindow(HWND Wnd)
|
|
|
|
{
|
|
|
|
PWINDOW_OBJECT Window;
|
2003-07-05 16:04:01 +00:00
|
|
|
BOOLEAN isChild;
|
|
|
|
HWND hWndFocus;
|
2003-06-14 10:00:58 +00:00
|
|
|
|
|
|
|
Window = W32kGetWindowObject(Wnd);
|
|
|
|
if (Window == NULL)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for desktop window (has NULL parent) */
|
|
|
|
if (NULL == Window->Parent)
|
|
|
|
{
|
2003-07-05 16:04:01 +00:00
|
|
|
W32kReleaseWindowObject(Window);
|
2003-06-14 10:00:58 +00:00
|
|
|
SetLastWin32Error(ERROR_ACCESS_DENIED);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Look whether the focus is within the tree of windows we will
|
|
|
|
* be destroying.
|
|
|
|
*/
|
2003-07-05 16:04:01 +00:00
|
|
|
hWndFocus = W32kGetFocusWindow();
|
|
|
|
if (hWndFocus == Wnd || W32kIsChildWindow(Wnd, hWndFocus))
|
2003-06-14 10:00:58 +00:00
|
|
|
{
|
2003-07-05 16:04:01 +00:00
|
|
|
HWND Parent = NtUserGetAncestor(Wnd, GA_PARENT);
|
|
|
|
if (Parent == W32kGetDesktopWindow())
|
|
|
|
{
|
|
|
|
Parent = NULL;
|
|
|
|
}
|
|
|
|
W32kSetFocusWindow(Parent);
|
2003-06-14 10:00:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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))
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Recursively destroy owned windows */
|
|
|
|
#if 0 /* FIXME */
|
|
|
|
if (! isChild)
|
|
|
|
{
|
|
|
|
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
|
|
|
|
|
|
|
|
/* Send destroy messages */
|
|
|
|
W32kSendDestroyMsg(Wnd);
|
|
|
|
|
|
|
|
#if 0 /* FIXME */
|
|
|
|
if (!IsWindow(Wnd))
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Unlink now so we won't bother with the children later on */
|
|
|
|
#if 0 /* FIXME */
|
|
|
|
WIN_UnlinkWindow( hwnd );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Destroy the window storage */
|
2003-06-25 22:37:07 +00:00
|
|
|
W32kDestroyWindow(Window, PsGetWin32Process(), PsGetWin32Thread(), TRUE);
|
2003-06-14 10:00:58 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2003-06-25 22:37:07 +00:00
|
|
|
VOID FASTCALL
|
2003-07-11 17:08:44 +00:00
|
|
|
DestroyThreadWindows(struct _ETHREAD *Thread)
|
2003-06-25 22:37:07 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
W32kDestroyWindow(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 */
|
2003-07-21 21:53:53 +00:00
|
|
|
KEBUGCHECK(0);
|
2003-06-25 22:37:07 +00:00
|
|
|
}
|
|
|
|
ExReleaseFastMutexUnsafe(&Win32Thread->WindowListLock);
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserEndDeferWindowPosEx(DWORD Unknown0,
|
|
|
|
DWORD Unknown1)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
2002-01-27 01:11:24 +00:00
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserFillWindow(DWORD Unknown0,
|
|
|
|
DWORD Unknown1,
|
|
|
|
DWORD Unknown2,
|
|
|
|
DWORD Unknown3)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-07-10 00:24:04 +00:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
HWND STDCALL
|
|
|
|
NtUserFindWindowEx(HWND hwndParent,
|
|
|
|
HWND hwndChildAfter,
|
2003-06-15 04:25:34 +00:00
|
|
|
PUNICODE_STRING ucClassName,
|
|
|
|
PUNICODE_STRING ucWindowName)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2002-01-27 01:11:24 +00:00
|
|
|
NTSTATUS status;
|
|
|
|
HWND windowHandle;
|
|
|
|
PWINDOW_OBJECT windowObject;
|
2003-07-10 00:24:04 +00:00
|
|
|
PWINDOW_OBJECT ParentWindow;
|
2002-01-27 01:11:24 +00:00
|
|
|
PLIST_ENTRY currentEntry;
|
|
|
|
PWNDCLASS_OBJECT classObject;
|
2001-07-06 00:05:05 +00:00
|
|
|
|
2003-07-10 00:24:04 +00:00
|
|
|
// Get a pointer to the class
|
2001-07-06 00:05:05 +00:00
|
|
|
status = ClassReferenceClassByNameOrAtom(&classObject, ucClassName->Buffer);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
|
|
{
|
2003-07-10 00:24:04 +00:00
|
|
|
return NULL;
|
2001-07-06 00:05:05 +00:00
|
|
|
}
|
2003-07-10 00:24:04 +00:00
|
|
|
|
|
|
|
// If hwndParent==NULL use the desktop window instead
|
|
|
|
if(!hwndParent)
|
|
|
|
hwndParent = PsGetWin32Thread()->Desktop->DesktopWindow;
|
2001-07-06 00:05:05 +00:00
|
|
|
|
2003-07-10 00:24:04 +00:00
|
|
|
// Get the object
|
|
|
|
ParentWindow = W32kGetWindowObject(hwndParent);
|
|
|
|
|
|
|
|
if(!ParentWindow)
|
|
|
|
{
|
|
|
|
ObmDereferenceObject(classObject);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ExAcquireFastMutexUnsafe (&ParentWindow->ChildrenListLock);
|
|
|
|
currentEntry = ParentWindow->ChildrenListHead.Flink;
|
|
|
|
|
|
|
|
if(hwndChildAfter)
|
|
|
|
{
|
|
|
|
while (currentEntry != &ParentWindow->ChildrenListHead)
|
|
|
|
{
|
|
|
|
windowObject = CONTAINING_RECORD (currentEntry, WINDOW_OBJECT,
|
|
|
|
SiblingListEntry);
|
|
|
|
|
|
|
|
if(windowObject->Self == hwndChildAfter)
|
|
|
|
{
|
|
|
|
/* "The search begins with the _next_ child window in the Z order." */
|
|
|
|
currentEntry = currentEntry->Flink;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
currentEntry = currentEntry->Flink;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If the child hwndChildAfter was not found:
|
|
|
|
currentEntry=&ParentWindow->ChildrenListHead now so the next
|
|
|
|
block of code will just fall through and the function returns NULL */
|
|
|
|
}
|
|
|
|
|
|
|
|
while (currentEntry != &ParentWindow->ChildrenListHead)
|
2002-01-27 01:11:24 +00:00
|
|
|
{
|
|
|
|
windowObject = CONTAINING_RECORD (currentEntry, WINDOW_OBJECT,
|
2003-07-10 00:24:04 +00:00
|
|
|
SiblingListEntry);
|
2002-01-27 01:11:24 +00:00
|
|
|
|
2003-07-10 00:24:04 +00:00
|
|
|
if (classObject == windowObject->Class && (ucWindowName->Buffer==NULL ||
|
|
|
|
RtlCompareUnicodeString (ucWindowName, &windowObject->WindowName, TRUE) == 0))
|
2002-01-27 01:11:24 +00:00
|
|
|
{
|
2003-07-10 00:24:04 +00:00
|
|
|
windowHandle = windowObject->Self;
|
|
|
|
|
|
|
|
ExReleaseFastMutexUnsafe (&ParentWindow->ChildrenListLock);
|
|
|
|
W32kReleaseWindowObject(ParentWindow);
|
2002-01-27 01:11:24 +00:00
|
|
|
ObmDereferenceObject (classObject);
|
|
|
|
|
|
|
|
return windowHandle;
|
|
|
|
}
|
|
|
|
currentEntry = currentEntry->Flink;
|
|
|
|
}
|
2003-07-10 00:24:04 +00:00
|
|
|
|
|
|
|
ExReleaseFastMutexUnsafe (&ParentWindow->ChildrenListLock);
|
|
|
|
W32kReleaseWindowObject(ParentWindow);
|
2002-01-27 01:11:24 +00:00
|
|
|
ObmDereferenceObject (classObject);
|
2001-07-06 00:05:05 +00:00
|
|
|
|
2003-07-10 00:24:04 +00:00
|
|
|
return NULL;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserFlashWindowEx(DWORD Unknown0)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
2001-06-12 17:51:51 +00:00
|
|
|
NtUserGetForegroundWindow(VOID)
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserGetInternalWindowPos(DWORD Unknown0,
|
|
|
|
DWORD Unknown1,
|
|
|
|
DWORD Unknown2)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
2001-06-12 17:51:51 +00:00
|
|
|
NtUserGetOpenClipboardWindow(VOID)
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
2003-03-04 00:40:37 +00:00
|
|
|
NtUserGetWindowDC(HWND hWnd)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-05-18 17:16:18 +00:00
|
|
|
return (DWORD) NtUserGetDCEx( hWnd, 0, DCX_USESTYLE | DCX_WINDOW );
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserGetWindowPlacement(DWORD Unknown0,
|
|
|
|
DWORD Unknown1)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserInternalGetWindowText(DWORD Unknown0,
|
|
|
|
DWORD Unknown1,
|
|
|
|
DWORD Unknown2)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserLockWindowUpdate(DWORD Unknown0)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-03-07 05:38:02 +00:00
|
|
|
BOOL STDCALL
|
|
|
|
NtUserMoveWindow(
|
|
|
|
HWND hWnd,
|
|
|
|
int X,
|
|
|
|
int Y,
|
|
|
|
int nWidth,
|
|
|
|
int nHeight,
|
|
|
|
BOOL bRepaint)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-07-24 15:59:34 +00:00
|
|
|
UINT flags = SWP_NOZORDER | SWP_NOACTIVATE;
|
2003-03-24 01:36:10 +00:00
|
|
|
|
2003-07-24 15:59:34 +00:00
|
|
|
if(!bRepaint)
|
|
|
|
flags |= SWP_NOREDRAW;
|
|
|
|
return NtUserSetWindowPos(hWnd, 0, X, Y, nWidth, nHeight, flags);
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-07-07 06:12:08 +00:00
|
|
|
/*
|
|
|
|
QueryWindow based on KJK::Hyperion and James Tabor.
|
|
|
|
|
|
|
|
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.
|
|
|
|
*/
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
2003-07-07 06:12:08 +00:00
|
|
|
NtUserQueryWindow(HWND hWnd, DWORD Index)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-07-07 06:12:08 +00:00
|
|
|
/*
|
|
|
|
W32kGetWndObj uses PsGetWin32Process() which came from
|
|
|
|
PsGetCurrentProcess() made from PsGetCurrentThread().
|
|
|
|
What would happen if hWnd was under a different EThread
|
|
|
|
all togeather?
|
|
|
|
*/
|
|
|
|
PWINDOW_OBJECT Window = W32kGetWindowObject(hWnd);
|
|
|
|
|
|
|
|
if(Window == NULL) return((DWORD)NULL);
|
|
|
|
|
|
|
|
W32kReleaseWindowObject(Window);
|
|
|
|
|
|
|
|
switch(Index)
|
|
|
|
{
|
|
|
|
case 0x00:
|
|
|
|
return((DWORD)PsGetCurrentProcessId());
|
|
|
|
|
|
|
|
case 0x01:
|
|
|
|
return((DWORD)PsGetCurrentThreadId());
|
|
|
|
|
|
|
|
default:
|
|
|
|
return((DWORD)NULL);
|
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserRealChildWindowFromPoint(DWORD Unknown0,
|
|
|
|
DWORD Unknown1,
|
|
|
|
DWORD Unknown2)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-07-06 23:04:19 +00:00
|
|
|
BOOL
|
|
|
|
STDCALL
|
|
|
|
NtUserRedrawWindow
|
|
|
|
(
|
|
|
|
HWND hWnd,
|
|
|
|
CONST RECT *lprcUpdate,
|
|
|
|
HRGN hrgnUpdate,
|
|
|
|
UINT flags
|
|
|
|
)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-07-06 23:04:19 +00:00
|
|
|
RECT SafeUpdateRect;
|
|
|
|
NTSTATUS Status;
|
2003-03-18 09:16:44 +00:00
|
|
|
|
2003-07-06 23:04:19 +00:00
|
|
|
if(NULL != lprcUpdate)
|
|
|
|
{
|
|
|
|
Status = MmCopyFromCaller(&SafeUpdateRect, (PRECT)lprcUpdate, sizeof(RECT));
|
2003-03-18 09:16:44 +00:00
|
|
|
|
2003-07-06 23:04:19 +00:00
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* FIXME: set last error */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = PaintRedrawWindow
|
|
|
|
(
|
|
|
|
hWnd,
|
|
|
|
NULL == lprcUpdate ? NULL : &SafeUpdateRect,
|
|
|
|
hrgnUpdate,
|
|
|
|
flags,
|
|
|
|
0
|
|
|
|
);
|
|
|
|
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* FIXME: set last error */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2002-05-06 22:20:32 +00:00
|
|
|
UINT STDCALL
|
2003-05-02 07:52:33 +00:00
|
|
|
NtUserRegisterWindowMessage(PUNICODE_STRING MessageNameUnsafe)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-05-02 07:52:33 +00:00
|
|
|
PLIST_ENTRY Current;
|
|
|
|
PREGISTERED_MESSAGE NewMsg, RegMsg;
|
|
|
|
UINT Msg = REGISTERED_MESSAGE_MIN;
|
|
|
|
UNICODE_STRING MessageName;
|
|
|
|
NTSTATUS Status;
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2003-05-02 07:52:33 +00:00
|
|
|
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)
|
|
|
|
{
|
|
|
|
RegMsg = CONTAINING_RECORD(Current, REGISTERED_MESSAGE, ListEntry);
|
|
|
|
if (0 == wcscmp(NewMsg->MessageName, RegMsg->MessageName))
|
|
|
|
{
|
|
|
|
ExFreePool(NewMsg);
|
|
|
|
return Msg;
|
|
|
|
}
|
|
|
|
Msg++;
|
|
|
|
Current = Current->Flink;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (REGISTERED_MESSAGE_MAX < Msg)
|
|
|
|
{
|
|
|
|
ExFreePool(NewMsg);
|
|
|
|
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
InsertTailList(&RegisteredMessageListHead, &(NewMsg->ListEntry));
|
|
|
|
|
|
|
|
return Msg;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserScrollWindowEx(DWORD Unknown0,
|
|
|
|
DWORD Unknown1,
|
|
|
|
DWORD Unknown2,
|
|
|
|
DWORD Unknown3,
|
|
|
|
DWORD Unknown4,
|
|
|
|
DWORD Unknown5,
|
|
|
|
DWORD Unknown6,
|
|
|
|
DWORD Unknown7)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserSetActiveWindow(DWORD Unknown0)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserSetImeOwnerWindow(DWORD Unknown0,
|
|
|
|
DWORD Unknown1)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserSetInternalWindowPos(DWORD Unknown0,
|
|
|
|
DWORD Unknown1,
|
|
|
|
DWORD Unknown2,
|
|
|
|
DWORD Unknown3)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
2002-08-24 11:09:17 +00:00
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserSetLayeredWindowAttributes(DWORD Unknown0,
|
|
|
|
DWORD Unknown1,
|
|
|
|
DWORD Unknown2,
|
|
|
|
DWORD Unknown3)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserSetLogonNotifyWindow(DWORD Unknown0)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserSetShellWindowEx(DWORD Unknown0,
|
|
|
|
DWORD Unknown1)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserSetWindowFNID(DWORD Unknown0,
|
|
|
|
DWORD Unknown1)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-05-17 09:20:23 +00:00
|
|
|
LONG STDCALL
|
2002-06-18 21:51:11 +00:00
|
|
|
NtUserGetWindowLong(HWND hWnd, DWORD Index)
|
|
|
|
{
|
|
|
|
PWINDOW_OBJECT WindowObject;
|
|
|
|
NTSTATUS Status;
|
2003-05-17 09:20:23 +00:00
|
|
|
LONG Result;
|
2002-06-18 21:51:11 +00:00
|
|
|
|
2002-07-04 19:56:38 +00:00
|
|
|
Status =
|
|
|
|
ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable,
|
|
|
|
hWnd,
|
|
|
|
otWindow,
|
|
|
|
(PVOID*)&WindowObject);
|
2002-06-18 21:51:11 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2003-05-12 18:52:14 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
2003-05-17 09:20:23 +00:00
|
|
|
return 0;
|
2002-06-18 21:51:11 +00:00
|
|
|
}
|
|
|
|
|
2003-05-17 09:20:23 +00:00
|
|
|
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
|
2002-06-18 21:51:11 +00:00
|
|
|
{
|
2003-05-17 09:20:23 +00:00
|
|
|
switch (Index)
|
|
|
|
{
|
|
|
|
case GWL_EXSTYLE:
|
|
|
|
Result = WindowObject->ExStyle;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GWL_STYLE:
|
|
|
|
Result = WindowObject->Style;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GWL_WNDPROC:
|
|
|
|
Result = (LONG) WindowObject->WndProc;
|
|
|
|
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;
|
2003-03-03 18:57:26 +00:00
|
|
|
|
2003-05-17 09:20:23 +00:00
|
|
|
default:
|
|
|
|
DPRINT1("NtUserGetWindowLong(): Unsupported index %d\n", Index);
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
Result = 0;
|
|
|
|
break;
|
|
|
|
}
|
2002-06-18 21:51:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ObmDereferenceObject(WindowObject);
|
2003-05-17 09:20:23 +00:00
|
|
|
|
|
|
|
return Result;
|
2002-06-18 21:51:11 +00:00
|
|
|
}
|
|
|
|
|
2003-05-17 09:20:23 +00:00
|
|
|
LONG STDCALL
|
|
|
|
NtUserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-05-17 09:20:23 +00:00
|
|
|
PWINDOW_OBJECT WindowObject;
|
|
|
|
NTSTATUS Status;
|
|
|
|
LONG OldValue;
|
2003-06-05 03:55:36 +00:00
|
|
|
STYLESTRUCT Style;
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2003-05-17 09:20:23 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
OldValue = WindowObject->ExtraData[Index / sizeof(LONG)];
|
|
|
|
WindowObject->ExtraData[Index / sizeof(LONG)] = NewValue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (Index)
|
|
|
|
{
|
|
|
|
case GWL_EXSTYLE:
|
|
|
|
OldValue = (LONG) WindowObject->ExStyle;
|
2003-06-05 03:55:36 +00:00
|
|
|
Style.styleOld = OldValue;
|
|
|
|
Style.styleNew = NewValue;
|
|
|
|
W32kSendSTYLECHANGINGMessage(hWnd, GWL_EXSTYLE, &Style);
|
|
|
|
WindowObject->ExStyle = (DWORD)Style.styleNew;
|
|
|
|
W32kSendSTYLECHANGEDMessage(hWnd, GWL_EXSTYLE, &Style);
|
2003-05-17 09:20:23 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case GWL_STYLE:
|
|
|
|
OldValue = (LONG) WindowObject->Style;
|
2003-06-05 03:55:36 +00:00
|
|
|
Style.styleOld = OldValue;
|
|
|
|
Style.styleNew = NewValue;
|
|
|
|
W32kSendSTYLECHANGINGMessage(hWnd, GWL_STYLE, &Style);
|
|
|
|
WindowObject->Style = (DWORD)Style.styleNew;
|
|
|
|
W32kSendSTYLECHANGEDMessage(hWnd, GWL_STYLE, &Style);
|
2003-05-17 09:20:23 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case GWL_WNDPROC:
|
|
|
|
/* FIXME: should check if window belongs to current process */
|
|
|
|
OldValue = (LONG) WindowObject->WndProc;
|
|
|
|
WindowObject->WndProc = (WNDPROC) NewValue;
|
|
|
|
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("NtUserSetWindowLong(): Unsupported index %d\n", Index);
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
OldValue = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ObmDereferenceObject(WindowObject);
|
|
|
|
return(OldValue);
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserSetWindowPlacement(DWORD Unknown0,
|
|
|
|
DWORD Unknown1)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-03-07 05:38:02 +00:00
|
|
|
BOOL
|
|
|
|
STDCALL NtUserSetWindowPos(
|
|
|
|
HWND hWnd,
|
|
|
|
HWND hWndInsertAfter,
|
|
|
|
int X,
|
|
|
|
int Y,
|
|
|
|
int cx,
|
|
|
|
int cy,
|
|
|
|
UINT uFlags)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-03-07 05:38:02 +00:00
|
|
|
return WinPosSetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags);
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserSetWindowRgn(DWORD Unknown0,
|
|
|
|
DWORD Unknown1,
|
|
|
|
DWORD Unknown2)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserSetWindowWord(DWORD Unknown0,
|
|
|
|
DWORD Unknown1,
|
|
|
|
DWORD Unknown2)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
BOOL STDCALL
|
|
|
|
NtUserShowWindow(HWND hWnd,
|
|
|
|
LONG nCmdShow)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2002-07-04 19:56:38 +00:00
|
|
|
return(WinPosShowWindow(hWnd, nCmdShow));
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserShowWindowAsync(DWORD Unknown0,
|
|
|
|
DWORD Unknown1)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-03-24 23:08:51 +00:00
|
|
|
BOOL STDCALL NtUserUpdateWindow( HWND hWnd )
|
|
|
|
{
|
|
|
|
PWINDOW_OBJECT pWindow = W32kGetWindowObject( hWnd);
|
|
|
|
|
|
|
|
if (!pWindow)
|
|
|
|
return FALSE;
|
|
|
|
if (pWindow->UpdateRegion)
|
|
|
|
NtUserSendMessage( hWnd, WM_PAINT,0,0);
|
2003-03-28 18:59:18 +00:00
|
|
|
W32kReleaseWindowObject(pWindow);
|
2003-03-24 23:08:51 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserUpdateLayeredWindow(DWORD Unknown0,
|
|
|
|
DWORD Unknown1,
|
|
|
|
DWORD Unknown2,
|
|
|
|
DWORD Unknown3,
|
|
|
|
DWORD Unknown4,
|
|
|
|
DWORD Unknown5,
|
|
|
|
DWORD Unknown6,
|
|
|
|
DWORD Unknown7,
|
|
|
|
DWORD Unknown8)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserWindowFromPoint(DWORD Unknown0,
|
|
|
|
DWORD Unknown1)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-05-23 16:44:12 +00:00
|
|
|
HWND STDCALL
|
|
|
|
NtUserGetDesktopWindow()
|
|
|
|
{
|
|
|
|
return W32kGetDesktopWindow();
|
|
|
|
}
|
2003-06-20 16:26:53 +00:00
|
|
|
|
2003-07-25 19:36:26 +00:00
|
|
|
|
|
|
|
DWORD FASTCALL
|
|
|
|
W32kGetWindowThreadProcessId(PWINDOW_OBJECT Wnd, PDWORD pid)
|
|
|
|
{
|
|
|
|
if (pid) *pid = (DWORD) Wnd->OwnerThread->Cid.UniqueThread;
|
|
|
|
return (DWORD) Wnd->OwnerThread->ThreadsProcess->UniqueProcessId;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DWORD STDCALL
|
|
|
|
NtUserGetWindowThreadProcessId(HWND hWnd, LPDWORD UnsafePid)
|
|
|
|
{
|
|
|
|
PWINDOW_OBJECT Wnd;
|
|
|
|
DWORD tid, pid;
|
|
|
|
|
|
|
|
//W32kAcquireWindowsLockShared();
|
|
|
|
|
|
|
|
if (!(Wnd = W32kGetWindowObject(hWnd)))
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
tid = W32kGetWindowThreadProcessId(Wnd, &pid);
|
|
|
|
W32kReleaseWindowObject(Wnd);
|
|
|
|
//W32kReleaseWindowsLock();
|
|
|
|
|
|
|
|
if (UnsafePid) MmCopyToCaller(UnsafePid, &pid, sizeof(DWORD));
|
|
|
|
|
|
|
|
return tid;
|
|
|
|
}
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
/* EOF */
|