3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
6 * FILE: subsys/win32k/ntuser/window.c
7 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
9 * 06-06-2001 CSH Created
11 /* INCLUDES ******************************************************************/
13 #include <ddk/ntddk.h>
14 #include <win32k/win32k.h>
15 #include <include/object.h>
16 #include <include/guicheck.h>
17 #include <include/window.h>
18 #include <include/class.h>
19 #include <include/error.h>
20 #include <include/winsta.h>
21 #include <include/winpos.h>
22 #include <include/callback.h>
23 #include <include/msgqueue.h>
24 #include <include/rect.h>
29 /* FUNCTIONS *****************************************************************/
32 NtUserGetAncestor(HWND hWnd, UINT Flags)
34 if (W32kIsDesktopWindow(hWnd))
38 if (Flags & GA_PARENT)
40 PWINDOW_OBJECT Window;
43 Window = W32kGetWindowObject(hWnd);
49 if (Window->Parent == NULL)
51 W32kReleaseWindowObject(Window);
54 hParent = Window->Parent->Self;
56 W32kReleaseWindowObject(Window);
68 W32kSetFocusWindow(HWND hWnd)
73 W32kIsChildWindow(HWND Parent, HWND Child)
75 PWINDOW_OBJECT BaseWindow = W32kGetWindowObject(Child);
76 PWINDOW_OBJECT Window = BaseWindow;
77 while (Window != NULL && Window->Style & WS_CHILD)
79 if (Window->Self == Parent)
81 W32kReleaseWindowObject(BaseWindow);
84 Window = Window->Parent;
86 W32kReleaseWindowObject(BaseWindow);
91 W32kIsWindowVisible(HWND Wnd)
93 PWINDOW_OBJECT BaseWindow = W32kGetWindowObject(Wnd);
94 PWINDOW_OBJECT Window = BaseWindow;
95 BOOLEAN Result = FALSE;
96 while (Window != NULL && Window->Style & WS_CHILD)
98 if (!(Window->Style & WS_VISIBLE))
100 W32kReleaseWindowObject(BaseWindow);
103 Window = Window->Parent;
105 if (Window != NULL && Window->Style & WS_VISIBLE)
109 W32kReleaseWindowObject(BaseWindow);
114 W32kIsDesktopWindow(HWND hWnd)
116 PWINDOW_OBJECT WindowObject;
118 WindowObject = W32kGetWindowObject(hWnd);
119 IsDesktop = WindowObject->Parent == NULL;
120 W32kReleaseWindowObject(WindowObject);
124 HWND W32kGetDesktopWindow()
126 return W32kGetActiveDesktop()->DesktopWindow;
129 HWND W32kGetParentWindow(HWND hWnd)
131 return W32kGetWindowObject(hWnd)->ParentHandle;
135 W32kGetWindowObject(HWND hWnd)
137 PWINDOW_OBJECT WindowObject;
140 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->
144 (PVOID*)&WindowObject);
145 if (!NT_SUCCESS(Status))
149 return(WindowObject);
153 W32kReleaseWindowObject(PWINDOW_OBJECT Window)
155 ObmDereferenceObject(Window);
159 W32kGetClientRect(PWINDOW_OBJECT WindowObject, PRECT Rect)
161 Rect->left = Rect->top = 0;
162 Rect->right = WindowObject->ClientRect.right - WindowObject->ClientRect.left;
164 WindowObject->ClientRect.bottom - WindowObject->ClientRect.top;
168 W32kGetWindowRect(HWND hWnd, LPRECT Rect)
170 PWINDOW_OBJECT WindowObject;
172 WindowObject = W32kGetWindowObject(hWnd);
173 if (WindowObject == NULL)
177 *Rect = WindowObject->WindowRect;
178 if (WindowObject->Style & WS_CHILD)
182 W32kReleaseWindowObject(WindowObject);
187 NtUserGetWindowRect(HWND hWnd, LPRECT Rect)
189 return(W32kGetWindowRect(hWnd, Rect));
193 W32kGetActiveWindow(VOID)
195 PUSER_MESSAGE_QUEUE Queue;
196 Queue = (PUSER_MESSAGE_QUEUE)W32kGetActiveDesktop()->ActiveMessageQueue;
203 return(Queue->ActiveWindow);
208 W32kGetFocusWindow(VOID)
210 PUSER_MESSAGE_QUEUE Queue;
211 Queue = (PUSER_MESSAGE_QUEUE)W32kGetActiveDesktop()->ActiveMessageQueue;
218 return(Queue->FocusWindow);
224 W32kGetWindowProc(HWND Wnd)
226 PWINDOW_OBJECT WindowObject;
229 WindowObject = W32kGetWindowObject(Wnd);
230 WndProc = WindowObject->Class->Class.lpfnWndProc;
231 W32kReleaseWindowObject(Wnd);
238 return(STATUS_SUCCESS);
242 CleanupWindowImpl(VOID)
244 return(STATUS_SUCCESS);
249 NtUserAlterWindowStyle(DWORD Unknown0,
259 NtUserChildWindowFromPointEx(HWND Parent,
270 W32kCreateDesktopWindow(PWINSTATION_OBJECT WindowStation,
271 PWNDCLASS_OBJECT DesktopClass,
272 ULONG Width, ULONG Height)
276 PWINDOW_OBJECT WindowObject;
278 /* Create the window object. */
279 WindowObject = (PWINDOW_OBJECT)ObmCreateObject(WindowStation->HandleTable,
282 sizeof(WINDOW_OBJECT));
289 * Fill out the structure describing it.
291 WindowObject->Class = DesktopClass;
292 WindowObject->ExStyle = 0;
293 WindowObject->Style = WS_VISIBLE;
296 WindowObject->Width = Width;
297 WindowObject->Height = Height;
298 WindowObject->ParentHandle = NULL;
299 WindowObject->Parent = NULL;
300 WindowObject->Menu = NULL;
301 WindowObject->Instance = NULL;
302 WindowObject->Parameters = NULL;
303 WindowObject->Self = Handle;
304 WindowObject->MessageQueue = NULL;
305 WindowObject->ExtraData = NULL;
306 WindowObject->ExtraDataSize = 0;
307 WindowObject->WindowRect.left = 0;
308 WindowObject->WindowRect.top = 0;
309 WindowObject->WindowRect.right = Width;
310 WindowObject->WindowRect.bottom = Height;
311 WindowObject->ClientRect = WindowObject->WindowRect;
312 InitializeListHead(&WindowObject->ChildrenListHead);
314 WindowName = ExAllocatePool(NonPagedPool, sizeof(L"DESKTOP"));
315 wcscpy(WindowName, L"DESKTOP");
316 RtlInitUnicodeString(&WindowObject->WindowName, WindowName);
322 NtUserCreateWindowEx(DWORD dwExStyle,
323 PUNICODE_STRING lpClassName,
324 PUNICODE_STRING lpWindowName,
336 PWINSTATION_OBJECT WinStaObject;
337 PWNDCLASS_OBJECT ClassObject;
338 PWINDOW_OBJECT WindowObject;
339 PWINDOW_OBJECT ParentWindow;
340 UNICODE_STRING WindowName;
343 POINT MaxSize, MaxPos, MinTrack, MaxTrack;
347 DPRINT("NtUserCreateWindowEx\n");
349 /* Initialize gui state if necessary. */
353 if (!RtlCreateUnicodeString(&WindowName, lpWindowName->Buffer))
355 SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
359 if (hWndParent != NULL)
361 ParentWindow = W32kGetWindowObject(hWndParent);
365 hWndParent = PsGetWin32Thread()->Desktop->DesktopWindow;
366 ParentWindow = W32kGetWindowObject(hWndParent);
369 /* Check the class. */
370 Status = ClassReferenceClassByNameOrAtom(&ClassObject, lpClassName->Buffer);
371 if (!NT_SUCCESS(Status))
373 RtlFreeUnicodeString(&WindowName);
377 /* Check the window station. */
378 DPRINT("IoGetCurrentProcess() %X\n", IoGetCurrentProcess());
379 DPRINT("PROCESS_WINDOW_STATION %X\n", PROCESS_WINDOW_STATION());
380 Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
384 if (!NT_SUCCESS(Status))
386 RtlFreeUnicodeString(&WindowName);
387 ObmDereferenceObject(ClassObject);
388 DPRINT("Validation of window station handle (0x%X) failed\n",
389 PROCESS_WINDOW_STATION());
393 /* Create the window object. */
394 WindowObject = (PWINDOW_OBJECT)
395 ObmCreateObject(PsGetWin32Process()->WindowStation->HandleTable, &Handle,
396 otWindow, sizeof(WINDOW_OBJECT));
397 DPRINT("Created object with handle %X\n", Handle);
400 ObDereferenceObject(WinStaObject);
401 ObmDereferenceObject(ClassObject);
402 RtlFreeUnicodeString(&WindowName);
403 SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
406 ObDereferenceObject(WinStaObject);
409 * Fill out the structure describing it.
411 WindowObject->Class = ClassObject;
412 WindowObject->ExStyle = dwExStyle;
413 WindowObject->Style = dwStyle;
416 WindowObject->Width = nWidth;
417 WindowObject->Height = nHeight;
418 WindowObject->ParentHandle = hWndParent;
419 WindowObject->Menu = hMenu;
420 WindowObject->Instance = hInstance;
421 WindowObject->Parameters = lpParam;
422 WindowObject->Self = Handle;
423 WindowObject->MessageQueue = PsGetWin32Thread()->MessageQueue;
424 WindowObject->Parent = ParentWindow;
425 InsertHeadList(&ParentWindow->ChildrenListHead,
426 &WindowObject->SiblingListEntry);
427 InitializeListHead(&WindowObject->ChildrenListHead);
428 InitializeListHead(&WindowObject->PropListHead);
430 RtlInitUnicodeString(&WindowObject->WindowName, WindowName.Buffer);
431 RtlFreeUnicodeString(&WindowName);
433 if (ClassObject->Class.cbWndExtra != 0)
435 WindowObject->ExtraData =
436 ExAllocatePool(PagedPool,
437 ClassObject->Class.cbWndExtra * sizeof(DWORD));
438 WindowObject->ExtraDataSize = ClassObject->Class.cbWndExtra;
442 WindowObject->ExtraData = NULL;
443 WindowObject->ExtraDataSize = 0;
446 /* Correct the window style. */
447 if (!(dwStyle & WS_CHILD))
449 WindowObject->Style |= WS_CLIPSIBLINGS;
450 if (!(dwStyle & WS_POPUP))
452 WindowObject->Style |= WS_CAPTION;
453 /* FIXME: Note the window needs a size. */
457 /* Insert the window into the process's window list. */
458 ExAcquireFastMutexUnsafe (&PsGetWin32Thread()->WindowListLock);
459 InsertTailList (&PsGetWin32Thread()->WindowListHead,
460 &WindowObject->ThreadListEntry);
461 ExReleaseFastMutexUnsafe (&PsGetWin32Thread()->WindowListLock);
464 * Insert the window into the list of windows associated with the thread's
467 InsertTailList(&PsGetWin32Thread()->Desktop->WindowListHead,
468 &WindowObject->DesktopListEntry);
470 /* FIXME: Maybe allocate a DCE for this window. */
472 /* Initialize the window dimensions. */
473 WindowObject->WindowRect.left = x;
474 WindowObject->WindowRect.top = y;
475 WindowObject->WindowRect.right = x + nWidth;
476 WindowObject->WindowRect.bottom = y + nHeight;
477 WindowObject->ClientRect = WindowObject->WindowRect;
480 * Get the size and position of the window.
482 if ((dwStyle & WS_THICKFRAME) || !(dwStyle & (WS_POPUP | WS_CHILD)))
484 WinPosGetMinMaxInfo(WindowObject, &MaxSize, &MaxPos, &MinTrack,
486 x = min(MaxSize.x, y);
487 y = min(MaxSize.y, y);
488 x = max(MinTrack.x, x);
489 y = max(MinTrack.y, y);
492 WindowObject->WindowRect.left = x;
493 WindowObject->WindowRect.top = y;
494 WindowObject->WindowRect.right = x + nWidth;
495 WindowObject->WindowRect.bottom = y + nHeight;
496 WindowObject->ClientRect = WindowObject->WindowRect;
498 /* FIXME: Initialize the window menu. */
500 /* Send a NCCREATE message. */
501 Cs.lpCreateParams = lpParam;
502 Cs.hInstance = hInstance;
504 Cs.hwndParent = hWndParent;
510 Cs.lpszName = lpWindowName->Buffer;
511 Cs.lpszClass = lpClassName->Buffer;
512 Cs.dwExStyle = dwExStyle;
513 DPRINT("NtUserCreateWindowEx(): About to send NCCREATE message.\n");
514 Result = W32kSendNCCREATEMessage(WindowObject->Self, &Cs);
517 /* FIXME: Cleanup. */
518 DPRINT("NtUserCreateWindowEx(): NCCREATE message failed.\n");
522 /* Calculate the non-client size. */
523 MaxPos.x = WindowObject->WindowRect.left;
524 MaxPos.y = WindowObject->WindowRect.top;
525 DPRINT("NtUserCreateWindowEx(): About to get non-client size.\n");
526 Result = WinPosGetNonClientSize(WindowObject->Self,
527 &WindowObject->WindowRect,
528 &WindowObject->ClientRect);
529 W32kOffsetRect(&WindowObject->WindowRect,
530 MaxPos.x - WindowObject->WindowRect.left,
531 MaxPos.y - WindowObject->WindowRect.top);
533 /* Send the CREATE message. */
534 DPRINT("NtUserCreateWindowEx(): about to send CREATE message.\n");
535 Result = W32kSendCREATEMessage(WindowObject->Self, &Cs);
536 if (Result == (LRESULT)-1)
538 /* FIXME: Cleanup. */
539 DPRINT("NtUserCreateWindowEx(): send CREATE message failed.\n");
543 /* Send move and size messages. */
544 if (!(WindowObject->Flags & WINDOWOBJECT_NEED_SIZE))
549 MAKE_LONG(WindowObject->ClientRect.right -
550 WindowObject->ClientRect.left,
551 WindowObject->ClientRect.bottom -
552 WindowObject->ClientRect.top);
553 DPRINT("NtUserCreateWindow(): About to send WM_SIZE\n");
554 W32kCallWindowProc(NULL, WindowObject->Self, WM_SIZE, SIZE_RESTORED,
557 MAKE_LONG(WindowObject->ClientRect.left,
558 WindowObject->ClientRect.top);
559 DPRINT("NtUserCreateWindow(): About to send WM_MOVE\n");
560 W32kCallWindowProc(NULL, WindowObject->Self, WM_MOVE, 0, lParam);
563 /* Show or maybe minimize or maximize the window. */
564 if (WindowObject->Style & (WS_MINIMIZE | WS_MAXIMIZE))
569 SwFlag = (WindowObject->Style & WS_MINIMIZE) ? SW_MINIMIZE :
571 WinPosMinMaximize(WindowObject, SwFlag, &NewPos);
573 ((WindowObject->Style & WS_CHILD) || W32kGetActiveWindow()) ?
574 SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED :
575 SWP_NOZORDER | SWP_FRAMECHANGED;
576 DPRINT("NtUserCreateWindow(): About to minimize/maximize\n");
577 WinPosSetWindowPos(WindowObject->Self, 0, NewPos.left, NewPos.top,
578 NewPos.right, NewPos.bottom, SwFlag);
581 /* Notify the parent window of a new child. */
582 if ((WindowObject->Style & WS_CHILD) ||
583 (!(WindowObject->ExStyle & WS_EX_NOPARENTNOTIFY)))
585 DPRINT("NtUserCreateWindow(): About to notify parent\n");
586 W32kCallWindowProc(NULL, WindowObject->Parent->Self,
588 MAKEWPARAM(WM_CREATE, WindowObject->IDMenu),
589 (LPARAM)WindowObject->Self);
592 if (dwStyle & WS_VISIBLE)
594 DPRINT("NtUserCreateWindow(): About to show window\n");
595 WinPosShowWindow(WindowObject->Self, dwShowMode);
598 DPRINT("NtUserCreateWindow(): = %X\n", Handle);
599 return((HWND)Handle);
603 NtUserDeferWindowPos(HDWP WinPosInfo,
618 NtUserDestroyWindow(HWND Wnd)
626 NtUserEndDeferWindowPosEx(DWORD Unknown0,
635 NtUserFillWindow(DWORD Unknown0,
646 NtUserFindWindowEx(HWND hwndParent,
648 PUNICODE_STRING ucClassName,
649 PUNICODE_STRING ucWindowName,
655 PWINDOW_OBJECT windowObject;
656 PLIST_ENTRY currentEntry;
657 PWNDCLASS_OBJECT classObject;
661 status = ClassReferenceClassByNameOrAtom(&classObject, ucClassName->Buffer);
662 if (!NT_SUCCESS(status))
667 ExAcquireFastMutexUnsafe (&PsGetWin32Process()->WindowListLock);
668 currentEntry = PsGetWin32Process()->WindowListHead.Flink;
669 while (currentEntry != &PsGetWin32Process()->WindowListHead)
671 windowObject = CONTAINING_RECORD (currentEntry, WINDOW_OBJECT,
674 if (classObject == windowObject->Class &&
675 RtlCompareUnicodeString (ucWindowName, &windowObject->WindowName,
678 ObmCreateHandle(PsGetWin32Process()->HandleTable,
681 ExReleaseFastMutexUnsafe (&PsGetWin32Process()->WindowListLock);
682 ObmDereferenceObject (classObject);
686 currentEntry = currentEntry->Flink;
688 ExReleaseFastMutexUnsafe (&PsGetWin32Process()->WindowListLock);
690 ObmDereferenceObject (classObject);
697 NtUserFlashWindowEx(DWORD Unknown0)
705 NtUserGetForegroundWindow(VOID)
713 NtUserGetInternalWindowPos(DWORD Unknown0,
723 NtUserGetOpenClipboardWindow(VOID)
731 NtUserGetWindowDC(DWORD Unknown0)
739 NtUserGetWindowPlacement(DWORD Unknown0,
748 NtUserInternalGetWindowText(DWORD Unknown0,
758 NtUserLockWindowUpdate(DWORD Unknown0)
766 NtUserMoveWindow(DWORD Unknown0,
779 NtUserQueryWindow(DWORD Unknown0,
788 NtUserRealChildWindowFromPoint(DWORD Unknown0,
798 NtUserRedrawWindow(DWORD Unknown0,
809 NtUserRegisterWindowMessage(LPCWSTR MessageName)
817 NtUserScrollWindowEx(DWORD Unknown0,
832 NtUserSetActiveWindow(DWORD Unknown0)
840 NtUserSetImeOwnerWindow(DWORD Unknown0,
849 NtUserSetInternalWindowPos(DWORD Unknown0,
861 NtUserSetLayeredWindowAttributes(DWORD Unknown0,
872 NtUserSetLogonNotifyWindow(DWORD Unknown0)
880 NtUserSetShellWindowEx(DWORD Unknown0,
889 NtUserSetWindowFNID(DWORD Unknown0,
898 NtUserGetWindowLong(HWND hWnd, DWORD Index)
900 PWINDOW_OBJECT WindowObject;
907 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable,
910 (PVOID*)&WindowObject);
911 if (!NT_SUCCESS(Status))
920 Result = (DWORD)WindowObject->ExStyle;
926 Result = (DWORD)WindowObject->Style;
932 Result = (DWORD)WindowObject->Class->Class.lpfnWndProc;
938 DPRINT1("NtUserGetWindowLong(): Unsupported index %d\n", Index);
944 ObmDereferenceObject(WindowObject);
949 NtUserSetWindowLong(DWORD Unknown0,
960 NtUserSetWindowPlacement(DWORD Unknown0,
969 NtUserSetWindowPos(DWORD Unknown0,
983 NtUserSetWindowRgn(DWORD Unknown0,
993 NtUserSetWindowWord(DWORD Unknown0,
1003 NtUserShowWindow(HWND hWnd,
1008 return(WinPosShowWindow(hWnd, nCmdShow));
1012 NtUserShowWindowAsync(DWORD Unknown0,
1021 NtUserUpdateLayeredWindow(DWORD Unknown0,
1037 NtUserWindowFromPoint(DWORD Unknown0,