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.17 2003/07/29 22:42:26 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 if (!(WinPos
->flags
& SWP_NOSIZE
))
395 WindowRect
->right
= WindowRect
->left
+ WinPos
->cx
;
396 WindowRect
->bottom
= WindowRect
->top
+ WinPos
->cy
;
399 if (!(WinPos
->flags
& SWP_NOMOVE
))
401 WindowRect
->left
= WinPos
->x
;
402 WindowRect
->top
= WinPos
->y
;
403 WindowRect
->right
+= WinPos
->x
- WindowObject
->WindowRect
.left
;
404 WindowRect
->bottom
+= WinPos
->y
- WindowObject
->WindowRect
.top
;
407 if (!(WinPos
->flags
& SWP_NOSIZE
) || !(WinPos
->flags
& SWP_NOMOVE
))
409 WinPosGetNonClientSize(WindowObject
->Self
, WindowRect
, ClientRect
);
412 WinPos
->flags
|= SWP_NOCLIENTMOVE
| SWP_NOCLIENTSIZE
;
417 WinPosSetWindowPos(HWND Wnd
, HWND WndInsertAfter
, INT x
, INT y
, INT cx
,
420 PWINDOW_OBJECT Window
;
428 /* FIXME: Get current active window from active queue. */
430 /* Check if the window is for a desktop. */
431 if (Wnd
== PsGetWin32Thread()->Desktop
->DesktopWindow
)
437 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation
->HandleTable
,
441 if (!NT_SUCCESS(Status
))
446 /* Fix up the flags. */
447 if (Window
->Style
& WS_VISIBLE
)
449 flags
&= ~SWP_SHOWWINDOW
;
453 if (!(flags
& SWP_SHOWWINDOW
))
455 flags
|= SWP_NOREDRAW
;
457 flags
&= ~SWP_HIDEWINDOW
;
463 if ((Window
->WindowRect
.right
- Window
->WindowRect
.left
) == cx
&&
464 (Window
->WindowRect
.bottom
- Window
->WindowRect
.top
) == cy
)
468 if (Window
->WindowRect
.left
== x
&& Window
->WindowRect
.top
== y
)
472 if (Window
->Style
& WIN_NCACTIVATED
)
474 flags
|= SWP_NOACTIVATE
;
476 else if ((Window
->Style
& (WS_POPUP
| WS_CHILD
)) != WS_CHILD
)
478 if (!(flags
& SWP_NOACTIVATE
))
480 flags
&= ~SWP_NOZORDER
;
481 WndInsertAfter
= HWND_TOP
;
485 if (WndInsertAfter
== HWND_TOPMOST
|| WndInsertAfter
== HWND_NOTOPMOST
)
487 WndInsertAfter
= HWND_TOP
;
490 if (WndInsertAfter
!= HWND_TOP
&& WndInsertAfter
!= HWND_BOTTOM
)
492 /* FIXME: Find the window to insert after. */
496 WinPos
.hwndInsertAfter
= WndInsertAfter
;
501 WinPos
.flags
= flags
;
503 WinPosDoWinPosChanging(Window
, &WinPos
, &NewWindowRect
, &NewClientRect
);
505 if ((WinPos
.flags
& (SWP_NOZORDER
| SWP_HIDEWINDOW
| SWP_SHOWWINDOW
)) !=
508 /* FIXME: SWP_DoOwnedPopups. */
511 /* FIXME: Adjust flags based on WndInsertAfter */
513 if ((!(WinPos
.flags
& (SWP_NOREDRAW
| SWP_SHOWWINDOW
)) &&
514 WinPos
.flags
& (SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
|
515 SWP_HIDEWINDOW
| SWP_FRAMECHANGED
)) !=
516 (SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
))
518 if (Window
->Style
& WS_CLIPCHILDREN
)
520 VisRgn
= DceGetVisRgn(Wnd
, DCX_WINDOW
| DCX_CLIPSIBLINGS
, 0, 0);
524 VisRgn
= DceGetVisRgn(Wnd
, DCX_WINDOW
, 0, 0);
528 WvrFlags
= WinPosDoNCCALCSize(Window
, &WinPos
, &NewWindowRect
,
531 /* FIXME: Relink windows. */
533 /* FIXME: Reset active DCEs */
535 /* FIXME: Check for redrawing the whole client rect. */
537 if (WinPos
.flags
& SWP_SHOWWINDOW
)
539 Window
->Style
|= WS_VISIBLE
;
540 flags
|= SWP_EX_PAINTSELF
;
545 /* FIXME: Move the window bits */
548 Window
->WindowRect
= NewWindowRect
;
549 Window
->ClientRect
= NewClientRect
;
551 if (WinPos
.flags
& SWP_HIDEWINDOW
)
553 Window
->Style
&= ~WS_VISIBLE
;
556 /* FIXME: Hide or show the claret */
560 if (!(WinPos
.flags
& SWP_NOREDRAW
))
562 if (flags
& SWP_EX_PAINTSELF
)
564 PaintRedrawWindow(Window
->Self
, NULL
,
565 (VisRgn
== (HRGN
) 1) ? 0 : VisRgn
,
566 RDW_ERASE
| RDW_FRAME
| RDW_INVALIDATE
|
567 RDW_ALLCHILDREN
| RDW_ERASENOW
,
568 RDW_EX_XYWINDOW
| RDW_EX_USEHRGN
);
572 PaintRedrawWindow(Window
->Self
, NULL
,
573 (VisRgn
== (HRGN
) 1) ? 0 : VisRgn
,
574 RDW_ERASE
| RDW_INVALIDATE
| RDW_ALLCHILDREN
|
578 /* FIXME: Redraw the window parent. */
580 /* FIXME: Delete VisRgn */
583 if (!(flags
& SWP_NOACTIVATE
))
585 WinPosChangeActiveWindow(WinPos
.hwnd
, FALSE
);
588 /* FIXME: Check some conditions before doing this. */
589 W32kSendWINDOWPOSCHANGEDMessage(Window
->Self
, &WinPos
);
591 ObmDereferenceObject(Window
);
596 WinPosGetNonClientSize(HWND Wnd
, RECT
* WindowRect
, RECT
* ClientRect
)
598 *ClientRect
= *WindowRect
;
599 return(W32kSendNCCALCSIZEMessage(Wnd
, FALSE
, ClientRect
, NULL
));
603 WinPosShowWindow(HWND Wnd
, INT Cmd
)
606 PWINDOW_OBJECT Window
;
613 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation
->HandleTable
,
617 if (!NT_SUCCESS(Status
))
622 WasVisible
= (Window
->Style
& WS_VISIBLE
) != 0;
630 ObmDereferenceObject(Window
);
633 Swp
|= SWP_HIDEWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
|
638 case SW_SHOWMINNOACTIVE
:
639 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
641 case SW_SHOWMINIMIZED
:
642 Swp
|= SWP_SHOWWINDOW
;
646 Swp
|= SWP_FRAMECHANGED
;
647 if (!(Window
->Style
& WS_MINIMIZE
))
649 Swp
|= WinPosMinMaximize(Window
, SW_MINIMIZE
, &NewPos
);
653 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
658 case SW_SHOWMAXIMIZED
:
660 Swp
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
661 if (!(Window
->Style
& WS_MAXIMIZE
))
663 Swp
|= WinPosMinMaximize(Window
, SW_MAXIMIZE
, &NewPos
);
667 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
673 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
676 Swp
|= SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
677 /* Don't activate the topmost window. */
680 case SW_SHOWNOACTIVATE
:
686 Swp
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
687 if (Window
->Style
& (WS_MINIMIZE
| WS_MAXIMIZE
))
689 Swp
|= WinPosMinMaximize(Window
, SW_RESTORE
, &NewPos
);
693 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
698 ShowFlag
= (Cmd
!= SW_HIDE
);
699 if (ShowFlag
!= WasVisible
)
701 NtUserSendMessage(Wnd
, WM_SHOWWINDOW
, ShowFlag
, 0);
703 * FIXME: Need to check the window wasn't destroyed during the
708 if (Window
->Style
& WS_CHILD
&&
709 !W32kIsWindowVisible(Window
->Parent
->Self
) &&
710 (Swp
& (SWP_NOSIZE
| SWP_NOMOVE
)) == (SWP_NOSIZE
| SWP_NOMOVE
))
714 Window
->Style
&= ~WS_VISIBLE
;
718 Window
->Style
|= WS_VISIBLE
;
723 if (Window
->Style
& WS_CHILD
&&
724 !(Window
->ExStyle
& WS_EX_MDICHILD
))
726 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
728 if (!(Swp
& MINMAX_NOSWP
))
730 WinPosSetWindowPos(Wnd
, HWND_TOP
, NewPos
.left
, NewPos
.top
,
731 NewPos
.right
, NewPos
.bottom
, LOWORD(Swp
));
734 /* Hide the window. */
735 if (Wnd
== W32kGetActiveWindow())
737 WinPosActivateOtherWindow(Window
);
739 /* Revert focus to parent. */
740 if (Wnd
== W32kGetFocusWindow() ||
741 W32kIsChildWindow(Wnd
, W32kGetFocusWindow()))
743 W32kSetFocusWindow(Window
->Parent
->Self
);
747 /* FIXME: Check for window destruction. */
748 /* Show title for minimized windows. */
749 if (Window
->Style
& WS_MINIMIZE
)
751 WinPosShowIconTitle(Window
, TRUE
);
755 if (Window
->Flags
& WINDOWOBJECT_NEED_SIZE
)
757 WPARAM wParam
= SIZE_RESTORED
;
759 Window
->Flags
&= ~WINDOWOBJECT_NEED_SIZE
;
760 if (Window
->Style
& WS_MAXIMIZE
)
762 wParam
= SIZE_MAXIMIZED
;
764 else if (Window
->Style
& WS_MINIMIZE
)
766 wParam
= SIZE_MINIMIZED
;
769 NtUserSendMessage(Wnd
, WM_SIZE
, wParam
,
770 MAKELONG(Window
->ClientRect
.right
-
771 Window
->ClientRect
.left
,
772 Window
->ClientRect
.bottom
-
773 Window
->ClientRect
.top
));
774 NtUserSendMessage(Wnd
, WM_MOVE
, 0,
775 MAKELONG(Window
->ClientRect
.left
,
776 Window
->ClientRect
.top
));
779 /* Activate the window if activation is not requested and the window is not minimized */
780 if (!(Swp
& (SWP_NOACTIVATE
| SWP_HIDEWINDOW
)) && !(Window
->Style
& WS_MINIMIZE
))
782 WinPosChangeActiveWindow(Wnd
, FALSE
);
785 ObmDereferenceObject(Window
);
790 WinPosPtInWindow(PWINDOW_OBJECT Window
, POINT Point
)
792 return(Point
.x
>= Window
->WindowRect
.left
&&
793 Point
.x
< Window
->WindowRect
.right
&&
794 Point
.y
>= Window
->WindowRect
.top
&&
795 Point
.y
< Window
->WindowRect
.bottom
);
798 USHORT STATIC STDCALL
799 WinPosSearchChildren(PWINDOW_OBJECT ScopeWin
, POINT Point
,
800 PWINDOW_OBJECT
* Window
)
802 PLIST_ENTRY CurrentEntry
;
803 PWINDOW_OBJECT Current
;
806 ExAcquireFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
807 CurrentEntry
= ScopeWin
->ChildrenListHead
.Flink
;
808 while (CurrentEntry
!= &ScopeWin
->ChildrenListHead
)
811 CONTAINING_RECORD(CurrentEntry
, WINDOW_OBJECT
, SiblingListEntry
);
813 if (Current
->Style
& WS_VISIBLE
&&
814 ((!(Current
->Style
& WS_DISABLED
)) ||
815 (Current
->Style
& (WS_CHILD
| WS_POPUP
)) != WS_CHILD
) &&
816 WinPosPtInWindow(Current
, Point
))
819 if (Current
->Style
& WS_DISABLED
)
821 ExReleaseFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
824 if (Current
->Style
& WS_MINIMIZE
)
826 ExReleaseFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
829 if (Point
.x
>= Current
->ClientRect
.left
&&
830 Point
.x
< Current
->ClientRect
.right
&&
831 Point
.y
>= Current
->ClientRect
.top
&&
832 Point
.y
< Current
->ClientRect
.bottom
)
834 Point
.x
-= Current
->ClientRect
.left
;
835 Point
.y
-= Current
->ClientRect
.top
;
837 ExReleaseFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
838 return(WinPosSearchChildren(Current
, Point
, Window
));
841 ExReleaseFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
844 CurrentEntry
= CurrentEntry
->Flink
;
847 ExReleaseFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
852 WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin
, POINT WinPoint
,
853 PWINDOW_OBJECT
* Window
)
855 HWND DesktopWindowHandle
;
856 PWINDOW_OBJECT DesktopWindow
;
857 POINT Point
= WinPoint
;
862 if (ScopeWin
->Style
& WS_DISABLED
)
867 /* Translate the point to the space of the scope window. */
868 DesktopWindowHandle
= W32kGetDesktopWindow();
869 DesktopWindow
= W32kGetWindowObject(DesktopWindowHandle
);
870 Point
.x
+= ScopeWin
->ClientRect
.left
- DesktopWindow
->ClientRect
.left
;
871 Point
.y
+= ScopeWin
->ClientRect
.top
- DesktopWindow
->ClientRect
.top
;
872 W32kReleaseWindowObject(DesktopWindow
);
874 HitTest
= WinPosSearchChildren(ScopeWin
, Point
, Window
);
880 if ((*Window
) == NULL
)
884 if ((*Window
)->MessageQueue
== PsGetWin32Thread()->MessageQueue
)
886 HitTest
= W32kSendMessage((*Window
)->Self
, WM_NCHITTEST
, 0,
887 MAKELONG(Point
.x
, Point
.y
), FALSE
);
888 /* FIXME: Check for HTTRANSPARENT here. */
899 WinPosSetActiveWindow(PWINDOW_OBJECT Window
, BOOL Mouse
, BOOL ChangeFocus
)
901 PUSER_MESSAGE_QUEUE ActiveQueue
;
904 ActiveQueue
= W32kGetFocusMessageQueue();
905 if (ActiveQueue
!= NULL
)
907 PrevActive
= ActiveQueue
->ActiveWindow
;
914 if (Window
->Self
== W32kGetActiveDesktop() || Window
->Self
== PrevActive
)
918 if (PrevActive
!= NULL
)
920 PWINDOW_OBJECT PrevActiveWindow
= W32kGetWindowObject(PrevActive
);
921 WORD Iconised
= HIWORD(PrevActiveWindow
->Style
& WS_MINIMIZE
);
922 if (!W32kSendMessage(PrevActive
, WM_NCACTIVATE
, FALSE
, 0, TRUE
))
924 /* FIXME: Check if the new window is system modal. */
927 W32kSendMessage(PrevActive
,
929 MAKEWPARAM(WA_INACTIVE
, Iconised
),
930 (LPARAM
)Window
->Self
,
932 /* FIXME: Check if anything changed while processing the message. */
933 W32kReleaseWindowObject(PrevActiveWindow
);
938 Window
->MessageQueue
->ActiveWindow
= Window
->Self
;
940 else if (ActiveQueue
!= NULL
)
942 ActiveQueue
->ActiveWindow
= NULL
;
945 /* FIXME: Send palette messages. */
947 /* FIXME: Redraw icon title of previously active window. */
949 /* FIXME: Bring the window to the top. */
951 /* FIXME: Send WM_ACTIVATEAPP */
953 W32kSetFocusMessageQueue(Window
->MessageQueue
);
955 /* FIXME: Send activate messages. */
957 /* FIXME: Change focus. */
959 /* FIXME: Redraw new window icon title. */
965 NtUserGetActiveWindow(VOID
)
967 PUSER_MESSAGE_QUEUE ActiveQueue
;
969 ActiveQueue
= W32kGetFocusMessageQueue();
970 if (ActiveQueue
== NULL
)
974 return(ActiveQueue
->ActiveWindow
);
978 NtUserSetActiveWindow(HWND hWnd
)
980 PWINDOW_OBJECT Window
;
981 PUSER_MESSAGE_QUEUE ThreadQueue
;
984 Window
= W32kGetWindowObject(hWnd
);
985 if (Window
== NULL
|| (Window
->Style
& (WS_DISABLED
| WS_CHILD
)))
987 W32kReleaseWindowObject(Window
);
990 ThreadQueue
= (PUSER_MESSAGE_QUEUE
)PsGetWin32Thread()->MessageQueue
;
991 if (Window
->MessageQueue
!= ThreadQueue
)
993 W32kReleaseWindowObject(Window
);
996 Prev
= Window
->MessageQueue
->ActiveWindow
;
997 WinPosSetActiveWindow(Window
, FALSE
, FALSE
);
998 W32kReleaseWindowObject(Window
);