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.47 2003/11/24 21:01:20 navaraf 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 NtGdid
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>
39 #include <include/winpos.h>
40 #include <include/rect.h>
41 #include <include/callback.h>
42 #include <include/painting.h>
43 #include <include/dce.h>
44 #include <include/vis.h>
49 /* GLOBALS *******************************************************************/
51 #define MINMAX_NOSWP (0x00010000)
53 #define SWP_EX_NOCOPY 0x0001
54 #define SWP_EX_PAINTSELF 0x0002
56 #define SWP_AGG_NOGEOMETRYCHANGE \
57 (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)
58 #define SWP_AGG_NOPOSCHANGE \
59 (SWP_AGG_NOGEOMETRYCHANGE | SWP_NOZORDER)
60 #define SWP_AGG_STATUSFLAGS \
61 (SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
63 ATOM AtomInternalPos
= (ATOM
) NULL
;
65 /* FUNCTIONS *****************************************************************/
67 #define HAS_DLGFRAME(Style, ExStyle) \
68 (((ExStyle) & WS_EX_DLGMODALFRAME) || \
69 (((Style) & WS_DLGFRAME) && !((Style) & WS_BORDER)))
71 #define HAS_THICKFRAME(Style, ExStyle) \
72 (((Style) & WS_THICKFRAME) && \
73 !((Style) & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)
76 WinPosSetupInternalPos(VOID
)
78 AtomInternalPos
= NtAddAtom(L
"SysIP", (ATOM
*)(PULONG
)&AtomInternalPos
);
82 NtUserGetClientOrigin(HWND hWnd
, LPPOINT Point
)
84 PWINDOW_OBJECT WindowObject
;
86 WindowObject
= IntGetWindowObject(hWnd
);
87 if (WindowObject
== NULL
)
89 Point
->x
= Point
->y
= 0;
92 Point
->x
= WindowObject
->ClientRect
.left
;
93 Point
->y
= WindowObject
->ClientRect
.top
;
97 /*******************************************************************
100 * Check if we can activate the specified window.
103 can_activate_window(HWND hwnd
)
111 style
= NtUserGetWindowLong(hwnd
, GWL_STYLE
, FALSE
);
112 if (! (style
& WS_VISIBLE
))
116 if ((style
& (WS_POPUP
|WS_CHILD
)) == WS_CHILD
)
120 return ! (style
& WS_DISABLED
);
123 /*******************************************************************
124 * WinPosActivateOtherWindow
126 * Activates window other than pWnd.
129 WinPosActivateOtherWindow(PWINDOW_OBJECT Window
)
136 if ((NtUserGetWindowLong(Window
->Self
, GWL_STYLE
, FALSE
) & WS_POPUP
)
137 && (hwndTo
= NtUserGetWindow(Window
->Self
, GW_OWNER
)))
139 hwndTo
= NtUserGetAncestor(hwndTo
, GA_ROOT
);
140 if (can_activate_window(hwndTo
)) goto done
;
143 hwndTo
= Window
->Self
;
146 if (!(hwndTo
= NtUserGetWindow(hwndTo
, GW_HWNDNEXT
)))
150 if (can_activate_window(hwndTo
))
158 fg
= NtUserGetForegroundWindow();
159 /* TRACE("win = %p fg = %p\n", hwndTo, fg); */
160 if (! fg
|| (hwnd
== fg
))
162 if (NtUserSetForegroundWindow(hwndTo
))
169 if (! NtUserSetActiveWindow(hwndTo
))
171 NtUserSetActiveWindow(NULL
);
175 POINT STATIC FASTCALL
176 WinPosFindIconPos(HWND hWnd
, POINT Pos
)
184 WinPosNtGdiIconTitle(PWINDOW_OBJECT WindowObject
)
190 WinPosShowIconTitle(PWINDOW_OBJECT WindowObject
, BOOL Show
)
192 PINTERNALPOS InternalPos
= (PINTERNALPOS
)IntGetProp(WindowObject
, AtomInternalPos
);
193 PWINDOW_OBJECT IconWindow
;
198 HWND hWnd
= InternalPos
->IconTitle
;
202 hWnd
= WinPosNtGdiIconTitle(WindowObject
);
207 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation
->
211 (PVOID
*)&IconWindow
);
212 if (NT_SUCCESS(Status
))
214 if (!(IconWindow
->Style
& WS_VISIBLE
))
216 NtUserSendMessage(hWnd
, WM_SHOWWINDOW
, TRUE
, 0);
217 WinPosSetWindowPos(hWnd
, 0, 0, 0, 0, 0, SWP_NOSIZE
|
218 SWP_NOMOVE
| SWP_NOACTIVATE
|
219 SWP_NOZORDER
| SWP_SHOWWINDOW
);
221 ObmDereferenceObject(IconWindow
);
226 WinPosShowWindow(hWnd
, SW_HIDE
);
232 PINTERNALPOS STATIC STDCALL
233 WinPosInitInternalPos(PWINDOW_OBJECT WindowObject
, POINT pt
, PRECT RestoreRect
)
235 PINTERNALPOS InternalPos
= (PINTERNALPOS
)IntGetProp(WindowObject
, AtomInternalPos
);
236 if (InternalPos
== NULL
)
239 ExAllocatePool(NonPagedPool
, sizeof(INTERNALPOS
));
240 IntSetProp(WindowObject
, AtomInternalPos
, InternalPos
);
241 InternalPos
->IconTitle
= 0;
242 InternalPos
->NormalRect
= WindowObject
->WindowRect
;
243 InternalPos
->IconPos
.x
= InternalPos
->MaxPos
.x
= 0xFFFFFFFF;
244 InternalPos
->IconPos
.y
= InternalPos
->MaxPos
.y
= 0xFFFFFFFF;
246 if (WindowObject
->Style
& WS_MINIMIZE
)
248 InternalPos
->IconPos
= pt
;
250 else if (WindowObject
->Style
& WS_MAXIMIZE
)
252 InternalPos
->MaxPos
= pt
;
254 else if (RestoreRect
!= NULL
)
256 InternalPos
->NormalRect
= *RestoreRect
;
262 WinPosMinMaximize(PWINDOW_OBJECT WindowObject
, UINT ShowFlag
, RECT
* NewPos
)
265 PINTERNALPOS InternalPos
;
268 Size
.x
= WindowObject
->WindowRect
.left
;
269 Size
.y
= WindowObject
->WindowRect
.top
;
270 InternalPos
= WinPosInitInternalPos(WindowObject
, Size
,
271 &WindowObject
->WindowRect
);
275 if (WindowObject
->Style
& WS_MINIMIZE
)
277 if (!NtUserSendMessage(WindowObject
->Self
, WM_QUERYOPEN
, 0, 0))
279 return(SWP_NOSIZE
| SWP_NOMOVE
);
281 SwpFlags
|= SWP_NOCOPYBITS
;
287 if (WindowObject
->Style
& WS_MAXIMIZE
)
289 WindowObject
->Flags
|= WINDOWOBJECT_RESTOREMAX
;
290 WindowObject
->Style
&= ~WS_MAXIMIZE
;
294 WindowObject
->Style
&= ~WINDOWOBJECT_RESTOREMAX
;
296 WindowObject
->Style
|= WS_MINIMIZE
;
297 InternalPos
->IconPos
= WinPosFindIconPos(WindowObject
,
298 InternalPos
->IconPos
);
299 NtGdiSetRect(NewPos
, InternalPos
->IconPos
.x
, InternalPos
->IconPos
.y
,
300 NtUserGetSystemMetrics(SM_CXICON
),
301 NtUserGetSystemMetrics(SM_CYICON
));
302 SwpFlags
|= SWP_NOCOPYBITS
;
308 WinPosGetMinMaxInfo(WindowObject
, &Size
, &InternalPos
->MaxPos
,
310 if (WindowObject
->Style
& WS_MINIMIZE
)
312 WinPosShowIconTitle(WindowObject
, FALSE
);
313 WindowObject
->Style
&= ~WS_MINIMIZE
;
315 WindowObject
->Style
|= WS_MINIMIZE
;
316 NtGdiSetRect(NewPos
, InternalPos
->MaxPos
.x
, InternalPos
->MaxPos
.y
,
323 if (WindowObject
->Style
& WS_MINIMIZE
)
325 WindowObject
->Style
&= ~WS_MINIMIZE
;
326 WinPosShowIconTitle(WindowObject
, FALSE
);
327 if (WindowObject
->Flags
& WINDOWOBJECT_RESTOREMAX
)
329 WinPosGetMinMaxInfo(WindowObject
, &Size
,
330 &InternalPos
->MaxPos
, NULL
, NULL
);
331 WindowObject
->Style
|= WS_MAXIMIZE
;
332 NtGdiSetRect(NewPos
, InternalPos
->MaxPos
.x
,
333 InternalPos
->MaxPos
.y
, Size
.x
, Size
.y
);
339 if (!(WindowObject
->Style
& WS_MAXIMIZE
))
345 WindowObject
->Style
&= ~WS_MAXIMIZE
;
347 *NewPos
= InternalPos
->NormalRect
;
348 NewPos
->right
-= NewPos
->left
;
349 NewPos
->bottom
-= NewPos
->top
;
357 SwpFlags
|= SWP_NOSIZE
| SWP_NOMOVE
;
363 WinPosGetMinMaxInfo(PWINDOW_OBJECT Window
, POINT
* MaxSize
, POINT
* MaxPos
,
364 POINT
* MinTrack
, POINT
* MaxTrack
)
370 /* Get default values. */
371 MinMax
.ptMaxSize
.x
= NtUserGetSystemMetrics(SM_CXSCREEN
);
372 MinMax
.ptMaxSize
.y
= NtUserGetSystemMetrics(SM_CYSCREEN
);
373 MinMax
.ptMinTrackSize
.x
= NtUserGetSystemMetrics(SM_CXMINTRACK
);
374 MinMax
.ptMinTrackSize
.y
= NtUserGetSystemMetrics(SM_CYMINTRACK
);
375 MinMax
.ptMaxTrackSize
.x
= NtUserGetSystemMetrics(SM_CXSCREEN
);
376 MinMax
.ptMaxTrackSize
.y
= NtUserGetSystemMetrics(SM_CYSCREEN
);
378 if (HAS_DLGFRAME(Window
->Style
, Window
->ExStyle
))
380 XInc
= NtUserGetSystemMetrics(SM_CXDLGFRAME
);
381 YInc
= NtUserGetSystemMetrics(SM_CYDLGFRAME
);
386 if (HAS_THICKFRAME(Window
->Style
, Window
->ExStyle
))
388 XInc
+= NtUserGetSystemMetrics(SM_CXFRAME
);
389 YInc
+= NtUserGetSystemMetrics(SM_CYFRAME
);
391 if (Window
->Style
& WS_BORDER
)
393 XInc
+= NtUserGetSystemMetrics(SM_CXBORDER
);
394 YInc
+= NtUserGetSystemMetrics(SM_CYBORDER
);
397 MinMax
.ptMaxSize
.x
+= 2 * XInc
;
398 MinMax
.ptMaxSize
.y
+= 2 * YInc
;
400 Pos
= (PINTERNALPOS
)IntGetProp(Window
, AtomInternalPos
);
403 MinMax
.ptMaxPosition
= Pos
->MaxPos
;
407 MinMax
.ptMaxPosition
.x
-= XInc
;
408 MinMax
.ptMaxPosition
.y
-= YInc
;
411 IntSendMessage(Window
->Self
, WM_GETMINMAXINFO
, 0, (LPARAM
)&MinMax
, TRUE
);
413 MinMax
.ptMaxTrackSize
.x
= max(MinMax
.ptMaxTrackSize
.x
,
414 MinMax
.ptMinTrackSize
.x
);
415 MinMax
.ptMaxTrackSize
.y
= max(MinMax
.ptMaxTrackSize
.y
,
416 MinMax
.ptMinTrackSize
.y
);
418 if (MaxSize
) *MaxSize
= MinMax
.ptMaxSize
;
419 if (MaxPos
) *MaxPos
= MinMax
.ptMaxPosition
;
420 if (MinTrack
) *MinTrack
= MinMax
.ptMinTrackSize
;
421 if (MaxTrack
) *MaxTrack
= MinMax
.ptMaxTrackSize
;
423 return 0; //FIXME: what does it return?
427 WinPosChangeActiveWindow(HWND hWnd
, BOOL MouseMsg
)
429 PWINDOW_OBJECT WindowObject
;
431 WindowObject
= IntGetWindowObject(hWnd
);
432 if (WindowObject
== NULL
)
437 NtUserSendMessage(hWnd
,
439 MAKELONG(MouseMsg
? WA_CLICKACTIVE
: WA_CLICKACTIVE
,
440 (WindowObject
->Style
& WS_MINIMIZE
) ? 1 : 0),
441 (LPARAM
)IntGetDesktopWindow()); /* FIXME: Previous active window */
443 IntReleaseWindowObject(WindowObject
);
449 WinPosDoNCCALCSize(PWINDOW_OBJECT Window
, PWINDOWPOS WinPos
,
450 RECT
* WindowRect
, RECT
* ClientRect
)
454 /* Send WM_NCCALCSIZE message to get new client area */
455 if ((WinPos
->flags
& (SWP_FRAMECHANGED
| SWP_NOSIZE
)) != SWP_NOSIZE
)
457 NCCALCSIZE_PARAMS params
;
458 WINDOWPOS winposCopy
;
460 params
.rgrc
[0] = *WindowRect
;
461 params
.rgrc
[1] = Window
->WindowRect
;
462 params
.rgrc
[2] = Window
->ClientRect
;
463 if (0 != (Window
->Style
& WS_CHILD
))
465 NtGdiOffsetRect(&(params
.rgrc
[0]), - Window
->Parent
->ClientRect
.left
,
466 - Window
->Parent
->ClientRect
.top
);
467 NtGdiOffsetRect(&(params
.rgrc
[1]), - Window
->Parent
->ClientRect
.left
,
468 - Window
->Parent
->ClientRect
.top
);
469 NtGdiOffsetRect(&(params
.rgrc
[2]), - Window
->Parent
->ClientRect
.left
,
470 - Window
->Parent
->ClientRect
.top
);
472 params
.lppos
= &winposCopy
;
473 winposCopy
= *WinPos
;
475 wvrFlags
= IntSendNCCALCSIZEMessage(Window
->Self
, TRUE
, NULL
, ¶ms
);
477 /* If the application send back garbage, ignore it */
478 if (params
.rgrc
[0].left
<= params
.rgrc
[0].right
&&
479 params
.rgrc
[0].top
<= params
.rgrc
[0].bottom
)
481 *ClientRect
= params
.rgrc
[0];
482 if (Window
->Style
& WS_CHILD
)
484 NtGdiOffsetRect(ClientRect
, Window
->Parent
->ClientRect
.left
,
485 Window
->Parent
->ClientRect
.top
);
489 /* FIXME: WVR_ALIGNxxx */
491 if (ClientRect
->left
!= Window
->ClientRect
.left
||
492 ClientRect
->top
!= Window
->ClientRect
.top
)
494 WinPos
->flags
&= ~SWP_NOCLIENTMOVE
;
497 if ((ClientRect
->right
- ClientRect
->left
!=
498 Window
->ClientRect
.right
- Window
->ClientRect
.left
) ||
499 (ClientRect
->bottom
- ClientRect
->top
!=
500 Window
->ClientRect
.bottom
- Window
->ClientRect
.top
))
502 WinPos
->flags
&= ~SWP_NOCLIENTSIZE
;
507 if (! (WinPos
->flags
& SWP_NOMOVE
)
508 && (ClientRect
->left
!= Window
->ClientRect
.left
||
509 ClientRect
->top
!= Window
->ClientRect
.top
))
511 WinPos
->flags
&= ~SWP_NOCLIENTMOVE
;
519 WinPosDoWinPosChanging(PWINDOW_OBJECT WindowObject
,
526 if (!(WinPos
->flags
& SWP_NOSENDCHANGING
))
528 IntSendWINDOWPOSCHANGINGMessage(WindowObject
->Self
, WinPos
);
531 *WindowRect
= WindowObject
->WindowRect
;
533 (WindowObject
->Style
& WS_MINIMIZE
) ? WindowObject
->WindowRect
:
534 WindowObject
->ClientRect
;
536 if (!(WinPos
->flags
& SWP_NOSIZE
))
538 WindowRect
->right
= WindowRect
->left
+ WinPos
->cx
;
539 WindowRect
->bottom
= WindowRect
->top
+ WinPos
->cy
;
542 if (!(WinPos
->flags
& SWP_NOMOVE
))
546 if (0 != (WindowObject
->Style
& WS_CHILD
))
548 X
+= WindowObject
->Parent
->ClientRect
.left
;
549 Y
+= WindowObject
->Parent
->ClientRect
.top
;
551 WindowRect
->left
= X
;
553 WindowRect
->right
+= X
- WindowObject
->WindowRect
.left
;
554 WindowRect
->bottom
+= Y
- WindowObject
->WindowRect
.top
;
555 NtGdiOffsetRect(ClientRect
,
556 X
- WindowObject
->WindowRect
.left
,
557 Y
- WindowObject
->WindowRect
.top
);
560 WinPos
->flags
|= SWP_NOCLIENTMOVE
| SWP_NOCLIENTSIZE
;
566 * Fix Z order taking into account owned popups -
567 * basically we need to maintain them above the window that owns them
570 WinPosDoOwnedPopups(HWND hWnd
, HWND hWndInsertAfter
)
573 return hWndInsertAfter
;
576 /***********************************************************************
577 * WinPosInternalMoveWindow
579 * Update WindowRect and ClientRect of Window and all of its children
580 * We keep both WindowRect and ClientRect in screen coordinates internally
583 WinPosInternalMoveWindow(PWINDOW_OBJECT Window
, INT MoveX
, INT MoveY
)
585 PWINDOW_OBJECT Child
;
587 Window
->WindowRect
.left
+= MoveX
;
588 Window
->WindowRect
.right
+= MoveX
;
589 Window
->WindowRect
.top
+= MoveY
;
590 Window
->WindowRect
.bottom
+= MoveY
;
592 Window
->ClientRect
.left
+= MoveX
;
593 Window
->ClientRect
.right
+= MoveX
;
594 Window
->ClientRect
.top
+= MoveY
;
595 Window
->ClientRect
.bottom
+= MoveY
;
597 ExAcquireFastMutexUnsafe(&Window
->ChildrenListLock
);
598 Child
= Window
->FirstChild
;
601 WinPosInternalMoveWindow(Child
, MoveX
, MoveY
);
602 Child
= Child
->NextSibling
;
604 ExReleaseFastMutexUnsafe(&Window
->ChildrenListLock
);
608 * WinPosFixupSWPFlags
610 * Fix redundant flags and values in the WINDOWPOS structure.
614 WinPosFixupFlags(WINDOWPOS
*WinPos
, PWINDOW_OBJECT Window
)
616 if (Window
->Style
& WS_VISIBLE
)
618 WinPos
->flags
&= ~SWP_SHOWWINDOW
;
622 WinPos
->flags
&= ~SWP_HIDEWINDOW
;
623 if (!(WinPos
->flags
& SWP_SHOWWINDOW
))
624 WinPos
->flags
|= SWP_NOREDRAW
;
627 WinPos
->cx
= max(WinPos
->cx
, 0);
628 WinPos
->cy
= max(WinPos
->cy
, 0);
630 /* Check for right size */
631 if (Window
->WindowRect
.right
- Window
->WindowRect
.left
== WinPos
->cx
&&
632 Window
->WindowRect
.bottom
- Window
->WindowRect
.top
== WinPos
->cy
)
634 WinPos
->flags
|= SWP_NOSIZE
;
637 /* Check for right position */
638 if (Window
->WindowRect
.left
== WinPos
->x
&&
639 Window
->WindowRect
.top
== WinPos
->y
)
641 WinPos
->flags
|= SWP_NOMOVE
;
644 /* FIXME: We don't have NtUserGetForegroundWindow yet. */
646 if (WinPos
->hwnd
== NtUserGetForegroundWindow())
648 WinPos
->flags
|= SWP_NOACTIVATE
; /* Already active */
652 if ((Window
->Style
& (WS_POPUP
| WS_CHILD
)) != WS_CHILD
)
654 /* Bring to the top when activating */
655 if (!(WinPos
->flags
& SWP_NOACTIVATE
))
657 WinPos
->flags
&= ~SWP_NOZORDER
;
658 WinPos
->hwndInsertAfter
= HWND_TOP
;
663 /* Check hwndInsertAfter */
664 if (!(WinPos
->flags
& SWP_NOZORDER
))
666 /* Fix sign extension */
667 if (WinPos
->hwndInsertAfter
== (HWND
)0xffff)
669 WinPos
->hwndInsertAfter
= HWND_TOPMOST
;
671 else if (WinPos
->hwndInsertAfter
== (HWND
)0xfffe)
673 WinPos
->hwndInsertAfter
= HWND_NOTOPMOST
;
676 /* FIXME: TOPMOST not supported yet */
677 if ((WinPos
->hwndInsertAfter
== HWND_TOPMOST
) ||
678 (WinPos
->hwndInsertAfter
== HWND_NOTOPMOST
))
680 WinPos
->hwndInsertAfter
= HWND_TOP
;
683 /* hwndInsertAfter must be a sibling of the window */
684 if ((WinPos
->hwndInsertAfter
!= HWND_TOP
) &&
685 (WinPos
->hwndInsertAfter
!= HWND_BOTTOM
))
687 if (NtUserGetAncestor(WinPos
->hwndInsertAfter
, GA_PARENT
) !=
695 * We don't need to change the Z order of hwnd if it's already
696 * inserted after hwndInsertAfter or when inserting hwnd after
699 if ((WinPos
->hwnd
== WinPos
->hwndInsertAfter
) ||
700 (WinPos
->hwnd
== NtUserGetWindow(WinPos
->hwndInsertAfter
, GW_HWNDNEXT
)))
702 WinPos
->flags
|= SWP_NOZORDER
;
711 /* x and y are always screen relative */
713 WinPosSetWindowPos(HWND Wnd
, HWND WndInsertAfter
, INT x
, INT y
, INT cx
,
716 PWINDOW_OBJECT Window
;
720 HRGN VisBefore
= NULL
;
721 HRGN VisAfter
= NULL
;
722 HRGN DirtyRgn
= NULL
;
723 HRGN ExposedRgn
= NULL
;
726 RECT OldWindowRect
, OldClientRect
;
732 /* FIXME: Get current active window from active queue. */
734 /* Check if the window is for a desktop. */
735 if (Wnd
== IntGetDesktopWindow())
740 Window
= IntGetWindowObject(Wnd
);
743 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
748 WinPos
.hwndInsertAfter
= WndInsertAfter
;
753 WinPos
.flags
= flags
;
754 if (Window
->Style
& WS_CHILD
)
756 WinPos
.x
-= Window
->Parent
->ClientRect
.left
;
757 WinPos
.y
-= Window
->Parent
->ClientRect
.top
;
760 WinPosDoWinPosChanging(Window
, &WinPos
, &NewWindowRect
, &NewClientRect
);
762 /* Fix up the flags. */
763 if (!WinPosFixupFlags(&WinPos
, Window
))
765 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
766 IntReleaseWindowObject(Window
);
770 /* Does the window still exist? */
771 if (!IntIsWindow(WinPos
.hwnd
))
773 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
777 if ((WinPos
.flags
& (SWP_NOZORDER
| SWP_HIDEWINDOW
| SWP_SHOWWINDOW
)) !=
779 NtUserGetAncestor(WinPos
.hwnd
, GA_PARENT
) == IntGetDesktopWindow())
781 WinPos
.hwndInsertAfter
= WinPosDoOwnedPopups(WinPos
.hwnd
, WinPos
.hwndInsertAfter
);
784 /* Compute the visible region before the window position is changed */
785 if ((!(WinPos
.flags
& (SWP_NOREDRAW
| SWP_SHOWWINDOW
)) &&
786 WinPos
.flags
& (SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
|
787 SWP_HIDEWINDOW
| SWP_FRAMECHANGED
)) !=
788 (SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
))
790 VisBefore
= VIS_ComputeVisibleRegion(
791 PsGetWin32Thread()->Desktop
, Window
, FALSE
, FALSE
, TRUE
);
793 if (UnsafeIntGetRgnBox(VisBefore
, &TempRect
) == NULLREGION
)
795 NtGdiDeleteObject(VisBefore
);
800 WvrFlags
= WinPosDoNCCALCSize(Window
, &WinPos
, &NewWindowRect
, &NewClientRect
);
802 /* Relink windows. (also take into account shell window in hwndShellWindow) */
803 if (!(WinPos
.flags
& SWP_NOZORDER
) && WinPos
.hwnd
!= NtUserGetShellWindow())
805 PWINDOW_OBJECT ParentWindow
;
806 PWINDOW_OBJECT InsertAfterWindow
;
808 ParentWindow
= Window
->Parent
;
811 if (WinPos
.hwndInsertAfter
== HWND_TOP
)
812 InsertAfterWindow
= NULL
;
813 else if (WinPos
.hwndInsertAfter
== HWND_BOTTOM
)
814 InsertAfterWindow
= ParentWindow
->LastChild
;
816 InsertAfterWindow
= IntGetWindowObject(WinPos
.hwndInsertAfter
);
817 ExAcquireFastMutexUnsafe(&ParentWindow
->ChildrenListLock
);
818 IntUnlinkWindow(Window
);
819 IntLinkWindow(Window
, ParentWindow
, InsertAfterWindow
);
820 ExReleaseFastMutexUnsafe(&ParentWindow
->ChildrenListLock
);
821 if (InsertAfterWindow
!= NULL
)
822 IntReleaseWindowObject(InsertAfterWindow
);
826 /* FIXME: Reset active DCEs */
828 OldWindowRect
= Window
->WindowRect
;
829 OldClientRect
= Window
->ClientRect
;
831 if (OldClientRect
.bottom
- OldClientRect
.top
==
832 NewClientRect
.bottom
- NewClientRect
.top
)
834 WvrFlags
&= ~WVR_VREDRAW
;
837 if (OldClientRect
.right
- OldClientRect
.left
==
838 NewClientRect
.right
- NewClientRect
.left
)
840 WvrFlags
&= ~WVR_HREDRAW
;
843 /* FIXME: Actually do something with WVR_VALIDRECTS */
845 if (!(WinPos
.flags
& SWP_NOMOVE
))
847 WinPosInternalMoveWindow(Window
,
848 NewWindowRect
.left
- OldWindowRect
.left
,
849 NewWindowRect
.top
- OldWindowRect
.top
);
852 Window
->WindowRect
= NewWindowRect
;
853 Window
->ClientRect
= NewClientRect
;
855 if (!(WinPos
.flags
& SWP_SHOWWINDOW
) && (WinPos
.flags
& SWP_HIDEWINDOW
))
857 /* Clear the update region */
858 IntRedrawWindow(Window
, NULL
, 0, RDW_VALIDATE
| RDW_NOFRAME
|
859 RDW_NOERASE
| RDW_NOINTERNALPAINT
| RDW_ALLCHILDREN
);
860 Window
->Style
&= ~WS_VISIBLE
;
862 else if (WinPos
.flags
& SWP_SHOWWINDOW
)
864 Window
->Style
|= WS_VISIBLE
;
867 if (!(WinPos
.flags
& SWP_NOACTIVATE
))
869 WinPosChangeActiveWindow(WinPos
.hwnd
, FALSE
);
872 /* Determine the new visible region */
873 VisAfter
= VIS_ComputeVisibleRegion(
874 PsGetWin32Thread()->Desktop
, Window
, FALSE
, FALSE
, TRUE
);
876 if (UnsafeIntGetRgnBox(VisAfter
, &TempRect
) == NULLREGION
)
878 NtGdiDeleteObject(VisAfter
);
883 * Determine which pixels can be copied from the old window position
884 * to the new. Those pixels must be visible in both the old and new
885 * position. Also, check the class style to see if the windows of this
886 * class need to be completely repainted on (horizontal/vertical) size
889 if (VisBefore
!= NULL
&& VisAfter
!= NULL
&& !(WinPos
.flags
& SWP_NOCOPYBITS
) &&
890 ((WinPos
.flags
& SWP_NOSIZE
) || !(WvrFlags
& WVR_REDRAW
)))
892 CopyRgn
= NtGdiCreateRectRgn(0, 0, 0, 0);
893 RgnType
= NtGdiCombineRgn(CopyRgn
, VisAfter
, VisBefore
, RGN_AND
);
896 * If this is (also) a window resize, the whole nonclient area
897 * needs to be repainted. So we limit the copy to the client area,
898 * 'cause there is no use in copying it (would possibly cause
899 * "flashing" too). However, if the copy region is already empty,
900 * we don't have to crop (can't take anything away from an empty
903 if (!(WinPos
.flags
& (SWP_NOSIZE
| SWP_NOZORDER
)) && RgnType
!= ERROR
&&
904 RgnType
!= NULLREGION
)
906 RECT ORect
= OldClientRect
;
907 RECT NRect
= NewClientRect
;
908 NtGdiOffsetRect(&ORect
, - OldWindowRect
.left
, - OldWindowRect
.top
);
909 NtGdiOffsetRect(&NRect
, - NewWindowRect
.left
, - NewWindowRect
.top
);
910 NtGdiIntersectRect(&CopyRect
, &ORect
, &NRect
);
911 REGION_CropRgn(CopyRgn
, CopyRgn
, &CopyRect
, NULL
);
914 /* No use in copying bits which are in the update region. */
915 if (Window
->UpdateRegion
!= NULL
)
917 NtGdiCombineRgn(CopyRgn
, CopyRgn
, Window
->UpdateRegion
, RGN_DIFF
);
921 * Now, get the bounding box of the copy region. If it's empty
922 * there's nothing to copy. Also, it's no use copying bits onto
925 if (UnsafeIntGetRgnBox(CopyRgn
, &CopyRect
) == NULLREGION
)
927 /* Nothing to copy, clean up */
928 NtGdiDeleteObject(CopyRgn
);
931 else if (OldWindowRect
.left
!= NewWindowRect
.left
||
932 OldWindowRect
.top
!= NewWindowRect
.top
)
935 * Small trick here: there is no function to bitblt a region. So
936 * we set the region as the clipping region, take the bounding box
937 * of the region and bitblt that. Since nothing outside the clipping
938 * region is copied, this has the effect of bitblt'ing the region.
940 * Since NtUserGetDCEx takes ownership of the clip region, we need
941 * to create a copy of CopyRgn and pass that. We need CopyRgn later
943 HRGN ClipRgn
= NtGdiCreateRectRgn(0, 0, 0, 0);
944 NtGdiCombineRgn(ClipRgn
, CopyRgn
, NULL
, RGN_COPY
);
945 Dc
= NtUserGetDCEx(Wnd
, ClipRgn
, DCX_WINDOW
| DCX_CACHE
|
946 DCX_INTERSECTRGN
| DCX_CLIPSIBLINGS
);
948 CopyRect
.left
, CopyRect
.top
, CopyRect
.right
- CopyRect
.left
,
949 CopyRect
.bottom
- CopyRect
.top
, Dc
,
950 CopyRect
.left
+ (OldWindowRect
.left
- NewWindowRect
.left
),
951 CopyRect
.top
+ (OldWindowRect
.top
- NewWindowRect
.top
), SRCCOPY
);
952 NtUserReleaseDC(Wnd
, Dc
);
960 /* We need to redraw what wasn't visible before */
961 if (VisAfter
!= NULL
)
965 DirtyRgn
= NtGdiCreateRectRgn(0, 0, 0, 0);
966 RgnType
= NtGdiCombineRgn(DirtyRgn
, VisAfter
, CopyRgn
, RGN_DIFF
);
967 if (RgnType
!= ERROR
&& RgnType
!= NULLREGION
)
969 NtGdiOffsetRgn(DirtyRgn
,
970 Window
->WindowRect
.left
- Window
->ClientRect
.left
,
971 Window
->WindowRect
.top
- Window
->ClientRect
.top
);
972 IntRedrawWindow(Window
, NULL
, DirtyRgn
,
973 RDW_ERASE
| RDW_FRAME
| RDW_INVALIDATE
| RDW_ALLCHILDREN
);
975 NtGdiDeleteObject(DirtyRgn
);
979 IntRedrawWindow(Window
, NULL
, 0,
980 RDW_ERASE
| RDW_FRAME
| RDW_INVALIDATE
| RDW_ALLCHILDREN
);
986 NtGdiDeleteObject(CopyRgn
);
989 /* Expose what was covered before but not covered anymore */
990 if (VisBefore
!= NULL
)
992 ExposedRgn
= NtGdiCreateRectRgn(0, 0, 0, 0);
993 NtGdiCombineRgn(ExposedRgn
, VisBefore
, NULL
, RGN_COPY
);
994 NtGdiOffsetRgn(ExposedRgn
, OldWindowRect
.left
- NewWindowRect
.left
,
995 OldWindowRect
.top
- NewWindowRect
.top
);
996 if (VisAfter
!= NULL
)
997 RgnType
= NtGdiCombineRgn(ExposedRgn
, ExposedRgn
, VisAfter
, RGN_DIFF
);
999 RgnType
= SIMPLEREGION
;
1001 if (RgnType
!= ERROR
&& RgnType
!= NULLREGION
)
1003 VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop
, Window
,
1006 NtGdiDeleteObject(ExposedRgn
);
1007 NtGdiDeleteObject(VisBefore
);
1010 if (VisAfter
!= NULL
)
1012 NtGdiDeleteObject(VisAfter
);
1015 if (!(WinPos
.flags
& SWP_NOREDRAW
))
1017 IntRedrawWindow(Window
, NULL
, 0, RDW_ALLCHILDREN
| RDW_ERASENOW
);
1020 /* FIXME: Check some conditions before doing this. */
1021 IntSendWINDOWPOSCHANGEDMessage(WinPos
.hwnd
, &WinPos
);
1023 IntReleaseWindowObject(Window
);
1029 WinPosGetNonClientSize(HWND Wnd
, RECT
* WindowRect
, RECT
* ClientRect
)
1031 *ClientRect
= *WindowRect
;
1032 return(IntSendNCCALCSIZEMessage(Wnd
, FALSE
, ClientRect
, NULL
));
1036 WinPosShowWindow(HWND Wnd
, INT Cmd
)
1039 PWINDOW_OBJECT Window
;
1047 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation
->HandleTable
,
1051 if (!NT_SUCCESS(Status
))
1056 WasVisible
= (Window
->Style
& WS_VISIBLE
) != 0;
1064 ObmDereferenceObject(Window
);
1067 Swp
|= SWP_HIDEWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
|
1072 case SW_SHOWMINNOACTIVE
:
1073 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
1075 case SW_SHOWMINIMIZED
:
1076 Swp
|= SWP_SHOWWINDOW
;
1080 Swp
|= SWP_FRAMECHANGED
;
1081 if (!(Window
->Style
& WS_MINIMIZE
))
1083 Swp
|= WinPosMinMaximize(Window
, SW_MINIMIZE
, &NewPos
);
1087 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
1092 case SW_SHOWMAXIMIZED
:
1094 Swp
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
1095 if (!(Window
->Style
& WS_MAXIMIZE
))
1097 Swp
|= WinPosMinMaximize(Window
, SW_MAXIMIZE
, &NewPos
);
1101 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
1107 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
1110 Swp
|= SWP_SHOWWINDOW
| SWP_NOSIZE
| SWP_NOMOVE
;
1111 /* Don't activate the topmost window. */
1114 case SW_SHOWNOACTIVATE
:
1115 Swp
|= SWP_NOZORDER
;
1118 case SW_SHOWDEFAULT
:
1120 Swp
|= SWP_SHOWWINDOW
| SWP_FRAMECHANGED
;
1121 if (Window
->Style
& (WS_MINIMIZE
| WS_MAXIMIZE
))
1123 Swp
|= WinPosMinMaximize(Window
, SW_RESTORE
, &NewPos
);
1127 Swp
|= SWP_NOSIZE
| SWP_NOMOVE
;
1132 ShowFlag
= (Cmd
!= SW_HIDE
);
1133 if (ShowFlag
!= WasVisible
)
1135 NtUserSendMessage(Wnd
, WM_SHOWWINDOW
, ShowFlag
, 0);
1137 * FIXME: Need to check the window wasn't destroyed during the
1143 /* We can't activate a child window */
1144 if ((Window
->Style
& WS_CHILD
) &&
1145 !(Window
->ExStyle
& WS_EX_MDICHILD
))
1147 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
1150 WinPosSetWindowPos(Window
->Self
, HWND_TOP
, NewPos
.left
, NewPos
.top
,
1151 NewPos
.right
, NewPos
.bottom
, LOWORD(Swp
));
1155 /* FIXME: This will cause the window to be activated irrespective
1156 * of whether it is owned by the same thread. Has to be done
1160 if (Window
->Self
== IntGetActiveWindow())
1162 WinPosActivateOtherWindow(Window
);
1165 /* Revert focus to parent */
1166 if (Wnd
== IntGetFocusWindow() ||
1167 IntIsChildWindow(Wnd
, IntGetFocusWindow()))
1169 IntSetFocusWindow(Window
->Parent
->Self
);
1173 /* FIXME: Check for window destruction. */
1174 /* Show title for minimized windows. */
1175 if (Window
->Style
& WS_MINIMIZE
)
1177 WinPosShowIconTitle(Window
, TRUE
);
1180 if (Window
->Style
& WS_CHILD
&&
1181 !IntIsWindowVisible(Window
->Parent
->Self
) &&
1182 (Swp
& (SWP_NOSIZE
| SWP_NOMOVE
)) == (SWP_NOSIZE
| SWP_NOMOVE
))
1186 VisibleRgn
= VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop
, Window
,
1187 FALSE
, FALSE
, FALSE
);
1188 Window
->Style
&= ~WS_VISIBLE
;
1189 VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop
, Window
, VisibleRgn
);
1190 NtGdiDeleteObject(VisibleRgn
);
1194 Window
->Style
|= WS_VISIBLE
;
1199 if (Window
->Style
& WS_CHILD
&&
1200 !(Window
->ExStyle
& WS_EX_MDICHILD
))
1202 Swp
|= SWP_NOACTIVATE
| SWP_NOZORDER
;
1204 if (!(Swp
& MINMAX_NOSWP
))
1206 WinPosSetWindowPos(Wnd
, HWND_TOP
, NewPos
.left
, NewPos
.top
,
1207 NewPos
.right
, NewPos
.bottom
, LOWORD(Swp
));
1210 /* Hide the window. */
1211 if (Wnd
== IntGetActiveWindow())
1213 WinPosActivateOtherWindow(Window
);
1215 /* Revert focus to parent. */
1216 if (Wnd
== IntGetFocusWindow() ||
1217 IntIsChildWindow(Wnd
, IntGetFocusWindow()))
1219 IntSetFocusWindow(Window
->Parent
->Self
);
1223 /* FIXME: Check for window destruction. */
1224 /* Show title for minimized windows. */
1225 if (Window
->Style
& WS_MINIMIZE
)
1227 WinPosShowIconTitle(Window
, TRUE
);
1232 if (Window
->Flags
& WINDOWOBJECT_NEED_SIZE
)
1234 WPARAM wParam
= SIZE_RESTORED
;
1236 Window
->Flags
&= ~WINDOWOBJECT_NEED_SIZE
;
1237 if (Window
->Style
& WS_MAXIMIZE
)
1239 wParam
= SIZE_MAXIMIZED
;
1241 else if (Window
->Style
& WS_MINIMIZE
)
1243 wParam
= SIZE_MINIMIZED
;
1246 NtUserSendMessage(Wnd
, WM_SIZE
, wParam
,
1247 MAKELONG(Window
->ClientRect
.right
-
1248 Window
->ClientRect
.left
,
1249 Window
->ClientRect
.bottom
-
1250 Window
->ClientRect
.top
));
1251 NtUserSendMessage(Wnd
, WM_MOVE
, 0,
1252 MAKELONG(Window
->ClientRect
.left
,
1253 Window
->ClientRect
.top
));
1256 /* Activate the window if activation is not requested and the window is not minimized */
1257 if (!(Swp
& (SWP_NOACTIVATE
| SWP_HIDEWINDOW
)) && !(Window
->Style
& WS_MINIMIZE
))
1259 WinPosChangeActiveWindow(Wnd
, FALSE
);
1262 ObmDereferenceObject(Window
);
1266 BOOL STATIC FASTCALL
1267 WinPosPtInWindow(PWINDOW_OBJECT Window
, POINT Point
)
1269 return(Point
.x
>= Window
->WindowRect
.left
&&
1270 Point
.x
< Window
->WindowRect
.right
&&
1271 Point
.y
>= Window
->WindowRect
.top
&&
1272 Point
.y
< Window
->WindowRect
.bottom
);
1275 USHORT STATIC STDCALL
1276 WinPosSearchChildren(PWINDOW_OBJECT ScopeWin
, POINT Point
,
1277 PWINDOW_OBJECT
* Window
)
1279 PWINDOW_OBJECT Current
;
1281 ExAcquireFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
1282 Current
= ScopeWin
->FirstChild
;
1285 if (Current
->Style
& WS_VISIBLE
&&
1286 ((!(Current
->Style
& WS_DISABLED
)) ||
1287 (Current
->Style
& (WS_CHILD
| WS_POPUP
)) != WS_CHILD
) &&
1288 WinPosPtInWindow(Current
, Point
))
1291 if (Current
->Style
& WS_DISABLED
)
1293 ExReleaseFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
1296 if (Current
->Style
& WS_MINIMIZE
)
1298 ExReleaseFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
1301 if (Point
.x
>= Current
->ClientRect
.left
&&
1302 Point
.x
< Current
->ClientRect
.right
&&
1303 Point
.y
>= Current
->ClientRect
.top
&&
1304 Point
.y
< Current
->ClientRect
.bottom
)
1307 ExReleaseFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
1308 return(WinPosSearchChildren(Current
, Point
, Window
));
1311 ExReleaseFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
1314 Current
= Current
->NextSibling
;
1317 ExReleaseFastMutexUnsafe(&ScopeWin
->ChildrenListLock
);
1322 WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin
, POINT WinPoint
,
1323 PWINDOW_OBJECT
* Window
)
1325 HWND DesktopWindowHandle
;
1326 PWINDOW_OBJECT DesktopWindow
;
1327 POINT Point
= WinPoint
;
1332 if (ScopeWin
->Style
& WS_DISABLED
)
1337 /* Translate the point to the space of the scope window. */
1338 DesktopWindowHandle
= IntGetDesktopWindow();
1339 DesktopWindow
= IntGetWindowObject(DesktopWindowHandle
);
1340 Point
.x
+= ScopeWin
->ClientRect
.left
- DesktopWindow
->ClientRect
.left
;
1341 Point
.y
+= ScopeWin
->ClientRect
.top
- DesktopWindow
->ClientRect
.top
;
1342 IntReleaseWindowObject(DesktopWindow
);
1344 HitTest
= WinPosSearchChildren(ScopeWin
, Point
, Window
);
1350 if ((*Window
) == NULL
)
1354 if ((*Window
)->MessageQueue
== PsGetWin32Thread()->MessageQueue
)
1356 HitTest
= IntSendMessage((*Window
)->Self
, WM_NCHITTEST
, 0,
1357 MAKELONG(Point
.x
, Point
.y
), FALSE
);
1358 /* FIXME: Check for HTTRANSPARENT here. */
1369 WinPosSetActiveWindow(PWINDOW_OBJECT Window
, BOOL Mouse
, BOOL ChangeFocus
)
1371 PUSER_MESSAGE_QUEUE ActiveQueue
;
1374 ActiveQueue
= IntGetFocusMessageQueue();
1375 if (ActiveQueue
!= NULL
)
1377 PrevActive
= ActiveQueue
->ActiveWindow
;
1384 if (Window
->Self
== IntGetActiveDesktop() || Window
->Self
== PrevActive
)
1388 if (PrevActive
!= NULL
)
1390 PWINDOW_OBJECT PrevActiveWindow
= IntGetWindowObject(PrevActive
);
1391 if(PrevActiveWindow
)
1393 WORD Iconised
= HIWORD(PrevActiveWindow
->Style
& WS_MINIMIZE
);
1394 if (!IntSendMessage(PrevActive
, WM_NCACTIVATE
, FALSE
, 0, TRUE
))
1396 /* FIXME: Check if the new window is system modal. */
1399 IntSendMessage(PrevActive
,
1401 MAKEWPARAM(WA_INACTIVE
, Iconised
),
1402 (LPARAM
)Window
->Self
,
1404 /* FIXME: Check if anything changed while processing the message. */
1405 IntReleaseWindowObject(PrevActiveWindow
);
1410 ActiveQueue
->ActiveWindow
= NULL
;
1417 Window
->MessageQueue
->ActiveWindow
= Window
->Self
;
1419 else if (ActiveQueue
!= NULL
)
1421 ActiveQueue
->ActiveWindow
= NULL
;
1423 /* FIXME: Unset this flag for inactive windows */
1424 //if ((Window->Style) & WS_CHILD) Window->Flags |= WIN_NCACTIVATED;
1426 /* FIXME: Send palette messages. */
1428 /* FIXME: Redraw icon title of previously active window. */
1430 /* FIXME: Bring the window to the top. */
1432 /* FIXME: Send WM_ACTIVATEAPP */
1434 IntSetFocusMessageQueue(Window
->MessageQueue
);
1436 /* FIXME: Send activate messages. */
1438 /* FIXME: Change focus. */
1440 /* FIXME: Redraw new window icon title. */
1446 NtUserGetActiveWindow(VOID
)
1448 PUSER_MESSAGE_QUEUE ActiveQueue
;
1450 ActiveQueue
= IntGetFocusMessageQueue();
1451 if (ActiveQueue
== NULL
)
1455 return(ActiveQueue
->ActiveWindow
);
1459 NtUserSetActiveWindow(HWND hWnd
)
1461 PWINDOW_OBJECT Window
;
1462 PUSER_MESSAGE_QUEUE ThreadQueue
;
1465 Window
= IntGetWindowObject(hWnd
);
1466 if (Window
== NULL
|| (Window
->Style
& (WS_DISABLED
| WS_CHILD
)))
1468 IntReleaseWindowObject(Window
);
1471 ThreadQueue
= (PUSER_MESSAGE_QUEUE
)PsGetWin32Thread()->MessageQueue
;
1472 if (Window
->MessageQueue
!= ThreadQueue
)
1474 IntReleaseWindowObject(Window
);
1477 Prev
= Window
->MessageQueue
->ActiveWindow
;
1478 WinPosSetActiveWindow(Window
, FALSE
, FALSE
);
1479 IntReleaseWindowObject(Window
);