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: winpos.c,v 1.16 2003/07/29 05:37:23 rcampbell 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 <win32k/win32k.h>
33 #include <include/object.h>
34 #include <include/guicheck.h>
35 #include <include/window.h>
36 #include <include/class.h>
37 #include <include/error.h>
38 #include <include/winsta.h>
40 #include <include/winpos.h>
41 #include <include/rect.h>
42 #include <include/callback.h>
43 #include <include/painting.h>
44 #include <include/dce.h>
49 /* GLOBALS *******************************************************************/
51 #define MINMAX_NOSWP (0x00010000)
53 #define SWP_EX_PAINTSELF 0x0002
55 ATOM AtomInternalPos
= (ATOM
) NULL
;
57 /* FUNCTIONS *****************************************************************/
59 #define HAS_DLGFRAME(Style, ExStyle) \
60 (((ExStyle) & WS_EX_DLGMODALFRAME) || \
61 (((Style) & WS_DLGFRAME) && !((Style) & WS_BORDER)))
63 #define HAS_THICKFRAME(Style, ExStyle) \
64 (((Style) & WS_THICKFRAME) && \
65 !((Style) & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)
68 WinPosSetupInternalPos(VOID
)
70 AtomInternalPos
= NtAddAtom(L
"SysIP", (ATOM
*)(PULONG
)&AtomInternalPos
);
74 NtUserGetClientOrigin(HWND hWnd
, LPPOINT Point
)
76 PWINDOW_OBJECT WindowObject
;
78 WindowObject
= W32kGetWindowObject(hWnd
);
79 if (WindowObject
== NULL
)
81 Point
->x
= Point
->y
= 0;
84 Point
->x
= WindowObject
->ClientRect
.left
;
85 Point
->y
= WindowObject
->ClientRect
.top
;
90 WinPosActivateOtherWindow(PWINDOW_OBJECT Window
)
96 WinPosFindIconPos(HWND hWnd
, POINT Pos
)
104 WinPosCreateIconTitle(PWINDOW_OBJECT WindowObject
)
110 WinPosShowIconTitle(PWINDOW_OBJECT WindowObject
, BOOL Show
)
112 PINTERNALPOS InternalPos
= NtUserGetProp(WindowObject
->Self
,
114 PWINDOW_OBJECT IconWindow
;
119 HWND hWnd
= InternalPos
->IconTitle
;
123 hWnd
= WinPosCreateIconTitle(WindowObject
);
128 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation
->
132 (PVOID
*)&IconWindow
);
133 if (NT_SUCCESS(Status
))
135 if (!(IconWindow
->Style
& WS_VISIBLE
))
137 NtUserSendMessage(hWnd
, WM_SHOWWINDOW
, TRUE
, 0);
138 WinPosSetWindowPos(hWnd
, 0, 0, 0, 0, 0, SWP_NOSIZE
|
139 SWP_NOMOVE
| SWP_NOACTIVATE
|
140 SWP_NOZORDER
| SWP_SHOWWINDOW
);
142 ObmDereferenceObject(IconWindow
);
147 WinPosShowWindow(hWnd
, SW_HIDE
);
153 PINTERNALPOS STATIC STDCALL
154 WinPosInitInternalPos(PWINDOW_OBJECT WindowObject
, POINT pt
, PRECT RestoreRect
)
156 PINTERNALPOS InternalPos
= NtUserGetProp(WindowObject
->Self
,
158 if (InternalPos
== NULL
)
161 ExAllocatePool(NonPagedPool
, sizeof(INTERNALPOS
));
162 NtUserSetProp(WindowObject
->Self
, AtomInternalPos
, InternalPos
);
163 InternalPos
->IconTitle
= 0;
164 InternalPos
->NormalRect
= WindowObject
->WindowRect
;
165 InternalPos
->IconPos
.x
= InternalPos
->MaxPos
.x
= 0xFFFFFFFF;
166 InternalPos
->IconPos
.y
= InternalPos
->MaxPos
.y
= 0xFFFFFFFF;
168 if (WindowObject
->Style
& WS_MINIMIZE
)
170 InternalPos
->IconPos
= pt
;
172 else if (WindowObject
->Style
& WS_MAXIMIZE
)
174 InternalPos
->MaxPos
= pt
;
176 else if (RestoreRect
!= NULL
)
178 InternalPos
->NormalRect
= *RestoreRect
;
184 WinPosMinMaximize(PWINDOW_OBJECT WindowObject
, UINT ShowFlag
, RECT
* NewPos
)
187 PINTERNALPOS InternalPos
;
190 Size
.x
= WindowObject
->WindowRect
.left
;
191 Size
.y
= WindowObject
->WindowRect
.top
;
192 InternalPos
= WinPosInitInternalPos(WindowObject
, Size
,
193 &WindowObject
->WindowRect
);
197 if (WindowObject
->Style
& WS_MINIMIZE
)
199 if (!NtUserSendMessage(WindowObject
->Self
, WM_QUERYOPEN
, 0, 0))
201 return(SWP_NOSIZE
| SWP_NOMOVE
);
203 SwpFlags
|= SWP_NOCOPYBITS
;
209 if (WindowObject
->Style
& WS_MAXIMIZE
)
211 WindowObject
->Flags
|= WINDOWOBJECT_RESTOREMAX
;
212 WindowObject
->Style
&= ~WS_MAXIMIZE
;
216 WindowObject
->Style
&= ~WINDOWOBJECT_RESTOREMAX
;
218 WindowObject
->Style
|= WS_MINIMIZE
;
219 InternalPos
->IconPos
= WinPosFindIconPos(WindowObject
,
220 InternalPos
->IconPos
);
221 W32kSetRect(NewPos
, InternalPos
->IconPos
.x
, InternalPos
->IconPos
.y
,
222 NtUserGetSystemMetrics(SM_CXICON
),
223 NtUserGetSystemMetrics(SM_CYICON
));
224 SwpFlags
|= SWP_NOCOPYBITS
;
230 WinPosGetMinMaxInfo(WindowObject
, &Size
, &InternalPos
->MaxPos
,
232 if (WindowObject
->Style
& WS_MINIMIZE
)
234 WinPosShowIconTitle(WindowObject
, FALSE
);
235 WindowObject
->Style
&= ~WS_MINIMIZE
;
237 WindowObject
->Style
|= WS_MINIMIZE
;
238 W32kSetRect(NewPos
, InternalPos
->MaxPos
.x
, InternalPos
->MaxPos
.y
,
245 if (WindowObject
->Style
& WS_MINIMIZE
)
247 WindowObject
->Style
&= ~WS_MINIMIZE
;
248 WinPosShowIconTitle(WindowObject
, FALSE
);
249 if (WindowObject
->Flags
& WINDOWOBJECT_RESTOREMAX
)
251 WinPosGetMinMaxInfo(WindowObject
, &Size
,
252 &InternalPos
->MaxPos
, NULL
, NULL
);
253 WindowObject
->Style
|= WS_MAXIMIZE
;
254 W32kSetRect(NewPos
, InternalPos
->MaxPos
.x
,
255 InternalPos
->MaxPos
.y
, Size
.x
, Size
.y
);
261 if (!(WindowObject
->Style
& WS_MAXIMIZE
))
267 WindowObject
->Style
&= ~WS_MAXIMIZE
;
269 *NewPos
= InternalPos
->NormalRect
;
270 NewPos
->right
-= NewPos
->left
;
271 NewPos
->bottom
-= NewPos
->top
;
279 SwpFlags
|= SWP_NOSIZE
| SWP_NOMOVE
;
285 WinPosGetMinMaxInfo(PWINDOW_OBJECT Window
, POINT
* MaxSize
, POINT
* MaxPos
,
286 POINT
* MinTrack
, POINT
* MaxTrack
)
292 /* Get default values. */
293 MinMax
.ptMaxSize
.x
= NtUserGetSystemMetrics(SM_CXSCREEN
);
294 MinMax
.ptMaxSize
.y
= NtUserGetSystemMetrics(SM_CYSCREEN
);
295 MinMax
.ptMinTrackSize
.x
= NtUserGetSystemMetrics(SM_CXMINTRACK
);
296 MinMax
.ptMinTrackSize
.y
= NtUserGetSystemMetrics(SM_CYMINTRACK
);
297 MinMax
.ptMaxTrackSize
.x
= NtUserGetSystemMetrics(SM_CXSCREEN
);
298 MinMax
.ptMaxTrackSize
.y
= NtUserGetSystemMetrics(SM_CYSCREEN
);
300 if (HAS_DLGFRAME(Window
->Style
, Window
->ExStyle
))
302 XInc
= NtUserGetSystemMetrics(SM_CXDLGFRAME
);
303 YInc
= NtUserGetSystemMetrics(SM_CYDLGFRAME
);
308 if (HAS_THICKFRAME(Window
->Style
, Window
->ExStyle
))
310 XInc
+= NtUserGetSystemMetrics(SM_CXFRAME
);
311 YInc
+= NtUserGetSystemMetrics(SM_CYFRAME
);
313 if (Window
->Style
& WS_BORDER
)
315 XInc
+= NtUserGetSystemMetrics(SM_CXBORDER
);
316 YInc
+= NtUserGetSystemMetrics(SM_CYBORDER
);
319 MinMax
.ptMaxSize
.x
+= 2 * XInc
;
320 MinMax
.ptMaxSize
.y
+= 2 * YInc
;
322 Pos
= NtUserGetProp(Window
->Self
, AtomInternalPos
);
325 MinMax
.ptMaxPosition
= Pos
->MaxPos
;
329 MinMax
.ptMaxPosition
.x
-= XInc
;
330 MinMax
.ptMaxPosition
.y
-= YInc
;
333 W32kSendMessage(Window
->Self
, WM_GETMINMAXINFO
, 0, (LPARAM
)&MinMax
, TRUE
);
335 MinMax
.ptMaxTrackSize
.x
= max(MinMax
.ptMaxTrackSize
.x
,
336 MinMax
.ptMinTrackSize
.x
);
337 MinMax
.ptMaxTrackSize
.y
= max(MinMax
.ptMaxTrackSize
.y
,
338 MinMax
.ptMinTrackSize
.y
);
340 if (MaxSize
) *MaxSize
= MinMax
.ptMaxSize
;
341 if (MaxPos
) *MaxPos
= MinMax
.ptMaxPosition
;
342 if (MinTrack
) *MinTrack
= MinMax
.ptMinTrackSize
;
343 if (MaxTrack
) *MaxTrack
= MinMax
.ptMaxTrackSize
;
345 return 0; //FIXME: what does it return?
349 WinPosChangeActiveWindow(HWND hWnd
, BOOL MouseMsg
)
351 PWINDOW_OBJECT WindowObject
;
353 WindowObject
= W32kGetWindowObject(hWnd
);
354 if (WindowObject
== NULL
)
359 NtUserSendMessage(hWnd
,
361 MAKELONG(MouseMsg
? WA_CLICKACTIVE
: WA_CLICKACTIVE
,
362 (WindowObject
->Style
& WS_MINIMIZE
) ? 1 : 0),
363 (LPARAM
)W32kGetDesktopWindow()); /* FIXME: Previous active window */
365 W32kReleaseWindowObject(WindowObject
);
371 WinPosDoNCCALCSize(PWINDOW_OBJECT Window
, PWINDOWPOS WinPos
,
372 RECT
* WindowRect
, RECT
* ClientRect
)
374 return 0; /* FIXME: Calculate non client size */
378 WinPosDoWinPosChanging(PWINDOW_OBJECT WindowObject
,
383 if (!(WinPos
->flags
& SWP_NOSENDCHANGING
))
385 W32kSendWINDOWPOSCHANGINGMessage(WindowObject
->Self
, WinPos
);
388 *WindowRect
= WindowObject
->WindowRect
;
390 (WindowObject
->Style
& WS_MINIMIZE
) ? WindowObject
->WindowRect
:
391 WindowObject
->ClientRect
;
393 /* Temp fix for WineMine */
395 if (!(WinPos
->flags
& SWP_NOSIZE
))
397 WindowRect
->right
= WindowRect
->left
+ WinPos
->cx
;
398 WindowRect
->bottom
= WindowRect
->top
+ WinPos
->cy
;
401 if (!(WinPos
->flags
& SWP_NOMOVE
))
403 WindowRect
->left
= WinPos
->x
;
404 WindowRect
->top
= WinPos
->y
;
405 WindowRect
->right
+= WinPos
->x
- WindowObject
->WindowRect
.left
;
406 WindowRect
->bottom
+= WinPos
->y
- WindowObject
->WindowRect
.top
;
409 if (!(WinPos
->flags
& SWP_NOSIZE
) || !(WinPos
->flags
& SWP_NOMOVE
))
411 WinPosGetNonClientSize(WindowObject
->Self
, WindowRect
, ClientRect
);
414 WinPos
->flags
|= SWP_NOCLIENTMOVE
| SWP_NOCLIENTSIZE
;
419 WinPosSetWindowPos(HWND Wnd
, HWND WndInsertAfter
, INT x
, INT y
, INT cx
,
422 PWINDOW_OBJECT Window
;
430 /* FIXME: Get current active window from active queue. */
432 /* Check if the window is for a desktop. */
433 if (Wnd
== PsGetWin32Thread()->Desktop
->DesktopWindow
)
439 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation
->HandleTable
,
443 if (!NT_SUCCESS(Status
))
448 /* Fix up the flags. */
449 if (Window
->Style
& WS_VISIBLE
)
451 flags
&= ~SWP_SHOWWINDOW
;
455 if (!(flags
& SWP_SHOWWINDOW
))
457 flags
|= SWP_NOREDRAW
;
459 flags
&= ~SWP_HIDEWINDOW
;
465 if ((Window
->WindowRect
.right
- Window
->WindowRect
.left
) == cx
&&
466 (Window
->WindowRect
.bottom
- Window
->WindowRect
.top
) == cy
)
470 if (Window
->WindowRect
.left
== x
&& Window
->WindowRect
.top
== y
)
474 if (FALSE
/* FIXME: Check if the window if already active. */)
476 flags
|= SWP_NOACTIVATE
;
478 else if ((Window
->Style
& (WS_POPUP
| WS_CHILD
)) != WS_CHILD
)
480 if (!(flags
& SWP_NOACTIVATE
))
482 flags
&= ~SWP_NOZORDER
;
483 WndInsertAfter
= HWND_TOP
;
487 if (WndInsertAfter
== HWND_TOPMOST
|| WndInsertAfter
== HWND_NOTOPMOST
)
489 WndInsertAfter
= HWND_TOP
;
492 if (WndInsertAfter
!= HWND_TOP
&& WndInsertAfter
!= HWND_BOTTOM
)
494 /* FIXME: Find the window to insert after. */
498 WinPos
.hwndInsertAfter
= WndInsertAfter
;
503 WinPos
.flags
= flags
;
505 WinPosDoWinPosChanging(Window
, &WinPos
, &NewWindowRect
, &NewClientRect
);
507 if ((WinPos
.flags
& (SWP_NOZORDER
| SWP_HIDEWINDOW
| SWP_SHOWWINDOW
)) !=
510 /* FIXME: SWP_DoOwnedPopups. */
513 /* FIXME: Adjust flags based on WndInsertAfter */
515 if ((!(WinPos
.flags
& (SWP_NOREDRAW
| SWP_SHOWWINDOW
)) &&
516 WinPos
.flags
& (SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
|
517 SWP_HIDEWINDOW
| SWP_FRAMECHANGED
)) !=
518 (SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
))
520 if (Window
->Style
& WS_CLIPCHILDREN
)
522 VisRgn
= DceGetVisRgn(Wnd
, DCX_WINDOW
| DCX_CLIPSIBLINGS
, 0, 0);
526 VisRgn
= DceGetVisRgn(Wnd
, DCX_WINDOW
, 0, 0);
530 WvrFlags
= WinPosDoNCCALCSize(Window
, &WinPos
, &NewWindowRect
,
533 /* FIXME: Relink windows. */
535 /* FIXME: Reset active DCEs */
537 /* FIXME: Check for redrawing the whole client rect. */
539 if (WinPos
.flags
& SWP_SHOWWINDOW
)
541 Window
->Style
|= WS_VISIBLE
;
542 flags
|= SWP_EX_PAINTSELF
;
547 /* FIXME: Move the window bits */
550 Window
->WindowRect
= NewWindowRect
;
551 Window
->ClientRect
= NewClientRect
;
553 if (WinPos
.flags
& SWP_HIDEWINDOW
)
555 Window
->Style
&= ~WS_VISIBLE
;
558 /* FIXME: Hide or show the claret */
562 if (!(WinPos
.flags
& SWP_NOREDRAW
))
564 if (flags
& SWP_EX_PAINTSELF
)
566 PaintRedrawWindow(Window
->Self
, NULL
,
567 (VisRgn
== (HRGN
) 1) ? 0 : VisRgn
,
568 RDW_ERASE
| RDW_FRAME
| RDW_INVALIDATE
|
569 RDW_ALLCHILDREN
| RDW_ERASENOW
,
570 RDW_EX_XYWINDOW
| RDW_EX_USEHRGN
);
574 PaintRedrawWindow(Window
->Self
, NULL
,
575 (VisRgn
== (HRGN
) 1) ? 0 : VisRgn
,
576 RDW_ERASE
| RDW_INVALIDATE
| RDW_ALLCHILDREN
|
580 /* FIXME: Redraw the window parent. */
582 /* FIXME: Delete VisRgn */
585 if (!(flags
& SWP_NOACTIVATE
))
587 WinPosChangeActiveWindow(WinPos
.hwnd
, FALSE
);
590 /* FIXME: Check some conditions before doing this. */
591 W32kSendWINDOWPOSCHANGEDMessage(Window
->Self
, &WinPos
);
593 ObmDereferenceObject(Window
);
598 WinPosGetNonClientSize(HWND Wnd
, RECT
* WindowRect
, RECT
* ClientRect
)
600 *ClientRect
= *WindowRect
;
601 return(W32kSendNCCALCSIZEMessage(Wnd
, FALSE
, ClientRect
, NULL
));
605 WinPosShowWindow(HWND Wnd
, INT Cmd
)
608 PWINDOW_OBJECT Window
;
615 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation
->HandleTable
,
619 if (!NT_SUCCESS(Status
))
624 WasVisible
= (Window
->Style
& WS_VISIBLE
) != 0;
632 ObmDereferenceObject(Window
);
635 Swp
|= SWP_HIDEWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
|
640 case SW_SHOWMINNOACTIVE
:
641 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
643 case SW_SHOWMINIMIZED
:
644 Swp
|= SWP_SHOWWINDOW
;
648 Swp
|= SWP_FRAMECHANGED
;
649 if (!(Window
->Style
& WS_MINIMIZE
))
651 Swp
|= WinPosMinMaximize(Window
, SW_MINIMIZE
, &NewPos
);
655 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
660 case SW_SHOWMAXIMIZED
:
662 Swp
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
663 if (!(Window
->Style
& WS_MAXIMIZE
))
665 Swp
|= WinPosMinMaximize(Window
, SW_MAXIMIZE
, &NewPos
);
669 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
675 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
678 Swp
|= SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
679 /* Don't activate the topmost window. */
682 case SW_SHOWNOACTIVATE
:
688 Swp
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
689 if (Window
->Style
& (WS_MINIMIZE
| WS_MAXIMIZE
))
691 Swp
|= WinPosMinMaximize(Window
, SW_RESTORE
, &NewPos
);
695 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
700 ShowFlag
= (Cmd
!= SW_HIDE
);
701 if (ShowFlag
!= WasVisible
)
703 NtUserSendMessage(Wnd
, WM_SHOWWINDOW
, ShowFlag
, 0);
705 * FIXME: Need to check the window wasn't destroyed during the
710 if (Window
->Style
& WS_CHILD
&&
711 !W32kIsWindowVisible(Window
->Parent
->Self
) &&
712 (Swp
& (SWP_NOSIZE
| SWP_NOMOVE
)) == (SWP_NOSIZE
| SWP_NOMOVE
))
716 Window
->Style
&= ~WS_VISIBLE
;
720 Window
->Style
|= WS_VISIBLE
;
725 if (Window
->Style
& WS_CHILD
&&
726 !(Window
->ExStyle
& WS_EX_MDICHILD
))
728 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
730 if (!(Swp
& MINMAX_NOSWP
))
732 WinPosSetWindowPos(Wnd
, HWND_TOP
, NewPos
.left
, NewPos
.top
,
733 NewPos
.right
, NewPos
.bottom
, LOWORD(Swp
));
736 /* Hide the window. */
737 if (Wnd
== W32kGetActiveWindow())
739 WinPosActivateOtherWindow(Window
);
741 /* Revert focus to parent. */
742 if (Wnd
== W32kGetFocusWindow() ||
743 W32kIsChildWindow(Wnd
, W32kGetFocusWindow()))
745 W32kSetFocusWindow(Window
->Parent
->Self
);
749 /* FIXME: Check for window destruction. */
750 /* Show title for minimized windows. */
751 if (Window
->Style
& WS_MINIMIZE
)
753 WinPosShowIconTitle(Window
, TRUE
);
757 if (Window
->Flags
& WINDOWOBJECT_NEED_SIZE
)
759 WPARAM wParam
= SIZE_RESTORED
;
761 Window
->Flags
&= ~WINDOWOBJECT_NEED_SIZE
;
762 if (Window
->Style
& WS_MAXIMIZE
)
764 wParam
= SIZE_MAXIMIZED
;
766 else if (Window
->Style
& WS_MINIMIZE
)
768 wParam
= SIZE_MINIMIZED
;
771 NtUserSendMessage(Wnd
, WM_SIZE
, wParam
,
772 MAKELONG(Window
->ClientRect
.right
-
773 Window
->ClientRect
.left
,
774 Window
->ClientRect
.bottom
-
775 Window
->ClientRect
.top
));
776 NtUserSendMessage(Wnd
, WM_MOVE
, 0,
777 MAKELONG(Window
->ClientRect
.left
,
778 Window
->ClientRect
.top
));
781 /* Activate the window if activation is not requested and the window is not minimized */
782 if (!(Swp
& (SWP_NOACTIVATE
| SWP_HIDEWINDOW
)) && !(Window
->Style
& WS_MINIMIZE
))
784 WinPosChangeActiveWindow(Wnd
, FALSE
);
787 ObmDereferenceObject(Window
);
792 WinPosPtInWindow(PWINDOW_OBJECT Window
, POINT Point
)
794 return(Point
.x
>= Window
->WindowRect
.left
&&
795 Point
.x
< Window
->WindowRect
.right
&&
796 Point
.y
>= Window
->WindowRect
.top
&&
797 Point
.y
< Window
->WindowRect
.bottom
);
800 USHORT STATIC STDCALL
801 WinPosSearchChildren(PWINDOW_OBJECT ScopeWin
, POINT Point
,
802 PWINDOW_OBJECT
* Window
)
804 PLIST_ENTRY CurrentEntry
;
805 PWINDOW_OBJECT Current
;
808 ExAcquireFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
809 CurrentEntry
= ScopeWin
->ChildrenListHead
.Flink
;
810 while (CurrentEntry
!= &ScopeWin
->ChildrenListHead
)
813 CONTAINING_RECORD(CurrentEntry
, WINDOW_OBJECT
, SiblingListEntry
);
815 if (Current
->Style
& WS_VISIBLE
&&
816 ((!(Current
->Style
& WS_DISABLED
)) ||
817 (Current
->Style
& (WS_CHILD
| WS_POPUP
)) != WS_CHILD
) &&
818 WinPosPtInWindow(Current
, Point
))
821 if (Current
->Style
& WS_DISABLED
)
823 ExReleaseFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
826 if (Current
->Style
& WS_MINIMIZE
)
828 ExReleaseFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
831 if (Point
.x
>= Current
->ClientRect
.left
&&
832 Point
.x
< Current
->ClientRect
.right
&&
833 Point
.y
>= Current
->ClientRect
.top
&&
834 Point
.y
< Current
->ClientRect
.bottom
)
836 Point
.x
-= Current
->ClientRect
.left
;
837 Point
.y
-= Current
->ClientRect
.top
;
839 ExReleaseFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
840 return(WinPosSearchChildren(Current
, Point
, Window
));
843 ExReleaseFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
846 CurrentEntry
= CurrentEntry
->Flink
;
849 ExReleaseFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
854 WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin
, POINT WinPoint
,
855 PWINDOW_OBJECT
* Window
)
857 HWND DesktopWindowHandle
;
858 PWINDOW_OBJECT DesktopWindow
;
859 POINT Point
= WinPoint
;
864 if (ScopeWin
->Style
& WS_DISABLED
)
869 /* Translate the point to the space of the scope window. */
870 DesktopWindowHandle
= W32kGetDesktopWindow();
871 DesktopWindow
= W32kGetWindowObject(DesktopWindowHandle
);
872 Point
.x
+= ScopeWin
->ClientRect
.left
- DesktopWindow
->ClientRect
.left
;
873 Point
.y
+= ScopeWin
->ClientRect
.top
- DesktopWindow
->ClientRect
.top
;
874 W32kReleaseWindowObject(DesktopWindow
);
876 HitTest
= WinPosSearchChildren(ScopeWin
, Point
, Window
);
882 if ((*Window
) == NULL
)
886 if ((*Window
)->MessageQueue
== PsGetWin32Thread()->MessageQueue
)
888 HitTest
= W32kSendMessage((*Window
)->Self
, WM_NCHITTEST
, 0,
889 MAKELONG(Point
.x
, Point
.y
), FALSE
);
890 /* FIXME: Check for HTTRANSPARENT here. */
901 WinPosSetActiveWindow(PWINDOW_OBJECT Window
, BOOL Mouse
, BOOL ChangeFocus
)
903 PUSER_MESSAGE_QUEUE ActiveQueue
;
906 ActiveQueue
= W32kGetFocusMessageQueue();
907 if (ActiveQueue
!= NULL
)
909 PrevActive
= ActiveQueue
->ActiveWindow
;
916 if (Window
->Self
== W32kGetActiveDesktop() || Window
->Self
== PrevActive
)
920 if (PrevActive
!= NULL
)
922 PWINDOW_OBJECT PrevActiveWindow
= W32kGetWindowObject(PrevActive
);
923 WORD Iconised
= HIWORD(PrevActiveWindow
->Style
& WS_MINIMIZE
);
924 if (!W32kSendMessage(PrevActive
, WM_NCACTIVATE
, FALSE
, 0, TRUE
))
926 /* FIXME: Check if the new window is system modal. */
929 W32kSendMessage(PrevActive
,
931 MAKEWPARAM(WA_INACTIVE
, Iconised
),
932 (LPARAM
)Window
->Self
,
934 /* FIXME: Check if anything changed while processing the message. */
935 W32kReleaseWindowObject(PrevActiveWindow
);
940 Window
->MessageQueue
->ActiveWindow
= Window
->Self
;
942 else if (ActiveQueue
!= NULL
)
944 ActiveQueue
->ActiveWindow
= NULL
;
947 /* FIXME: Send palette messages. */
949 /* FIXME: Redraw icon title of previously active window. */
951 /* FIXME: Bring the window to the top. */
953 /* FIXME: Send WM_ACTIVATEAPP */
955 W32kSetFocusMessageQueue(Window
->MessageQueue
);
957 /* FIXME: Send activate messages. */
959 /* FIXME: Change focus. */
961 /* FIXME: Redraw new window icon title. */
967 NtUserGetActiveWindow(VOID
)
969 PUSER_MESSAGE_QUEUE ActiveQueue
;
971 ActiveQueue
= W32kGetFocusMessageQueue();
972 if (ActiveQueue
== NULL
)
976 return(ActiveQueue
->ActiveWindow
);
980 NtUserSetActiveWindow(HWND hWnd
)
982 PWINDOW_OBJECT Window
;
983 PUSER_MESSAGE_QUEUE ThreadQueue
;
986 Window
= W32kGetWindowObject(hWnd
);
987 if (Window
== NULL
|| (Window
->Style
& (WS_DISABLED
| WS_CHILD
)))
989 W32kReleaseWindowObject(Window
);
992 ThreadQueue
= (PUSER_MESSAGE_QUEUE
)PsGetWin32Thread()->MessageQueue
;
993 if (Window
->MessageQueue
!= ThreadQueue
)
995 W32kReleaseWindowObject(Window
);
998 Prev
= Window
->MessageQueue
->ActiveWindow
;
999 WinPosSetActiveWindow(Window
, FALSE
, FALSE
);
1000 W32kReleaseWindowObject(Window
);