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.10 2003/05/18 17:16:17 ea 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 Wnd
, BOOL MouseMsg
)
355 WinPosDoNCCALCSize(PWINDOW_OBJECT Window
, PWINDOWPOS WinPos
,
356 RECT
* WindowRect
, RECT
* ClientRect
)
362 WinPosDoWinPosChanging(PWINDOW_OBJECT WindowObject
,
367 if (!(WinPos
->flags
& SWP_NOSENDCHANGING
))
369 W32kSendWINDOWPOSCHANGINGMessage(WindowObject
->Self
, WinPos
);
372 *WindowRect
= WindowObject
->WindowRect
;
374 (WindowObject
->Style
& WS_MINIMIZE
) ? WindowObject
->WindowRect
:
375 WindowObject
->ClientRect
;
377 if (!(WinPos
->flags
& SWP_NOSIZE
))
379 WindowRect
->right
= WindowRect
->left
+ WinPos
->cx
;
380 WindowRect
->bottom
= WindowRect
->top
+ WinPos
->cy
;
383 if (!(WinPos
->flags
& SWP_NOMOVE
))
385 WindowRect
->left
= WinPos
->x
;
386 WindowRect
->top
= WinPos
->y
;
387 WindowRect
->right
+= WinPos
->x
- WindowObject
->WindowRect
.left
;
388 WindowRect
->bottom
+= WinPos
->y
- WindowObject
->WindowRect
.top
;
390 W32kOffsetRect(ClientRect
, WinPos
->x
- WindowObject
->WindowRect
.left
,
391 WinPos
->y
- WindowObject
->WindowRect
.top
);
394 WinPos
->flags
|= SWP_NOCLIENTMOVE
| SWP_NOCLIENTSIZE
;
399 WinPosSetWindowPos(HWND Wnd
, HWND WndInsertAfter
, INT x
, INT y
, INT cx
,
402 PWINDOW_OBJECT Window
;
410 /* FIXME: Get current active window from active queue. */
412 /* Check if the window is for a desktop. */
413 if (Wnd
== PsGetWin32Thread()->Desktop
->DesktopWindow
)
419 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation
->HandleTable
,
423 if (!NT_SUCCESS(Status
))
428 /* Fix up the flags. */
429 if (Window
->Style
& WS_VISIBLE
)
431 flags
&= ~SWP_SHOWWINDOW
;
435 if (!(flags
& SWP_SHOWWINDOW
))
437 flags
|= SWP_NOREDRAW
;
439 flags
&= ~SWP_HIDEWINDOW
;
445 if ((Window
->WindowRect
.right
- Window
->WindowRect
.left
) == cx
&&
446 (Window
->WindowRect
.bottom
- Window
->WindowRect
.top
) == cy
)
450 if (Window
->WindowRect
.left
== x
&& Window
->WindowRect
.top
== y
)
454 if (FALSE
/* FIXME: Check if the window if already active. */)
456 flags
|= SWP_NOACTIVATE
;
458 else if ((Window
->Style
& (WS_POPUP
| WS_CHILD
)) != WS_CHILD
)
460 if (!(flags
& SWP_NOACTIVATE
))
462 flags
&= ~SWP_NOZORDER
;
463 WndInsertAfter
= HWND_TOP
;
467 if (WndInsertAfter
== HWND_TOPMOST
|| WndInsertAfter
== HWND_NOTOPMOST
)
469 WndInsertAfter
= HWND_TOP
;
472 if (WndInsertAfter
!= HWND_TOP
&& WndInsertAfter
!= HWND_BOTTOM
)
474 /* FIXME: Find the window to insert after. */
478 WinPos
.hwndInsertAfter
= WndInsertAfter
;
483 WinPos
.flags
= flags
;
485 WinPosDoWinPosChanging(Window
, &WinPos
, &NewWindowRect
, &NewClientRect
);
487 if ((WinPos
.flags
& (SWP_NOZORDER
| SWP_HIDEWINDOW
| SWP_SHOWWINDOW
)) !=
490 /* FIXME: SWP_DoOwnedPopups. */
493 /* FIXME: Adjust flags based on WndInsertAfter */
495 if ((!(WinPos
.flags
& (SWP_NOREDRAW
| SWP_SHOWWINDOW
)) &&
496 WinPos
.flags
& (SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
|
497 SWP_HIDEWINDOW
| SWP_FRAMECHANGED
)) !=
498 (SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
))
500 if (Window
->Style
& WS_CLIPCHILDREN
)
502 VisRgn
= DceGetVisRgn(Wnd
, DCX_WINDOW
| DCX_CLIPSIBLINGS
, 0, 0);
506 VisRgn
= DceGetVisRgn(Wnd
, DCX_WINDOW
, 0, 0);
510 WvrFlags
= WinPosDoNCCALCSize(Window
, &WinPos
, &NewWindowRect
,
513 /* FIXME: Relink windows. */
515 /* FIXME: Reset active DCEs */
517 /* FIXME: Check for redrawing the whole client rect. */
519 if (WinPos
.flags
& SWP_SHOWWINDOW
)
521 Window
->Style
|= WS_VISIBLE
;
522 flags
|= SWP_EX_PAINTSELF
;
527 /* FIXME: Move the window bits */
530 Window
->WindowRect
= NewWindowRect
;
531 Window
->ClientRect
= NewClientRect
;
533 if (WinPos
.flags
& SWP_HIDEWINDOW
)
535 Window
->Style
&= ~WS_VISIBLE
;
538 /* FIXME: Hide or show the claret */
542 if (!(WinPos
.flags
& SWP_NOREDRAW
))
544 if (flags
& SWP_EX_PAINTSELF
)
546 PaintRedrawWindow(Window
->Self
, NULL
,
547 (VisRgn
== (HRGN
) 1) ? 0 : VisRgn
,
548 RDW_ERASE
| RDW_FRAME
| RDW_INVALIDATE
|
550 RDW_EX_XYWINDOW
| RDW_EX_USEHRGN
);
554 PaintRedrawWindow(Window
->Self
, NULL
,
555 (VisRgn
== (HRGN
) 1) ? 0 : VisRgn
,
556 RDW_ERASE
| RDW_INVALIDATE
| RDW_ALLCHILDREN
,
559 /* FIXME: Redraw the window parent. */
561 /* FIXME: Delete VisRgn */
564 if (!(flags
& SWP_NOACTIVATE
))
566 WinPosChangeActiveWindow(WinPos
.hwnd
, FALSE
);
569 /* FIXME: Check some conditions before doing this. */
570 W32kSendWINDOWPOSCHANGEDMessage(Window
->Self
, &WinPos
);
572 ObmDereferenceObject(Window
);
577 WinPosGetNonClientSize(HWND Wnd
, RECT
* WindowRect
, RECT
* ClientRect
)
579 *ClientRect
= *WindowRect
;
580 return(W32kSendNCCALCSIZEMessage(Wnd
, FALSE
, ClientRect
, NULL
));
584 WinPosShowWindow(HWND Wnd
, INT Cmd
)
587 PWINDOW_OBJECT Window
;
594 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation
->HandleTable
,
598 if (!NT_SUCCESS(Status
))
603 WasVisible
= (Window
->Style
& WS_VISIBLE
) != 0;
611 ObmDereferenceObject(Window
);
614 Swp
|= SWP_HIDEWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
|
619 case SW_SHOWMINNOACTIVE
:
620 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
622 case SW_SHOWMINIMIZED
:
623 Swp
|= SWP_SHOWWINDOW
;
627 Swp
|= SWP_FRAMECHANGED
;
628 if (!(Window
->Style
& WS_MINIMIZE
))
630 Swp
|= WinPosMinMaximize(Window
, SW_MINIMIZE
, &NewPos
);
634 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
639 case SW_SHOWMAXIMIZED
:
641 Swp
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
642 if (!(Window
->Style
& WS_MAXIMIZE
))
644 Swp
|= WinPosMinMaximize(Window
, SW_MAXIMIZE
, &NewPos
);
648 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
654 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
657 Swp
|= SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
658 /* Don't activate the topmost window. */
661 case SW_SHOWNOACTIVATE
:
667 Swp
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
668 if (Window
->Style
& (WS_MINIMIZE
| WS_MAXIMIZE
))
670 Swp
|= WinPosMinMaximize(Window
, SW_RESTORE
, &NewPos
);
674 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
679 ShowFlag
= (Cmd
!= SW_HIDE
);
680 if (ShowFlag
!= WasVisible
)
682 NtUserSendMessage(Wnd
, WM_SHOWWINDOW
, ShowFlag
, 0);
684 * FIXME: Need to check the window wasn't destroyed during the
689 if (Window
->Style
& WS_CHILD
&&
690 !W32kIsWindowVisible(Window
->Parent
->Self
) &&
691 (Swp
& (SWP_NOSIZE
| SWP_NOMOVE
)) == (SWP_NOSIZE
| SWP_NOMOVE
))
695 Window
->Style
&= ~WS_VISIBLE
;
699 Window
->Style
|= WS_VISIBLE
;
704 if (Window
->Style
& WS_CHILD
&&
705 !(Window
->ExStyle
& WS_EX_MDICHILD
))
707 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
709 if (!(Swp
& MINMAX_NOSWP
))
711 WinPosSetWindowPos(Wnd
, HWND_TOP
, NewPos
.left
, NewPos
.top
,
712 NewPos
.right
, NewPos
.bottom
, LOWORD(Swp
));
715 /* Hide the window. */
716 if (Wnd
== W32kGetActiveWindow())
718 WinPosActivateOtherWindow(Window
);
720 /* Revert focus to parent. */
721 if (Wnd
== W32kGetFocusWindow() ||
722 W32kIsChildWindow(Wnd
, W32kGetFocusWindow()))
724 W32kSetFocusWindow(Window
->Parent
->Self
);
728 /* FIXME: Check for window destruction. */
729 /* Show title for minimized windows. */
730 if (Window
->Style
& WS_MINIMIZE
)
732 WinPosShowIconTitle(Window
, TRUE
);
736 if (Window
->Flags
& WINDOWOBJECT_NEED_SIZE
)
738 WPARAM wParam
= SIZE_RESTORED
;
740 Window
->Flags
&= ~WINDOWOBJECT_NEED_SIZE
;
741 if (Window
->Style
& WS_MAXIMIZE
)
743 wParam
= SIZE_MAXIMIZED
;
745 else if (Window
->Style
& WS_MINIMIZE
)
747 wParam
= SIZE_MINIMIZED
;
750 NtUserSendMessage(Wnd
, WM_SIZE
, wParam
,
751 MAKELONG(Window
->ClientRect
.right
-
752 Window
->ClientRect
.left
,
753 Window
->ClientRect
.bottom
-
754 Window
->ClientRect
.top
));
755 NtUserSendMessage(Wnd
, WM_MOVE
, 0,
756 MAKELONG(Window
->ClientRect
.left
,
757 Window
->ClientRect
.top
));
759 ObmDereferenceObject(Window
);
764 WinPosPtInWindow(PWINDOW_OBJECT Window
, POINT Point
)
766 return(Point
.x
>= Window
->WindowRect
.left
&&
767 Point
.x
< Window
->WindowRect
.right
&&
768 Point
.y
>= Window
->WindowRect
.top
&&
769 Point
.y
< Window
->WindowRect
.bottom
);
772 USHORT STATIC STDCALL
773 WinPosSearchChildren(PWINDOW_OBJECT ScopeWin
, POINT Point
,
774 PWINDOW_OBJECT
* Window
)
776 PLIST_ENTRY CurrentEntry
;
777 PWINDOW_OBJECT Current
;
779 CurrentEntry
= ScopeWin
->ChildrenListHead
.Flink
;
780 while (CurrentEntry
!= &ScopeWin
->ChildrenListHead
)
783 CONTAINING_RECORD(CurrentEntry
, WINDOW_OBJECT
, SiblingListEntry
);
785 if (Current
->Style
& WS_VISIBLE
&&
786 ((!(Current
->Style
& WS_DISABLED
)) ||
787 (Current
->Style
& (WS_CHILD
| WS_POPUP
)) != WS_CHILD
) &&
788 WinPosPtInWindow(Current
, Point
))
791 if (Current
->Style
& WS_DISABLED
)
795 if (Current
->Style
& WS_MINIMIZE
)
799 if (Point
.x
>= Current
->ClientRect
.left
&&
800 Point
.x
< Current
->ClientRect
.right
&&
801 Point
.y
>= Current
->ClientRect
.top
&&
802 Point
.y
< Current
->ClientRect
.bottom
)
804 Point
.x
-= Current
->ClientRect
.left
;
805 Point
.y
-= Current
->ClientRect
.top
;
807 return(WinPosSearchChildren(Current
, Point
, Window
));
811 CurrentEntry
= CurrentEntry
->Flink
;
817 WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin
, POINT WinPoint
,
818 PWINDOW_OBJECT
* Window
)
820 HWND DesktopWindowHandle
;
821 PWINDOW_OBJECT DesktopWindow
;
822 POINT Point
= WinPoint
;
827 if (ScopeWin
->Style
& WS_DISABLED
)
832 /* Translate the point to the space of the scope window. */
833 DesktopWindowHandle
= W32kGetDesktopWindow();
834 DesktopWindow
= W32kGetWindowObject(DesktopWindowHandle
);
835 Point
.x
+= ScopeWin
->ClientRect
.left
- DesktopWindow
->ClientRect
.left
;
836 Point
.y
+= ScopeWin
->ClientRect
.top
- DesktopWindow
->ClientRect
.top
;
837 W32kReleaseWindowObject(DesktopWindow
);
839 HitTest
= WinPosSearchChildren(ScopeWin
, Point
, Window
);
845 if ((*Window
) == NULL
)
849 if ((*Window
)->MessageQueue
== PsGetWin32Thread()->MessageQueue
)
851 HitTest
= W32kSendMessage((*Window
)->Self
, WM_NCHITTEST
, 0,
852 MAKELONG(Point
.x
, Point
.y
), FALSE
);
853 /* FIXME: Check for HTTRANSPARENT here. */