ReactOS 0.4.15-dev-7788-g1ad9096
focus.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: Focus functions
5 * FILE: win32ss/user/ntuser/focus.c
6 * PROGRAMER: ReactOS Team
7 */
8
9#include <win32k.h>
10#include <immdev.h>
12
17ULONG guSFWLockCount = 0; // Rule #8, No menus are active. So should be zero.
20
21/*
22 Check locking of a process or one or more menus are active.
23*/
26{
27 return (gppiLockSFW || guSFWLockCount);
28}
29
30/*
31 Get capture window via foreground Queue.
32*/
35{
37 return ( ForegroundQueue ? (ForegroundQueue->spwndCapture ? UserHMGetHandle(ForegroundQueue->spwndCapture) : 0) : 0);
38}
39
42{
43 PTHREADINFO pti;
44 PUSER_MESSAGE_QUEUE ThreadQueue;
45
47 ThreadQueue = pti->MessageQueue;
48 if (!ThreadQueue)
49 return NULL;
50 return ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
51}
52
54{
55 RECTL rclAnd, rclMonitor, rclWindow;
56 PMONITOR pMonitor;
57
58 if (!Window || !(Window->style & WS_VISIBLE) || (Window->style & WS_CHILD) ||
59 (Window->ExStyle & WS_EX_TOOLWINDOW) || !IntGetWindowRect(Window, &rclWindow))
60 {
61 return FALSE;
62 }
63
64 pMonitor = UserGetPrimaryMonitor();
65 if (!pMonitor)
66 {
67 RECTL_vSetRect(&rclMonitor, 0, 0,
69 }
70 else
71 {
72 rclMonitor = *(LPRECTL)&pMonitor->rcMonitor;
73 }
74
75 RECTL_bIntersectRect(&rclAnd, &rclMonitor, &rclWindow);
76 return RtlEqualMemory(&rclAnd, &rclMonitor, sizeof(RECTL));
77}
78
80{
81 HWND hWnd;
82
85
87 return FALSE;
88
91 {
94 }
95 return TRUE;
96}
97
100{
102 return;
103
104 if ( Window->spwndParent == UserGetDesktopWindow() &&
105 (!(Window->ExStyle & WS_EX_TOOLWINDOW) ||
106 (Window->ExStyle & WS_EX_APPWINDOW)))
107 {
108 // FIXME lParam; The value is TRUE if the window is in full-screen mode, or FALSE otherwise.
109 co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (WPARAM) UserHMGetHandle(Window), FALSE);
110 }
111 else
112 {
113 co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, 0, FALSE);
114 }
115}
116
119{
120 USER_REFERENCE_ENTRY RefPrev;
121 PWND WndPrev;
122 BOOL Ret = TRUE;
123 LPARAM lParam = hWnd ? (LPARAM)hWnd : 0;
124
125 if (hWndPrev && (WndPrev = ValidateHwndNoErr(hWndPrev)))
126 {
127 UserRefObjectCo(WndPrev, &RefPrev);
128
130 {
132 MAKEWPARAM(WA_INACTIVE, (WndPrev->style & WS_MINIMIZE) != 0),
133 (LPARAM)hWnd);
134
135 if (WndPrev && Clear)
137 }
138 else
139 {
140 ERR("Application is keeping itself Active to prevent the change!\n");
141 Ret = FALSE;
142 }
143
144 UserDerefObjectCo(WndPrev);
145 }
146 return Ret;
147}
148
149// Win: xxxFocusSetInputContext
150VOID IntFocusSetInputContext(PWND pWnd, BOOL bActivate, BOOL bCallback)
151{
152 PTHREADINFO pti;
153 PWND pImeWnd;
155 HWND hImeWnd;
158
159 if (!pWnd || !pWnd->pcls || IS_WND_IMELIKE(pWnd))
160 return;
161
162 pti = pWnd->head.pti;
163 if (!pti || (pti->TIF_flags & TIF_INCLEANUP))
164 return;
165
166 pImeWnd = pti->spwndDefaultIme;
167 if (!pImeWnd)
168 return;
169
170 UserRefObjectCo(pImeWnd, &Ref);
171
172 hImeWnd = UserHMGetHandle(pImeWnd);
173 wParam = (bActivate ? IMS_IMEACTIVATE : IMS_IMEDEACTIVATE);
175
176 if (bCallback)
178 else
180
181 UserDerefObjectCo(pImeWnd);
182}
183
184//
185// Deactivating the foreground message queue.
186//
187// Release Active, Capture and Focus Windows associated with this message queue.
188//
189// Win: xxxDeactivate
192{
194 PTHREADINFO ptiPrev;
195 PWND pwndPrev;
196 BOOL InAAPM = FALSE;
198
199 if ( !pti->MessageQueue->spwndActive )
200 {
201 TRACE("IDAW E : Nothing to do, Active is NULL! pti 0x%p tid 0x%p\n",pti,tid);
202 return TRUE;
203 }
204
205 TRACE("IDAW : pti 0x%p tid 0x%p\n",pti,tid);
206
207 if (ptiCurrent != pti)
208 {
210 IntReferenceThreadInfo(ptiCurrent);
211 }
212
213 if (!(pti->TIF_flags & TIF_INACTIVATEAPPMSG) )
214 {
216 InAAPM = TRUE;
217 }
218
219 //
220 // Check for Capture and release it.
221 //
222 if ( pti->MessageQueue->spwndCapture )
223 {
224 MSG msg;
225 PWND pwndCapture = pti->MessageQueue->spwndCapture;
226
227 UserRefObjectCo(pwndCapture, &Ref);
229 UserDerefObjectCo(pwndCapture);
230
231 /* Generate mouse move message */
232 msg.message = WM_MOUSEMOVE;
233 msg.wParam = UserGetMouseButtonsState();
234 msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y);
235 msg.pt = gpsi->ptCursor;
237 }
238
239 //
240 // Check for Active and release it.
241 //
242 if ( pti->MessageQueue->spwndActive )
243 {
244 pwndPrev = pti->MessageQueue->spwndActive;
245 ptiPrev = pwndPrev->head.pti;
246
248 {
249 if (InAAPM) pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
250 if (ptiCurrent != pti)
251 {
253 IntDereferenceThreadInfo(ptiCurrent);
254 }
255 return FALSE;
256 }
257
258 if ( pti->MessageQueue->spwndActive == pwndPrev )
259 {
260 pti->MessageQueue->spwndActivePrev = pwndPrev;
261 pti->MessageQueue->spwndActive = NULL;
262 }
263
264 if (ptiPrev->TIF_flags & TIF_INCLEANUP) ptiPrev = NULL;
265 }
266 else
267 {
268 ptiPrev = pti;
269 pwndPrev = (PWND)-1; // Avoid zero Active window.
270 }
271
272 if ( ptiPrev )
273 {
274 HANDLE OldTID = PsGetThreadId(ptiPrev->pEThread);
275 PWND cWindow;
276 HWND *List, *phWnd;
277
279 if ( List )
280 {
281 if ( OldTID )
282 {
283 for (phWnd = List; *phWnd; ++phWnd)
284 {
285 cWindow = ValidateHwndNoErr(*phWnd);
286 if ( cWindow && cWindow->head.pti == ptiPrev )
287 { // FALSE if the window is being deactivated,
288 // ThreadId that owns the window being activated.
289 //ERR("IDW : WM_ACTIVATEAPP(0) hwnd %p tid Old %p New %p\n",UserHMGetHandle(cWindow),OldTID,tid);
290 UserRefObjectCo(cWindow, &Ref);
292 UserDerefObjectCo(cWindow);
293 }
294 }
295 }
297 }
298 }
299
300 //
301 // Now check for a change (Bounce), if Active same as previous window, release it too.
302 //
303 if ( pti->MessageQueue->spwndActive == pwndPrev )
304 {
306 {
307 if (InAAPM) pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
308 if (ptiCurrent != pti)
309 {
311 IntDereferenceThreadInfo(ptiCurrent);
312 }
313 return FALSE;
314 }
315
316 if ( pti->MessageQueue->spwndActive == pwndPrev )
317 {
318 pti->MessageQueue->spwndActivePrev = pwndPrev;
319 pti->MessageQueue->spwndActive = NULL;
320 }
321 }
322
323 //
324 // Check for Focus and release it.
325 //
326 if ( pti->MessageQueue->spwndFocus )
327 {
328 PWND pwndFocus = pti->MessageQueue->spwndFocus;
329
330 //
331 // Fix win.c:test_SetForegroundWindow:SetActiveWindow(0)!
332 //
333 pti->MessageQueue->spwndFocus = NULL; // Null out Focus.
334
335 UserRefObjectCo(pwndFocus, &Ref);
337 if (IS_IMM_MODE())
338 {
340 }
341 UserDerefObjectCo(pwndFocus);
342 }
343
344 if (InAAPM) pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
345 if (ptiCurrent != pti)
346 {
348 IntDereferenceThreadInfo(ptiCurrent);
349 }
350 return TRUE;
351}
352
353//
354// Activating another threads foreground window after a switch.
355//
358{
361
362 if (Wnd)
363 {
364 Wnd = VerifyWnd(Wnd);
365
366 if (!Wnd) return;
367
368 UserRefObjectCo(Wnd, &Ref);
369
370 if (!gpqForeground)
371 {
372 // No foreground queue set.
374 }
375 else
376 {
377 // Same Active and Wnd.
378 if ( pmq->spwndActive == Wnd )
379 {
380 WPARAM wParam = (Wnd->head.pti->MessageQueue == gpqForeground);
381
383
384 if (wParam)
385 {
386 UpdateShellHook(Wnd);
387
389 }
390 }
391 else // Not the same, set the active Wnd.
392 {
394 }
395 }
397 }
398 else // Handle no Wnd!
399 {
400 if ( tid && // TID,
401 pmq->spwndActive && // Active WND not zero,
402 gpqForeground == pmq ) // Same message queues.
403 {
404 Wnd = pmq->spwndActive; // Use active window from current queue.
405
406 UserRefObjectCo(Wnd, &Ref);
407
409
410 UpdateShellHook(Wnd);
411
413
415 }
416 else if (gpqForeground != pmq)
417 {
418 // Not the same message queue so clear flags for foreground switching.
419 pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE;
420 pti->ppi->W32PF_flags &= ~W32PF_ALLOWFOREGROUNDACTIVATE;
421 }
422 }
423}
424
427{
428 PWND spwndOwner;
429 if (VerifyWnd(Window))
430 { // Set last active for window and it's owner.
431 spwndOwner = Window;
432 while (spwndOwner->spwndOwner)
433 {
434 spwndOwner = spwndOwner->spwndOwner;
435 }
436 WndSetLastActive(spwndOwner, Window);
437 return TRUE;
438 }
439 ERR("MakeWindowActive Failed!\n");
440 return FALSE;
441}
442
444co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOOL Async)
445{
446 USER_REFERENCE_ENTRY Ref, RefPrev, RefCall;
447 HANDLE OldTID, NewTID;
448 PTHREADINFO pti, ptiOld, ptiNew;
449 BOOL InAAPM = FALSE;
450
451 //ERR("SendActivateMessages\n");
452
454
455 if (Window)
456 {
457 UserRefObjectCo(Window, &Ref);
458
459 if (WindowPrev) UserRefObjectCo(WindowPrev, &RefPrev);
460
461 pti->MessageQueue->QF_flags &= ~QF_EVENTDEACTIVATEREMOVED;
462
463 /* Send palette messages */
464 if (gpsi->PUSIFlags & PUSIF_PALETTEDISPLAY &&
465 //co_IntPostOrSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
467 {
471 0);
472 }
474 if (!(Window->style & WS_CHILD))
475 {
477
478 while (pwndTemp && !(pwndTemp->style & WS_VISIBLE)) pwndTemp = pwndTemp->spwndNext;
479
480 if (Window != pwndTemp || (WindowPrev && !IntIsWindowVisible(WindowPrev)))
481 {
482 if (!Async || pti->MessageQueue == gpqForeground)
483 {
485 if (Window == pwndTemp) flags |= SWP_NOACTIVATE;
486 //ERR("co_IntSendActivateMessages SetWindowPos! Async %d pti Q == FGQ %d\n",Async,pti->MessageQueue == gpqForeground);
488 }
489 }
490 }
493 if (Window->spwndPrev)
494 {
495 HWND *phwndTopLevel, *phwndCurrent;
496 PWND pwndCurrent, pwndDesktop;
497
498 pwndDesktop = co_GetDesktopWindow(Window);//UserGetDesktopWindow();
499 if (Window->spwndParent == pwndDesktop )
500 {
501 phwndTopLevel = IntWinListChildren(pwndDesktop);
502 phwndCurrent = phwndTopLevel;
503 while(*phwndCurrent)
504 {
505 pwndCurrent = UserGetWindowObject(*phwndCurrent);
506
507 if (pwndCurrent && pwndCurrent->spwndOwner == Window )
508 {
510 }
511 phwndCurrent++;
512 }
514 }
515 }
517 }
518
519 OldTID = WindowPrev ? IntGetWndThreadId(WindowPrev) : NULL;
520 NewTID = Window ? IntGetWndThreadId(Window) : NULL;
521 ptiOld = WindowPrev ? WindowPrev->head.pti : NULL;
522 ptiNew = Window ? Window->head.pti : NULL;
523
524 //ERR("SendActivateMessage Old -> %x, New -> %x\n", OldTID, NewTID);
525
526 if (!(pti->TIF_flags & TIF_INACTIVATEAPPMSG) &&
527 (OldTID != NewTID) )
528 {
529 PWND cWindow;
530 HWND *List, *phWnd;
531
533 if ( List )
534 {
535 if ( OldTID )
536 {
538 // Note: Do not set pci flags, this does crash!
539 for (phWnd = List; *phWnd; ++phWnd)
540 {
541 cWindow = ValidateHwndNoErr(*phWnd);
542 if (cWindow && cWindow->head.pti == ptiOld)
543 { // FALSE if the window is being deactivated,
544 // ThreadId that owns the window being activated.
545 //ERR("SAM : WM_ACTIVATEAPP(0) tid Old %p New %p\n",OldTID,NewTID);
546 UserRefObjectCo(cWindow, &RefCall);
547 co_IntSendMessage(*phWnd, WM_ACTIVATEAPP, FALSE, (LPARAM)NewTID);
548 UserDerefObjectCo(cWindow);
549 }
550 }
551 ptiOld->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
552 }
553 if ( NewTID )
554 {
555 InAAPM = TRUE;
558 for (phWnd = List; *phWnd; ++phWnd)
559 {
560 cWindow = ValidateHwndNoErr(*phWnd);
561 if (cWindow && cWindow->head.pti == ptiNew)
562 { // TRUE if the window is being activated,
563 // ThreadId that owns the window being deactivated.
564 //ERR("SAM : WM_ACTIVATEAPP(1) hwnd %p tid New %p Old %p\n",UserHMGetHandle(cWindow),NewTID,OldTID);
565 UserRefObjectCo(cWindow, &RefCall);
566 co_IntSendMessage(*phWnd, WM_ACTIVATEAPP, TRUE, (LPARAM)OldTID);
567 UserDerefObjectCo(cWindow);
568 }
569 }
570 }
572 }
573 }
574
575 if (Window)
576 {
577 if (WindowPrev)
578 UserDerefObjectCo(WindowPrev); // Now allow the previous window to die.
579
580 if (Window->state & WNDS_ACTIVEFRAME)
581 { // If already active frame do not allow NCPaint.
582 //ERR("SendActivateMessage Is Active Frame!\n");
583 Window->state |= WNDS_NONCPAINT;
584 }
585
586 if (Window->style & WS_MINIMIZE)
587 {
588 TRACE("Widow was minimized\n");
589 }
590
592
596 0);
597
600 MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE, (Window->style & WS_MINIMIZE) != 0),
601 (LPARAM)(WindowPrev ? UserHMGetHandle(WindowPrev) : 0));
602
603 if (Window->style & WS_VISIBLE)
605
606 Window->state &= ~WNDS_NONCPAINT;
607
609 }
610 return InAAPM;
611}
612
613// Win: xxxSendFocusMessages
616{
617 PWND pWndPrev;
618 PUSER_MESSAGE_QUEUE ThreadQueue = pti->MessageQueue; // Queue can change...
619 HWND hwndPrev;
621
622 ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;
623 if (!pWnd && ThreadQueue->spwndActive)
624 {
625 ThreadQueue->QF_flags |= QF_FOCUSNULLSINCEACTIVE;
626 }
627
628 pWndPrev = ThreadQueue->spwndFocus;
629 if (pWndPrev)
630 UserRefObjectCo(pWndPrev, &Ref);
631
632 /* check if the specified window can be set in the input data of a given queue */
633 if (!pWnd || ThreadQueue == pWnd->head.pti->MessageQueue)
634 /* set the current thread focus window */
635 ThreadQueue->spwndFocus = pWnd;
636
637 if (pWnd)
638 {
639 if (pWndPrev)
640 {
642 if (IS_IMM_MODE())
643 {
645 }
646 }
647 if (ThreadQueue->spwndFocus == pWnd)
648 {
649 if (IS_IMM_MODE())
650 {
652 }
653
654 IntNotifyWinEvent(EVENT_OBJECT_FOCUS, pWnd, OBJID_CLIENT, CHILDID_SELF, 0);
655
656 hwndPrev = (pWndPrev ? UserHMGetHandle(pWndPrev) : NULL);
658 }
659 }
660 else
661 {
662 if (pWndPrev)
663 {
664 IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
665
667 if (IS_IMM_MODE())
668 {
670 }
671 }
672 }
673
674 if (pWndPrev)
675 UserDerefObjectCo(pWndPrev);
676}
677
680{
683 BOOL Ret = FALSE;
684
686 while (Entry != &pti->PostedMessagesListHead)
687 {
688 // Scan posted queue messages to see if we received async messages.
690 Entry = Entry->Flink;
691
692 if (Message->dwQEvent == EventLast)
693 {
694 //ERR("Event D/SAW: Last Activate/Deactivate %d\n", EventLast);
695 return Ret;
696 }
697
698 if (Message->dwQEvent == Event)
699 {
700 //ERR("Event D/SAW: Found one in the Post Msg Queue! Activate/Deactivate %d\n", Event);
701 ClearMsgBitsMask(pti, Message->QS_Flags);
703 Ret = TRUE;
704 }
705 }
706 return Ret;
707}
708
711{
712 BOOL Ret;
713 PPROCESSINFO ppi = pti->ppi;
714
715 Ret = !!(pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE);
716 if (Ret)
717 {
718 pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE;
719 }
720 else
721 Ret = !!(ppi->W32PF_flags & W32PF_ALLOWFOREGROUNDACTIVATE);
722
723 if (Ret)
724 ppi->W32PF_flags &= ~W32PF_ALLOWFOREGROUNDACTIVATE;
725 //ERR("ToggleFGActivate is %d\n",Ret);
726 return Ret;
727}
728
731{
732 // Not allowed if one or more,,
733 if (!ToggleFGActivate(pti) || // bits not set,
734 pti->rpdesk != gpdeskInputDesktop || // not current Desktop,
735 pti->MessageQueue == gpqForeground || // if already the queue foreground,
736 IsFGLocked() || // foreground is locked,
737 (Wnd->ExStyle & WS_EX_NOACTIVATE)) // or, does not become the foreground window when the user clicks it.
738 {
739 return FALSE;
740 }
741 //ERR("IsAllowedFGActive is TRUE\n");
742 return TRUE;
743}
744
745/*
746 Can the system force foreground from one or more conditions.
747 */
750{
751 if (!ptiLastInput ||
752 ptiLastInput->ppi == ppi ||
754 gptiForeground->ppi == ppi ||
756 gppiInputProvider == ppi ||
758 ) return TRUE;
759 //ERR("CanForceFG is FALSE\n");
760 return FALSE;
761}
762
763//
764// Switching out foreground message queues.
765//
768 _In_opt_ PWND Wnd,
769 _In_ PTHREADINFO pti,
770 _In_ BOOL MouseActivate,
771 _In_ DWORD Type )
772{
773 PTHREADINFO ptiChg, ptiPrev;
774 PUSER_MESSAGE_QUEUE pumq, pumqChg, pumqPrev;
775 BOOL Removed, Ret = TRUE;
776
777 if (Wnd && !VerifyWnd(Wnd))
778 {
779 return FALSE;
780 }
781
783 ptiPrev = NULL;
784 else
785 ptiPrev = gptiForeground;
786
787 if (Wnd)
788 {
789 ptiChg = Wnd->head.pti;
790 IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue);
791 gptiForeground = Wnd->head.pti;
792 //ERR("Set Foreground pti 0x%p Q 0x%p hWnd 0x%p\n", Wnd->head.pti, Wnd->head.pti->MessageQueue, UserHMGetHandle(Wnd));
793 }
794 else
795 {
796 ptiChg = NULL;
799 //ERR("Set Foreground pti 0x0 Q 0x0 hWnd 0x0\n");
800 }
801
802 //
803 // Process the changing out of the message queues.
804 //
806 {
807 pumqPrev = NULL;
808 if ( ptiPrev && !(ptiPrev->TIF_flags & TIF_INCLEANUP) )
809 {
810 pumqPrev = ptiPrev->MessageQueue;
811 }
812
813 pumq = pti ? pti->MessageQueue : NULL;
814
815 // Deactivate the previous message queue.
816 if (pumqPrev)
817 {
818 if ( pumq != pumqPrev )
819 {
820 MSG Msg;
821 HWND hWndPrev = pumqPrev->spwndActive ? UserHMGetHandle(pumqPrev->spwndActive) : NULL;
822 HANDLE tid = gptiForeground ? PsGetThreadId(gptiForeground->pEThread) : NULL; // TID from changing Window PTI.
823
825 Msg.hwnd = hWndPrev;
826 Msg.wParam = (WPARAM)pumqPrev->spwndActive;
827 Msg.lParam = 0;
828 Msg.time = 0;
829 //ERR("SFWAMQ : DAW P pti 0x%p tid 0x%p hWndPrev 0x%p\n",ptiPrev,tid,hWndPrev);
831 }
832 }
833
834 pumqChg = NULL;
835 if ( ptiChg && !(ptiChg->TIF_flags & TIF_INCLEANUP) )
836 {
837 pumqChg = ptiChg->MessageQueue;
838 }
839
840 pumq = pti ? pti->MessageQueue : NULL;
841
842 // Activate changing message queue.
843 if (pumqChg)
844 {
845 /*
846 Henri Verbeet,
847 What happens is that we get the WM_WINE_SETACTIVEWINDOW message sent by the
848 other thread after we already changed the foreground window back to our own
849 window.
850 */
851 //ERR("SFWAMQ : 1\n");
853
854 if (pumqChg != pumq)
855 {
856 MSG Msg;
857 HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
858 HANDLE tid = ptiPrev ? PsGetThreadId(ptiPrev->pEThread) : NULL;
859
861
863 Msg.hwnd = hWnd;
864 Msg.wParam = (WPARAM)Wnd;
865 Msg.lParam = (LPARAM)tid;
866 Msg.time = 0;
867 //ERR("SFWAMQ : SAW P pti 0x%p tid 0x%p hWnd 0x%p\n",ptiChg,tid,hWnd);
868 MsqPostMessage(ptiChg, &Msg, FALSE, QS_EVENT, POSTEVENT_SAW, (LONG_PTR)Type|MouseActivate);
869 }
870 else // Current message queue same as changed message queue.
871 {
872 if (pumq->spwndActive == Wnd)
873 {
875
876 UpdateShellHook(Wnd);
877
879 }
880 else
881 {
882 //ERR("SFWAMQ : SAW I pti 0x%p hWnd 0x%p\n", ptiChg, Wnd ? UserHMGetHandle(Wnd) : NULL);
883 Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE/*Type*/, FALSE);
884 //if (!Ret) ERR("SFWAMQ : ISAW : return error\n");
885 return Ret;
886 }
887 }
888 }
889
890 // Handle same message queue after switch out.
891 pumqPrev = NULL;
892 if ( ptiPrev && !(ptiPrev->TIF_flags & TIF_INCLEANUP) )
893 {
894 pumqPrev = ptiPrev->MessageQueue;
895 }
896 pumq = pti ? pti->MessageQueue : NULL;
897
898 if ( pumqPrev && pumq == pumqPrev )
899 {
900 HANDLE tid = Wnd ? PsGetThreadId(Wnd->head.pti->pEThread) : NULL;
901 //ERR("SFWAMQ : DAW I pti 0x%p tid 0x%p hWnd 0x%p\n", ptiPrev, tid, Wnd ? UserHMGetHandle(Wnd) : NULL);
903 }
904 }
905 return Ret;
906}
907
908/*
909 MSDN:
910 The system restricts which processes can set the foreground window. A process
911 can set the foreground window only if one of the following conditions is true:
912
913 * The process is the foreground process.
914 * The process was started by the foreground process.
915 * The process received the last input event.
916 * There is no foreground process.
917 * The foreground process is being debugged.
918 * The foreground is not locked (see LockSetForegroundWindow).
919 * The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
920 * No menus are active.
921*/
922static
925 _In_opt_ PWND Wnd,
926 _In_ BOOL MouseActivate,
927 _In_ BOOL bFlash )
928{
929 HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
930 PUSER_MESSAGE_QUEUE PrevForegroundQueue;
931 PTHREADINFO pti;
932 BOOL Ret = FALSE;
933
934 if (Wnd) ASSERT_REFS_CO(Wnd);
935
936 TRACE("SetForegroundAndFocusWindow(%x, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE"));
937
938 PrevForegroundQueue = IntGetFocusMessageQueue(); // Use this active desktop.
940
941 if (Wnd && PrevForegroundQueue)
942 { // Same Window Q as foreground just do active.
943 if (Wnd->head.pti->MessageQueue == PrevForegroundQueue)
944 {
945 //ERR("Same Window Q as foreground just do active.\n");
946 if (pti->MessageQueue == PrevForegroundQueue)
947 { // Same WQ and TQ go active.
948 //ERR("Same WQ and TQ go active.\n");
949 Ret = IntUserSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
950 }
951 else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
952 { // Same WQ and it is active.
953 //ERR("Same WQ and it is active.\n");
954 Ret = TRUE;
955 }
956 else
957 { // Same WQ as FG but not the same TQ send active.
958 //ERR("Same WQ as FG but not the same TQ send active.\n");
959 MSG Msg;
960 PTHREADINFO ptiNew = Wnd->head.pti;
961
963 Msg.hwnd = hWnd;
964 Msg.wParam = (WPARAM)Wnd;
965 Msg.lParam = 0;
966 Msg.time = 0;
967 //ERR("SFAFW 1 : SAW P pti 0x%p hWnd 0x%p\n",ptiNew,hWnd);
968 MsqPostMessage(ptiNew, &Msg, FALSE, QS_EVENT, POSTEVENT_SAW, (LONG_PTR)MouseActivate);
969
970 Ret = TRUE;
971 }
972 return Ret;
973 }
974 }
975
976 if ( (( !IsFGLocked() || pti->ppi == gppiInputProvider ) &&
978 pti->ppi == ppiScrnSaver
979 )
980 {
981
982 ToggleFGActivate(pti);
983
984 return co_IntSetForegroundMessageQueue( Wnd, pti, MouseActivate, 0 );
985 }
986
987 if (!Wnd) return FALSE; // No window, always return FALSE.
988
990
991 if (pti->MessageQueue == Wnd->head.pti->MessageQueue)
992 {
993 //ERR("Same PQ and WQ go active.\n");
994 Ret = IntUserSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
995 //if (!Ret) ERR("ISFAFW : IUSAW : return error\n");
996 }
997 else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
998 {
999 TRACE("Same Active and Wnd.\n"); // Leave this for now.
1000 }
1001 else
1002 {
1003 //ERR("Activate Not same PQ and WQ and Wnd.\n");
1005 MSG Msg;
1006 PTHREADINFO ptiNew = Wnd->head.pti;
1007
1008 Msg.message = WM_ASYNC_SETACTIVEWINDOW;
1009 Msg.hwnd = hWnd;
1010 Msg.wParam = (WPARAM)Wnd;
1011 Msg.lParam = 0;
1012 Msg.time = 0;
1013 //ERR("SFAFW 2 : SAW P pti 0x%p hWnd 0x%p\n",ptiNew,hWnd);
1014 MsqPostMessage(ptiNew, &Msg, FALSE, QS_EVENT, POSTEVENT_SAW, (LONG_PTR)MouseActivate);
1015 }
1016 // Always return FALSE.
1017 return FALSE;
1018}
1019
1020//
1021// Set the Active Window.
1022//
1025 _In_ PWND Wnd,
1026 _In_ BOOL bMouse,
1027 _In_ BOOL bFocus,
1028 _In_ BOOL Async )
1029{
1030 PTHREADINFO pti;
1031 PUSER_MESSAGE_QUEUE ThreadQueue;
1032 PWND pWndChg, WndPrev; // State changes.
1033 HWND hWndPrev;
1034 HWND hWnd = 0;
1035 BOOL InAAPM;
1037
1038 //ERR("co_IntSetActiveWindow 1\n");
1039
1041 ThreadQueue = pti->MessageQueue;
1042 ASSERT(ThreadQueue != 0);
1043
1044 pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch.
1045 hWndPrev = (pWndChg ? UserHMGetHandle(pWndChg) : NULL);
1046
1047 if ( !Wnd || Wnd == UserGetDesktopWindow() )
1048 {
1049 //ERR("ISAW : NULL %p\n",Wnd);
1050 return FALSE;
1051 }
1052
1053 ASSERT_REFS_CO(Wnd);
1054 hWnd = UserHMGetHandle(Wnd);
1055 //ERR("co_IntSetActiveWindow 2 hWnd 0x%p\n",hWnd);
1056
1057 if (Wnd->ExStyle & WS_EX_NOACTIVATE)
1058 return TRUE;
1059
1060 /* check if the specified window can be set in the input data of a given queue */
1061 if ( ThreadQueue != Wnd->head.pti->MessageQueue )
1062 {
1063 //ERR("ISAW : Must have the same Message Queue\n");
1064 return FALSE;
1065 }
1066
1067 if (!VerifyWnd(Wnd))
1068 {
1069 //ERR("ISAW : Window is in Destroy!\n");
1070 return FALSE;
1071 }
1072
1073 if ( Wnd == pWndChg )
1074 {
1075 //ERR("ISAW : Nothing to do\n");
1076 return TRUE; // Fix CORE-8780 and CORE-11979. See CORE-11324 for breakage.
1077 }
1078
1079 if ( Wnd->state & WNDS_BEINGACTIVATED ) return TRUE;
1080
1081 /* Call CBT hook chain */
1082 cbt.fMouse = bMouse;
1083 cbt.hWndActive = hWndPrev;
1085 {
1086 ERR("SetActiveWindow: WH_CBT Call Hook return!\n");
1087 return FALSE;
1088 }
1089
1090 ThreadQueue->QF_flags &= ~QF_EVENTDEACTIVATEREMOVED;
1091
1092 if ( ThreadQueue->spwndActive && ThreadQueue->spwndActive->state & WNDS_DESTROYED )
1093 ThreadQueue->spwndActive = NULL;
1094 else
1095 ThreadQueue->spwndActivePrev = ThreadQueue->spwndActive;
1096
1097 WndPrev = ThreadQueue->spwndActive; // Keep to save changing active.
1098
1099 if (WndPrev)
1100 {
1101 if (ThreadQueue == gpqForeground) gpqForegroundPrev = ThreadQueue;
1103 }
1104
1105 WndPrev = ThreadQueue->spwndActive; // Again keep to save changing active.
1106
1107 // While in calling message proc or hook:
1108 // Fail if a preemptive switch was made, current active not made previous,
1109 // focus window is dead or no longer the same thread queue.
1110 if ( ThreadQueue->spwndActivePrev != ThreadQueue->spwndActive ||
1111 pWndChg != WndPrev ||
1112 (Wnd && !VerifyWnd(Wnd)) ||
1113 ThreadQueue != pti->MessageQueue )
1114 {
1115 ERR("SetActiveWindow: Summary ERROR, active state changed!\n");
1116 return FALSE;
1117 }
1118
1119 if (!WndPrev) ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;
1120
1121 /* set the current thread active window */
1122 ThreadQueue->spwndActive = Wnd;
1123
1124 // Set state flag to prevent recursions.
1125 Wnd->state |= WNDS_BEINGACTIVATED;
1126
1127 IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
1128
1129 // Clear out activate EVENT messages.
1131
1132 WndPrev = VerifyWnd(ThreadQueue->spwndActivePrev); // Now should be set but verify it again.
1133
1134 InAAPM = co_IntSendActivateMessages(WndPrev, Wnd, bMouse, Async);
1135
1136 /* now change focus if necessary */
1138 if (bFocus && !(ThreadQueue->QF_flags & QF_FOCUSNULLSINCEACTIVE))
1139 {
1140 /* Do not change focus if the window is no longer active */
1141 if (pti->MessageQueue->spwndActive != IntGetNonChildAncestor(pti->MessageQueue->spwndFocus))
1142 {
1143 PWND pWndSend = pti->MessageQueue->spwndActive;
1144 // Clear focus if the active window is minimized.
1145 if (pWndSend && pti->MessageQueue->spwndActive->style & WS_MINIMIZE) pWndSend = NULL;
1146 // Send focus messages and if so, set the focus.
1147 IntSendFocusMessages( pti, pWndSend);
1148 }
1149 }
1151 if (InAAPM)
1152 {
1153 pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
1154 }
1155
1156 // Checked in MENU_TrackMenu
1157 ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE;
1158
1159 //ERR("co_IntSetActiveWindow Exit\n");
1160 Wnd->state &= ~WNDS_BEINGACTIVATED;
1161 return (ThreadQueue->spwndActive == Wnd);
1162}
1163
1164//
1165// Set the Active Window.
1166//
1167// Window is not optional!
1168//
1171 _In_ PWND Wnd,
1172 _In_ BOOL bMouse,
1173 _In_ BOOL bFocus,
1174 _In_ BOOL Async)
1175{
1176 PTHREADINFO pti;
1177 PUSER_MESSAGE_QUEUE ThreadQueue;
1178
1179 //ERR("IntUserSetActiveWindow 1\n");
1180 ASSERT_REFS_CO(Wnd);
1181 if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
1182 //ERR("IntUserSetActiveWindow 1a hWnd 0x%p\n",UserHMGetHandle(Wnd));
1183
1184 //ERR("IntUserSetActiveWindow 2\n");
1186 ThreadQueue = pti->MessageQueue;
1187 ASSERT(ThreadQueue != 0);
1188
1189 while (Wnd)
1190 {
1191 BOOL Ret, DoFG, AllowFG;
1192
1193 if (ThreadQueue == Wnd->head.pti->MessageQueue)
1194 {
1195 if (IsAllowedFGActive(pti, Wnd))
1196 {
1197 DoFG = TRUE;
1198 }
1199 else
1200 {
1201 //ERR("IntUserSetActiveWindow 3 Go Out!\n");
1202 break;
1203 }
1204 AllowFG = !pti->cVisWindows; // Nothing is visable.
1205 //ERR("IntUserSetActiveWindow 3a DoFG = %d AllowFG = %d\n",DoFG,AllowFG);
1206 }
1207 else //if (ThreadQueue != Wnd->head.pti->MessageQueue)
1208 {
1209 //PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
1210 // Rule 1 & 4, We are foreground so set this FG window or NULL foreground....
1211 if (!gpqForeground || gpqForeground == ThreadQueue)
1212 {
1213 DoFG = TRUE;
1214 }
1215 else
1216 DoFG = FALSE;
1217 if (DoFG)
1218 {
1220 AllowFG = TRUE;
1221 else
1222 AllowFG = FALSE;
1223 }
1224 else
1225 AllowFG = FALSE;
1226 //ERR("IntUserSetActiveWindow 3b DoFG = %d AllowFG = %d\n",DoFG,AllowFG);
1227 }
1228 Ret = FALSE;
1229 if (DoFG)
1230 {
1232 //ERR("IntUserSetActiveWindow 3c FG set\n");
1233 Ret = co_IntSetForegroundAndFocusWindow(Wnd, bMouse, TRUE);
1234 if (AllowFG)
1235 {
1237 }
1238 else
1239 {
1240 pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE;
1241 }
1242 }
1243 return Ret;
1244 }
1245
1246 return co_IntSetActiveWindow(Wnd, bMouse, bFocus, Async);
1247}
1248
1251{
1252 TRACE("Mouse Active\n");
1253 if (Wnd && (Wnd->ExStyle & WS_EX_NOACTIVATE))
1254 return TRUE;
1256}
1257
1258/* Win: PWND xxxSetActiveWindow(Wnd) */
1261{
1263
1264 if (Wnd)
1265 {
1266 if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
1267
1268 return IntUserSetActiveWindow(Wnd, FALSE, TRUE, FALSE);
1269 }
1270 /*
1271 Yes your eye are not deceiving you~!
1272
1273 First part of wines Win.c test_SetActiveWindow:
1274
1275 flush_events( TRUE );
1276 ShowWindow(hwnd, SW_HIDE);
1277 SetFocus(0);
1278 SetActiveWindow(0);
1279 check_wnd_state(0, 0, 0, 0); <-- This should pass if ShowWindow does it's job!!! As of 10/28/2012 it does!
1280
1281 Now Handle wines Msg.c test_SetActiveWindow( 0 )...
1282 */
1283 TRACE("USAW: Previous active window\n");
1284 if ( gpqForegroundPrev &&
1289 {
1290 TRACE("USAW:PAW hwnd %p\n", UserHMGetHandle(Wnd));
1291 return IntUserSetActiveWindow(Wnd, FALSE, TRUE, FALSE);
1292 }
1293
1294 // Activate anyone but the active window.
1295 if ( pti->MessageQueue->spwndActive &&
1296 (Wnd = VerifyWnd(pti->MessageQueue->spwndActive)) != NULL )
1297 {
1298 //ERR("USAW:AOWM hwnd %p\n", UserHMGetHandle(Wnd));
1299 if (!ActivateOtherWindowMin(Wnd))
1300 {
1301 // Okay, now go find someone else to play with!
1302 //ERR("USAW: Going to WPAOW\n");
1304 }
1305 return TRUE;
1306 }
1307
1308 TRACE("USAW: Nothing\n");
1309 return FALSE;
1310}
1311
1312// Win: PWND xxxSetFocus(Window)
1315{
1316 HWND hWndPrev = 0;
1317 PWND pwndTop;
1318 PTHREADINFO pti;
1319 PUSER_MESSAGE_QUEUE ThreadQueue;
1320
1321 if (Window)
1323
1325 ThreadQueue = pti->MessageQueue;
1326 ASSERT(ThreadQueue != 0);
1327
1328 TRACE("Enter SetFocus hWnd 0x%p pti 0x%p\n",Window ? UserHMGetHandle(Window) : 0, pti );
1329
1330 hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
1331
1332 if (Window != 0)
1333 {
1334 if (hWndPrev == UserHMGetHandle(Window))
1335 {
1336 return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0; /* Nothing to do */
1337 }
1338
1339 if (Window->head.pti->MessageQueue != ThreadQueue)
1340 {
1341 ERR("SetFocus Must have the same Q!\n");
1342 return 0;
1343 }
1344
1345 /* Check if we can set the focus to this window */
1347 for (pwndTop = Window; pwndTop; pwndTop = pwndTop->spwndParent)
1348 {
1349 if (pwndTop->style & (WS_MINIMIZED|WS_DISABLED)) return 0;
1350 if ((pwndTop->style & (WS_POPUP|WS_CHILD)) != WS_CHILD) break;
1351 if (pwndTop->spwndParent == NULL) break;
1352 }
1355 {
1356 ERR("SetFocus 1 WH_CBT Call Hook return!\n");
1357 return 0;
1358 }
1359
1360 /* Activate pwndTop if needed. */
1361 if (pwndTop != ThreadQueue->spwndActive)
1362 {
1363 PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); // Keep it based on desktop.
1364 if (ThreadQueue != ForegroundQueue && IsAllowedFGActive(pti, pwndTop)) // Rule 2 & 3.
1365 {
1366 //ERR("SetFocus: Set Foreground!\n");
1367 if (!(pwndTop->style & WS_VISIBLE))
1368 {
1369 pti->ppi->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE;
1370 }
1372 {
1373 ERR("SetFocus: Set Foreground and Focus Failed!\n");
1374 return 0;
1375 }
1376 }
1377
1378 /* Set Active when it is needed. */
1379 if (pwndTop != ThreadQueue->spwndActive)
1380 {
1381 //ERR("SetFocus: Set Active! %p\n",pwndTop?UserHMGetHandle(pwndTop):0);
1382 if (!co_IntSetActiveWindow(pwndTop, FALSE, FALSE, FALSE))
1383 {
1384 ERR("SetFocus: Set Active Failed!\n");
1385 return 0;
1386 }
1387 }
1388
1389 /* Abort if window destroyed */
1390 if (Window->state2 & WNDS2_INDESTROY) return 0;
1391 /* Do not change focus if the window is no longer active */
1392 if (pwndTop != ThreadQueue->spwndActive)
1393 {
1394 ERR("SetFocus: Top window did not go active!\n");
1395 return 0;
1396 }
1397 }
1398
1399 // Check again! SetActiveWindow could have set the focus via WM_ACTIVATE.
1400 hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
1401
1403
1404 TRACE("Focus: %p -> %p\n", hWndPrev, UserHMGetHandle(Window));
1405 }
1406 else /* NULL hwnd passed in */
1407 {
1408 if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev))
1409 {
1410 ERR("SetFocus: 2 WH_CBT Call Hook return!\n");
1411 return 0;
1412 }
1413 //ERR("SetFocus: Set Focus NULL\n");
1414 /* set the current thread focus window null */
1416 }
1417 return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0;
1418}
1419
1422{
1423 PUSER_MESSAGE_QUEUE ForegroundQueue;
1424
1425 ForegroundQueue = IntGetFocusMessageQueue();
1426 return( ForegroundQueue ? (ForegroundQueue->spwndActive ? UserHMGetHandle(ForegroundQueue->spwndActive) : 0) : 0);
1427}
1428
1430{
1431 PTHREADINFO pti;
1432 PUSER_MESSAGE_QUEUE ThreadQueue;
1433
1435 ThreadQueue = pti->MessageQueue;
1436 return( ThreadQueue ? (ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : 0) : 0);
1437}
1438
1441{
1442 PTHREADINFO pti;
1443 PUSER_MESSAGE_QUEUE ThreadQueue;
1444 HWND Ret;
1445
1446 TRACE("Enter IntGetCapture\n");
1447
1449 ThreadQueue = pti->MessageQueue;
1450 Ret = ((ThreadQueue && ThreadQueue->spwndCapture) ? UserHMGetHandle(ThreadQueue->spwndCapture) : NULL);
1451
1452 TRACE("Leave IntGetCapture, ret=%p\n", Ret);
1453 return Ret;
1454}
1455
1458{
1459 PTHREADINFO pti;
1460 PUSER_MESSAGE_QUEUE ThreadQueue;
1461 PWND pWnd, Window = NULL;
1462 HWND hWndPrev;
1463
1465 ThreadQueue = pti->MessageQueue;
1466
1467 if (ThreadQueue->QF_flags & QF_CAPTURELOCKED)
1468 return NULL;
1469
1470 if (hWnd && (Window = UserGetWindowObject(hWnd)))
1471 {
1472 if (Window->head.pti->MessageQueue != ThreadQueue)
1473 {
1474 ERR("Window Thread does not match Current!\n");
1475 return NULL;
1476 }
1477 }
1478
1479 hWndPrev = MsqSetStateWindow(pti, MSQ_STATE_CAPTURE, hWnd);
1480
1481 if (hWndPrev)
1482 {
1483 pWnd = UserGetWindowObject(hWndPrev);
1484 if (pWnd)
1485 IntNotifyWinEvent(EVENT_SYSTEM_CAPTUREEND, pWnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
1486 }
1487
1488 if (Window)
1489 IntNotifyWinEvent(EVENT_SYSTEM_CAPTURESTART, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
1490
1491 //
1492 // Only send the message if we have a previous Window!
1493 // Fix msg_menu tracking popup menu and win test_capture_4!!!!
1494 //
1495 if (hWndPrev)
1496 {
1497 if (ThreadQueue->MenuOwner && Window) ThreadQueue->QF_flags |= QF_CAPTURELOCKED;
1498
1500
1501 ThreadQueue->QF_flags &= ~QF_CAPTURELOCKED;
1502 }
1503
1504 if (hWnd == NULL) // Release mode.
1505 {
1506 MOUSEINPUT mi;
1508 /* Also remove other windows if not capturing anymore */
1512 /* Somebody may have missed some mouse movements */
1513 mi.dx = 0;
1514 mi.dy = 0;
1515 mi.mouseData = 0;
1517 mi.time = 0;
1518 mi.dwExtraInfo = 0;
1520 }
1521 return hWndPrev;
1522}
1523
1524/*
1525 API Call
1526*/
1527BOOL
1530{
1531 PTHREADINFO pti;
1532 PUSER_MESSAGE_QUEUE ThreadQueue;
1533
1535 ThreadQueue = pti->MessageQueue;
1536
1537 // Can not release inside WM_CAPTURECHANGED!!
1538 if (ThreadQueue->QF_flags & QF_CAPTURELOCKED) return FALSE;
1539
1541
1542 return TRUE;
1543}
1544
1545/*
1546 API Call
1547*/
1550{
1552
1554}
1555
1556/*
1557 API Call
1558*/
1561{
1563
1565}
1566
1567/*
1568 API Call
1569*/
1572{
1575 switch (uLockCode)
1576 {
1577 case LSFW_LOCK:
1578 if ( CanForceFG(ppi) && !gppiLockSFW )
1579 {
1580 gppiLockSFW = ppi;
1581 return TRUE;
1582 }
1583 break;
1584 case LSFW_UNLOCK:
1585 if ( gppiLockSFW == ppi)
1586 {
1587 gppiLockSFW = NULL;
1588 return TRUE;
1589 }
1590 break;
1591 default:
1593 }
1594 EngSetLastError(Err);
1595 return FALSE;
1596}
1597
1598/*
1599 API Call
1600*/
1603{
1604 PPROCESSINFO ppi, ppiCur;
1606
1607 ppi = NULL;
1608 if (dwProcessId != ASFW_ANY)
1609 {
1611 {
1613 return FALSE;
1614 }
1616 if (!ppi)
1617 {
1619 return FALSE;
1620 }
1621 }
1623 if (!CanForceFG(ppiCur))
1624 {
1627 return FALSE;
1628 }
1629 if (dwProcessId == ASFW_ANY)
1630 { // All processes will be enabled to set the foreground window.
1631 //ERR("ptiLastInput is CLEARED!!\n");
1633 }
1634 else
1635 { // Rule #3, last input event in force.
1636 ERR("ptiLastInput is SET!!\n");
1637 //ptiLastInput = ppi->ptiList; // See CORE-6384 & CORE-7030.
1639 }
1640 return TRUE;
1641}
1642
1643/*
1644 * @implemented
1645 */
1648{
1649 HWND Ret;
1650
1651 TRACE("Enter NtUserGetForegroundWindow\n");
1653
1655
1656 TRACE("Leave NtUserGetForegroundWindow, ret=%p\n", Ret);
1657 UserLeave();
1658 return Ret;
1659}
1660
1663{
1665 HWND hWndPrev;
1666 PWND Window, pwndPrev;
1667 HWND Ret = NULL;
1668
1669 TRACE("Enter NtUserSetActiveWindow(%p)\n", hWnd);
1671
1672 Window = NULL;
1673 if (hWnd)
1674 {
1676 {
1677 ERR("NtUserSetActiveWindow: Invalid handle 0x%p!\n",hWnd);
1678 goto Exit; // Return NULL
1679 }
1680 }
1681
1682 if (!Window ||
1683 Window->head.pti->MessageQueue == gptiCurrent->MessageQueue)
1684 {
1685 pwndPrev = gptiCurrent->MessageQueue->spwndActive;
1686 hWndPrev = (pwndPrev ? UserHMGetHandle(pwndPrev) : NULL);
1687 if (Window) UserRefObjectCo(Window, &Ref);
1690 Ret = ((hWndPrev && IntIsWindow(hWndPrev)) ? hWndPrev : NULL);
1691 }
1692
1693Exit:
1694 TRACE("Leave NtUserSetActiveWindow, ret=%p\n", Ret);
1695 UserLeave();
1696 return Ret;
1697}
1698
1699/*
1700 * @implemented
1701 */
1704{
1705 HWND Ret;
1706
1707 TRACE("Enter NtUserSetCapture(%p)\n", hWnd);
1709
1710 Ret = co_UserSetCapture(hWnd);
1711
1712 TRACE("Leave NtUserSetCapture, ret=%p\n", Ret);
1713 UserLeave();
1714 return Ret;
1715}
1716
1717/*
1718 * @implemented
1719 */
1722{
1723 PWND Window;
1725 HWND ret = NULL;
1726
1727 TRACE("Enter NtUserSetFocus(%p)\n", hWnd);
1729
1730 if (hWnd)
1731 {
1733 {
1734 ERR("NtUserSetFocus: Invalid handle 0x%p!\n",hWnd);
1735 goto Exit; // Return NULL
1736 }
1737
1738 UserRefObjectCo(Window, &Ref);
1741 }
1742 else
1743 {
1745 }
1746
1747Exit:
1748 TRACE("Leave NtUserSetFocus, ret=%p\n", ret);
1749 UserLeave();
1750 return ret;
1751}
1752
1753/* EOF */
Type
Definition: Type.h:7
#define msg(x)
Definition: auth_time.c:54
HWND hWnd
Definition: settings.c:17
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define ERR(fmt,...)
Definition: debug.h:110
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:103
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
struct @1627 Msg[]
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define APIENTRY
Definition: api.h:79
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
PSERVERINFO gpsi
Definition: imm.c:18
#define ValidateHwndNoErr(hwnd)
Definition: precomp.h:84
static const WCHAR Message[]
Definition: register.c:74
@ Removed
Definition: fbtusb.h:86
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
HWND APIENTRY NtUserSetActiveWindow(HWND hWnd)
Definition: focus.c:1662
BOOL FASTCALL co_IntMouseActivateWindow(PWND Wnd)
Definition: focus.c:1250
BOOL FASTCALL FindRemoveEventMsg(PTHREADINFO pti, DWORD Event, DWORD EventLast)
Definition: focus.c:679
BOOL FASTCALL IntDeactivateWindow(PTHREADINFO pti, HANDLE tid)
Definition: focus.c:191
BOOL FASTCALL IntLockSetForegroundWindow(UINT uLockCode)
Definition: focus.c:1571
HWND APIENTRY NtUserSetCapture(HWND hWnd)
Definition: focus.c:1703
BOOL FASTCALL CanForceFG(PPROCESSINFO ppi)
Definition: focus.c:749
BOOL FASTCALL co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd, BOOL Clear)
Definition: focus.c:118
BOOL FASTCALL IntAllowSetForegroundWindow(DWORD dwProcessId)
Definition: focus.c:1602
VOID FASTCALL IntActivateWindow(PWND Wnd, PTHREADINFO pti, HANDLE tid, DWORD Type)
Definition: focus.c:357
HWND ghwndOldFullscreen
Definition: focus.c:19
HWND FASTCALL IntGetThreadFocusWindow(VOID)
Definition: focus.c:41
HWND FASTCALL co_UserSetFocus(PWND Window)
Definition: focus.c:1314
BOOL FASTCALL ToggleFGActivate(PTHREADINFO pti)
Definition: focus.c:710
PPROCESSINFO gppiLockSFW
Definition: focus.c:16
BOOL FASTCALL IntCheckFullscreen(PWND Window)
Definition: focus.c:79
BOOL FASTCALL UserSetActiveWindow(_In_opt_ PWND Wnd)
Definition: focus.c:1260
HWND FASTCALL IntGetCaptureWindow(VOID)
Definition: focus.c:34
BOOL FASTCALL co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOOL Async)
Definition: focus.c:444
BOOL FASTCALL IsFGLocked(VOID)
Definition: focus.c:25
PUSER_MESSAGE_QUEUE gpqForeground
Definition: focus.c:13
BOOL FASTCALL IsAllowedFGActive(PTHREADINFO pti, PWND Wnd)
Definition: focus.c:730
BOOL FASTCALL co_IntMakeWindowActive(PWND Window)
Definition: focus.c:426
PTHREADINFO gptiForeground
Definition: focus.c:15
BOOL FASTCALL IntIsWindowFullscreen(PWND Window)
Definition: focus.c:53
ULONG guSFWLockCount
Definition: focus.c:17
HWND APIENTRY NtUserGetForegroundWindow(VOID)
Definition: focus.c:1647
HWND FASTCALL co_UserSetCapture(HWND hWnd)
Definition: focus.c:1457
HWND APIENTRY IntGetCapture(VOID)
Definition: focus.c:1440
VOID FASTCALL UpdateShellHook(PWND Window)
Definition: focus.c:99
VOID FASTCALL IntSendFocusMessages(PTHREADINFO pti, PWND pWnd)
Definition: focus.c:615
BOOL FASTCALL co_IntSetForegroundWindow(PWND Window)
Definition: focus.c:1549
BOOL FASTCALL co_IntSetForegroundMessageQueue(_In_opt_ PWND Wnd, _In_ PTHREADINFO pti, _In_ BOOL MouseActivate, _In_ DWORD Type)
Definition: focus.c:767
BOOL FASTCALL IntReleaseCapture(VOID)
Definition: focus.c:1529
BOOL FASTCALL co_IntSetForegroundWindowMouse(PWND Window)
Definition: focus.c:1560
HWND APIENTRY NtUserSetFocus(HWND hWnd)
Definition: focus.c:1721
BOOL FASTCALL co_IntSetActiveWindow(_In_ PWND Wnd, _In_ BOOL bMouse, _In_ BOOL bFocus, _In_ BOOL Async)
Definition: focus.c:1024
PTHREADINFO ptiLastInput
Definition: focus.c:18
HWND FASTCALL UserGetActiveWindow(VOID)
Definition: focus.c:1429
static BOOL FASTCALL co_IntSetForegroundAndFocusWindow(_In_opt_ PWND Wnd, _In_ BOOL MouseActivate, _In_ BOOL bFlash)
Definition: focus.c:924
VOID IntFocusSetInputContext(PWND pWnd, BOOL bActivate, BOOL bCallback)
Definition: focus.c:150
PUSER_MESSAGE_QUEUE gpqForegroundPrev
Definition: focus.c:14
HWND FASTCALL UserGetForegroundWindow(VOID)
Definition: focus.c:1421
BOOL FASTCALL IntUserSetActiveWindow(_In_ PWND Wnd, _In_ BOOL bMouse, _In_ BOOL bFocus, _In_ BOOL Async)
Definition: focus.c:1170
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
GLbitfield flags
Definition: glext.h:7161
#define IMS_IMEACTIVATE
Definition: immdev.h:108
#define IMS_IMEDEACTIVATE
Definition: immdev.h:109
#define TIF_CSRSSTHREAD
Definition: ntuser.h:266
#define TIF_INCLEANUP
Definition: ntuser.h:263
#define WNDS_ACTIVEFRAME
Definition: ntuser.h:611
#define WNDS_BEINGACTIVATED
Definition: ntuser.h:625
#define WNDS_DESTROYED
Definition: ntuser.h:636
#define WNDS2_BOTTOMMOST
Definition: ntuser.h:646
#define PUSIF_PALETTEDISPLAY
Definition: ntuser.h:993
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
#define MSQ_STATE_MOVESIZE
Definition: ntuser.h:3585
struct _WND * PWND
#define WNDS_NONCPAINT
Definition: ntuser.h:613
#define MSQ_STATE_CAPTURE
Definition: ntuser.h:3581
#define TIF_INACTIVATEAPPMSG
Definition: ntuser.h:272
#define IS_IMM_MODE()
Definition: ntuser.h:1209
#define MSQ_STATE_MENUOWNER
Definition: ntuser.h:3584
#define WEF_SETBYWNDPTI
Definition: ntuser.h:236
#define WNDS2_INDESTROY
Definition: ntuser.h:648
#define TIF_SYSTEMTHREAD
Definition: ntuser.h:265
#define WNDS_HASCAPTION
Definition: ntuser.h:608
#define TIF_ALLOWFOREGROUNDACTIVATE
Definition: ntuser.h:268
#define RtlEqualMemory(a, b, c)
Definition: kdvm.h:18
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static void Clear(void)
Definition: treeview.c:386
static TfClientId tid
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
VOID FASTCALL ClearMsgBitsMask(PTHREADINFO pti, UINT MessageBits)
Definition: msgqueue.c:445
VOID FASTCALL MsqDestroyMessage(PUSER_MESSAGE Message)
Definition: msgqueue.c:748
HWND FASTCALL MsqSetStateWindow(PTHREADINFO pti, ULONG Type, HWND hWnd)
Definition: msgqueue.c:2495
VOID FASTCALL co_MsqInsertMouseMessage(MSG *Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook)
Definition: msgqueue.c:580
VOID FASTCALL MsqPostMessage(PTHREADINFO pti, MSG *Msg, BOOLEAN HardwareMessage, DWORD MessageBits, DWORD dwQEvent, LONG_PTR ExtraInfo)
Definition: msgqueue.c:1337
#define POSTEVENT_NONE
Definition: msgqueue.h:126
#define QF_ACTIVATIONCHANGE
Definition: msgqueue.h:100
#define QF_CAPTURELOCKED
Definition: msgqueue.h:111
#define QF_EVENTDEACTIVATEREMOVED
Definition: msgqueue.h:107
@ WM_ASYNC_SETACTIVEWINDOW
Definition: msgqueue.h:119
#define QF_FOCUSNULLSINCEACTIVE
Definition: msgqueue.h:105
#define POSTEVENT_SAW
Definition: msgqueue.h:124
#define POSTEVENT_DAW
Definition: msgqueue.h:123
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
#define FASTCALL
Definition: nt_native.h:50
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
NTSTATUS NTAPI PsLookupProcessByProcessId(IN HANDLE ProcessId, OUT PEPROCESS *Process)
Definition: process.c:919
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
HANDLE NTAPI PsGetThreadId(IN PETHREAD Thread)
Definition: thread.c:705
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
LRESULT APIENTRY co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:1102
VOID FASTCALL co_WinPosActivateOtherWindow(PWND Wnd)
Definition: winpos.c:397
BOOLEAN FASTCALL co_WinPosSetWindowPos(PWND Window, HWND WndInsertAfter, INT x, INT y, INT cx, INT cy, UINT flags)
Definition: winpos.c:1786
BOOL FASTCALL ActivateOtherWindowMin(PWND Wnd)
Definition: winpos.c:285
BOOL FASTCALL IntGetWindowRect(PWND Wnd, RECTL *Rect)
Definition: winpos.c:121
PPROCESSINFO gppiInputProvider
Definition: ntuser.c:16
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:251
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:242
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:40
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Definition: object.h:27
#define WS_CHILD
Definition: pedump.c:617
#define WS_POPUP
Definition: pedump.c:616
#define WS_MINIMIZE
Definition: pedump.c:622
#define WS_VISIBLE
Definition: pedump.c:620
#define WS_DISABLED
Definition: pedump.c:621
static void Exit(void)
Definition: sock.c:1330
#define TRACE(s)
Definition: solgame.cpp:4
base of all file and directory entries
Definition: entries.h:83
Definition: window.c:28
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
RECT rcMonitor
Definition: monitor.h:18
PPROCESSINFO ppi
Definition: win32.h:88
UINT cVisWindows
Definition: win32.h:141
LIST_ENTRY PostedMessagesListHead
Definition: win32.h:137
FLONG TIF_flags
Definition: win32.h:95
struct _DESKTOP * rpdesk
Definition: win32.h:92
struct _WND * spwndDefaultIme
Definition: win32.h:131
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:89
Definition: object.h:4
Definition: ntuser.h:694
DWORD ExStyle
Definition: ntuser.h:704
PCLS pcls
Definition: ntuser.h:720
struct _WND * spwndOwner
Definition: ntuser.h:715
THRDESKHEAD head
Definition: ntuser.h:695
DWORD style
Definition: ntuser.h:706
DWORD state2
Definition: ntuser.h:702
struct _WND * spwndChild
Definition: ntuser.h:714
DWORD state
Definition: ntuser.h:701
struct _WND * spwndNext
Definition: ntuser.h:711
struct _WND * spwndParent
Definition: ntuser.h:713
DWORD dwFlags
Definition: winuser.h:3787
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define WM_IME_SYSTEM
Definition: undocuser.h:60
#define WS_MINIMIZED
Definition: undocuser.h:18
#define QS_EVENT
Definition: undocuser.h:97
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:122
#define ASSERT_REFS_CO(_obj_)
Definition: userfuncs.h:14
int ret
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
#define IntDereferenceThreadInfo(pti)
Definition: win32.h:171
#define W32PF_ALLOWFOREGROUNDACTIVATE
Definition: win32.h:12
#define IntReferenceThreadInfo(pti)
Definition: win32.h:166
#define W32PF_SETFOREGROUNDALLOWED
Definition: win32.h:20
BOOL FASTCALL RECTL_bIntersectRect(_Out_ RECTL *prclDst, _In_ const RECTL *prcl1, _In_ const RECTL *prcl2)
Definition: rect.c:55
FORCEINLINE VOID RECTL_vSetRect(_Out_ RECTL *prcl, _In_ LONG left, _In_ LONG top, _In_ LONG right, _In_ LONG bottom)
Definition: rect.h:5
PWND FASTCALL UserGetDesktopWindow(VOID)
Definition: desktop.c:1386
VOID FASTCALL IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue)
Definition: desktop.c:1319
PUSER_MESSAGE_QUEUE FASTCALL IntGetFocusMessageQueue(VOID)
Definition: desktop.c:1307
VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam)
Definition: desktop.c:1692
PDESKTOP gpdeskInputDesktop
Definition: desktop.c:35
PWND FASTCALL co_GetDesktopWindow(PWND pWnd)
Definition: desktop.c:1366
VOID FASTCALL IntNotifyWinEvent(DWORD Event, PWND pWnd, LONG idObject, LONG idChild, DWORD flags)
Definition: event.c:178
WORD FASTCALL UserGetMouseButtonsState(VOID)
Definition: mouse.c:22
BOOL NTAPI UserSendMouseInput(MOUSEINPUT *pMouseInput, BOOL bInjected)
Definition: mouse.c:168
PPROCESSINFO ppiScrnSaver
Definition: main.c:29
LRESULT FASTCALL co_IntSendMessageWithCallBack(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, SENDASYNCPROC CompletionCallback, ULONG_PTR CompletionCallbackContext, ULONG_PTR *uResult)
Definition: message.c:1735
BOOL FASTCALL UserSendNotifyMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:2040
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1445
LONG NTAPI UserGetSystemMetrics(ULONG Index)
Definition: metric.c:213
PMONITOR NTAPI UserGetPrimaryMonitor(VOID)
Definition: monitor.c:102
#define USERTAG_WINDOWLIST
Definition: tags.h:298
HWND *FASTCALL IntWinListChildren(PWND Window)
Definition: window.c:274
PWND FASTCALL VerifyWnd(PWND pWnd)
Definition: window.c:86
BOOL FASTCALL IntIsWindow(HWND hWnd)
Definition: window.c:176
BOOL FASTCALL IntIsWindowVisible(PWND Wnd)
Definition: window.c:189
PWND FASTCALL IntGetNonChildAncestor(PWND pWnd)
Definition: window.c:351
#define IS_WND_IMELIKE(pWnd)
Definition: window.h:114
#define IntGetWndThreadId(WndObj)
Definition: window.h:35
static VOID WndSetLastActive(_Inout_ PWND pwnd, _In_opt_ PWND pwndLastActive)
Definition: window.h:185
static MONITORINFO mi
Definition: win.c:7338
#define OBJID_CLIENT
Definition: winable.h:19
#define OBJID_WINDOW
Definition: winable.h:15
#define CHILDID_SELF
Definition: winable.h:14
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:22
LONG_PTR LPARAM
Definition: windef.h:208
UINT_PTR WPARAM
Definition: windef.h:207
struct _RECTL * LPRECTL
#define WM_QUERYNEWPALETTE
Definition: winuser.h:1878
#define HSHELL_RUDEAPPACTIVATED
Definition: winuser.h:1281
#define MAKEWPARAM(l, h)
Definition: winuser.h:4009
#define SWP_NOACTIVATE
Definition: winuser.h:1242
#define MAKELPARAM(l, h)
Definition: winuser.h:4008
#define SM_CYSCREEN
Definition: winuser.h:960
#define WM_CAPTURECHANGED
Definition: winuser.h:1808
#define WS_EX_APPWINDOW
Definition: winuser.h:383
#define HCBT_ACTIVATE
Definition: winuser.h:60
#define HWND_BROADCAST
Definition: winuser.h:1204
#define WM_CANCELMODE
Definition: winuser.h:1635
#define SWP_NOMOVE
Definition: winuser.h:1244
#define WS_EX_NOACTIVATE
Definition: winuser.h:395
#define WS_EX_TOOLWINDOW
Definition: winuser.h:404
#define WM_SETFOCUS
Definition: winuser.h:1613
#define SWP_NOSIZE
Definition: winuser.h:1245
#define WM_MOUSEMOVE
Definition: winuser.h:1775
#define WA_INACTIVE
Definition: winuser.h:2622
#define WH_CBT
Definition: winuser.h:35
#define WM_ACTIVATE
Definition: winuser.h:1612
#define MOUSEEVENTF_MOVE
Definition: winuser.h:1183
#define WM_NCACTIVATE
Definition: winuser.h:1688
#define HWND_TOP
Definition: winuser.h:1207
#define HCBT_SETFOCUS
Definition: winuser.h:64
#define WA_ACTIVE
Definition: winuser.h:2623
#define WA_CLICKACTIVE
Definition: winuser.h:2624
#define WM_ACTIVATEAPP
Definition: winuser.h:1632
#define SM_CXSCREEN
Definition: winuser.h:959
#define WM_KILLFOCUS
Definition: winuser.h:1614
#define WM_PALETTEISCHANGING
Definition: winuser.h:1876
#define ObDereferenceObject
Definition: obfuncs.h:203