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 /* Initialize the window's scrollbars */
501 if (dwStyle & WS_VSCROLL)
502 SCROLL_CreateScrollBar(WindowObject, SB_VERT);
503 if (dwStyle & WS_HSCROLL)
504 SCROLL_CreateScrollBar(WindowObject, SB_HORZ);
506 /* Send a NCCREATE message. */
507 Cs.lpCreateParams = lpParam;
508 Cs.hInstance = hInstance;
510 Cs.hwndParent = hWndParent;
516 Cs.lpszName = lpWindowName->Buffer;
517 Cs.lpszClass = lpClassName->Buffer;
518 Cs.dwExStyle = dwExStyle;
519 DPRINT("NtUserCreateWindowEx(): About to send NCCREATE message.\n");
520 Result = W32kSendNCCREATEMessage(WindowObject->Self, &Cs);
523 /* FIXME: Cleanup. */
524 DPRINT("NtUserCreateWindowEx(): NCCREATE message failed.\n");
528 /* Calculate the non-client size. */
529 MaxPos.x = WindowObject->WindowRect.left;
530 MaxPos.y = WindowObject->WindowRect.top;
531 DPRINT("NtUserCreateWindowEx(): About to get non-client size.\n");
532 Result = WinPosGetNonClientSize(WindowObject->Self,
533 &WindowObject->WindowRect,
534 &WindowObject->ClientRect);
535 W32kOffsetRect(&WindowObject->WindowRect,
536 MaxPos.x - WindowObject->WindowRect.left,
537 MaxPos.y - WindowObject->WindowRect.top);
539 /* Send the CREATE message. */
540 DPRINT("NtUserCreateWindowEx(): about to send CREATE message.\n");
541 Result = W32kSendCREATEMessage(WindowObject->Self, &Cs);
542 if (Result == (LRESULT)-1)
544 /* FIXME: Cleanup. */
545 DPRINT("NtUserCreateWindowEx(): send CREATE message failed.\n");
549 /* Send move and size messages. */
550 if (!(WindowObject->Flags & WINDOWOBJECT_NEED_SIZE))
555 MAKE_LONG(WindowObject->ClientRect.right -
556 WindowObject->ClientRect.left,
557 WindowObject->ClientRect.bottom -
558 WindowObject->ClientRect.top);
559 DPRINT("NtUserCreateWindow(): About to send WM_SIZE\n");
560 W32kCallWindowProc(NULL, WindowObject->Self, WM_SIZE, SIZE_RESTORED,
563 MAKE_LONG(WindowObject->ClientRect.left,
564 WindowObject->ClientRect.top);
565 DPRINT("NtUserCreateWindow(): About to send WM_MOVE\n");
566 W32kCallWindowProc(NULL, WindowObject->Self, WM_MOVE, 0, lParam);
569 /* Show or maybe minimize or maximize the window. */
570 if (WindowObject->Style & (WS_MINIMIZE | WS_MAXIMIZE))
575 SwFlag = (WindowObject->Style & WS_MINIMIZE) ? SW_MINIMIZE :
577 WinPosMinMaximize(WindowObject, SwFlag, &NewPos);
579 ((WindowObject->Style & WS_CHILD) || W32kGetActiveWindow()) ?
580 SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED :
581 SWP_NOZORDER | SWP_FRAMECHANGED;
582 DPRINT("NtUserCreateWindow(): About to minimize/maximize\n");
583 WinPosSetWindowPos(WindowObject->Self, 0, NewPos.left, NewPos.top,
584 NewPos.right, NewPos.bottom, SwFlag);
587 /* Notify the parent window of a new child. */
588 if ((WindowObject->Style & WS_CHILD) ||
589 (!(WindowObject->ExStyle & WS_EX_NOPARENTNOTIFY)))
591 DPRINT("NtUserCreateWindow(): About to notify parent\n");
592 W32kCallWindowProc(NULL, WindowObject->Parent->Self,
594 MAKEWPARAM(WM_CREATE, WindowObject->IDMenu),
595 (LPARAM)WindowObject->Self);
598 if (dwStyle & WS_VISIBLE)
600 DPRINT("NtUserCreateWindow(): About to show window\n");
601 WinPosShowWindow(WindowObject->Self, dwShowMode);
604 DPRINT("NtUserCreateWindow(): = %X\n", Handle);
605 return((HWND)Handle);
609 NtUserDeferWindowPos(HDWP WinPosInfo,
624 NtUserDestroyWindow(HWND Wnd)
632 NtUserEndDeferWindowPosEx(DWORD Unknown0,
641 NtUserFillWindow(DWORD Unknown0,
652 NtUserFindWindowEx(HWND hwndParent,
654 PUNICODE_STRING ucClassName,
655 PUNICODE_STRING ucWindowName,
661 PWINDOW_OBJECT windowObject;
662 PLIST_ENTRY currentEntry;
663 PWNDCLASS_OBJECT classObject;
667 status = ClassReferenceClassByNameOrAtom(&classObject, ucClassName->Buffer);
668 if (!NT_SUCCESS(status))
673 ExAcquireFastMutexUnsafe (&PsGetWin32Process()->WindowListLock);
674 currentEntry = PsGetWin32Process()->WindowListHead.Flink;
675 while (currentEntry != &PsGetWin32Process()->WindowListHead)
677 windowObject = CONTAINING_RECORD (currentEntry, WINDOW_OBJECT,
680 if (classObject == windowObject->Class &&
681 RtlCompareUnicodeString (ucWindowName, &windowObject->WindowName,
684 ObmCreateHandle(PsGetWin32Process()->HandleTable,
687 ExReleaseFastMutexUnsafe (&PsGetWin32Process()->WindowListLock);
688 ObmDereferenceObject (classObject);
692 currentEntry = currentEntry->Flink;
694 ExReleaseFastMutexUnsafe (&PsGetWin32Process()->WindowListLock);
696 ObmDereferenceObject (classObject);
703 NtUserFlashWindowEx(DWORD Unknown0)
711 NtUserGetForegroundWindow(VOID)
719 NtUserGetInternalWindowPos(DWORD Unknown0,
729 NtUserGetOpenClipboardWindow(VOID)
737 NtUserGetWindowDC(DWORD Unknown0)
745 NtUserGetWindowPlacement(DWORD Unknown0,
754 NtUserInternalGetWindowText(DWORD Unknown0,
764 NtUserLockWindowUpdate(DWORD Unknown0)
772 NtUserMoveWindow(DWORD Unknown0,
785 NtUserQueryWindow(DWORD Unknown0,
794 NtUserRealChildWindowFromPoint(DWORD Unknown0,
804 NtUserRedrawWindow(DWORD Unknown0,
815 NtUserRegisterWindowMessage(LPCWSTR MessageName)
823 NtUserScrollWindowEx(DWORD Unknown0,
838 NtUserSetActiveWindow(DWORD Unknown0)
846 NtUserSetImeOwnerWindow(DWORD Unknown0,
855 NtUserSetInternalWindowPos(DWORD Unknown0,
867 NtUserSetLayeredWindowAttributes(DWORD Unknown0,
878 NtUserSetLogonNotifyWindow(DWORD Unknown0)
886 NtUserSetShellWindowEx(DWORD Unknown0,
895 NtUserSetWindowFNID(DWORD Unknown0,
904 NtUserGetWindowLong(HWND hWnd, DWORD Index)
906 PWINDOW_OBJECT WindowObject;
913 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable,
916 (PVOID*)&WindowObject);
917 if (!NT_SUCCESS(Status))
926 Result = (DWORD)WindowObject->ExStyle;
932 Result = (DWORD)WindowObject->Style;
938 Result = (DWORD)WindowObject->Class->Class.lpfnWndProc;
944 DPRINT1("NtUserGetWindowLong(): Unsupported index %d\n", Index);
950 ObmDereferenceObject(WindowObject);
955 NtUserSetWindowLong(DWORD Unknown0,
966 NtUserSetWindowPlacement(DWORD Unknown0,
975 NtUserSetWindowPos(DWORD Unknown0,
989 NtUserSetWindowRgn(DWORD Unknown0,
999 NtUserSetWindowWord(DWORD Unknown0,
1009 NtUserShowWindow(HWND hWnd,
1014 return(WinPosShowWindow(hWnd, nCmdShow));
1018 NtUserShowWindowAsync(DWORD Unknown0,
1027 NtUserUpdateLayeredWindow(DWORD Unknown0,
1043 NtUserWindowFromPoint(DWORD Unknown0,