2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* $Id: window.c,v 1.210 2004/04/09 20:03:19 navaraf Exp $
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
24 * FILE: subsys/win32k/ntuser/window.c
25 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
27 * 06-06-2001 CSH Created
29 /* INCLUDES ******************************************************************/
31 #include <ddk/ntddk.h>
32 #include <internal/safe.h>
33 #include <win32k/win32k.h>
34 #include <include/object.h>
35 #include <include/guicheck.h>
36 #include <include/window.h>
37 #include <include/class.h>
38 #include <include/error.h>
39 #include <include/winsta.h>
40 #include <include/desktop.h>
41 #include <include/winpos.h>
42 #include <include/callback.h>
43 #include <include/msgqueue.h>
44 #include <include/rect.h>
45 #include <include/dce.h>
46 #include <include/paint.h>
47 #include <include/painting.h>
48 #include <include/scroll.h>
49 #include <include/vis.h>
50 #include <include/menu.h>
51 #include <include/hotkey.h>
52 #include <include/focus.h>
53 #include <include/hook.h>
54 #include <include/useratom.h>
55 #include <include/tags.h>
56 #include <include/timer.h>
59 #include <win32k/debug1.h>
62 static WndProcHandle
*WndProcHandlesArray
= 0;
63 static WORD WndProcHandlesArraySize
= 0;
64 #define WPH_SIZE 0x40 /* the size to add to the WndProcHandle array each time */
66 #define POINT_IN_RECT(p, r) (((r.bottom >= p.y) && (r.top <= p.y))&&((r.left <= p.x )&&( r.right >= p.x )))
68 /* PRIVATE FUNCTIONS **********************************************************/
73 * Initialize windowing implementation.
79 WndProcHandlesArray
= ExAllocatePoolWithTag(PagedPool
,WPH_SIZE
* sizeof(WndProcHandle
), TAG_WINPROCLST
);
80 WndProcHandlesArraySize
= WPH_SIZE
;
81 return STATUS_SUCCESS
;
87 * Cleanup windowing implementation.
91 CleanupWindowImpl(VOID
)
93 ExFreePool(WndProcHandlesArray
);
94 WndProcHandlesArray
= 0;
95 WndProcHandlesArraySize
= 0;
96 return STATUS_SUCCESS
;
99 /* HELPER FUNCTIONS ***********************************************************/
104 * The function determines whether the specified window handle identifies
105 * an existing window.
109 * Handle to the window to test.
112 * If the window handle identifies an existing window, the return value
113 * is TRUE. If the window handle does not identify an existing window,
114 * the return value is FALSE.
118 IntIsWindow(HWND hWnd
)
120 PWINDOW_OBJECT Window
;
122 if (!(Window
= IntGetWindowObject(hWnd
)))
125 IntReleaseWindowObject(Window
);
130 * IntGetProcessWindowObject
132 * Get window object from handle of specified process.
135 PWINDOW_OBJECT FASTCALL
136 IntGetProcessWindowObject(PW32PROCESS ProcessData
, HWND hWnd
)
138 PWINDOW_OBJECT WindowObject
;
141 Status
= ObmReferenceObjectByHandle(ProcessData
->WindowStation
->HandleTable
,
142 hWnd
, otWindow
, (PVOID
*)&WindowObject
);
143 if (!NT_SUCCESS(Status
))
151 PWINDOW_OBJECT FASTCALL
152 IntGetParent(PWINDOW_OBJECT Wnd
)
156 if (Wnd
->Style
& WS_POPUP
)
158 IntLockRelatives(Wnd
);
160 IntUnLockRelatives(Wnd
);
161 return IntGetWindowObject(hWnd
);
163 else if (Wnd
->Style
& WS_CHILD
)
165 IntLockRelatives(Wnd
);
167 IntUnLockRelatives(Wnd
);
168 return IntGetWindowObject(hWnd
);
175 PWINDOW_OBJECT FASTCALL
176 IntGetParentObject(PWINDOW_OBJECT Wnd
)
180 IntLockRelatives(Wnd
);
181 hParent
= Wnd
->Parent
;
182 IntUnLockRelatives(Wnd
);
183 return IntGetWindowObject(hParent
);
189 * Compile a list of all child window handles from given window.
192 * This function is similar to Wine WIN_ListChildren. The caller
193 * must free the returned list with ExFreePool.
197 IntWinListChildren(PWINDOW_OBJECT Window
)
199 PWINDOW_OBJECT Child
;
201 UINT Index
, NumChildren
= 0;
203 IntLockRelatives(Window
);
205 for (Child
= Window
->FirstChild
; Child
; Child
= Child
->NextSibling
)
208 if (NumChildren
!= 0)
210 List
= ExAllocatePoolWithTag(PagedPool
, (NumChildren
+ 1) * sizeof(HWND
), TAG_WINLIST
);
213 DPRINT1("Failed to allocate memory for children array\n");
214 IntUnLockRelatives(Window
);
217 for (Child
= Window
->FirstChild
, Index
= 0;
219 Child
= Child
->NextSibling
, ++Index
)
220 List
[Index
] = Child
->Self
;
224 IntUnLockRelatives(Window
);
226 return (NumChildren
> 0) ? List
: NULL
;
229 /***********************************************************************
232 static void IntSendDestroyMsg(HWND Wnd
)
237 if (GetGUIThreadInfo(GetCurrentThreadId(), &info
))
239 if (Wnd
== info
.hwndCaret
)
247 * Send the WM_DESTROY to the window.
249 IntSendMessage(Wnd
, WM_DESTROY
, 0, 0);
252 * This WM_DESTROY message can trigger re-entrant calls to DestroyWindow
253 * make sure that the window still exists when we come back.
261 if (!(pWndArray
= WIN_ListChildren( hwnd
))) return;
263 /* start from the end (FIXME: is this needed?) */
264 for (i
= 0; pWndArray
[i
]; i
++) ;
268 if (IsWindow( pWndArray
[i
] )) WIN_SendDestroyMsg( pWndArray
[i
] );
270 HeapFree(GetProcessHeap(), 0, pWndArray
);
274 DPRINT("destroyed itself while in WM_DESTROY!\n");
279 /***********************************************************************
282 * Destroy storage associated to a window. "Internals" p.358
284 static LRESULT
IntDestroyWindow(PWINDOW_OBJECT Window
,
285 PW32PROCESS ProcessData
,
286 PW32THREAD ThreadData
,
287 BOOLEAN SendMessages
)
291 PWINDOW_OBJECT Child
;
293 BOOL BelongsToThreadData
;
297 RemoveTimersWindow(Window
->Self
);
299 IntLockThreadWindows(Window
->OwnerThread
->Win32Thread
);
300 if(Window
->Status
& WINDOWSTATUS_DESTROYING
)
302 IntUnLockThreadWindows(Window
->OwnerThread
->Win32Thread
);
303 DPRINT("Tried to call IntDestroyWindow() twice\n");
306 Window
->Status
|= WINDOWSTATUS_DESTROYING
;
307 /* remove the window already at this point from the thread window list so we
308 don't get into trouble when destroying the thread windows while we're still
309 in IntDestroyWindow() */
310 RemoveEntryList(&Window
->ThreadListEntry
);
311 IntUnLockThreadWindows(Window
->OwnerThread
->Win32Thread
);
313 BelongsToThreadData
= IntWndBelongsToThread(Window
, ThreadData
);
317 /* Send destroy messages */
318 IntSendDestroyMsg(Window
->Self
);
321 /* free child windows */
322 Children
= IntWinListChildren(Window
);
325 for (ChildHandle
= Children
; *ChildHandle
; ++ChildHandle
)
327 if ((Child
= IntGetWindowObject(*ChildHandle
)))
329 if(!IntWndBelongsToThread(Child
, ThreadData
))
331 /* send WM_DESTROY messages to windows not belonging to the same thread */
332 IntSendDestroyMsg(Child
->Self
);
335 IntDestroyWindow(Child
, ProcessData
, ThreadData
, SendMessages
);
336 IntReleaseWindowObject(Child
);
339 ExFreePool(Children
);
345 * Clear the update region to make sure no WM_PAINT messages will be
346 * generated for this window while processing the WM_NCDESTROY.
348 IntRedrawWindow(Window
, NULL
, 0,
349 RDW_VALIDATE
| RDW_NOFRAME
| RDW_NOERASE
|
350 RDW_NOINTERNALPAINT
| RDW_NOCHILDREN
);
353 * Send the WM_NCDESTROY to the window being destroyed.
355 if(BelongsToThreadData
)
356 IntSendMessage(Window
->Self
, WM_NCDESTROY
, 0, 0);
359 /* reset shell window handles */
360 if(ProcessData
->WindowStation
)
362 if (Window
->Self
== ProcessData
->WindowStation
->ShellWindow
)
363 ProcessData
->WindowStation
->ShellWindow
= NULL
;
365 if (Window
->Self
== ProcessData
->WindowStation
->ShellListView
)
366 ProcessData
->WindowStation
->ShellListView
= NULL
;
369 /* Unregister hot keys */
370 UnregisterWindowHotKeys (Window
);
372 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
375 WinPosCheckInternalPos(Window
->Self
);
376 if (Window
->Self
== GetCapture())
381 /* free resources associated with the window */
382 TIMER_RemoveWindowTimers(Window
->Self
);
385 if (!(Window
->Style
& WS_CHILD
) && Window
->IDMenu
386 && (Menu
= IntGetMenuObject((HMENU
)Window
->IDMenu
)))
388 IntDestroyMenuObject(Menu
, TRUE
, TRUE
);
390 IntReleaseMenuObject(Menu
);
393 if(Window
->SystemMenu
394 && (Menu
= IntGetMenuObject(Window
->SystemMenu
)))
396 IntDestroyMenuObject(Menu
, TRUE
, TRUE
);
397 Window
->SystemMenu
= (HMENU
)0;
398 IntReleaseMenuObject(Menu
);
401 DceFreeWindowDCE(Window
); /* Always do this to catch orphaned DCs */
403 WINPROC_FreeProc(Window
->winproc
, WIN_PROC_WINDOW
);
404 CLASS_RemoveWindow(Window
->Class
);
407 IntUnlinkWindow(Window
);
409 IntReferenceWindowObject(Window
);
410 ObmCloseHandle(ProcessData
->WindowStation
->HandleTable
, Window
->Self
);
412 IntDestroyScrollBar(Window
, SB_VERT
);
413 IntDestroyScrollBar(Window
, SB_HORZ
);
415 IntLockThreadWindows(Window
->OwnerThread
->Win32Thread
);
416 Window
->Status
|= WINDOWSTATUS_DESTROYED
;
417 /* don't remove the WINDOWSTATUS_DESTROYING bit */
418 IntUnLockThreadWindows(Window
->OwnerThread
->Win32Thread
);
420 ObmDereferenceObject(Window
->Class
);
421 Window
->Class
= NULL
;
423 if(Window
->WindowRegion
)
425 NtGdiDeleteObject(Window
->WindowRegion
);
428 IntReleaseWindowObject(Window
);
434 IntGetWindowBorderMeasures(PWINDOW_OBJECT WindowObject
, INT
*cx
, INT
*cy
)
436 if(HAS_DLGFRAME(WindowObject
->Style
, WindowObject
->ExStyle
) && !(WindowObject
->Style
& WS_MINIMIZE
))
438 *cx
= NtUserGetSystemMetrics(SM_CXDLGFRAME
);
439 *cy
= NtUserGetSystemMetrics(SM_CYDLGFRAME
);
443 if(HAS_THICKFRAME(WindowObject
->Style
, WindowObject
->ExStyle
)&& !(WindowObject
->Style
& WS_MINIMIZE
))
445 *cx
= NtUserGetSystemMetrics(SM_CXFRAME
);
446 *cy
= NtUserGetSystemMetrics(SM_CYFRAME
);
448 else if(HAS_THINFRAME(WindowObject
->Style
, WindowObject
->ExStyle
))
450 *cx
= NtUserGetSystemMetrics(SM_CXBORDER
);
451 *cy
= NtUserGetSystemMetrics(SM_CYBORDER
);
461 IntGetWindowInfo(PWINDOW_OBJECT WindowObject
, PWINDOWINFO pwi
)
463 pwi
->cbSize
= sizeof(WINDOWINFO
);
464 pwi
->rcWindow
= WindowObject
->WindowRect
;
465 pwi
->rcClient
= WindowObject
->ClientRect
;
466 pwi
->dwStyle
= WindowObject
->Style
;
467 pwi
->dwExStyle
= WindowObject
->ExStyle
;
468 pwi
->dwWindowStatus
= (NtUserGetForegroundWindow() == WindowObject
->Self
); /* WS_ACTIVECAPTION */
469 IntGetWindowBorderMeasures(WindowObject
, &pwi
->cxWindowBorders
, &pwi
->cyWindowBorders
);
470 pwi
->atomWindowType
= (WindowObject
->Class
? WindowObject
->Class
->Atom
: 0);
471 pwi
->wCreatorVersion
= 0x400; /* FIXME - return a real version number */
477 PWINDOW_OBJECT WindowObject
,
481 PMENU_OBJECT OldMenuObject
, NewMenuObject
;
483 *Changed
= (WindowObject
->IDMenu
!= (UINT
) Menu
);
489 if (0 != WindowObject
->IDMenu
)
491 OldMenuObject
= IntGetMenuObject((HMENU
) WindowObject
->IDMenu
);
492 ASSERT(NULL
== OldMenuObject
|| OldMenuObject
->MenuInfo
.Wnd
== WindowObject
->Self
);
496 OldMenuObject
= NULL
;
501 NewMenuObject
= IntGetMenuObject(Menu
);
502 if (NULL
== NewMenuObject
)
504 if (NULL
!= OldMenuObject
)
506 IntReleaseMenuObject(OldMenuObject
);
508 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
511 if (NULL
!= NewMenuObject
->MenuInfo
.Wnd
)
513 /* Can't use the same menu for two windows */
514 if (NULL
!= OldMenuObject
)
516 IntReleaseMenuObject(OldMenuObject
);
518 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
524 WindowObject
->IDMenu
= (UINT
) Menu
;
525 if (NULL
!= NewMenuObject
)
527 NewMenuObject
->MenuInfo
.Wnd
= WindowObject
->Self
;
528 IntReleaseMenuObject(NewMenuObject
);
530 if (NULL
!= OldMenuObject
)
532 OldMenuObject
->MenuInfo
.Wnd
= NULL
;
533 IntReleaseMenuObject(OldMenuObject
);
540 /* INTERNAL ******************************************************************/
544 DestroyThreadWindows(struct _ETHREAD
*Thread
)
547 PW32PROCESS Win32Process
;
548 PW32THREAD Win32Thread
;
549 PWINDOW_OBJECT
*List
, *pWnd
;
552 Win32Thread
= Thread
->Win32Thread
;
553 Win32Process
= Thread
->ThreadsProcess
->Win32Process
;
555 IntLockThreadWindows(Win32Thread
);
556 Current
= Win32Thread
->WindowListHead
.Flink
;
557 while (Current
!= &(Win32Thread
->WindowListHead
))
560 Current
= Current
->Flink
;
565 List
= ExAllocatePool(PagedPool
, (Cnt
+ 1) * sizeof(PWINDOW_OBJECT
));
568 DPRINT("Not enough memory to allocate window handle list\n");
569 IntUnLockThreadWindows(Win32Thread
);
573 Current
= Win32Thread
->WindowListHead
.Flink
;
574 while (Current
!= &(Win32Thread
->WindowListHead
))
576 *pWnd
= CONTAINING_RECORD(Current
, WINDOW_OBJECT
, ThreadListEntry
);
577 IntReferenceWindowObject(*pWnd
);
579 Current
= Current
->Flink
;
581 IntUnLockThreadWindows(Win32Thread
);
584 for(pWnd
= List
; *pWnd
; pWnd
++)
586 NtUserDestroyWindow((*pWnd
)->Self
);
587 IntReleaseWindowObject(*pWnd
);
593 IntUnLockThreadWindows(Win32Thread
);
599 * Returns client window rectangle relative to the upper-left corner of client area.
601 * \note Does not check the validity of the parameters
604 IntGetClientRect(PWINDOW_OBJECT WindowObject
, PRECT Rect
)
606 ASSERT( WindowObject
);
609 Rect
->left
= Rect
->top
= 0;
610 Rect
->right
= WindowObject
->ClientRect
.right
- WindowObject
->ClientRect
.left
;
611 Rect
->bottom
= WindowObject
->ClientRect
.bottom
- WindowObject
->ClientRect
.top
;
617 IntGetFocusWindow(VOID
)
619 PUSER_MESSAGE_QUEUE Queue
;
620 PDESKTOP_OBJECT pdo
= IntGetActiveDesktop();
625 Queue
= (PUSER_MESSAGE_QUEUE
)pdo
->ActiveMessageQueue
;
630 return(Queue
->FocusWindow
);
634 PMENU_OBJECT FASTCALL
635 IntGetSystemMenu(PWINDOW_OBJECT WindowObject
, BOOL bRevert
, BOOL RetMenu
)
637 PMENU_OBJECT MenuObject
, NewMenuObject
, SysMenuObject
, ret
= NULL
;
638 PW32PROCESS W32Process
;
639 HMENU NewMenu
, SysMenu
;
640 ROSMENUITEMINFO ItemInfo
;
644 W32Process
= PsGetWin32Process();
646 if(!W32Process
->WindowStation
)
649 if(WindowObject
->SystemMenu
)
651 MenuObject
= IntGetMenuObject(WindowObject
->SystemMenu
);
654 IntDestroyMenuObject(MenuObject
, FALSE
, TRUE
);
655 WindowObject
->SystemMenu
= (HMENU
)0;
656 IntReleaseMenuObject(MenuObject
);
660 if(W32Process
->WindowStation
->SystemMenuTemplate
)
662 /* clone system menu */
663 MenuObject
= IntGetMenuObject(W32Process
->WindowStation
->SystemMenuTemplate
);
667 NewMenuObject
= IntCloneMenu(MenuObject
);
670 WindowObject
->SystemMenu
= NewMenuObject
->MenuInfo
.Self
;
671 NewMenuObject
->MenuInfo
.Flags
|= MF_SYSMENU
;
672 NewMenuObject
->MenuInfo
.Wnd
= WindowObject
->Self
;
674 //IntReleaseMenuObject(NewMenuObject);
676 IntReleaseMenuObject(MenuObject
);
680 SysMenu
= NtUserCreateMenu(FALSE
);
685 SysMenuObject
= IntGetMenuObject(SysMenu
);
686 if (NULL
== SysMenuObject
)
688 NtUserDestroyMenu(SysMenu
);
691 SysMenuObject
->MenuInfo
.Flags
|= MF_SYSMENU
;
692 SysMenuObject
->MenuInfo
.Wnd
= WindowObject
->Self
;
693 NewMenu
= IntLoadSysMenuTemplate();
696 IntReleaseMenuObject(SysMenuObject
);
697 NtUserDestroyMenu(SysMenu
);
700 MenuObject
= IntGetMenuObject(NewMenu
);
703 IntReleaseMenuObject(SysMenuObject
);
704 NtUserDestroyMenu(SysMenu
);
708 NewMenuObject
= IntCloneMenu(MenuObject
);
711 NewMenuObject
->MenuInfo
.Flags
|= MF_SYSMENU
| MF_POPUP
;
712 IntReleaseMenuObject(NewMenuObject
);
713 NtUserSetMenuDefaultItem(NewMenuObject
->MenuInfo
.Self
, SC_CLOSE
, FALSE
);
715 ItemInfo
.cbSize
= sizeof(MENUITEMINFOW
);
716 ItemInfo
.fMask
= MIIM_FTYPE
| MIIM_STRING
| MIIM_STATE
| MIIM_SUBMENU
;
717 ItemInfo
.fType
= MF_POPUP
;
718 ItemInfo
.fState
= MFS_ENABLED
;
719 ItemInfo
.dwTypeData
= NULL
;
721 ItemInfo
.hSubMenu
= NewMenuObject
->MenuInfo
.Self
;
722 IntInsertMenuItem(SysMenuObject
, (UINT
) -1, TRUE
, &ItemInfo
);
724 WindowObject
->SystemMenu
= SysMenuObject
->MenuInfo
.Self
;
728 IntDestroyMenuObject(MenuObject
, FALSE
, TRUE
);
729 IntReleaseMenuObject(MenuObject
);
738 if(WindowObject
->SystemMenu
)
739 return IntGetMenuObject((HMENU
)WindowObject
->SystemMenu
);
747 IntIsChildWindow(HWND Parent
, HWND Child
)
749 PWINDOW_OBJECT BaseWindow
, Window
, Old
;
751 if(!(BaseWindow
= IntGetWindowObject(Child
)))
759 if (Window
->Self
== Parent
)
761 if(Window
!= BaseWindow
)
762 IntReleaseWindowObject(Window
);
763 IntReleaseWindowObject(BaseWindow
);
766 if(!(Window
->Style
& WS_CHILD
))
768 if(Window
!= BaseWindow
)
769 IntReleaseWindowObject(Window
);
773 Window
= IntGetParentObject(Window
);
774 if(Old
!= BaseWindow
)
775 IntReleaseWindowObject(Old
);
778 IntReleaseWindowObject(BaseWindow
);
783 IntIsWindowVisible(HWND hWnd
)
785 PWINDOW_OBJECT BaseWindow
, Window
, Old
;
787 if(!(BaseWindow
= IntGetWindowObject(hWnd
)))
795 if(!(Window
->Style
& WS_CHILD
))
799 if(!(Window
->Style
& WS_VISIBLE
))
801 if(Window
!= BaseWindow
)
802 IntReleaseWindowObject(Window
);
803 IntReleaseWindowObject(BaseWindow
);
807 Window
= IntGetParentObject(Window
);
808 if(Old
!= BaseWindow
)
809 IntReleaseWindowObject(Old
);
814 if(Window
->Style
& WS_VISIBLE
)
816 if(Window
!= BaseWindow
)
817 IntReleaseWindowObject(Window
);
818 IntReleaseWindowObject(BaseWindow
);
821 if(Window
!= BaseWindow
)
822 IntReleaseWindowObject(Window
);
824 IntReleaseWindowObject(BaseWindow
);
829 /* link the window into siblings and parent. children are kept in place. */
833 PWINDOW_OBJECT WndParent
,
834 PWINDOW_OBJECT WndPrevSibling
/* set to NULL if top sibling */
837 PWINDOW_OBJECT Parent
;
839 IntLockRelatives(Wnd
);
840 Wnd
->Parent
= WndParent
->Self
;
841 if ((Wnd
->PrevSibling
= WndPrevSibling
))
843 /* link after WndPrevSibling */
844 if ((Wnd
->NextSibling
= WndPrevSibling
->NextSibling
))
845 Wnd
->NextSibling
->PrevSibling
= Wnd
;
846 else if ((Parent
= IntGetWindowObject(Wnd
->Parent
)))
848 IntLockRelatives(Parent
);
849 if(Parent
->LastChild
== WndPrevSibling
)
850 Parent
->LastChild
= Wnd
;
851 IntUnLockRelatives(Parent
);
852 IntReleaseWindowObject(Parent
);
854 Wnd
->PrevSibling
->NextSibling
= Wnd
;
859 Parent
= IntGetWindowObject(Wnd
->Parent
);
860 if ((Wnd
->NextSibling
= WndParent
->FirstChild
))
861 Wnd
->NextSibling
->PrevSibling
= Wnd
;
864 IntLockRelatives(Parent
);
865 Parent
->LastChild
= Wnd
;
866 Parent
->FirstChild
= Wnd
;
867 IntUnLockRelatives(Parent
);
868 IntReleaseWindowObject(Parent
);
869 IntUnLockRelatives(Wnd
);
874 IntLockRelatives(Parent
);
875 Parent
->FirstChild
= Wnd
;
876 IntUnLockRelatives(Parent
);
877 IntReleaseWindowObject(Parent
);
880 IntUnLockRelatives(Wnd
);
884 IntSetOwner(HWND hWnd
, HWND hWndNewOwner
)
886 PWINDOW_OBJECT Wnd
, WndOldOwner
, WndNewOwner
;
889 Wnd
= IntGetWindowObject(hWnd
);
893 IntLockRelatives(Wnd
);
894 WndOldOwner
= IntGetWindowObject(Wnd
->Owner
);
897 ret
= WndOldOwner
->Self
;
898 IntReleaseWindowObject(WndOldOwner
);
905 if((WndNewOwner
= IntGetWindowObject(hWndNewOwner
)))
907 Wnd
->Owner
= hWndNewOwner
;
908 IntReleaseWindowObject(WndNewOwner
);
913 IntUnLockRelatives(Wnd
);
914 IntReleaseWindowObject(Wnd
);
918 PWINDOW_OBJECT FASTCALL
919 IntSetParent(PWINDOW_OBJECT Wnd
, PWINDOW_OBJECT WndNewParent
)
921 PWINDOW_OBJECT WndOldParent
, Sibling
, InsertAfter
;
922 HWND hWnd
, hWndNewParent
, hWndOldParent
;
927 ASSERT(WndNewParent
);
930 hWndNewParent
= WndNewParent
->Self
;
933 * Windows hides the window first, then shows it again
934 * including the WM_SHOWWINDOW messages and all
936 WasVisible
= WinPosShowWindow(hWnd
, SW_HIDE
);
938 /* Validate that window and parent still exist */
939 if (!IntIsWindow(hWnd
) || !IntIsWindow(hWndNewParent
))
942 /* Window must belong to current process */
943 if (Wnd
->OwnerThread
->ThreadsProcess
!= PsGetCurrentProcess())
946 WndOldParent
= IntGetParentObject(Wnd
);
947 hWndOldParent
= (WndOldParent
? WndOldParent
->Self
: NULL
);
949 if (WndNewParent
!= WndOldParent
)
951 IntUnlinkWindow(Wnd
);
953 if (0 == (Wnd
->ExStyle
& WS_EX_TOPMOST
))
955 /* Not a TOPMOST window, put after TOPMOSTs of new parent */
956 IntLockRelatives(WndNewParent
);
957 Sibling
= WndNewParent
->FirstChild
;
958 while (NULL
!= Sibling
&& 0 != (Sibling
->ExStyle
& WS_EX_TOPMOST
))
960 InsertAfter
= Sibling
;
961 Sibling
= Sibling
->NextSibling
;
963 IntUnLockRelatives(WndNewParent
);
965 if (NULL
== InsertAfter
)
967 IntLinkWindow(Wnd
, WndNewParent
, InsertAfter
/*prev sibling*/);
971 IntReferenceWindowObject(InsertAfter
);
972 IntLinkWindow(Wnd
, WndNewParent
, InsertAfter
/*prev sibling*/);
973 IntReleaseWindowObject(InsertAfter
);
976 if (WndNewParent
->Self
!= IntGetDesktopWindow()) /* a child window */
978 if (!(Wnd
->Style
& WS_CHILD
))
980 //if ( Wnd->Menu ) DestroyMenu ( Wnd->menu );
981 IntSetMenu(Wnd
, NULL
, &MenuChanged
);
987 * SetParent additionally needs to make hwnd the top window
988 * in the z-order and send the expected WM_WINDOWPOSCHANGING and
989 * WM_WINDOWPOSCHANGED notification messages.
991 WinPosSetWindowPos(hWnd
, (0 == (Wnd
->ExStyle
& WS_EX_TOPMOST
) ? HWND_TOP
: HWND_TOPMOST
),
992 0, 0, 0, 0, SWP_NOACTIVATE
| SWP_NOMOVE
| SWP_NOSIZE
993 | (WasVisible
? SWP_SHOWWINDOW
: 0));
996 * FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
997 * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE
1001 * Validate that the old parent still exist, since it migth have been
1002 * destroyed during the last callbacks to user-mode
1006 if(!IntIsWindow(WndOldParent
->Self
))
1008 IntReleaseWindowObject(WndOldParent
);
1012 /* don't dereference the window object here, it must be done by the caller
1013 of IntSetParent() */
1014 return WndOldParent
;
1020 IntSetSystemMenu(PWINDOW_OBJECT WindowObject
, PMENU_OBJECT MenuObject
)
1022 PMENU_OBJECT OldMenuObject
;
1023 if(WindowObject
->SystemMenu
)
1025 OldMenuObject
= IntGetMenuObject(WindowObject
->SystemMenu
);
1028 OldMenuObject
->MenuInfo
.Flags
&= ~ MF_SYSMENU
;
1029 IntReleaseMenuObject(OldMenuObject
);
1035 /* FIXME check window style, propably return FALSE ? */
1036 WindowObject
->SystemMenu
= MenuObject
->MenuInfo
.Self
;
1037 MenuObject
->MenuInfo
.Flags
|= MF_SYSMENU
;
1040 WindowObject
->SystemMenu
= (HMENU
)0;
1046 /* unlink the window from siblings and parent. children are kept in place. */
1048 IntUnlinkWindow(PWINDOW_OBJECT Wnd
)
1050 PWINDOW_OBJECT WndParent
;
1052 IntLockRelatives(Wnd
);
1053 if((WndParent
= IntGetWindowObject(Wnd
->Parent
)))
1055 IntLockRelatives(WndParent
);
1058 if (Wnd
->NextSibling
) Wnd
->NextSibling
->PrevSibling
= Wnd
->PrevSibling
;
1059 else if (WndParent
&& WndParent
->LastChild
== Wnd
) WndParent
->LastChild
= Wnd
->PrevSibling
;
1061 if (Wnd
->PrevSibling
) Wnd
->PrevSibling
->NextSibling
= Wnd
->NextSibling
;
1062 else if (WndParent
&& WndParent
->FirstChild
== Wnd
) WndParent
->FirstChild
= Wnd
->NextSibling
;
1066 IntUnLockRelatives(WndParent
);
1067 IntReleaseWindowObject(WndParent
);
1069 Wnd
->PrevSibling
= Wnd
->NextSibling
= Wnd
->Parent
= NULL
;
1070 IntUnLockRelatives(Wnd
);
1073 /* FUNCTIONS *****************************************************************/
1079 NtUserAlterWindowStyle(DWORD Unknown0
,
1090 * As best as I can figure, this function is used by EnumWindows,
1091 * EnumChildWindows, EnumDesktopWindows, & EnumThreadWindows.
1093 * It's supposed to build a list of HWNDs to return to the caller.
1094 * We can figure out what kind of list by what parameters are
1102 NtUserBuildHwndList(
1113 /* FIXME handle bChildren */
1116 PWINDOW_OBJECT WindowObject
= NULL
;
1117 PWINDOW_OBJECT Child
;
1119 WindowObject
= IntGetWindowObject ( hwndParent
);
1120 if ( !WindowObject
)
1122 DPRINT("Bad window handle 0x%x\n", hwndParent
);
1123 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
1127 IntLockRelatives(WindowObject
);
1128 Child
= WindowObject
->FirstChild
;
1131 if ( pWnd
&& dwCount
< nBufSize
)
1132 pWnd
[dwCount
] = Child
->Self
;
1134 Child
= Child
->NextSibling
;
1136 IntUnLockRelatives(WindowObject
);
1137 IntReleaseWindowObject ( WindowObject
);
1139 else if ( dwThreadId
)
1142 struct _ETHREAD
* Thread
;
1143 struct _EPROCESS
* ThreadsProcess
;
1144 struct _W32PROCESS
* Win32Process
;
1145 struct _WINSTATION_OBJECT
* WindowStation
;
1146 PUSER_HANDLE_TABLE HandleTable
;
1147 PLIST_ENTRY Current
;
1148 PUSER_HANDLE_BLOCK Block
= NULL
;
1151 Status
= PsLookupThreadByThreadId ( (PVOID
)dwThreadId
, &Thread
);
1152 if ( !NT_SUCCESS(Status
) || !Thread
)
1154 DPRINT("Bad ThreadId 0x%x\n", dwThreadId
);
1155 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1158 ThreadsProcess
= Thread
->ThreadsProcess
;
1159 ASSERT(ThreadsProcess
);
1160 Win32Process
= ThreadsProcess
->Win32Process
;
1161 ASSERT(Win32Process
);
1162 WindowStation
= Win32Process
->WindowStation
;
1163 ASSERT(WindowStation
);
1164 HandleTable
= (PUSER_HANDLE_TABLE
)(WindowStation
->HandleTable
);
1165 ASSERT(HandleTable
);
1167 ObDereferenceObject(Thread
);
1169 ObmpLockHandleTable(HandleTable
);
1171 Current
= HandleTable
->ListHead
.Flink
;
1172 while ( Current
!= &HandleTable
->ListHead
)
1174 Block
= CONTAINING_RECORD(Current
, USER_HANDLE_BLOCK
, ListEntry
);
1175 for ( i
= 0; i
< HANDLE_BLOCK_ENTRIES
; i
++ )
1177 PVOID ObjectBody
= Block
->Handles
[i
].ObjectBody
;
1180 if ( pWnd
&& dwCount
< nBufSize
)
1183 (HWND
)IntReferenceWindowObject(ObjectBody
);
1188 Current
= Current
->Flink
;
1191 ObmpUnlockHandleTable(HandleTable
);
1195 PDESKTOP_OBJECT DesktopObject
= NULL
;
1197 PWINDOW_OBJECT Child
, WndDesktop
;
1201 DesktopObject
= IntGetDesktopObject ( hDesktop
);
1204 DesktopObject
= IntGetActiveDesktop();
1207 DPRINT("Bad desktop handle 0x%x\n", hDesktop
);
1208 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1212 KeAcquireSpinLock ( &DesktopObject
->Lock
, &OldIrql
);
1214 WndDesktop
= IntGetWindowObject(DesktopObject
->DesktopWindow
);
1215 Child
= (WndDesktop
? WndDesktop
->FirstChild
: NULL
);
1218 if ( pWnd
&& dwCount
< nBufSize
)
1219 pWnd
[dwCount
] = Child
->Self
;
1221 Child
= Child
->NextSibling
;
1223 KeReleaseSpinLock ( &DesktopObject
->Lock
, OldIrql
);
1234 /* FIXME - NEEDS TO BE FIXED - UNSAFE !!! */
1236 NtUserChildWindowFromPointEx(HWND hwndParent
,
1241 PWINDOW_OBJECT pParent
, pCurrent
, pLast
, pPar
;
1244 BOOL bFirstRun
= TRUE
;
1248 pParent
= IntGetWindowObject(hwndParent
);
1251 IntLockRelatives(pParent
);
1253 pLast
= IntGetWindowObject(pParent
->LastChild
->Self
);
1254 pCurrent
= IntGetWindowObject(pParent
->FirstChild
->Self
);
1260 pCurrent
= IntGetWindowObject(pCurrent
->NextSibling
->Self
);
1267 IntUnLockRelatives(pParent
);
1270 if(!(pPar
= IntGetWindowObject(pCurrent
->Parent
)))
1272 IntUnLockRelatives(pParent
);
1275 rc
.left
= pCurrent
->WindowRect
.left
- pPar
->ClientRect
.left
;
1276 rc
.top
= pCurrent
->WindowRect
.top
- pPar
->ClientRect
.top
;
1277 rc
.right
= rc
.left
+ (pCurrent
->WindowRect
.right
- pCurrent
->WindowRect
.left
);
1278 rc
.bottom
= rc
.top
+ (pCurrent
->WindowRect
.bottom
- pCurrent
->WindowRect
.top
);
1279 DbgPrint("Rect: %i,%i,%i,%i\n",rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
1280 IntReleaseWindowObject(pPar
);
1281 if (POINT_IN_RECT(p
,rc
)) /* Found a match */
1283 if ( (uiFlags
& CWP_SKIPDISABLED
) && (pCurrent
->Style
& WS_DISABLED
) )
1285 if( (uiFlags
& CWP_SKIPTRANSPARENT
) && (pCurrent
->ExStyle
& WS_EX_TRANSPARENT
) )
1287 if( (uiFlags
& CWP_SKIPINVISIBLE
) && !(pCurrent
->Style
& WS_VISIBLE
) )
1290 IntUnLockRelatives(pParent
);
1291 return pCurrent
->Self
;
1294 while(pCurrent
!= pLast
);
1296 IntUnLockRelatives(pParent
);
1299 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1310 NtUserCreateWindowEx(DWORD dwExStyle
,
1311 PUNICODE_STRING lpClassName
,
1312 PUNICODE_STRING lpWindowName
,
1320 HINSTANCE hInstance
,
1323 BOOL bUnicodeWindow
)
1325 PWINSTATION_OBJECT WinStaObject
;
1326 PWNDCLASS_OBJECT ClassObject
;
1327 PWINDOW_OBJECT WindowObject
;
1328 PWINDOW_OBJECT ParentWindow
, OwnerWindow
;
1329 HWND ParentWindowHandle
;
1330 HWND OwnerWindowHandle
;
1331 PMENU_OBJECT SystemMenu
;
1332 UNICODE_STRING WindowName
;
1336 POINT MaxSize
, MaxPos
, MinTrack
, MaxTrack
;
1341 CBT_CREATEWNDW CbtCreate
;
1345 DPRINT("NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x
, y
, nWidth
, nHeight
);
1347 if (! RtlCreateUnicodeString(&WindowName
,
1348 NULL
== lpWindowName
->Buffer
?
1349 L
"" : lpWindowName
->Buffer
))
1351 SetLastNtError(STATUS_INSUFFICIENT_RESOURCES
);
1355 ParentWindowHandle
= PsGetWin32Thread()->Desktop
->DesktopWindow
;
1356 OwnerWindowHandle
= NULL
;
1358 if (hWndParent
== HWND_MESSAGE
)
1361 * native ole32.OleInitialize uses HWND_MESSAGE to create the
1362 * message window (style: WS_POPUP|WS_DISABLED)
1366 else if (hWndParent
)
1368 if ((dwStyle
& (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
1369 ParentWindowHandle
= hWndParent
;
1371 OwnerWindowHandle
= NtUserGetAncestor(hWndParent
, GA_ROOT
);
1373 else if ((dwStyle
& (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
1375 RtlFreeUnicodeString(&WindowName
);
1376 return (HWND
)0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
1379 if (NULL
!= ParentWindowHandle
)
1381 ParentWindow
= IntGetWindowObject(ParentWindowHandle
);
1385 ParentWindow
= NULL
;
1388 /* FIXME: parent must belong to the current process */
1390 /* Check the class. */
1391 Status
= ClassReferenceClassByNameOrAtom(&ClassObject
, lpClassName
->Buffer
);
1392 if (!NT_SUCCESS(Status
))
1394 RtlFreeUnicodeString(&WindowName
);
1395 if (NULL
!= ParentWindow
)
1397 IntReleaseWindowObject(ParentWindow
);
1402 /* Check the window station. */
1403 DPRINT("IoGetCurrentProcess() %X\n", IoGetCurrentProcess());
1404 DPRINT("PROCESS_WINDOW_STATION %X\n", PROCESS_WINDOW_STATION());
1405 Status
= IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
1409 if (!NT_SUCCESS(Status
))
1411 ObmDereferenceObject(ClassObject
);
1412 RtlFreeUnicodeString(&WindowName
);
1413 if (NULL
!= ParentWindow
)
1415 IntReleaseWindowObject(ParentWindow
);
1417 DPRINT("Validation of window station handle (0x%X) failed\n",
1418 PROCESS_WINDOW_STATION());
1422 /* Create the window object. */
1423 WindowObject
= (PWINDOW_OBJECT
)
1424 ObmCreateObject(PsGetWin32Process()->WindowStation
->HandleTable
, &Handle
,
1425 otWindow
, sizeof(WINDOW_OBJECT
) + ClassObject
->cbWndExtra
1428 DPRINT("Created object with handle %X\n", Handle
);
1431 ObDereferenceObject(WinStaObject
);
1432 ObmDereferenceObject(ClassObject
);
1433 RtlFreeUnicodeString(&WindowName
);
1434 if (NULL
!= ParentWindow
)
1436 IntReleaseWindowObject(ParentWindow
);
1438 SetLastNtError(STATUS_INSUFFICIENT_RESOURCES
);
1441 ObDereferenceObject(WinStaObject
);
1443 if (NULL
== PsGetWin32Thread()->Desktop
->DesktopWindow
)
1445 /* If there is no desktop window yet, we must be creating it */
1446 PsGetWin32Thread()->Desktop
->DesktopWindow
= Handle
;
1450 * Fill out the structure describing it.
1452 WindowObject
->Class
= ClassObject
;
1453 WindowObject
->ExStyle
= dwExStyle
;
1454 WindowObject
->Style
= dwStyle
& ~WS_VISIBLE
;
1455 DPRINT("1: Style is now %d\n", WindowObject
->Style
);
1457 WindowObject
->SystemMenu
= (HMENU
)0;
1458 WindowObject
->ContextHelpId
= 0;
1459 WindowObject
->IDMenu
= 0;
1460 WindowObject
->Instance
= hInstance
;
1461 WindowObject
->Self
= Handle
;
1462 if (0 != (dwStyle
& WS_CHILD
))
1464 WindowObject
->IDMenu
= (UINT
) hMenu
;
1468 IntSetMenu(WindowObject
, hMenu
, &MenuChanged
);
1470 WindowObject
->MessageQueue
= PsGetWin32Thread()->MessageQueue
;
1471 WindowObject
->Parent
= (ParentWindow
? ParentWindow
->Self
: NULL
);
1472 if((OwnerWindow
= IntGetWindowObject(OwnerWindowHandle
)))
1474 WindowObject
->Owner
= OwnerWindowHandle
;
1475 IntReleaseWindowObject(OwnerWindow
);
1478 WindowObject
->Owner
= NULL
;
1479 WindowObject
->UserData
= 0;
1480 if ((((DWORD
)ClassObject
->lpfnWndProcA
& 0xFFFF0000) != 0xFFFF0000)
1481 && (((DWORD
)ClassObject
->lpfnWndProcW
& 0xFFFF0000) != 0xFFFF0000))
1483 WindowObject
->Unicode
= bUnicodeWindow
;
1487 WindowObject
->Unicode
= ClassObject
->Unicode
;
1489 WindowObject
->WndProcA
= ClassObject
->lpfnWndProcA
;
1490 WindowObject
->WndProcW
= ClassObject
->lpfnWndProcW
;
1491 WindowObject
->OwnerThread
= PsGetCurrentThread();
1492 WindowObject
->FirstChild
= NULL
;
1493 WindowObject
->LastChild
= NULL
;
1494 WindowObject
->PrevSibling
= NULL
;
1495 WindowObject
->NextSibling
= NULL
;
1497 /* extra window data */
1498 if (ClassObject
->cbWndExtra
!= 0)
1500 WindowObject
->ExtraData
= (PCHAR
)(WindowObject
+ 1);
1501 WindowObject
->ExtraDataSize
= ClassObject
->cbWndExtra
;
1502 RtlZeroMemory(WindowObject
->ExtraData
, WindowObject
->ExtraDataSize
);
1506 WindowObject
->ExtraData
= NULL
;
1507 WindowObject
->ExtraDataSize
= 0;
1510 InitializeListHead(&WindowObject
->PropListHead
);
1511 ExInitializeFastMutex(&WindowObject
->PropListLock
);
1512 ExInitializeFastMutex(&WindowObject
->RelativesLock
);
1513 ExInitializeFastMutex(&WindowObject
->UpdateLock
);
1515 RtlInitUnicodeString(&WindowObject
->WindowName
, WindowName
.Buffer
);
1517 /* Correct the window style. */
1518 if (!(dwStyle
& WS_CHILD
))
1520 WindowObject
->Style
|= WS_CLIPSIBLINGS
;
1521 DPRINT("3: Style is now %d\n", WindowObject
->Style
);
1522 if (!(dwStyle
& WS_POPUP
))
1524 WindowObject
->Style
|= WS_CAPTION
;
1525 WindowObject
->Flags
|= WINDOWOBJECT_NEED_SIZE
;
1526 DPRINT("4: Style is now %d\n", WindowObject
->Style
);
1527 /* FIXME: Note the window needs a size. */
1531 /* create system menu */
1532 if((WindowObject
->Style
& WS_SYSMENU
) && (WindowObject
->Style
& WS_CAPTION
))
1534 SystemMenu
= IntGetSystemMenu(WindowObject
, TRUE
, TRUE
);
1537 WindowObject
->SystemMenu
= SystemMenu
->MenuInfo
.Self
;
1538 IntReleaseMenuObject(SystemMenu
);
1542 /* Insert the window into the thread's window list. */
1543 IntLockThreadWindows(PsGetWin32Thread());
1544 InsertTailList (&PsGetWin32Thread()->WindowListHead
,
1545 &WindowObject
->ThreadListEntry
);
1546 IntUnLockThreadWindows(PsGetWin32Thread());
1548 /* Allocate a DCE for this window. */
1549 if (dwStyle
& CS_OWNDC
)
1551 WindowObject
->Dce
= DceAllocDCE(WindowObject
->Self
, DCE_WINDOW_DC
);
1553 /* FIXME: Handle "CS_CLASSDC" */
1555 /* Initialize the window dimensions. */
1556 WindowObject
->WindowRect
.left
= x
;
1557 WindowObject
->WindowRect
.top
= y
;
1558 WindowObject
->WindowRect
.right
= x
+ nWidth
;
1559 WindowObject
->WindowRect
.bottom
= y
+ nHeight
;
1560 if (0 != (WindowObject
->Style
& WS_CHILD
) && ParentWindow
)
1562 NtGdiOffsetRect(&(WindowObject
->WindowRect
), ParentWindow
->ClientRect
.left
,
1563 ParentWindow
->ClientRect
.top
);
1565 WindowObject
->ClientRect
= WindowObject
->WindowRect
;
1567 Cs
.lpCreateParams
= lpParam
;
1568 Cs
.hInstance
= hInstance
;
1570 Cs
.hwndParent
= ParentWindowHandle
;
1576 Cs
.lpszName
= lpWindowName
->Buffer
;
1577 Cs
.lpszClass
= lpClassName
->Buffer
;
1578 Cs
.dwExStyle
= dwExStyle
;
1579 CbtCreate
.lpcs
= &Cs
;
1580 CbtCreate
.hwndInsertAfter
= HWND_TOP
;
1581 if (HOOK_CallHooks(WH_CBT
, HCBT_CREATEWND
, (WPARAM
) Handle
, (LPARAM
) &CbtCreate
))
1583 if (NULL
!= ParentWindow
)
1585 IntReleaseWindowObject(ParentWindow
);
1587 DPRINT1("CBT-hook returned !0\n");
1592 * Get the size and position of the window.
1594 if ((dwStyle
& WS_THICKFRAME
) || !(dwStyle
& (WS_POPUP
| WS_CHILD
)))
1596 POINT MaxSize
, MaxPos
, MinTrack
, MaxTrack
;
1598 /* WinPosGetMinMaxInfo sends the WM_GETMINMAXINFO message */
1599 WinPosGetMinMaxInfo(WindowObject
, &MaxSize
, &MaxPos
, &MinTrack
,
1601 if (MaxSize
.x
< nWidth
) nWidth
= MaxSize
.x
;
1602 if (MaxSize
.y
< nHeight
) nHeight
= MaxSize
.y
;
1603 if (nWidth
< MinTrack
.x
) nWidth
= MinTrack
.x
;
1604 if (nHeight
< MinTrack
.y
) nHeight
= MinTrack
.y
;
1605 if (nWidth
< 0) nWidth
= 0;
1606 if (nHeight
< 0) nHeight
= 0;
1609 WindowObject
->WindowRect
.left
= x
;
1610 WindowObject
->WindowRect
.top
= y
;
1611 WindowObject
->WindowRect
.right
= x
+ nWidth
;
1612 WindowObject
->WindowRect
.bottom
= y
+ nHeight
;
1613 if (0 != (WindowObject
->Style
& WS_CHILD
) && ParentWindow
)
1615 NtGdiOffsetRect(&(WindowObject
->WindowRect
), ParentWindow
->ClientRect
.left
,
1616 ParentWindow
->ClientRect
.top
);
1618 WindowObject
->ClientRect
= WindowObject
->WindowRect
;
1620 /* FIXME: Initialize the window menu. */
1622 /* Initialize the window's scrollbars */
1623 if (dwStyle
& WS_VSCROLL
)
1625 WindowObject
->Style
&= ~WS_VSCROLL
;
1626 NtUserShowScrollBar(WindowObject
->Self
, SB_VERT
, TRUE
);
1628 if (dwStyle
& WS_HSCROLL
)
1630 WindowObject
->Style
&= ~WS_HSCROLL
;
1631 NtUserShowScrollBar(WindowObject
->Self
, SB_HORZ
, TRUE
);
1634 /* Send a NCCREATE message. */
1640 DPRINT("[win32k.window] NtUserCreateWindowEx style %d, exstyle %d, parent %d\n", Cs
.style
, Cs
.dwExStyle
, Cs
.hwndParent
);
1641 DPRINT("NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x
, y
, nWidth
, nHeight
);
1642 DPRINT("NtUserCreateWindowEx(): About to send NCCREATE message.\n");
1643 Result
= IntSendMessage(WindowObject
->Self
, WM_NCCREATE
, 0, (LPARAM
) &Cs
);
1646 /* FIXME: Cleanup. */
1647 if (NULL
!= ParentWindow
)
1649 IntReleaseWindowObject(ParentWindow
);
1651 DPRINT("NtUserCreateWindowEx(): NCCREATE message failed.\n");
1655 /* Calculate the non-client size. */
1656 MaxPos
.x
= WindowObject
->WindowRect
.left
;
1657 MaxPos
.y
= WindowObject
->WindowRect
.top
;
1658 DPRINT("NtUserCreateWindowEx(): About to get non-client size.\n");
1659 /* WinPosGetNonClientSize SENDS THE WM_NCCALCSIZE message */
1660 Result
= WinPosGetNonClientSize(WindowObject
->Self
,
1661 &WindowObject
->WindowRect
,
1662 &WindowObject
->ClientRect
);
1663 NtGdiOffsetRect(&WindowObject
->WindowRect
,
1664 MaxPos
.x
- WindowObject
->WindowRect
.left
,
1665 MaxPos
.y
- WindowObject
->WindowRect
.top
);
1667 if (NULL
!= ParentWindow
)
1669 /* link the window into the parent's child list */
1670 if ((dwStyle
& (WS_CHILD
|WS_MAXIMIZE
)) == WS_CHILD
)
1672 PWINDOW_OBJECT PrevSibling
;
1673 IntLockRelatives(ParentWindow
);
1674 if((PrevSibling
= ParentWindow
->LastChild
))
1675 IntReferenceWindowObject(PrevSibling
);
1676 IntUnLockRelatives(ParentWindow
);
1677 /* link window as bottom sibling */
1678 IntLinkWindow(WindowObject
, ParentWindow
, PrevSibling
/*prev sibling*/);
1680 IntReleaseWindowObject(PrevSibling
);
1684 /* link window as top sibling (but after topmost siblings) */
1685 PWINDOW_OBJECT InsertAfter
, Sibling
;
1686 if (0 == (dwExStyle
& WS_EX_TOPMOST
))
1688 IntLockRelatives(ParentWindow
);
1690 Sibling
= ParentWindow
->FirstChild
;
1691 while (NULL
!= Sibling
&& 0 != (Sibling
->ExStyle
& WS_EX_TOPMOST
))
1693 InsertAfter
= Sibling
;
1694 Sibling
= Sibling
->NextSibling
;
1696 IntUnLockRelatives(ParentWindow
);
1702 if (NULL
!= InsertAfter
)
1704 IntReferenceWindowObject(InsertAfter
);
1706 IntLinkWindow(WindowObject
, ParentWindow
, InsertAfter
/* prev sibling */);
1707 if (NULL
!= InsertAfter
)
1709 IntReleaseWindowObject(InsertAfter
);
1714 /* Send the WM_CREATE message. */
1715 DPRINT("NtUserCreateWindowEx(): about to send CREATE message.\n");
1716 Result
= IntSendMessage(WindowObject
->Self
, WM_CREATE
, 0, (LPARAM
) &Cs
);
1717 if (Result
== (LRESULT
)-1)
1719 /* FIXME: Cleanup. */
1720 if (NULL
!= ParentWindow
)
1722 IntReleaseWindowObject(ParentWindow
);
1724 DPRINT("NtUserCreateWindowEx(): send CREATE message failed.\n");
1728 /* Send move and size messages. */
1729 if (!(WindowObject
->Flags
& WINDOWOBJECT_NEED_SIZE
))
1733 DPRINT("NtUserCreateWindow(): About to send WM_SIZE\n");
1735 if ((WindowObject
->ClientRect
.right
- WindowObject
->ClientRect
.left
) < 0 ||
1736 (WindowObject
->ClientRect
.bottom
- WindowObject
->ClientRect
.top
) < 0)
1737 DPRINT("Sending bogus WM_SIZE\n");
1739 lParam
= MAKE_LONG(WindowObject
->ClientRect
.right
-
1740 WindowObject
->ClientRect
.left
,
1741 WindowObject
->ClientRect
.bottom
-
1742 WindowObject
->ClientRect
.top
);
1743 IntSendMessage(WindowObject
->Self
, WM_SIZE
, SIZE_RESTORED
,
1746 DPRINT("NtUserCreateWindow(): About to send WM_MOVE\n");
1748 if (0 != (WindowObject
->Style
& WS_CHILD
) && ParentWindow
)
1750 lParam
= MAKE_LONG(WindowObject
->ClientRect
.left
- ParentWindow
->ClientRect
.left
,
1751 WindowObject
->ClientRect
.top
- ParentWindow
->ClientRect
.top
);
1755 lParam
= MAKE_LONG(WindowObject
->ClientRect
.left
,
1756 WindowObject
->ClientRect
.top
);
1758 IntSendMessage(WindowObject
->Self
, WM_MOVE
, 0, lParam
);
1761 /* Show or maybe minimize or maximize the window. */
1762 if (WindowObject
->Style
& (WS_MINIMIZE
| WS_MAXIMIZE
))
1767 SwFlag
= (WindowObject
->Style
& WS_MINIMIZE
) ? SW_MINIMIZE
:
1769 WinPosMinMaximize(WindowObject
, SwFlag
, &NewPos
);
1771 ((WindowObject
->Style
& WS_CHILD
) || NtUserGetActiveWindow()) ?
1772 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
:
1773 SWP_NOZORDER
| SWP_FRAMECHANGED
;
1774 DPRINT("NtUserCreateWindow(): About to minimize/maximize\n");
1775 DPRINT("%d,%d %dx%d\n", NewPos
.left
, NewPos
.top
, NewPos
.right
, NewPos
.bottom
);
1776 WinPosSetWindowPos(WindowObject
->Self
, 0, NewPos
.left
, NewPos
.top
,
1777 NewPos
.right
, NewPos
.bottom
, SwFlag
);
1780 /* Notify the parent window of a new child. */
1781 if ((WindowObject
->Style
& WS_CHILD
) &&
1782 (!(WindowObject
->ExStyle
& WS_EX_NOPARENTNOTIFY
)) && ParentWindow
)
1784 DPRINT("NtUserCreateWindow(): About to notify parent\n");
1785 IntSendMessage(ParentWindow
->Self
,
1787 MAKEWPARAM(WM_CREATE
, WindowObject
->IDMenu
),
1788 (LPARAM
)WindowObject
->Self
);
1791 if (NULL
!= ParentWindow
)
1793 IntReleaseWindowObject(ParentWindow
);
1796 if (dwStyle
& WS_VISIBLE
)
1798 DPRINT("NtUserCreateWindow(): About to show window\n");
1799 WinPosShowWindow(WindowObject
->Self
, dwShowMode
);
1802 DPRINT("NtUserCreateWindow(): = %X\n", Handle
);
1803 DPRINT("WindowObject->SystemMenu = 0x%x\n", WindowObject
->SystemMenu
);
1804 return((HWND
)Handle
);
1812 NtUserDeferWindowPos(HDWP WinPosInfo
,
1814 HWND WndInsertAfter
,
1831 NtUserDestroyWindow(HWND Wnd
)
1833 PWINDOW_OBJECT Window
;
1836 Window
= IntGetWindowObject(Wnd
);
1842 /* Check for owner thread and desktop window */
1843 if ((Window
->OwnerThread
!= PsGetCurrentThread()) || IntIsDesktopWindow(Window
))
1845 IntReleaseWindowObject(Window
);
1846 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1850 /* Look whether the focus is within the tree of windows we will
1853 if (!WinPosShowWindow(Wnd
, SW_HIDE
))
1855 if (NtUserGetActiveWindow() == Wnd
)
1857 WinPosActivateOtherWindow(Window
);
1860 IntLockMessageQueue(Window
->MessageQueue
);
1861 if (Window
->MessageQueue
->ActiveWindow
== Window
->Self
)
1862 Window
->MessageQueue
->ActiveWindow
= NULL
;
1863 if (Window
->MessageQueue
->FocusWindow
== Window
->Self
)
1864 Window
->MessageQueue
->FocusWindow
= NULL
;
1865 if (Window
->MessageQueue
->CaptureWindow
== Window
->Self
)
1866 Window
->MessageQueue
->CaptureWindow
= NULL
;
1867 IntUnLockMessageQueue(Window
->MessageQueue
);
1871 if (HOOK_CallHooks(WH_CBT
, HCBT_DESTROYWND
, (WPARAM
) hwnd
, 0, TRUE
))
1877 isChild
= (0 != (Window
->Style
& WS_CHILD
));
1882 if (! USER_IsExitingThread(GetCurrentThreadId()))
1884 send_parent_notify(hwnd
, WM_DESTROY
);
1887 else if (NULL
!= GetWindow(Wnd
, GW_OWNER
))
1889 HOOK_CallHooks( WH_SHELL
, HSHELL_WINDOWDESTROYED
, (WPARAM
)hwnd
, 0L, TRUE
);
1890 /* FIXME: clean up palette - see "Internals" p.352 */
1893 if (! IsWindow(Wnd
))
1899 if (!IntIsWindow(Wnd
))
1904 /* Recursively destroy owned windows */
1909 BOOL GotOne
= FALSE
;
1912 PWINDOW_OBJECT Child
, Desktop
;
1914 Desktop
= IntGetWindowObject(IntGetDesktopWindow());
1915 Children
= IntWinListChildren(Desktop
);
1916 IntReleaseWindowObject(Desktop
);
1919 for (ChildHandle
= Children
; *ChildHandle
; ++ChildHandle
)
1921 Child
= IntGetWindowObject(*ChildHandle
);
1926 if(Child
->Self
== Wnd
)
1928 IntReleaseWindowObject(Child
);
1931 IntLockRelatives(Child
);
1932 if (Child
->Parent
!= Window
->Self
)
1934 IntUnLockRelatives(Child
);
1935 IntReleaseWindowObject(Child
);
1938 IntUnLockRelatives(Child
);
1939 if (IntWndBelongsToThread(Child
, PsGetWin32Thread()))
1941 IntReleaseWindowObject(Child
);
1942 NtUserDestroyWindow(*ChildHandle
);
1946 IntLockRelatives(Child
);
1947 if (Child
->Owner
!= NULL
)
1949 Child
->Owner
= NULL
;
1951 IntUnLockRelatives(Child
);
1952 IntReleaseWindowObject(Child
);
1954 ExFreePool(Children
);
1963 if (!IntIsWindow(Wnd
))
1965 IntReleaseWindowObject(Window
);
1969 /* Destroy the window storage */
1970 IntDestroyWindow(Window
, PsGetWin32Process(), PsGetWin32Thread(), TRUE
);
1972 IntReleaseWindowObject(Window
);
1982 NtUserDrawMenuBarTemp(
1989 /* we'll use this function just for caching the menu bar */
1999 NtUserEndDeferWindowPosEx(DWORD Unknown0
,
2012 NtUserFillWindow(DWORD Unknown0
,
2025 * Searches a window's children for a window with the specified
2028 * hwndParent = The window whose childs are to be searched.
2031 * hwndChildAfter = Search starts after this child window.
2032 * NULL = start from beginning
2034 * ucClassName = Class name to search for
2035 * Reguired parameter.
2037 * ucWindowName = Window name
2038 * ->Buffer == NULL = don't care
2041 * The HWND of the window if it was found, otherwise NULL
2044 * Should use MmCopyFromCaller, we don't want an access violation in here
2051 NtUserFindWindowEx(HWND hwndParent
,
2052 HWND hwndChildAfter
,
2053 PUNICODE_STRING ucClassName
,
2054 PUNICODE_STRING ucWindowName
)
2058 PWINDOW_OBJECT ParentWindow
, WndChildAfter
, WndChild
;
2059 PWNDCLASS_OBJECT classObject
;
2061 // Get a pointer to the class
2062 status
= ClassReferenceClassByNameOrAtom(&classObject
, ucClassName
->Buffer
);
2063 if (!NT_SUCCESS(status
))
2068 // If hwndParent==NULL use the desktop window instead
2070 hwndParent
= PsGetWin32Thread()->Desktop
->DesktopWindow
;
2073 ParentWindow
= IntGetWindowObject(hwndParent
);
2077 ObmDereferenceObject(classObject
);
2081 IntLockRelatives(ParentWindow
);
2085 if (!(WndChildAfter
= IntGetWindowObject(hwndChildAfter
)))
2087 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
2091 /* must be a direct child (not a decendant child)*/
2092 IntLockRelatives(WndChildAfter
);
2093 if (WndChildAfter
->Parent
!= ParentWindow
->Self
)
2095 IntUnLockRelatives(WndChildAfter
);
2096 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2099 IntUnLockRelatives(WndChildAfter
);
2101 WndChild
= WndChildAfter
->NextSibling
;
2105 WndChild
= ParentWindow
->FirstChild
;
2110 if (classObject
== WndChild
->Class
&& (ucWindowName
->Buffer
==NULL
||
2111 RtlCompareUnicodeString (ucWindowName
, &WndChild
->WindowName
, TRUE
) == 0))
2113 windowHandle
= WndChild
->Self
;
2115 IntUnLockRelatives(ParentWindow
);
2116 IntReleaseWindowObject(ParentWindow
);
2117 ObmDereferenceObject (classObject
);
2119 return windowHandle
;
2122 WndChild
= WndChild
->NextSibling
;
2125 IntUnLockRelatives(ParentWindow
);
2127 IntReleaseWindowObject(ParentWindow
);
2128 ObmDereferenceObject (classObject
);
2138 NtUserFlashWindowEx(DWORD Unknown0
)
2150 NtUserGetAncestor(HWND hWnd
, UINT Type
)
2152 PWINDOW_OBJECT Wnd
, WndAncestor
, Parent
;
2155 if (hWnd
== IntGetDesktopWindow())
2160 if (!(Wnd
= IntGetWindowObject(hWnd
)))
2162 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
2170 WndAncestor
= IntGetParentObject(Wnd
);
2183 if(!(Parent
= IntGetParentObject(WndAncestor
)))
2187 if(IntIsDesktopWindow(Parent
))
2189 IntReleaseWindowObject(Parent
);
2193 IntReleaseWindowObject(tmp
);
2194 WndAncestor
= Parent
;
2202 IntReferenceWindowObject(WndAncestor
);
2207 Parent
= IntGetParent(WndAncestor
);
2208 IntReleaseWindowObject(Old
);
2213 WndAncestor
= Parent
;
2220 IntReleaseWindowObject(Wnd
);
2225 hWndAncestor
= (WndAncestor
? WndAncestor
->Self
: NULL
);
2226 IntReleaseWindowObject(Wnd
);
2228 if(WndAncestor
&& (WndAncestor
!= Wnd
))
2229 IntReleaseWindowObject(WndAncestor
);
2231 return hWndAncestor
;
2236 * Returns client window rectangle relative to the upper-left corner of client area.
2238 * \param hWnd window handle.
2239 * \param Rect pointer to the buffer where the coordinates are returned.
2246 NtUserGetClientRect(HWND hWnd
, LPRECT Rect
)
2248 PWINDOW_OBJECT WindowObject
;
2251 if(!(WindowObject
= IntGetWindowObject(hWnd
)))
2253 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
2257 IntGetClientRect(WindowObject
, &SafeRect
);
2258 IntReleaseWindowObject(WindowObject
);
2260 if(!NT_SUCCESS(MmCopyToCaller(Rect
, &SafeRect
, sizeof(RECT
))))
2272 NtUserGetDesktopWindow()
2274 return IntGetDesktopWindow();
2282 NtUserGetInternalWindowPos(DWORD Unknown0
,
2296 NtUserGetLastActivePopup(HWND hWnd
)
2299 * This code can't work, because hWndLastPopup member of WINDOW_OBJECT is
2300 * not changed anywhere.
2301 * -- Filip, 01/nov/2003
2307 IntAcquireWinLockShared();
2309 if (!(Wnd
= IntGetWindowObject(hWnd
)))
2311 IntReleaseWinLock();
2312 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
2316 hWndLastPopup
= Wnd
->hWndLastPopup
;
2318 IntReleaseWinLock();
2320 return hWndLastPopup
;
2329 * The NtUserGetParent function retrieves a handle to the specified window's
2333 * Note that, despite its name, this function can return an owner window
2334 * instead of a parent window.
2341 NtUserGetParent(HWND hWnd
)
2343 PWINDOW_OBJECT Wnd
, WndParent
;
2344 HWND hWndParent
= NULL
;
2346 if (!(Wnd
= IntGetWindowObject(hWnd
)))
2348 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
2352 WndParent
= IntGetParent(Wnd
);
2355 hWndParent
= WndParent
->Self
;
2356 IntReleaseWindowObject(WndParent
);
2359 IntReleaseWindowObject(Wnd
);
2367 * The NtUserSetParent function changes the parent window of the specified
2371 * The new parent window and the child window must belong to the same
2372 * application. If the window identified by the hWndChild parameter is
2373 * visible, the system performs the appropriate redrawing and repainting.
2374 * For compatibility reasons, NtUserSetParent does not modify the WS_CHILD
2375 * or WS_POPUP window styles of the window whose parent is being changed.
2382 NtUserSetParent(HWND hWndChild
, HWND hWndNewParent
)
2384 PWINDOW_OBJECT Wnd
= NULL
, WndParent
= NULL
, WndOldParent
;
2385 HWND hWndOldParent
= NULL
;
2387 if (IntIsBroadcastHwnd(hWndChild
) || IntIsBroadcastHwnd(hWndNewParent
))
2389 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2393 if (hWndChild
== IntGetDesktopWindow())
2395 SetLastWin32Error(ERROR_ACCESS_DENIED
);
2401 if (!(WndParent
= IntGetWindowObject(hWndNewParent
)))
2403 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
2409 if (!(WndParent
= IntGetWindowObject(IntGetDesktopWindow())))
2411 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
2416 if (!(Wnd
= IntGetWindowObject(hWndChild
)))
2418 IntReleaseWindowObject(WndParent
);
2419 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
2423 WndOldParent
= IntSetParent(Wnd
, WndParent
);
2427 hWndOldParent
= WndOldParent
->Self
;
2428 IntReleaseWindowObject(WndOldParent
);
2431 IntReleaseWindowObject(Wnd
);
2432 IntReleaseWindowObject(WndParent
);
2434 return hWndOldParent
;
2438 * NtUserGetShellWindow
2440 * Returns a handle to shell window that was set by NtUserSetShellWindowEx.
2447 NtUserGetShellWindow()
2449 PWINSTATION_OBJECT WinStaObject
;
2452 NTSTATUS Status
= IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
2457 if (!NT_SUCCESS(Status
))
2459 SetLastNtError(Status
);
2463 Ret
= (HWND
)WinStaObject
->ShellWindow
;
2465 ObDereferenceObject(WinStaObject
);
2470 * NtUserSetShellWindowEx
2472 * This is undocumented function to set global shell window. The global
2473 * shell window has special handling of window position.
2480 NtUserSetShellWindowEx(HWND hwndShell
, HWND hwndListView
)
2482 PWINSTATION_OBJECT WinStaObject
;
2484 NTSTATUS Status
= IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
2489 if (!NT_SUCCESS(Status
))
2491 SetLastNtError(Status
);
2496 * Test if we are permitted to change the shell window.
2498 if (WinStaObject
->ShellWindow
)
2500 ObDereferenceObject(WinStaObject
);
2505 * Move shell window into background.
2507 if (hwndListView
&& hwndListView
!= hwndShell
)
2510 * Disabled for now to get Explorer working.
2511 * -- Filip, 01/nov/2003
2514 WinPosSetWindowPos(hwndListView
, HWND_BOTTOM
, 0, 0, 0, 0, SWP_NOMOVE
|SWP_NOSIZE
|SWP_NOACTIVATE
);
2517 if (NtUserGetWindowLong(hwndListView
, GWL_EXSTYLE
, FALSE
) & WS_EX_TOPMOST
)
2519 ObDereferenceObject(WinStaObject
);
2524 if (NtUserGetWindowLong(hwndShell
, GWL_EXSTYLE
, FALSE
) & WS_EX_TOPMOST
)
2526 ObDereferenceObject(WinStaObject
);
2530 WinPosSetWindowPos(hwndShell
, HWND_BOTTOM
, 0, 0, 0, 0, SWP_NOMOVE
|SWP_NOSIZE
|SWP_NOACTIVATE
);
2532 WinStaObject
->ShellWindow
= hwndShell
;
2533 WinStaObject
->ShellListView
= hwndListView
;
2535 ObDereferenceObject(WinStaObject
);
2540 * NtUserGetSystemMenu
2542 * The NtUserGetSystemMenu function allows the application to access the
2543 * window menu (also known as the system menu or the control menu) for
2544 * copying and modifying.
2548 * Handle to the window that will own a copy of the window menu.
2550 * Specifies the action to be taken. If this parameter is FALSE,
2551 * NtUserGetSystemMenu returns a handle to the copy of the window menu
2552 * currently in use. The copy is initially identical to the window menu
2553 * but it can be modified.
2554 * If this parameter is TRUE, GetSystemMenu resets the window menu back
2555 * to the default state. The previous window menu, if any, is destroyed.
2558 * If the bRevert parameter is FALSE, the return value is a handle to a
2559 * copy of the window menu. If the bRevert parameter is TRUE, the return
2567 NtUserGetSystemMenu(HWND hWnd
, BOOL bRevert
)
2570 PWINDOW_OBJECT WindowObject
;
2571 PMENU_OBJECT MenuObject
;
2573 WindowObject
= IntGetWindowObject((HWND
)hWnd
);
2574 if (WindowObject
== NULL
)
2576 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
2580 MenuObject
= IntGetSystemMenu(WindowObject
, bRevert
, FALSE
);
2583 Result
= MenuObject
->MenuInfo
.Self
;
2584 IntReleaseMenuObject(MenuObject
);
2587 IntReleaseWindowObject(WindowObject
);
2592 * NtUserSetSystemMenu
2599 NtUserSetSystemMenu(HWND hWnd
, HMENU hMenu
)
2601 BOOL Result
= FALSE
;
2602 PWINDOW_OBJECT WindowObject
;
2603 PMENU_OBJECT MenuObject
;
2605 WindowObject
= IntGetWindowObject(hWnd
);
2608 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
2615 * Assign new menu handle.
2617 MenuObject
= IntGetMenuObject(hMenu
);
2620 IntReleaseWindowObject(WindowObject
);
2621 SetLastWin32Error(ERROR_INVALID_MENU_HANDLE
);
2625 Result
= IntSetSystemMenu(WindowObject
, MenuObject
);
2627 IntReleaseMenuObject(MenuObject
);
2630 IntReleaseWindowObject(WindowObject
);
2638 * The NtUserGetWindow function retrieves a handle to a window that has the
2639 * specified relationship (Z order or owner) to the specified window.
2646 NtUserGetWindow(HWND hWnd
, UINT Relationship
)
2648 PWINDOW_OBJECT WindowObject
, Parent
;
2649 HWND hWndResult
= NULL
;
2651 if (!(WindowObject
= IntGetWindowObject(hWnd
)))
2653 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
2657 switch (Relationship
)
2660 if((Parent
= IntGetParentObject(WindowObject
)))
2662 IntLockRelatives(Parent
);
2663 if (Parent
->FirstChild
)
2664 hWndResult
= Parent
->FirstChild
->Self
;
2665 IntUnLockRelatives(Parent
);
2666 IntReleaseWindowObject(Parent
);
2671 if((Parent
= IntGetParentObject(WindowObject
)))
2673 IntLockRelatives(Parent
);
2674 if (Parent
->LastChild
)
2675 hWndResult
= Parent
->LastChild
->Self
;
2676 IntUnLockRelatives(Parent
);
2677 IntReleaseWindowObject(Parent
);
2682 IntLockRelatives(WindowObject
);
2683 if (WindowObject
->NextSibling
)
2684 hWndResult
= WindowObject
->NextSibling
->Self
;
2685 IntUnLockRelatives(WindowObject
);
2689 IntLockRelatives(WindowObject
);
2690 if (WindowObject
->PrevSibling
)
2691 hWndResult
= WindowObject
->PrevSibling
->Self
;
2692 IntUnLockRelatives(WindowObject
);
2696 IntLockRelatives(WindowObject
);
2697 if((Parent
= IntGetWindowObject(WindowObject
->Owner
)))
2699 hWndResult
= Parent
->Self
;
2700 IntReleaseWindowObject(Parent
);
2702 IntUnLockRelatives(WindowObject
);
2705 IntLockRelatives(WindowObject
);
2706 if (WindowObject
->FirstChild
)
2707 hWndResult
= WindowObject
->FirstChild
->Self
;
2708 IntUnLockRelatives(WindowObject
);
2712 IntReleaseWindowObject(WindowObject
);
2718 * NtUserGetWindowLong
2720 * The NtUserGetWindowLong function retrieves information about the specified
2721 * window. The function also retrieves the 32-bit (long) value at the
2722 * specified offset into the extra window memory.
2729 NtUserGetWindowLong(HWND hWnd
, DWORD Index
, BOOL Ansi
)
2731 PWINDOW_OBJECT WindowObject
, Parent
;
2734 DPRINT("NtUserGetWindowLong(%x,%d,%d)\n", hWnd
, (INT
)Index
, Ansi
);
2736 WindowObject
= IntGetWindowObject(hWnd
);
2737 if (WindowObject
== NULL
)
2739 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
2744 * Only allow CSRSS to mess with the desktop window
2746 if (hWnd
== IntGetDesktopWindow()
2747 && WindowObject
->OwnerThread
->ThreadsProcess
!= PsGetCurrentProcess())
2749 SetLastWin32Error(STATUS_ACCESS_DENIED
);
2753 if ((INT
)Index
>= 0)
2755 if ((Index
+ sizeof(LONG
)) > WindowObject
->ExtraDataSize
)
2757 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2760 Result
= *((LONG
*)(WindowObject
->ExtraData
+ Index
));
2767 Result
= WindowObject
->ExStyle
;
2771 Result
= WindowObject
->Style
;
2776 Result
= (LONG
) WindowObject
->WndProcA
;
2778 Result
= (LONG
) WindowObject
->WndProcW
;
2782 Result
= (LONG
) WindowObject
->Instance
;
2785 case GWL_HWNDPARENT
:
2786 IntLockRelatives(WindowObject
);
2787 Parent
= IntGetWindowObject(WindowObject
->Parent
);
2788 IntUnLockRelatives(WindowObject
);
2791 if (Parent
&& Parent
->Self
== IntGetDesktopWindow())
2792 Result
= (LONG
) NtUserGetWindow(WindowObject
->Self
, GW_OWNER
);
2794 Result
= (LONG
) Parent
->Self
;
2795 IntReleaseWindowObject(Parent
);
2800 Result
= (LONG
) WindowObject
->IDMenu
;
2804 Result
= WindowObject
->UserData
;
2808 DPRINT1("NtUserGetWindowLong(): Unsupported index %d\n", Index
);
2809 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2815 IntReleaseWindowObject(WindowObject
);
2821 * NtUserSetWindowLong
2823 * The NtUserSetWindowLong function changes an attribute of the specified
2824 * window. The function also sets the 32-bit (long) value at the specified
2825 * offset into the extra window memory.
2832 NtUserSetWindowLong(HWND hWnd
, DWORD Index
, LONG NewValue
, BOOL Ansi
)
2834 PWINDOW_OBJECT WindowObject
, Parent
;
2835 PW32PROCESS Process
;
2836 PWINSTATION_OBJECT WindowStation
;
2840 if (hWnd
== IntGetDesktopWindow())
2842 SetLastWin32Error(STATUS_ACCESS_DENIED
);
2846 WindowObject
= IntGetWindowObject(hWnd
);
2847 if (WindowObject
== NULL
)
2849 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
2853 if ((INT
)Index
>= 0)
2855 if ((Index
+ sizeof(LONG
)) > WindowObject
->ExtraDataSize
)
2857 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2858 IntReleaseWindowObject(WindowObject
);
2861 OldValue
= *((LONG
*)(WindowObject
->ExtraData
+ Index
));
2862 *((LONG
*)(WindowObject
->ExtraData
+ Index
)) = NewValue
;
2869 OldValue
= (LONG
) WindowObject
->ExStyle
;
2870 Style
.styleOld
= OldValue
;
2871 Style
.styleNew
= NewValue
;
2874 * Remove extended window style bit WS_EX_TOPMOST for shell windows.
2876 Process
= WindowObject
->OwnerThread
->ThreadsProcess
->Win32Process
;
2877 WindowStation
= Process
->WindowStation
;
2880 if (hWnd
== WindowStation
->ShellWindow
|| hWnd
== WindowStation
->ShellListView
)
2881 Style
.styleNew
&= ~WS_EX_TOPMOST
;
2884 IntSendMessage(hWnd
, WM_STYLECHANGING
, GWL_EXSTYLE
, (LPARAM
) &Style
);
2885 WindowObject
->ExStyle
= (DWORD
)Style
.styleNew
;
2886 IntSendMessage(hWnd
, WM_STYLECHANGED
, GWL_EXSTYLE
, (LPARAM
) &Style
);
2890 OldValue
= (LONG
) WindowObject
->Style
;
2891 Style
.styleOld
= OldValue
;
2892 Style
.styleNew
= NewValue
;
2893 IntSendMessage(hWnd
, WM_STYLECHANGING
, GWL_STYLE
, (LPARAM
) &Style
);
2894 WindowObject
->Style
= (DWORD
)Style
.styleNew
;
2895 IntSendMessage(hWnd
, WM_STYLECHANGED
, GWL_STYLE
, (LPARAM
) &Style
);
2899 /* FIXME: should check if window belongs to current process */
2902 OldValue
= (LONG
) WindowObject
->WndProcA
;
2903 WindowObject
->WndProcA
= (WNDPROC
) NewValue
;
2904 WindowObject
->WndProcW
= (WNDPROC
) IntAddWndProcHandle((WNDPROC
)NewValue
,FALSE
);
2905 WindowObject
->Unicode
= FALSE
;
2909 OldValue
= (LONG
) WindowObject
->WndProcW
;
2910 WindowObject
->WndProcW
= (WNDPROC
) NewValue
;
2911 WindowObject
->WndProcA
= (WNDPROC
) IntAddWndProcHandle((WNDPROC
)NewValue
,TRUE
);
2912 WindowObject
->Unicode
= TRUE
;
2917 OldValue
= (LONG
) WindowObject
->Instance
;
2918 WindowObject
->Instance
= (HINSTANCE
) NewValue
;
2921 case GWL_HWNDPARENT
:
2922 Parent
= IntGetParentObject(WindowObject
);
2923 if (Parent
&& (Parent
->Self
== IntGetDesktopWindow()))
2924 OldValue
= (LONG
) IntSetOwner(WindowObject
->Self
, (HWND
) NewValue
);
2926 OldValue
= (LONG
) NtUserSetParent(WindowObject
->Self
, (HWND
) NewValue
);
2928 IntReleaseWindowObject(Parent
);
2932 OldValue
= (LONG
) WindowObject
->IDMenu
;
2933 WindowObject
->IDMenu
= (UINT
) NewValue
;
2937 OldValue
= WindowObject
->UserData
;
2938 WindowObject
->UserData
= NewValue
;
2942 DPRINT1("NtUserSetWindowLong(): Unsupported index %d\n", Index
);
2943 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2949 IntReleaseWindowObject(WindowObject
);
2955 * NtUserSetWindowWord
2957 * Legacy function similar to NtUserSetWindowLong.
2964 NtUserSetWindowWord(HWND hWnd
, INT Index
, WORD NewValue
)
2966 PWINDOW_OBJECT WindowObject
;
2973 case GWL_HWNDPARENT
:
2974 return NtUserSetWindowLong(hWnd
, Index
, (UINT
)NewValue
, TRUE
);
2978 SetLastWin32Error(ERROR_INVALID_INDEX
);
2983 WindowObject
= IntGetWindowObject(hWnd
);
2984 if (WindowObject
== NULL
)
2986 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
2990 if (Index
> WindowObject
->ExtraDataSize
- sizeof(WORD
))
2992 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
2993 IntReleaseWindowObject(WindowObject
);
2997 OldValue
= *((WORD
*)(WindowObject
->ExtraData
+ Index
));
2998 *((WORD
*)(WindowObject
->ExtraData
+ Index
)) = NewValue
;
3000 IntReleaseWindowObject(WindowObject
);
3009 NtUserGetWindowPlacement(HWND hWnd
,
3010 WINDOWPLACEMENT
*lpwndpl
)
3012 PWINDOW_OBJECT WindowObject
;
3013 PINTERNALPOS InternalPos
;
3015 WINDOWPLACEMENT Safepl
;
3018 WindowObject
= IntGetWindowObject(hWnd
);
3019 if (WindowObject
== NULL
)
3021 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
3025 Status
= MmCopyFromCaller(&Safepl
, lpwndpl
, sizeof(WINDOWPLACEMENT
));
3026 if(!NT_SUCCESS(Status
))
3028 SetLastNtError(Status
);
3029 IntReleaseWindowObject(WindowObject
);
3032 if(Safepl
.length
!= sizeof(WINDOWPLACEMENT
))
3034 IntReleaseWindowObject(WindowObject
);
3039 Safepl
.showCmd
= ((WindowObject
->Flags
& WINDOWOBJECT_RESTOREMAX
) ? SW_MAXIMIZE
: SW_SHOWNORMAL
);
3041 Size
.x
= WindowObject
->WindowRect
.left
;
3042 Size
.y
= WindowObject
->WindowRect
.top
;
3043 InternalPos
= WinPosInitInternalPos(WindowObject
, &Size
,
3044 &WindowObject
->WindowRect
);
3047 Safepl
.rcNormalPosition
= InternalPos
->NormalRect
;
3048 Safepl
.ptMinPosition
= InternalPos
->IconPos
;
3049 Safepl
.ptMaxPosition
= InternalPos
->MaxPos
;
3053 IntReleaseWindowObject(WindowObject
);
3057 Status
= MmCopyToCaller(lpwndpl
, &Safepl
, sizeof(WINDOWPLACEMENT
));
3058 if(!NT_SUCCESS(Status
))
3060 SetLastNtError(Status
);
3061 IntReleaseWindowObject(WindowObject
);
3065 IntReleaseWindowObject(WindowObject
);
3071 * Return the dimension of the window in the screen coordinates.
3072 * \param hWnd window handle.
3073 * \param Rect pointer to the buffer where the coordinates are returned.
3079 NtUserGetWindowRect(HWND hWnd
, LPRECT Rect
)
3084 if (!(Wnd
= IntGetWindowObject(hWnd
)))
3086 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
3089 Status
= MmCopyToCaller(Rect
, &Wnd
->WindowRect
, sizeof(RECT
));
3090 if (!NT_SUCCESS(Status
))
3092 IntReleaseWindowObject(Wnd
);
3093 SetLastNtError(Status
);
3097 IntReleaseWindowObject(Wnd
);
3106 NtUserGetWindowThreadProcessId(HWND hWnd
, LPDWORD UnsafePid
)
3111 if (!(Wnd
= IntGetWindowObject(hWnd
)))
3113 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
3117 tid
= (DWORD
)IntGetWndThreadId(Wnd
);
3118 pid
= (DWORD
)IntGetWndProcessId(Wnd
);
3120 if (UnsafePid
) MmCopyToCaller(UnsafePid
, &pid
, sizeof(DWORD
));
3130 NtUserLockWindowUpdate(DWORD Unknown0
)
3150 return NtUserSetWindowPos(hWnd
, 0, X
, Y
, nWidth
, nHeight
,
3151 (bRepaint
? SWP_NOZORDER
| SWP_NOACTIVATE
:
3152 SWP_NOZORDER
| SWP_NOACTIVATE
| SWP_NOREDRAW
));
3156 QueryWindow based on KJK::Hyperion and James Tabor.
3158 0 = QWUniqueProcessId
3159 1 = QWUniqueThreadId
3160 4 = QWIsHung Implements IsHungAppWindow found
3163 9 = QWKillWindow When I called this with hWnd ==
3164 DesktopWindow, it shutdown the system
3171 NtUserQueryWindow(HWND hWnd
, DWORD Index
)
3173 PWINDOW_OBJECT Window
= IntGetWindowObject(hWnd
);
3178 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
3184 case QUERY_WINDOW_UNIQUE_PROCESS_ID
:
3185 Result
= (DWORD
)IntGetWndProcessId(Window
);
3188 case QUERY_WINDOW_UNIQUE_THREAD_ID
:
3189 Result
= (DWORD
)IntGetWndThreadId(Window
);
3192 case QUERY_WINDOW_ISHUNG
:
3193 Result
= (DWORD
)MsqIsHung(Window
->MessageQueue
);
3197 Result
= (DWORD
)NULL
;
3201 IntReleaseWindowObject(Window
);
3211 NtUserRealChildWindowFromPoint(DWORD Unknown0
,
3225 NtUserRegisterWindowMessage(PUNICODE_STRING MessageNameUnsafe
)
3228 PLIST_ENTRY Current
;
3229 PREGISTERED_MESSAGE NewMsg
, RegMsg
;
3230 UINT Msg
= REGISTERED_MESSAGE_MIN
;
3231 UNICODE_STRING MessageName
;
3234 Status
= MmCopyFromCaller(&MessageName
, MessageNameUnsafe
, sizeof(UNICODE_STRING
));
3235 if (! NT_SUCCESS(Status
))
3237 SetLastNtError(Status
);
3241 NewMsg
= ExAllocatePoolWithTag(PagedPool
,
3242 sizeof(REGISTERED_MESSAGE
) +
3247 SetLastNtError(STATUS_NO_MEMORY
);
3251 Status
= MmCopyFromCaller(NewMsg
->MessageName
, MessageName
.Buffer
, MessageName
.Length
);
3252 if (! NT_SUCCESS(Status
))
3255 SetLastNtError(Status
);
3258 NewMsg
->MessageName
[MessageName
.Length
/ sizeof(WCHAR
)] = L
'\0';
3259 if (wcslen(NewMsg
->MessageName
) != MessageName
.Length
/ sizeof(WCHAR
))
3262 SetLastNtError(STATUS_INVALID_PARAMETER
);
3266 Current
= RegisteredMessageListHead
.Flink
;
3267 while (Current
!= &RegisteredMessageListHead
)
3269 RegMsg
= CONTAINING_RECORD(Current
, REGISTERED_MESSAGE
, ListEntry
);
3270 if (0 == wcscmp(NewMsg
->MessageName
, RegMsg
->MessageName
))
3276 Current
= Current
->Flink
;
3279 if (REGISTERED_MESSAGE_MAX
< Msg
)
3282 SetLastNtError(STATUS_INSUFFICIENT_RESOURCES
);
3286 InsertTailList(&RegisteredMessageListHead
, &(NewMsg
->ListEntry
));
3292 * - There's no need to call MmSafe*, because it should be done in kernel.
3293 * - The passed UNICODE_STRING is expected to be NULL-terminated.
3295 return (UINT
)IntAddAtom(MessageNameUnsafe
->Buffer
);
3304 NtUserSetImeOwnerWindow(DWORD Unknown0
,
3317 NtUserSetInternalWindowPos(DWORD Unknown0
,
3333 NtUserSetLayeredWindowAttributes(DWORD Unknown0
,
3348 NtUserSetLogonNotifyWindow(DWORD Unknown0
)
3365 PWINDOW_OBJECT WindowObject
;
3368 WindowObject
= IntGetWindowObject((HWND
) Wnd
);
3369 if (NULL
== WindowObject
)
3371 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
3375 if (! IntSetMenu(WindowObject
, Menu
, &Changed
))
3377 IntReleaseWindowObject(WindowObject
);
3381 IntReleaseWindowObject(WindowObject
);
3383 if (Changed
&& Repaint
)
3385 WinPosSetWindowPos(Wnd
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
|
3386 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
3397 NtUserSetWindowFNID(DWORD Unknown0
,
3411 NtUserSetWindowPlacement(HWND hWnd
,
3412 WINDOWPLACEMENT
*lpwndpl
)
3414 PWINDOW_OBJECT WindowObject
;
3415 WINDOWPLACEMENT Safepl
;
3418 WindowObject
= IntGetWindowObject(hWnd
);
3419 if (WindowObject
== NULL
)
3421 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
3424 Status
= MmCopyFromCaller(&Safepl
, lpwndpl
, sizeof(WINDOWPLACEMENT
));
3425 if(!NT_SUCCESS(Status
))
3427 SetLastNtError(Status
);
3428 IntReleaseWindowObject(WindowObject
);
3431 if(Safepl
.length
!= sizeof(WINDOWPLACEMENT
))
3433 IntReleaseWindowObject(WindowObject
);
3437 if ((WindowObject
->Style
& (WS_MAXIMIZE
| WS_MINIMIZE
)) == 0)
3439 WinPosSetWindowPos(WindowObject
->Self
, NULL
,
3440 Safepl
.rcNormalPosition
.left
, Safepl
.rcNormalPosition
.top
,
3441 Safepl
.rcNormalPosition
.right
- Safepl
.rcNormalPosition
.left
,
3442 Safepl
.rcNormalPosition
.bottom
- Safepl
.rcNormalPosition
.top
,
3443 SWP_NOZORDER
| SWP_NOACTIVATE
);
3446 /* FIXME - change window status */
3447 WinPosShowWindow(WindowObject
->Self
, Safepl
.showCmd
);
3449 if (WindowObject
->InternalPos
== NULL
)
3450 WindowObject
->InternalPos
= ExAllocatePoolWithTag(PagedPool
, sizeof(INTERNALPOS
), TAG_WININTLIST
);
3451 WindowObject
->InternalPos
->NormalRect
= Safepl
.rcNormalPosition
;
3452 WindowObject
->InternalPos
->IconPos
= Safepl
.ptMinPosition
;
3453 WindowObject
->InternalPos
->MaxPos
= Safepl
.ptMaxPosition
;
3455 IntReleaseWindowObject(WindowObject
);
3466 HWND hWndInsertAfter
,
3473 return WinPosSetWindowPos(hWnd
, hWndInsertAfter
, X
, Y
, cx
, cy
, uFlags
);
3478 IntGetWindowRgn(HWND hWnd
, HRGN hRgn
)
3481 PWINDOW_OBJECT WindowObject
;
3485 if(!(WindowObject
= IntGetWindowObject(hWnd
)))
3487 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
3492 IntReleaseWindowObject(WindowObject
);
3496 /* Create a new window region using the window rectangle */
3497 VisRgn
= UnsafeIntCreateRectRgnIndirect(&WindowObject
->WindowRect
);
3498 NtGdiOffsetRgn(VisRgn
, -WindowObject
->WindowRect
.left
, -WindowObject
->WindowRect
.top
);
3499 /* if there's a region assigned to the window, combine them both */
3500 if(WindowObject
->WindowRegion
&& !(WindowObject
->Style
& WS_MINIMIZE
))
3501 NtGdiCombineRgn(VisRgn
, VisRgn
, WindowObject
->WindowRegion
, RGN_AND
);
3502 /* Copy the region into hRgn */
3503 NtGdiCombineRgn(hRgn
, VisRgn
, NULL
, RGN_COPY
);
3505 if((pRgn
= RGNDATA_LockRgn(hRgn
)))
3507 Ret
= pRgn
->rdh
.iType
;
3508 RGNDATA_UnlockRgn(hRgn
);
3513 NtGdiDeleteObject(VisRgn
);
3515 IntReleaseWindowObject(WindowObject
);
3520 IntGetWindowRgnBox(HWND hWnd
, RECT
*Rect
)
3523 PWINDOW_OBJECT WindowObject
;
3527 if(!(WindowObject
= IntGetWindowObject(hWnd
)))
3529 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
3534 IntReleaseWindowObject(WindowObject
);
3538 /* Create a new window region using the window rectangle */
3539 VisRgn
= UnsafeIntCreateRectRgnIndirect(&WindowObject
->WindowRect
);
3540 NtGdiOffsetRgn(VisRgn
, -WindowObject
->WindowRect
.left
, -WindowObject
->WindowRect
.top
);
3541 /* if there's a region assigned to the window, combine them both */
3542 if(WindowObject
->WindowRegion
&& !(WindowObject
->Style
& WS_MINIMIZE
))
3543 NtGdiCombineRgn(VisRgn
, VisRgn
, WindowObject
->WindowRegion
, RGN_AND
);
3545 if((pRgn
= RGNDATA_LockRgn(VisRgn
)))
3547 Ret
= pRgn
->rdh
.iType
;
3548 *Rect
= pRgn
->rdh
.rcBound
;
3549 RGNDATA_UnlockRgn(VisRgn
);
3554 NtGdiDeleteObject(VisRgn
);
3556 IntReleaseWindowObject(WindowObject
);
3570 PWINDOW_OBJECT WindowObject
;
3572 WindowObject
= IntGetWindowObject(hWnd
);
3573 if (WindowObject
== NULL
)
3575 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
3579 /* FIXME - Verify if hRgn is a valid handle!!!!
3580 Propably make this operation thread-safe, but maybe it's not necessary */
3582 if(WindowObject
->WindowRegion
)
3584 /* Delete no longer needed region handle */
3585 NtGdiDeleteObject(WindowObject
->WindowRegion
);
3587 WindowObject
->WindowRegion
= hRgn
;
3589 /* FIXME - send WM_WINDOWPOSCHANGING and WM_WINDOWPOSCHANGED messages to the window */
3593 IntRedrawWindow(WindowObject
, NULL
, NULL
, RDW_INVALIDATE
);
3596 IntReleaseWindowObject(WindowObject
);
3605 NtUserShowWindow(HWND hWnd
,
3608 return WinPosShowWindow(hWnd
, nCmdShow
);
3616 NtUserShowWindowAsync(DWORD Unknown0
,
3629 NtUserUpdateLayeredWindow(DWORD Unknown0
,
3649 NtUserValidateRect(HWND hWnd
, const RECT
* Rect
)
3651 return (VOID
)NtUserRedrawWindow(hWnd
, Rect
, 0, RDW_VALIDATE
| RDW_NOCHILDREN
);
3659 NtUserWindowFromPoint(LONG X
, LONG Y
)
3663 PWINDOW_OBJECT DesktopWindow
, Window
= NULL
;
3665 if ((DesktopWindow
= IntGetWindowObject(IntGetDesktopWindow())))
3672 Hit
= WinPosWindowFromPoint(DesktopWindow
, TRUE
, &pt
, &Window
);
3677 IntReleaseWindowObject(Window
);
3678 IntReleaseWindowObject(DesktopWindow
);
3682 IntReleaseWindowObject(DesktopWindow
);
3692 * Undocumented function that is called from DefWindowProc to set
3695 * FIXME: Call this from user32.dll!
3702 NtUserDefSetText(HWND WindowHandle
, PANSI_STRING Text
)
3704 PWINDOW_OBJECT WindowObject
;
3705 UNICODE_STRING NewWindowName
;
3706 BOOL Result
= FALSE
;
3708 WindowObject
= IntGetWindowObject(WindowHandle
);
3711 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
3715 if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&NewWindowName
, Text
, TRUE
)))
3717 RtlFreeUnicodeString(&WindowObject
->WindowName
);
3718 WindowObject
->WindowName
.Buffer
= NewWindowName
.Buffer
;
3719 WindowObject
->WindowName
.Length
= NewWindowName
.Length
;
3720 WindowObject
->WindowName
.MaximumLength
= NewWindowName
.MaximumLength
;
3724 IntReleaseWindowObject(WindowObject
);
3730 * NtUserInternalGetWindowText
3732 * FIXME: Call this from user32.dll!
3739 NtUserInternalGetWindowText(HWND WindowHandle
, LPWSTR Text
, INT MaxCount
)
3741 PWINDOW_OBJECT WindowObject
;
3744 WindowObject
= IntGetWindowObject(WindowHandle
);
3747 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
3751 Result
= WindowObject
->WindowName
.Length
/ sizeof(WCHAR
);
3754 /* FIXME: Shouldn't it be always NULL terminated? */
3755 wcsncpy(Text
, WindowObject
->WindowName
.Buffer
, MaxCount
);
3756 if (MaxCount
< Result
)
3762 IntReleaseWindowObject(WindowObject
);
3768 NtUserDereferenceWndProcHandle(WNDPROC wpHandle
, WndProcHandle
*Data
)
3770 WndProcHandle Entry
;
3771 if (((DWORD
)wpHandle
& 0xFFFF0000) == 0xFFFF0000)
3773 Entry
= WndProcHandlesArray
[(DWORD
)wpHandle
& 0x0000FFFF];
3774 Data
->WindowProc
= Entry
.WindowProc
;
3775 Data
->IsUnicode
= Entry
.IsUnicode
;
3776 Data
->ProcessID
= Entry
.ProcessID
;
3785 IntAddWndProcHandle(WNDPROC WindowProc
, BOOL IsUnicode
)
3790 WndProcHandle
*OldArray
;
3793 for (i
= 0;i
< WndProcHandlesArraySize
;i
++)
3795 if (WndProcHandlesArray
[i
].WindowProc
== NULL
)
3803 OldArray
= WndProcHandlesArray
;
3804 OldArraySize
= WndProcHandlesArraySize
;
3805 WndProcHandlesArray
= ExAllocatePoolWithTag(PagedPool
,(OldArraySize
+ WPH_SIZE
) * sizeof(WndProcHandle
), TAG_WINPROCLST
);
3806 WndProcHandlesArraySize
= OldArraySize
+ WPH_SIZE
;
3807 RtlCopyMemory(WndProcHandlesArray
,OldArray
,OldArraySize
* sizeof(WndProcHandle
));
3808 ExFreePool(OldArray
);
3809 FreeSpot
= OldArraySize
+ 1;
3811 WndProcHandlesArray
[FreeSpot
].WindowProc
= WindowProc
;
3812 WndProcHandlesArray
[FreeSpot
].IsUnicode
= IsUnicode
;
3813 WndProcHandlesArray
[FreeSpot
].ProcessID
= PsGetCurrentProcessId();
3814 return FreeSpot
+ 0xFFFF0000;
3818 IntRemoveWndProcHandle(WNDPROC Handle
)
3821 position
= (DWORD
)Handle
& 0x0000FFFF;
3822 if (position
> WndProcHandlesArraySize
)
3826 WndProcHandlesArray
[position
].WindowProc
= NULL
;
3827 WndProcHandlesArray
[position
].IsUnicode
= FALSE
;
3828 WndProcHandlesArray
[position
].ProcessID
= NULL
;
3833 IntRemoveProcessWndProcHandles(HANDLE ProcessID
)
3836 for (i
= 0;i
< WndProcHandlesArraySize
;i
++)
3838 if (WndProcHandlesArray
[i
].ProcessID
== ProcessID
)
3840 WndProcHandlesArray
[i
].WindowProc
= NULL
;
3841 WndProcHandlesArray
[i
].IsUnicode
= FALSE
;
3842 WndProcHandlesArray
[i
].ProcessID
= NULL
;