Misc. user fixes.
[reactos.git] / reactos / subsys / win32k / ntuser / winpos.c
1 /* $Id: winpos.c,v 1.5 2002/09/17 23:43:28 dwelch Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Windows
6 * FILE: subsys/win32k/ntuser/window.c
7 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * REVISION HISTORY:
9 * 06-06-2001 CSH Created
10 */
11 /* INCLUDES ******************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include <win32k/win32k.h>
15 #include <include/object.h>
16 #include <include/guicheck.h>
17 #include <include/window.h>
18 #include <include/class.h>
19 #include <include/error.h>
20 #include <include/winsta.h>
21 #include <windows.h>
22 #include <include/winpos.h>
23 #include <include/rect.h>
24 #include <include/callback.h>
25 #include <include/painting.h>
26
27 #define NDEBUG
28 #include <debug.h>
29
30 /* GLOBALS *******************************************************************/
31
32 #define MINMAX_NOSWP (0x00010000)
33
34 #define SWP_EX_PAINTSELF 0x0002
35
36 ATOM AtomInternalPos = NULL;
37
38 /* FUNCTIONS *****************************************************************/
39
40 #define HAS_DLGFRAME(Style, ExStyle) \
41 (((ExStyle) & WS_EX_DLGMODALFRAME) || \
42 (((Style) & WS_DLGFRAME) && !((Style) & WS_BORDER)))
43
44 #define HAS_THICKFRAME(Style, ExStyle) \
45 (((Style) & WS_THICKFRAME) && \
46 !((Style) & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)
47
48 VOID
49 WinPosSetupInternalPos(VOID)
50 {
51 AtomInternalPos = NtAddAtom(L"SysIP", (ATOM*)(PULONG)&AtomInternalPos);
52 }
53
54 BOOL STDCALL
55 NtUserGetClientOrigin(HWND hWnd, LPPOINT Point)
56 {
57 PWINDOW_OBJECT WindowObject;
58
59 WindowObject = W32kGetWindowObject(hWnd);
60 if (WindowObject == NULL)
61 {
62 return(FALSE);
63 }
64 Point->x = WindowObject->ClientRect.left;
65 Point->y = WindowObject->ClientRect.right;
66 return(TRUE);
67 }
68
69 BOOL
70 WinPosActivateOtherWindow(PWINDOW_OBJECT Window)
71 {
72 }
73
74 POINT STATIC
75 WinPosFindIconPos(HWND hWnd, POINT Pos)
76 {
77 }
78
79 HWND STATIC
80 WinPosCreateIconTitle(PWINDOW_OBJECT WindowObject)
81 {
82 return(NULL);
83 }
84
85 BOOL STATIC
86 WinPosShowIconTitle(PWINDOW_OBJECT WindowObject, BOOL Show)
87 {
88 PINTERNALPOS InternalPos = NtUserGetProp(WindowObject->Self,
89 AtomInternalPos);
90 PWINDOW_OBJECT IconWindow;
91 NTSTATUS Status;
92
93 if (InternalPos)
94 {
95 HWND hWnd = InternalPos->IconTitle;
96
97 if (hWnd == NULL)
98 {
99 hWnd = WinPosCreateIconTitle(WindowObject);
100 }
101 if (Show)
102 {
103 Status =
104 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->
105 HandleTable,
106 hWnd,
107 otWindow,
108 (PVOID*)&IconWindow);
109 if (NT_SUCCESS(Status))
110 {
111 if (!(IconWindow->Style & WS_VISIBLE))
112 {
113 NtUserSendMessage(hWnd, WM_SHOWWINDOW, TRUE, 0);
114 WinPosSetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE |
115 SWP_NOMOVE | SWP_NOACTIVATE |
116 SWP_NOZORDER | SWP_SHOWWINDOW);
117 }
118 ObmDereferenceObject(IconWindow);
119 }
120 }
121 else
122 {
123 WinPosShowWindow(hWnd, SW_HIDE);
124 }
125 }
126 return(FALSE);
127 }
128
129 PINTERNALPOS STATIC
130 WinPosInitInternalPos(PWINDOW_OBJECT WindowObject, POINT pt, PRECT RestoreRect)
131 {
132 PINTERNALPOS InternalPos = NtUserGetProp(WindowObject->Self,
133 AtomInternalPos);
134 if (InternalPos == NULL)
135 {
136 InternalPos =
137 ExAllocatePool(NonPagedPool, sizeof(INTERNALPOS));
138 NtUserSetProp(WindowObject->Self, AtomInternalPos, InternalPos);
139 InternalPos->IconTitle = 0;
140 InternalPos->NormalRect = WindowObject->WindowRect;
141 InternalPos->IconPos.x = InternalPos->MaxPos.x = 0xFFFFFFFF;
142 InternalPos->IconPos.y = InternalPos->MaxPos.y = 0xFFFFFFFF;
143 }
144 if (WindowObject->Style & WS_MINIMIZE)
145 {
146 InternalPos->IconPos = pt;
147 }
148 else if (WindowObject->Style & WS_MAXIMIZE)
149 {
150 InternalPos->MaxPos = pt;
151 }
152 else if (RestoreRect != NULL)
153 {
154 InternalPos->NormalRect = *RestoreRect;
155 }
156 return(InternalPos);
157 }
158
159 UINT
160 WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos)
161 {
162 POINT Size;
163 PINTERNALPOS InternalPos;
164 UINT SwpFlags = 0;
165
166 Size.x = WindowObject->WindowRect.left;
167 Size.y = WindowObject->WindowRect.top;
168 InternalPos = WinPosInitInternalPos(WindowObject, Size,
169 &WindowObject->WindowRect);
170
171 if (InternalPos)
172 {
173 if (WindowObject->Style & WS_MINIMIZE)
174 {
175 if (!NtUserSendMessage(WindowObject->Self, WM_QUERYOPEN, 0, 0))
176 {
177 return(SWP_NOSIZE | SWP_NOMOVE);
178 }
179 SwpFlags |= SWP_NOCOPYBITS;
180 }
181 switch (ShowFlag)
182 {
183 case SW_MINIMIZE:
184 {
185 if (WindowObject->Style & WS_MAXIMIZE)
186 {
187 WindowObject->Flags |= WINDOWOBJECT_RESTOREMAX;
188 WindowObject->Style &= ~WS_MAXIMIZE;
189 }
190 else
191 {
192 WindowObject->Style &= ~WINDOWOBJECT_RESTOREMAX;
193 }
194 WindowObject->Style |= WS_MINIMIZE;
195 InternalPos->IconPos = WinPosFindIconPos(WindowObject,
196 InternalPos->IconPos);
197 W32kSetRect(NewPos, InternalPos->IconPos.x, InternalPos->IconPos.y,
198 NtUserGetSystemMetrics(SM_CXICON),
199 NtUserGetSystemMetrics(SM_CYICON));
200 SwpFlags |= SWP_NOCOPYBITS;
201 break;
202 }
203
204 case SW_MAXIMIZE:
205 {
206 WinPosGetMinMaxInfo(WindowObject, &Size, &InternalPos->MaxPos,
207 NULL, NULL);
208 if (WindowObject->Style & WS_MINIMIZE)
209 {
210 WinPosShowIconTitle(WindowObject, FALSE);
211 WindowObject->Style &= ~WS_MINIMIZE;
212 }
213 WindowObject->Style |= WS_MINIMIZE;
214 W32kSetRect(NewPos, InternalPos->MaxPos.x, InternalPos->MaxPos.y,
215 Size.x, Size.y);
216 break;
217 }
218
219 case SW_RESTORE:
220 {
221 if (WindowObject->Style & WS_MINIMIZE)
222 {
223 WindowObject->Style &= ~WS_MINIMIZE;
224 WinPosShowIconTitle(WindowObject, FALSE);
225 if (WindowObject->Flags & WINDOWOBJECT_RESTOREMAX)
226 {
227 WinPosGetMinMaxInfo(WindowObject, &Size,
228 &InternalPos->MaxPos, NULL, NULL);
229 WindowObject->Style |= WS_MAXIMIZE;
230 W32kSetRect(NewPos, InternalPos->MaxPos.x,
231 InternalPos->MaxPos.y, Size.x, Size.y);
232 break;
233 }
234 }
235 else
236 {
237 if (!(WindowObject->Style & WS_MAXIMIZE))
238 {
239 return(-1);
240 }
241 else
242 {
243 WindowObject->Style &= ~WS_MAXIMIZE;
244 }
245 *NewPos = InternalPos->NormalRect;
246 NewPos->right -= NewPos->left;
247 NewPos->bottom -= NewPos->top;
248 break;
249 }
250 }
251 }
252 }
253 else
254 {
255 SwpFlags |= SWP_NOSIZE | SWP_NOMOVE;
256 }
257 return(SwpFlags);
258 }
259
260 UINT
261 WinPosGetMinMaxInfo(PWINDOW_OBJECT Window, POINT* MaxSize, POINT* MaxPos,
262 POINT* MinTrack, POINT* MaxTrack)
263 {
264 MINMAXINFO MinMax;
265 INT XInc, YInc;
266 INTERNALPOS* Pos;
267
268 /* Get default values. */
269 MinMax.ptMaxSize.x = NtUserGetSystemMetrics(SM_CXSCREEN);
270 MinMax.ptMaxSize.y = NtUserGetSystemMetrics(SM_CYSCREEN);
271 MinMax.ptMinTrackSize.x = NtUserGetSystemMetrics(SM_CXMINTRACK);
272 MinMax.ptMinTrackSize.y = NtUserGetSystemMetrics(SM_CYMINTRACK);
273 MinMax.ptMaxTrackSize.x = NtUserGetSystemMetrics(SM_CXSCREEN);
274 MinMax.ptMaxTrackSize.y = NtUserGetSystemMetrics(SM_CYSCREEN);
275
276 if (HAS_DLGFRAME(Window->Style, Window->ExStyle))
277 {
278 XInc = NtUserGetSystemMetrics(SM_CXDLGFRAME);
279 YInc = NtUserGetSystemMetrics(SM_CYDLGFRAME);
280 }
281 else
282 {
283 XInc = YInc = 0;
284 if (HAS_THICKFRAME(Window->Style, Window->ExStyle))
285 {
286 XInc += NtUserGetSystemMetrics(SM_CXFRAME);
287 YInc += NtUserGetSystemMetrics(SM_CYFRAME);
288 }
289 if (Window->Style & WS_BORDER)
290 {
291 XInc += NtUserGetSystemMetrics(SM_CXBORDER);
292 YInc += NtUserGetSystemMetrics(SM_CYBORDER);
293 }
294 }
295 MinMax.ptMaxSize.x += 2 * XInc;
296 MinMax.ptMaxSize.y += 2 * YInc;
297
298 Pos = NtUserGetProp(Window->Self, AtomInternalPos);
299 if (Pos != NULL)
300 {
301 MinMax.ptMaxPosition = Pos->MaxPos;
302 }
303 else
304 {
305 MinMax.ptMaxPosition.x -= XInc;
306 MinMax.ptMaxPosition.y -= YInc;
307 }
308
309 W32kSendMessage(Window->Self, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax, TRUE);
310
311 MinMax.ptMaxTrackSize.x = max(MinMax.ptMaxTrackSize.x,
312 MinMax.ptMinTrackSize.x);
313 MinMax.ptMaxTrackSize.y = max(MinMax.ptMaxTrackSize.y,
314 MinMax.ptMinTrackSize.y);
315
316 if (MaxSize) *MaxSize = MinMax.ptMaxSize;
317 if (MaxPos) *MaxPos = MinMax.ptMaxPosition;
318 if (MinTrack) *MinTrack = MinMax.ptMinTrackSize;
319 if (MaxTrack) *MaxTrack = MinMax.ptMaxTrackSize;
320 }
321
322 BOOL STATIC
323 WinPosChangeActiveWindow(HWND Wnd, BOOL MouseMsg)
324 {
325 }
326
327 LONG STATIC
328 WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
329 RECT* WindowRect, RECT* ClientRect)
330 {
331 }
332
333 BOOL
334 WinPosDoWinPosChanging(PWINDOW_OBJECT WindowObject,
335 PWINDOWPOS WinPos,
336 PRECT WindowRect,
337 PRECT ClientRect)
338 {
339 if (!(WinPos->flags & SWP_NOSENDCHANGING))
340 {
341 NtUserSendMessage(WindowObject->Self, WM_WINDOWPOSCHANGING, 0,
342 (LPARAM)WinPos);
343 }
344
345 *WindowRect = WindowObject->WindowRect;
346 *ClientRect =
347 (WindowObject->Style & WS_MINIMIZE) ? WindowObject->WindowRect :
348 WindowObject->ClientRect;
349
350 if (!(WinPos->flags & SWP_NOSIZE))
351 {
352 WindowRect->right = WindowRect->left + WinPos->cx;
353 WindowRect->bottom = WindowRect->top + WinPos->cy;
354 }
355
356 if (!(WinPos->flags & SWP_NOMOVE))
357 {
358 WindowRect->left = WinPos->x;
359 WindowRect->top = WinPos->y;
360 WindowRect->right += WinPos->x - WindowObject->WindowRect.left;
361 WindowRect->bottom += WinPos->y - WindowObject->WindowRect.top;
362
363 W32kOffsetRect(ClientRect, WinPos->x - WindowObject->WindowRect.left,
364 WinPos->y - WindowObject->WindowRect.top);
365 }
366
367 WinPos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
368 return(TRUE);
369 }
370
371 BOOLEAN
372 WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
373 INT cy, UINT flags)
374 {
375 PWINDOW_OBJECT Window;
376 NTSTATUS Status;
377 WINDOWPOS WinPos;
378 RECT NewWindowRect;
379 RECT NewClientRect;
380 HRGN VisRgn = NULL;
381 ULONG WvrFlags = 0;
382
383 /* FIXME: Get current active window from active queue. */
384
385 /* Check if the window is for a desktop. */
386 if (Wnd == PsGetWin32Thread()->Desktop->DesktopWindow)
387 {
388 return(FALSE);
389 }
390
391 Status =
392 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable,
393 Wnd,
394 otWindow,
395 (PVOID*)&Window);
396 if (!NT_SUCCESS(Status))
397 {
398 return(FALSE);
399 }
400
401 /* Fix up the flags. */
402 if (Window->Style & WS_VISIBLE)
403 {
404 flags &= ~SWP_SHOWWINDOW;
405 }
406 else
407 {
408 if (!(flags & SWP_SHOWWINDOW))
409 {
410 flags |= SWP_NOREDRAW;
411 }
412 flags &= ~SWP_HIDEWINDOW;
413 }
414
415 cx = max(cx, 0);
416 cy = max(cy, 0);
417
418 if ((Window->WindowRect.right - Window->WindowRect.left) == cx &&
419 (Window->WindowRect.bottom - Window->WindowRect.top) == cy)
420 {
421 flags |= SWP_NOSIZE;
422 }
423 if (Window->WindowRect.left == x && Window->WindowRect.top == y)
424 {
425 flags |= SWP_NOMOVE;
426 }
427 if (FALSE /* FIXME: Check if the window if already active. */)
428 {
429 flags |= SWP_NOACTIVATE;
430 }
431 else if ((Window->Style & (WS_POPUP | WS_CHILD)) != WS_CHILD)
432 {
433 if (!(flags & SWP_NOACTIVATE))
434 {
435 flags &= ~SWP_NOZORDER;
436 WndInsertAfter = HWND_TOP;
437 }
438 }
439
440 if (WndInsertAfter == HWND_TOPMOST || WndInsertAfter == HWND_NOTOPMOST)
441 {
442 WndInsertAfter = HWND_TOP;
443 }
444
445 if (WndInsertAfter != HWND_TOP && WndInsertAfter != HWND_BOTTOM)
446 {
447 /* FIXME: Find the window to insert after. */
448 }
449
450 WinPos.hwnd = Wnd;
451 WinPos.hwndInsertAfter = WndInsertAfter;
452 WinPos.x = x;
453 WinPos.y = y;
454 WinPos.cx = cx;
455 WinPos.cy = cy;
456 WinPos.flags = flags;
457
458 WinPosDoWinPosChanging(Window, &WinPos, &NewWindowRect, &NewClientRect);
459
460 if ((WinPos.flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) !=
461 SWP_NOZORDER)
462 {
463 /* FIXME: SWP_DoOwnedPopups. */
464 }
465
466 /* FIXME: Adjust flags based on WndInsertAfter */
467
468 if ((!(WinPos.flags & (SWP_NOREDRAW | SWP_SHOWWINDOW)) &&
469 WinPos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
470 SWP_HIDEWINDOW | SWP_FRAMECHANGED)) !=
471 (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER))
472 {
473 if (Window->Style & WS_CLIPCHILDREN)
474 {
475 VisRgn = DceGetVisRgn(Wnd, DCX_WINDOW | DCX_CLIPSIBLINGS, 0, 0);
476 }
477 else
478 {
479 VisRgn = DceGetVisRgn(Wnd, DCX_WINDOW, 0, 0);
480 }
481 }
482
483 WvrFlags = WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect,
484 &NewClientRect);
485
486 /* FIXME: Relink windows. */
487
488 /* FIXME: Reset active DCEs */
489
490 /* FIXME: Check for redrawing the whole client rect. */
491
492 if (WinPos.flags & SWP_SHOWWINDOW)
493 {
494 Window->Style |= WS_VISIBLE;
495 flags |= SWP_EX_PAINTSELF;
496 VisRgn = 1;
497 }
498 else
499 {
500 /* FIXME: Move the window bits */
501 }
502
503 if (WinPos.flags & SWP_HIDEWINDOW)
504 {
505 Window->Style &= ~WS_VISIBLE;
506 }
507
508 /* FIXME: Hide or show the claret */
509
510 if (VisRgn)
511 {
512 if (!(WinPos.flags & SWP_NOREDRAW))
513 {
514 if (flags & SWP_EX_PAINTSELF)
515 {
516 PaintRedrawWindow(Window->Self, NULL,
517 (VisRgn == 1) ? 0 : VisRgn,
518 RDW_ERASE | RDW_FRAME | RDW_INVALIDATE |
519 RDW_ALLCHILDREN,
520 RDW_EX_XYWINDOW | RDW_EX_USEHRGN);
521 }
522 else
523 {
524 PaintRedrawWindow(Window->Self, NULL,
525 (VisRgn == 1) ? 0 : VisRgn,
526 RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN,
527 RDW_EX_USEHRGN);
528 }
529 /* FIXME: Redraw the window parent. */
530 }
531 /* FIXME: Delete VisRgn */
532 }
533
534 if (!(flags & SWP_NOACTIVATE))
535 {
536 WinPosChangeActiveWindow(WinPos.hwnd, FALSE);
537 }
538
539 /* FIXME: Check some conditions before doing this. */
540 NtUserSendMessage(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&WinPos);
541
542 ObmDereferenceObject(Window);
543 return(TRUE);
544 }
545
546 LRESULT
547 WinPosGetNonClientSize(HWND Wnd, RECT* WindowRect, RECT* ClientRect)
548 {
549 *ClientRect = *WindowRect;
550 return(W32kSendNCCALCSIZEMessage(Wnd, FALSE, ClientRect, NULL));
551 }
552
553 BOOLEAN
554 WinPosShowWindow(HWND Wnd, INT Cmd)
555 {
556 BOOLEAN WasVisible;
557 PWINDOW_OBJECT Window;
558 NTSTATUS Status;
559 UINT Swp = 0;
560 RECT NewPos;
561 BOOLEAN ShowFlag;
562
563 Status =
564 ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable,
565 Wnd,
566 otWindow,
567 (PVOID*)&Window);
568 if (!NT_SUCCESS(Status))
569 {
570 return(FALSE);
571 }
572
573 WasVisible = (Window->Style & WS_VISIBLE) != 0;
574
575 switch (Cmd)
576 {
577 case SW_HIDE:
578 {
579 if (!WasVisible)
580 {
581 ObmDereferenceObject(Window);
582 return(FALSE);
583 }
584 Swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE |
585 SWP_NOZORDER;
586 break;
587 }
588
589 case SW_SHOWMINNOACTIVE:
590 Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
591 /* Fall through. */
592 case SW_SHOWMINIMIZED:
593 Swp |= SWP_SHOWWINDOW;
594 /* Fall through. */
595 case SW_MINIMIZE:
596 {
597 Swp |= SWP_FRAMECHANGED;
598 if (!(Window->Style & WS_MINIMIZE))
599 {
600 Swp |= WinPosMinMaximize(Window, SW_MINIMIZE, &NewPos);
601 }
602 else
603 {
604 Swp |= SWP_NOSIZE | SWP_NOMOVE;
605 }
606 break;
607 }
608
609 case SW_SHOWMAXIMIZED:
610 {
611 Swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
612 if (!(Window->Style & WS_MAXIMIZE))
613 {
614 Swp |= WinPosMinMaximize(Window, SW_MAXIMIZE, &NewPos);
615 }
616 else
617 {
618 Swp |= SWP_NOSIZE | SWP_NOMOVE;
619 }
620 break;
621 }
622
623 case SW_SHOWNA:
624 Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
625 /* Fall through. */
626 case SW_SHOW:
627 Swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
628 /* Don't activate the topmost window. */
629 break;
630
631 case SW_SHOWNOACTIVATE:
632 Swp |= SWP_NOZORDER;
633 /* Fall through. */
634 case SW_SHOWNORMAL:
635 case SW_SHOWDEFAULT:
636 case SW_RESTORE:
637 Swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
638 if (Window->Style & (WS_MINIMIZE | WS_MAXIMIZE))
639 {
640 Swp |= WinPosMinMaximize(Window, SW_RESTORE, &NewPos);
641 }
642 else
643 {
644 Swp |= SWP_NOSIZE | SWP_NOMOVE;
645 }
646 break;
647 }
648
649 ShowFlag = (Cmd != SW_HIDE);
650 if (ShowFlag != WasVisible)
651 {
652 NtUserSendMessage(Wnd, WM_SHOWWINDOW, ShowFlag, 0);
653 /*
654 * FIXME: Need to check the window wasn't destroyed during the
655 * window procedure.
656 */
657 }
658
659 if (Window->Style & WS_CHILD &&
660 !W32kIsWindowVisible(Window->Parent->Self) &&
661 (Swp & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE))
662 {
663 if (Cmd == SW_HIDE)
664 {
665 Window->Style &= ~WS_VISIBLE;
666 }
667 else
668 {
669 Window->Style |= WS_VISIBLE;
670 }
671 }
672 else
673 {
674 if (Window->Style & WS_CHILD &&
675 !(Window->ExStyle & WS_EX_MDICHILD))
676 {
677 Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
678 }
679 if (!(Swp & MINMAX_NOSWP))
680 {
681 WinPosSetWindowPos(Wnd, HWND_TOP, NewPos.left, NewPos.top,
682 NewPos.right, NewPos.bottom, LOWORD(Swp));
683 if (Cmd == SW_HIDE)
684 {
685 /* Hide the window. */
686 if (Wnd == W32kGetActiveWindow())
687 {
688 WinPosActivateOtherWindow(Window);
689 }
690 /* Revert focus to parent. */
691 if (Wnd == W32kGetFocusWindow() ||
692 W32kIsChildWindow(Wnd, W32kGetFocusWindow()))
693 {
694 W32kSetFocusWindow(Window->Parent->Self);
695 }
696 }
697 }
698 /* FIXME: Check for window destruction. */
699 /* Show title for minimized windows. */
700 if (Window->Style & WS_MINIMIZE)
701 {
702 WinPosShowIconTitle(Window, TRUE);
703 }
704 }
705
706 if (Window->Flags & WINDOWOBJECT_NEED_SIZE)
707 {
708 WPARAM wParam = SIZE_RESTORED;
709
710 Window->Flags &= ~WINDOWOBJECT_NEED_SIZE;
711 if (Window->Style & WS_MAXIMIZE)
712 {
713 wParam = SIZE_MAXIMIZED;
714 }
715 else if (Window->Style & WS_MINIMIZE)
716 {
717 wParam = SIZE_MINIMIZED;
718 }
719
720 NtUserSendMessage(Wnd, WM_SIZE, wParam,
721 MAKELONG(Window->ClientRect.right -
722 Window->ClientRect.left,
723 Window->ClientRect.bottom -
724 Window->ClientRect.top));
725 NtUserSendMessage(Wnd, WM_MOVE, 0,
726 MAKELONG(Window->ClientRect.left,
727 Window->ClientRect.top));
728 }
729 ObmDereferenceObject(Window);
730 return(WasVisible);
731 }