ReactOS 0.4.16-dev-1946-g52006dd
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 if (!ForegroundQueue)
38 return NULL;
39 return (ForegroundQueue->spwndCapture ? UserHMGetHandle(ForegroundQueue->spwndCapture) : NULL);
40}
41
44{
46 PUSER_MESSAGE_QUEUE ThreadQueue = pti->MessageQueue;
47 if (!ThreadQueue)
48 return NULL;
49 return (ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : NULL);
50}
51
53{
54 RECTL rclAnd, rclMonitor, rclWindow;
55 PMONITOR pMonitor;
56
57 if (!Window || !(Window->style & WS_VISIBLE) || (Window->style & WS_CHILD) ||
58 !IntGetWindowRect(Window, &rclWindow))
59 {
60 return FALSE;
61 }
62
63 pMonitor = UserGetPrimaryMonitor();
64 if (!pMonitor)
65 {
66 RECTL_vSetRect(&rclMonitor, 0, 0,
68 }
69 else
70 {
71 rclMonitor = *(LPRECTL)&pMonitor->rcMonitor;
72 }
73
74 RECTL_bIntersectRect(&rclAnd, &rclMonitor, &rclWindow);
75 return RtlEqualMemory(&rclAnd, &rclMonitor, sizeof(RECTL));
76}
77
79{
80 HWND hWnd;
81
84
86 return FALSE;
87
90 {
93 }
94 return TRUE;
95}
96
99{
101 return;
102
103 if ( Window->spwndParent == UserGetDesktopWindow() &&
104 (!(Window->ExStyle & WS_EX_TOOLWINDOW) ||
105 (Window->ExStyle & WS_EX_APPWINDOW)))
106 {
107 // FIXME lParam; The value is TRUE if the window is in full-screen mode, or FALSE otherwise.
108 co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (WPARAM) UserHMGetHandle(Window), FALSE);
109 }
110 else
111 {
112 co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, 0, FALSE);
113 }
114}
115
118{
119 USER_REFERENCE_ENTRY RefPrev;
120 PWND WndPrev;
121 BOOL Ret = TRUE;
122 LPARAM lParam = hWnd ? (LPARAM)hWnd : 0;
123
124 if (hWndPrev && (WndPrev = ValidateHwndNoErr(hWndPrev)))
125 {
126 UserRefObjectCo(WndPrev, &RefPrev);
127
129 {
131 MAKEWPARAM(WA_INACTIVE, (WndPrev->style & WS_MINIMIZE) != 0),
132 (LPARAM)hWnd);
133
134 if (WndPrev && Clear)
136 }
137 else
138 {
139 ERR("Application is keeping itself Active to prevent the change!\n");
140 Ret = FALSE;
141 }
142
143 UserDerefObjectCo(WndPrev);
144 }
145 return Ret;
146}
147
148// Win: xxxFocusSetInputContext
149VOID IntFocusSetInputContext(PWND pWnd, BOOL bActivate, BOOL bCallback)
150{
151 PTHREADINFO pti;
152 PWND pImeWnd;
154 HWND hImeWnd;
157
158 if (!pWnd || !pWnd->pcls || IS_WND_IMELIKE(pWnd))
159 return;
160
161 pti = pWnd->head.pti;
162 if (!pti || (pti->TIF_flags & TIF_INCLEANUP))
163 return;
164
165 pImeWnd = pti->spwndDefaultIme;
166 if (!pImeWnd)
167 return;
168
169 UserRefObjectCo(pImeWnd, &Ref);
170
171 hImeWnd = UserHMGetHandle(pImeWnd);
172 wParam = (bActivate ? IMS_IMEACTIVATE : IMS_IMEDEACTIVATE);
174
175 if (bCallback)
177 else
179
180 UserDerefObjectCo(pImeWnd);
181}
182
183//
184// Deactivating the foreground message queue.
185//
186// Release Active, Capture and Focus Windows associated with this message queue.
187//
188// Win: xxxDeactivate
191{
193 PTHREADINFO ptiPrev;
194 PWND pwndPrev;
195 BOOL InAAPM = FALSE;
197
198 if ( !pti->MessageQueue->spwndActive )
199 {
200 TRACE("IDAW E : Nothing to do, Active is NULL! pti 0x%p tid 0x%p\n",pti,tid);
201 return TRUE;
202 }
203
204 TRACE("IDAW : pti 0x%p tid 0x%p\n",pti,tid);
205
206 if (ptiCurrent != pti)
207 {
209 IntReferenceThreadInfo(ptiCurrent);
210 }
211
212 if (!(pti->TIF_flags & TIF_INACTIVATEAPPMSG) )
213 {
215 InAAPM = TRUE;
216 }
217
218 //
219 // Check for Capture and release it.
220 //
221 if ( pti->MessageQueue->spwndCapture )
222 {
223 MSG msg;
224 PWND pwndCapture = pti->MessageQueue->spwndCapture;
225
226 UserRefObjectCo(pwndCapture, &Ref);
228 UserDerefObjectCo(pwndCapture);
229
230 /* Generate mouse move message */
231 msg.message = WM_MOUSEMOVE;
232 msg.wParam = UserGetMouseButtonsState();
233 msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y);
234 msg.pt = gpsi->ptCursor;
236 }
237
238 //
239 // Check for Active and release it.
240 //
241 if ( pti->MessageQueue->spwndActive )
242 {
243 pwndPrev = pti->MessageQueue->spwndActive;
244 ptiPrev = pwndPrev->head.pti;
245
247 {
248 if (InAAPM) pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
249 if (ptiCurrent != pti)
250 {
252 IntDereferenceThreadInfo(ptiCurrent);
253 }
254 return FALSE;
255 }
256
257 if ( pti->MessageQueue->spwndActive == pwndPrev )
258 {
259 pti->MessageQueue->spwndActivePrev = pwndPrev;
260 pti->MessageQueue->spwndActive = NULL;
261 }
262
263 if (ptiPrev->TIF_flags & TIF_INCLEANUP) ptiPrev = NULL;
264 }
265 else
266 {
267 ptiPrev = pti;
268 pwndPrev = (PWND)-1; // Avoid zero Active window.
269 }
270
271 if ( ptiPrev )
272 {
273 HANDLE OldTID = PsGetThreadId(ptiPrev->pEThread);
274 PWND cWindow;
275 HWND *List, *phWnd;
276
278 if ( List )
279 {
280 if ( OldTID )
281 {
282 for (phWnd = List; *phWnd; ++phWnd)
283 {
284 cWindow = ValidateHwndNoErr(*phWnd);
285 if ( cWindow && cWindow->head.pti == ptiPrev )
286 { // FALSE if the window is being deactivated,
287 // ThreadId that owns the window being activated.
288 //ERR("IDW : WM_ACTIVATEAPP(0) hwnd %p tid Old %p New %p\n",UserHMGetHandle(cWindow),OldTID,tid);
289 UserRefObjectCo(cWindow, &Ref);
291 UserDerefObjectCo(cWindow);
292 }
293 }
294 }
296 }
297 }
298
299 //
300 // Now check for a change (Bounce), if Active same as previous window, release it too.
301 //
302 if ( pti->MessageQueue->spwndActive == pwndPrev )
303 {
305 {
306 if (InAAPM) pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
307 if (ptiCurrent != pti)
308 {
310 IntDereferenceThreadInfo(ptiCurrent);
311 }
312 return FALSE;
313 }
314
315 if ( pti->MessageQueue->spwndActive == pwndPrev )
316 {
317 pti->MessageQueue->spwndActivePrev = pwndPrev;
318 pti->MessageQueue->spwndActive = NULL;
319 }
320 }
321
322 //
323 // Check for Focus and release it.
324 //
325 if ( pti->MessageQueue->spwndFocus )
326 {
327 PWND pwndFocus = pti->MessageQueue->spwndFocus;
328
329 //
330 // Fix win.c:test_SetForegroundWindow:SetActiveWindow(0)!
331 //
332 pti->MessageQueue->spwndFocus = NULL; // Null out Focus.
333
334 UserRefObjectCo(pwndFocus, &Ref);
336 if (IS_IMM_MODE())
337 {
339 }
340 UserDerefObjectCo(pwndFocus);
341 }
342
343 /* Check for keyboard modifiers and release them (CORE-14768) */
345
346 if (InAAPM) pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
347 if (ptiCurrent != pti)
348 {
350 IntDereferenceThreadInfo(ptiCurrent);
351 }
352 return TRUE;
353}
354
355//
356// Activating another threads foreground window after a switch.
357//
360{
363
364 if (Wnd)
365 {
366 Wnd = VerifyWnd(Wnd);
367
368 if (!Wnd) return;
369
370 UserRefObjectCo(Wnd, &Ref);
371
372 if (!gpqForeground)
373 {
374 // No foreground queue set.
376 }
377 else
378 {
379 // Same Active and Wnd.
380 if ( pmq->spwndActive == Wnd )
381 {
382 WPARAM wParam = (Wnd->head.pti->MessageQueue == gpqForeground);
383
385
386 if (wParam)
387 {
388 UpdateShellHook(Wnd);
389
391 }
392 }
393 else // Not the same, set the active Wnd.
394 {
396 }
397 }
399 }
400 else // Handle no Wnd!
401 {
402 if ( tid && // TID,
403 pmq->spwndActive && // Active WND not zero,
404 gpqForeground == pmq ) // Same message queues.
405 {
406 Wnd = pmq->spwndActive; // Use active window from current queue.
407
408 UserRefObjectCo(Wnd, &Ref);
409
411
412 UpdateShellHook(Wnd);
413
415
417 }
418 else if (gpqForeground != pmq)
419 {
420 // Not the same message queue so clear flags for foreground switching.
421 pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE;
422 pti->ppi->W32PF_flags &= ~W32PF_ALLOWFOREGROUNDACTIVATE;
423 }
424 }
425}
426
429{
430 PWND spwndOwner;
431 if (VerifyWnd(Window))
432 { // Set last active for window and it's owner.
433 spwndOwner = Window;
434 while (spwndOwner->spwndOwner)
435 {
436 spwndOwner = spwndOwner->spwndOwner;
437 }
438 WndSetLastActive(spwndOwner, Window);
439 return TRUE;
440 }
441 ERR("MakeWindowActive Failed!\n");
442 return FALSE;
443}
444
446co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOOL Async)
447{
448 USER_REFERENCE_ENTRY Ref, RefPrev, RefCall;
449 HANDLE OldTID, NewTID;
450 PTHREADINFO pti, ptiOld, ptiNew;
451 BOOL InAAPM = FALSE;
452
453 //ERR("SendActivateMessages\n");
454
456
457 if (Window)
458 {
459 UserRefObjectCo(Window, &Ref);
460
461 if (WindowPrev) UserRefObjectCo(WindowPrev, &RefPrev);
462
463 pti->MessageQueue->QF_flags &= ~QF_EVENTDEACTIVATEREMOVED;
464
465 /* Send palette messages */
466 if (gpsi->PUSIFlags & PUSIF_PALETTEDISPLAY &&
467 //co_IntPostOrSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
469 {
473 0);
474 }
476 if (!(Window->style & WS_CHILD))
477 {
479
480 while (pwndTemp && !(pwndTemp->style & WS_VISIBLE)) pwndTemp = pwndTemp->spwndNext;
481
482 if (Window != pwndTemp || (WindowPrev && !IntIsWindowVisible(WindowPrev)))
483 {
484 if (!Async || pti->MessageQueue == gpqForeground)
485 {
487 if (Window == pwndTemp) flags |= SWP_NOACTIVATE;
488 //ERR("co_IntSendActivateMessages SetWindowPos! Async %d pti Q == FGQ %d\n",Async,pti->MessageQueue == gpqForeground);
490 }
491 }
492 }
495 if (Window->spwndPrev)
496 {
497 HWND *phwndTopLevel, *phwndCurrent;
498 PWND pwndCurrent, pwndDesktop;
499
500 pwndDesktop = co_GetDesktopWindow(Window);//UserGetDesktopWindow();
501 if (Window->spwndParent == pwndDesktop )
502 {
503 phwndTopLevel = IntWinListChildren(pwndDesktop);
504 phwndCurrent = phwndTopLevel;
505 while(*phwndCurrent)
506 {
507 pwndCurrent = UserGetWindowObject(*phwndCurrent);
508
509 if (pwndCurrent && pwndCurrent->spwndOwner == Window )
510 {
512 }
513 phwndCurrent++;
514 }
516 }
517 }
519 }
520
521 OldTID = WindowPrev ? IntGetWndThreadId(WindowPrev) : NULL;
522 NewTID = Window ? IntGetWndThreadId(Window) : NULL;
523 ptiOld = WindowPrev ? WindowPrev->head.pti : NULL;
524 ptiNew = Window ? Window->head.pti : NULL;
525
526 //ERR("SendActivateMessage Old -> %x, New -> %x\n", OldTID, NewTID);
527
528 if (!(pti->TIF_flags & TIF_INACTIVATEAPPMSG) &&
529 (OldTID != NewTID) )
530 {
531 PWND cWindow;
532 HWND *List, *phWnd;
533
535 if ( List )
536 {
537 if ( OldTID )
538 {
540 // Note: Do not set pci flags, this does crash!
541 for (phWnd = List; *phWnd; ++phWnd)
542 {
543 cWindow = ValidateHwndNoErr(*phWnd);
544 if (cWindow && cWindow->head.pti == ptiOld)
545 { // FALSE if the window is being deactivated,
546 // ThreadId that owns the window being activated.
547 //ERR("SAM : WM_ACTIVATEAPP(0) tid Old %p New %p\n",OldTID,NewTID);
548 UserRefObjectCo(cWindow, &RefCall);
549 co_IntSendMessage(*phWnd, WM_ACTIVATEAPP, FALSE, (LPARAM)NewTID);
550 UserDerefObjectCo(cWindow);
551 }
552 }
553 ptiOld->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
554 }
555 if ( NewTID )
556 {
557 InAAPM = TRUE;
560 for (phWnd = List; *phWnd; ++phWnd)
561 {
562 cWindow = ValidateHwndNoErr(*phWnd);
563 if (cWindow && cWindow->head.pti == ptiNew)
564 { // TRUE if the window is being activated,
565 // ThreadId that owns the window being deactivated.
566 //ERR("SAM : WM_ACTIVATEAPP(1) hwnd %p tid New %p Old %p\n",UserHMGetHandle(cWindow),NewTID,OldTID);
567 UserRefObjectCo(cWindow, &RefCall);
568 co_IntSendMessage(*phWnd, WM_ACTIVATEAPP, TRUE, (LPARAM)OldTID);
569 UserDerefObjectCo(cWindow);
570 }
571 }
572 }
574 }
575 }
576
577 if (Window)
578 {
579 if (WindowPrev)
580 UserDerefObjectCo(WindowPrev); // Now allow the previous window to die.
581
582 if (Window->state & WNDS_ACTIVEFRAME)
583 { // If already active frame do not allow NCPaint.
584 //ERR("SendActivateMessage Is Active Frame!\n");
585 Window->state |= WNDS_NONCPAINT;
586 }
587
588 if (Window->style & WS_MINIMIZE)
589 {
590 TRACE("Widow was minimized\n");
591 }
592
594
598 0);
599
602 MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE, (Window->style & WS_MINIMIZE) != 0),
603 (LPARAM)(WindowPrev ? UserHMGetHandle(WindowPrev) : 0));
604
605 if (Window->style & WS_VISIBLE)
607
608 Window->state &= ~WNDS_NONCPAINT;
609
611 }
612 return InAAPM;
613}
614
615// Win: xxxSendFocusMessages
618{
619 PWND pWndPrev;
620 PUSER_MESSAGE_QUEUE ThreadQueue = pti->MessageQueue; // Queue can change...
621 HWND hwndPrev;
623
624 ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;
625 if (!pWnd && ThreadQueue->spwndActive)
626 {
627 ThreadQueue->QF_flags |= QF_FOCUSNULLSINCEACTIVE;
628 }
629
630 pWndPrev = ThreadQueue->spwndFocus;
631 if (pWndPrev)
632 UserRefObjectCo(pWndPrev, &Ref);
633
634 /* check if the specified window can be set in the input data of a given queue */
635 if (!pWnd || ThreadQueue == pWnd->head.pti->MessageQueue)
636 /* set the current thread focus window */
637 ThreadQueue->spwndFocus = pWnd;
638
639 if (pWnd)
640 {
641 if (pWndPrev)
642 {
644 if (IS_IMM_MODE())
645 {
647 }
648 }
649 if (ThreadQueue->spwndFocus == pWnd)
650 {
651 if (IS_IMM_MODE())
652 {
654 }
655
656 IntNotifyWinEvent(EVENT_OBJECT_FOCUS, pWnd, OBJID_CLIENT, CHILDID_SELF, 0);
657
658 hwndPrev = (pWndPrev ? UserHMGetHandle(pWndPrev) : NULL);
660 }
661 }
662 else
663 {
664 if (pWndPrev)
665 {
666 IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
667
669 if (IS_IMM_MODE())
670 {
672 }
673 }
674 }
675
676 if (pWndPrev)
677 UserDerefObjectCo(pWndPrev);
678}
679
682{
685 BOOL Ret = FALSE;
686
688 while (Entry != &pti->PostedMessagesListHead)
689 {
690 // Scan posted queue messages to see if we received async messages.
692 Entry = Entry->Flink;
693
694 if (Message->dwQEvent == EventLast)
695 {
696 //ERR("Event D/SAW: Last Activate/Deactivate %d\n", EventLast);
697 return Ret;
698 }
699
700 if (Message->dwQEvent == Event)
701 {
702 //ERR("Event D/SAW: Found one in the Post Msg Queue! Activate/Deactivate %d\n", Event);
703 ClearMsgBitsMask(pti, Message->QS_Flags);
705 Ret = TRUE;
706 }
707 }
708 return Ret;
709}
710
713{
714 BOOL Ret;
715 PPROCESSINFO ppi = pti->ppi;
716
717 Ret = !!(pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE);
718 if (Ret)
719 {
720 pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE;
721 }
722 else
723 Ret = !!(ppi->W32PF_flags & W32PF_ALLOWFOREGROUNDACTIVATE);
724
725 if (Ret)
726 ppi->W32PF_flags &= ~W32PF_ALLOWFOREGROUNDACTIVATE;
727 //ERR("ToggleFGActivate is %d\n",Ret);
728 return Ret;
729}
730
733{
734 // Not allowed if one or more,,
735 if (!ToggleFGActivate(pti) || // bits not set,
736 pti->rpdesk != gpdeskInputDesktop || // not current Desktop,
737 pti->MessageQueue == gpqForeground || // if already the queue foreground,
738 IsFGLocked() || // foreground is locked,
739 (Wnd->ExStyle & WS_EX_NOACTIVATE)) // or, does not become the foreground window when the user clicks it.
740 {
741 return FALSE;
742 }
743 //ERR("IsAllowedFGActive is TRUE\n");
744 return TRUE;
745}
746
747/*
748 Can the system force foreground from one or more conditions.
749 */
752{
753 if (!ptiLastInput ||
754 ptiLastInput->ppi == ppi ||
756 gptiForeground->ppi == ppi ||
758 gppiInputProvider == ppi ||
760 ) return TRUE;
761 //ERR("CanForceFG is FALSE\n");
762 return FALSE;
763}
764
765//
766// Switching out foreground message queues.
767//
770 _In_opt_ PWND Wnd,
771 _In_ PTHREADINFO pti,
772 _In_ BOOL MouseActivate,
773 _In_ DWORD Type )
774{
775 PTHREADINFO ptiChg, ptiPrev;
776 PUSER_MESSAGE_QUEUE pumq, pumqChg, pumqPrev;
777 BOOL Removed, Ret = TRUE;
778
779 if (Wnd && !VerifyWnd(Wnd))
780 {
781 return FALSE;
782 }
783
785 ptiPrev = NULL;
786 else
787 ptiPrev = gptiForeground;
788
789 if (Wnd)
790 {
791 ptiChg = Wnd->head.pti;
792 IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue);
793 gptiForeground = Wnd->head.pti;
794 //ERR("Set Foreground pti 0x%p Q 0x%p hWnd 0x%p\n", Wnd->head.pti, Wnd->head.pti->MessageQueue, UserHMGetHandle(Wnd));
795 }
796 else
797 {
798 ptiChg = NULL;
801 //ERR("Set Foreground pti 0x0 Q 0x0 hWnd 0x0\n");
802 }
803
804 //
805 // Process the changing out of the message queues.
806 //
808 {
809 pumqPrev = NULL;
810 if ( ptiPrev && !(ptiPrev->TIF_flags & TIF_INCLEANUP) )
811 {
812 pumqPrev = ptiPrev->MessageQueue;
813 }
814
815 pumq = pti ? pti->MessageQueue : NULL;
816
817 // Deactivate the previous message queue.
818 if (pumqPrev)
819 {
820 if ( pumq != pumqPrev )
821 {
822 MSG Msg;
823 HWND hWndPrev = pumqPrev->spwndActive ? UserHMGetHandle(pumqPrev->spwndActive) : NULL;
824 HANDLE tid = gptiForeground ? PsGetThreadId(gptiForeground->pEThread) : NULL; // TID from changing Window PTI.
825
827 Msg.hwnd = hWndPrev;
828 Msg.wParam = (WPARAM)pumqPrev->spwndActive;
829 Msg.lParam = 0;
830 Msg.time = 0;
831 //ERR("SFWAMQ : DAW P pti 0x%p tid 0x%p hWndPrev 0x%p\n",ptiPrev,tid,hWndPrev);
833 }
834 }
835
836 pumqChg = NULL;
837 if ( ptiChg && !(ptiChg->TIF_flags & TIF_INCLEANUP) )
838 {
839 pumqChg = ptiChg->MessageQueue;
840 }
841
842 pumq = pti ? pti->MessageQueue : NULL;
843
844 // Activate changing message queue.
845 if (pumqChg)
846 {
847 /*
848 Henri Verbeet,
849 What happens is that we get the WM_WINE_SETACTIVEWINDOW message sent by the
850 other thread after we already changed the foreground window back to our own
851 window.
852 */
853 //ERR("SFWAMQ : 1\n");
855
856 if (pumqChg != pumq)
857 {
858 MSG Msg;
859 HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
860 HANDLE tid = ptiPrev ? PsGetThreadId(ptiPrev->pEThread) : NULL;
861
863
865 Msg.hwnd = hWnd;
866 Msg.wParam = (WPARAM)Wnd;
867 Msg.lParam = (LPARAM)tid;
868 Msg.time = 0;
869 //ERR("SFWAMQ : SAW P pti 0x%p tid 0x%p hWnd 0x%p\n",ptiChg,tid,hWnd);
870 MsqPostMessage(ptiChg, &Msg, FALSE, QS_EVENT, POSTEVENT_SAW, (LONG_PTR)Type|MouseActivate);
871 }
872 else // Current message queue same as changed message queue.
873 {
874 if (pumq->spwndActive == Wnd)
875 {
877
878 UpdateShellHook(Wnd);
879
881 }
882 else
883 {
884 //ERR("SFWAMQ : SAW I pti 0x%p hWnd 0x%p\n", ptiChg, Wnd ? UserHMGetHandle(Wnd) : NULL);
885 Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE/*Type*/, FALSE);
886 //if (!Ret) ERR("SFWAMQ : ISAW : return error\n");
887 return Ret;
888 }
889 }
890 }
891
892 // Handle same message queue after switch out.
893 pumqPrev = NULL;
894 if ( ptiPrev && !(ptiPrev->TIF_flags & TIF_INCLEANUP) )
895 {
896 pumqPrev = ptiPrev->MessageQueue;
897 }
898 pumq = pti ? pti->MessageQueue : NULL;
899
900 if ( pumqPrev && pumq == pumqPrev )
901 {
902 HANDLE tid = Wnd ? PsGetThreadId(Wnd->head.pti->pEThread) : NULL;
903 //ERR("SFWAMQ : DAW I pti 0x%p tid 0x%p hWnd 0x%p\n", ptiPrev, tid, Wnd ? UserHMGetHandle(Wnd) : NULL);
905 }
906 }
907 return Ret;
908}
909
910/*
911 MSDN:
912 The system restricts which processes can set the foreground window. A process
913 can set the foreground window only if one of the following conditions is true:
914
915 * The process is the foreground process.
916 * The process was started by the foreground process.
917 * The process received the last input event.
918 * There is no foreground process.
919 * The foreground process is being debugged.
920 * The foreground is not locked (see LockSetForegroundWindow).
921 * The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
922 * No menus are active.
923*/
924static
927 _In_opt_ PWND Wnd,
928 _In_ BOOL MouseActivate,
929 _In_ BOOL bFlash )
930{
931 HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
932 PUSER_MESSAGE_QUEUE PrevForegroundQueue;
933 PTHREADINFO pti;
934 BOOL Ret = FALSE;
935
936 if (Wnd) ASSERT_REFS_CO(Wnd);
937
938 TRACE("SetForegroundAndFocusWindow(%x, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE"));
939
940 PrevForegroundQueue = IntGetFocusMessageQueue(); // Use this active desktop.
942
943 if (Wnd && PrevForegroundQueue)
944 { // Same Window Q as foreground just do active.
945 if (Wnd->head.pti->MessageQueue == PrevForegroundQueue)
946 {
947 //ERR("Same Window Q as foreground just do active.\n");
948 if (pti->MessageQueue == PrevForegroundQueue)
949 { // Same WQ and TQ go active.
950 //ERR("Same WQ and TQ go active.\n");
951 Ret = IntUserSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
952 }
953 else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
954 { // Same WQ and it is active.
955 //ERR("Same WQ and it is active.\n");
956 Ret = TRUE;
957 }
958 else
959 { // Same WQ as FG but not the same TQ send active.
960 //ERR("Same WQ as FG but not the same TQ send active.\n");
961 MSG Msg;
962 PTHREADINFO ptiNew = Wnd->head.pti;
963
965 Msg.hwnd = hWnd;
966 Msg.wParam = (WPARAM)Wnd;
967 Msg.lParam = 0;
968 Msg.time = 0;
969 //ERR("SFAFW 1 : SAW P pti 0x%p hWnd 0x%p\n",ptiNew,hWnd);
970 MsqPostMessage(ptiNew, &Msg, FALSE, QS_EVENT, POSTEVENT_SAW, (LONG_PTR)MouseActivate);
971
972 Ret = TRUE;
973 }
974 return Ret;
975 }
976 }
977
978 if ( (( !IsFGLocked() || pti->ppi == gppiInputProvider ) &&
980 pti->ppi == ppiScrnSaver
981 )
982 {
983
984 ToggleFGActivate(pti);
985
986 return co_IntSetForegroundMessageQueue( Wnd, pti, MouseActivate, 0 );
987 }
988
989 if (!Wnd) return FALSE; // No window, always return FALSE.
990
992
993 if (pti->MessageQueue == Wnd->head.pti->MessageQueue)
994 {
995 //ERR("Same PQ and WQ go active.\n");
996 Ret = IntUserSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
997 //if (!Ret) ERR("ISFAFW : IUSAW : return error\n");
998 }
999 else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
1000 {
1001 TRACE("Same Active and Wnd.\n"); // Leave this for now.
1002 }
1003 else
1004 {
1005 //ERR("Activate Not same PQ and WQ and Wnd.\n");
1007 MSG Msg;
1008 PTHREADINFO ptiNew = Wnd->head.pti;
1009
1010 Msg.message = WM_ASYNC_SETACTIVEWINDOW;
1011 Msg.hwnd = hWnd;
1012 Msg.wParam = (WPARAM)Wnd;
1013 Msg.lParam = 0;
1014 Msg.time = 0;
1015 //ERR("SFAFW 2 : SAW P pti 0x%p hWnd 0x%p\n",ptiNew,hWnd);
1016 MsqPostMessage(ptiNew, &Msg, FALSE, QS_EVENT, POSTEVENT_SAW, (LONG_PTR)MouseActivate);
1017 }
1018 // Always return FALSE.
1019 return FALSE;
1020}
1021
1022//
1023// Set the Active Window.
1024//
1027 _In_ PWND Wnd,
1028 _In_ BOOL bMouse,
1029 _In_ BOOL bFocus,
1030 _In_ BOOL Async )
1031{
1032 PTHREADINFO pti;
1033 PUSER_MESSAGE_QUEUE ThreadQueue;
1034 PWND pWndChg, WndPrev; // State changes.
1035 HWND hWndPrev;
1036 HWND hWnd = 0;
1037 BOOL InAAPM;
1039
1040 //ERR("co_IntSetActiveWindow 1\n");
1041
1043 ThreadQueue = pti->MessageQueue;
1044 ASSERT(ThreadQueue != 0);
1045
1046 pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch.
1047 hWndPrev = (pWndChg ? UserHMGetHandle(pWndChg) : NULL);
1048
1049 if ( !Wnd || Wnd == UserGetDesktopWindow() )
1050 {
1051 //ERR("ISAW : NULL %p\n",Wnd);
1052 return FALSE;
1053 }
1054
1055 ASSERT_REFS_CO(Wnd);
1056 hWnd = UserHMGetHandle(Wnd);
1057 //ERR("co_IntSetActiveWindow 2 hWnd 0x%p\n",hWnd);
1058
1059 if (Wnd->ExStyle & WS_EX_NOACTIVATE)
1060 return TRUE;
1061
1062 /* check if the specified window can be set in the input data of a given queue */
1063 if ( ThreadQueue != Wnd->head.pti->MessageQueue )
1064 {
1065 //ERR("ISAW : Must have the same Message Queue\n");
1066 return FALSE;
1067 }
1068
1069 if (!VerifyWnd(Wnd))
1070 {
1071 //ERR("ISAW : Window is in Destroy!\n");
1072 return FALSE;
1073 }
1074
1075 if ( Wnd == pWndChg )
1076 {
1077 //ERR("ISAW : Nothing to do\n");
1078 return TRUE; // Fix CORE-8780 and CORE-11979. See CORE-11324 for breakage.
1079 }
1080
1081 if ( Wnd->state & WNDS_BEINGACTIVATED ) return TRUE;
1082
1083 /* Call CBT hook chain */
1084 cbt.fMouse = bMouse;
1085 cbt.hWndActive = hWndPrev;
1087 {
1088 ERR("SetActiveWindow: WH_CBT Call Hook return!\n");
1089 return FALSE;
1090 }
1091
1092 ThreadQueue->QF_flags &= ~QF_EVENTDEACTIVATEREMOVED;
1093
1094 if ( ThreadQueue->spwndActive && ThreadQueue->spwndActive->state & WNDS_DESTROYED )
1095 ThreadQueue->spwndActive = NULL;
1096 else
1097 ThreadQueue->spwndActivePrev = ThreadQueue->spwndActive;
1098
1099 WndPrev = ThreadQueue->spwndActive; // Keep to save changing active.
1100
1101 if (WndPrev)
1102 {
1103 if (ThreadQueue == gpqForeground) gpqForegroundPrev = ThreadQueue;
1105 }
1106
1107 WndPrev = ThreadQueue->spwndActive; // Again keep to save changing active.
1108
1109 // While in calling message proc or hook:
1110 // Fail if a preemptive switch was made, current active not made previous,
1111 // focus window is dead or no longer the same thread queue.
1112 if ( ThreadQueue->spwndActivePrev != ThreadQueue->spwndActive ||
1113 pWndChg != WndPrev ||
1114 (Wnd && !VerifyWnd(Wnd)) ||
1115 ThreadQueue != pti->MessageQueue )
1116 {
1117 ERR("SetActiveWindow: Summary ERROR, active state changed!\n");
1118 return FALSE;
1119 }
1120
1121 if (!WndPrev) ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;
1122
1123 /* set the current thread active window */
1124 ThreadQueue->spwndActive = Wnd;
1125
1126 // Set state flag to prevent recursions.
1127 Wnd->state |= WNDS_BEINGACTIVATED;
1128
1129 IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
1130
1131 // Clear out activate EVENT messages.
1133
1134 WndPrev = VerifyWnd(ThreadQueue->spwndActivePrev); // Now should be set but verify it again.
1135
1136 InAAPM = co_IntSendActivateMessages(WndPrev, Wnd, bMouse, Async);
1137
1138 /* now change focus if necessary */
1140 if (bFocus && !(ThreadQueue->QF_flags & QF_FOCUSNULLSINCEACTIVE))
1141 {
1142 /* Do not change focus if the window is no longer active */
1143 if (pti->MessageQueue->spwndActive != IntGetNonChildAncestor(pti->MessageQueue->spwndFocus))
1144 {
1145 PWND pWndSend = pti->MessageQueue->spwndActive;
1146 // Clear focus if the active window is minimized.
1147 if (pWndSend && pti->MessageQueue->spwndActive->style & WS_MINIMIZE) pWndSend = NULL;
1148 // Send focus messages and if so, set the focus.
1149 IntSendFocusMessages( pti, pWndSend);
1150 }
1151 }
1153 if (InAAPM)
1154 {
1155 pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
1156 }
1157
1158 // Checked in MENU_TrackMenu
1159 ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE;
1160
1161 //ERR("co_IntSetActiveWindow Exit\n");
1162 Wnd->state &= ~WNDS_BEINGACTIVATED;
1163 return (ThreadQueue->spwndActive == Wnd);
1164}
1165
1166//
1167// Set the Active Window.
1168//
1169// Window is not optional!
1170//
1173 _In_ PWND Wnd,
1174 _In_ BOOL bMouse,
1175 _In_ BOOL bFocus,
1176 _In_ BOOL Async)
1177{
1178 PTHREADINFO pti;
1179 PUSER_MESSAGE_QUEUE ThreadQueue;
1180
1181 //ERR("IntUserSetActiveWindow 1\n");
1182 ASSERT_REFS_CO(Wnd);
1183 if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
1184 //ERR("IntUserSetActiveWindow 1a hWnd 0x%p\n",UserHMGetHandle(Wnd));
1185
1186 //ERR("IntUserSetActiveWindow 2\n");
1188 ThreadQueue = pti->MessageQueue;
1189 ASSERT(ThreadQueue != 0);
1190
1191 while (Wnd)
1192 {
1193 BOOL Ret, DoFG, AllowFG;
1194
1195 if (ThreadQueue == Wnd->head.pti->MessageQueue)
1196 {
1197 if (IsAllowedFGActive(pti, Wnd))
1198 {
1199 DoFG = TRUE;
1200 }
1201 else
1202 {
1203 //ERR("IntUserSetActiveWindow 3 Go Out!\n");
1204 break;
1205 }
1206 AllowFG = !pti->cVisWindows; // Nothing is visable.
1207 //ERR("IntUserSetActiveWindow 3a DoFG = %d AllowFG = %d\n",DoFG,AllowFG);
1208 }
1209 else //if (ThreadQueue != Wnd->head.pti->MessageQueue)
1210 {
1211 //PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
1212 // Rule 1 & 4, We are foreground so set this FG window or NULL foreground....
1213 if (!gpqForeground || gpqForeground == ThreadQueue)
1214 {
1215 DoFG = TRUE;
1216 }
1217 else
1218 DoFG = FALSE;
1219 if (DoFG)
1220 {
1222 AllowFG = TRUE;
1223 else
1224 AllowFG = FALSE;
1225 }
1226 else
1227 AllowFG = FALSE;
1228 //ERR("IntUserSetActiveWindow 3b DoFG = %d AllowFG = %d\n",DoFG,AllowFG);
1229 }
1230 Ret = FALSE;
1231 if (DoFG)
1232 {
1234 //ERR("IntUserSetActiveWindow 3c FG set\n");
1235 Ret = co_IntSetForegroundAndFocusWindow(Wnd, bMouse, TRUE);
1236 if (AllowFG)
1237 {
1239 }
1240 else
1241 {
1242 pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE;
1243 }
1244 }
1245 return Ret;
1246 }
1247
1248 return co_IntSetActiveWindow(Wnd, bMouse, bFocus, Async);
1249}
1250
1253{
1254 TRACE("Mouse Active\n");
1255 if (Wnd && (Wnd->ExStyle & WS_EX_NOACTIVATE))
1256 return TRUE;
1258}
1259
1260/* Win: PWND xxxSetActiveWindow(Wnd) */
1263{
1265
1266 if (Wnd)
1267 {
1268 if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
1269
1270 return IntUserSetActiveWindow(Wnd, FALSE, TRUE, FALSE);
1271 }
1272 /*
1273 Yes your eye are not deceiving you~!
1274
1275 First part of wines Win.c test_SetActiveWindow:
1276
1277 flush_events( TRUE );
1278 ShowWindow(hwnd, SW_HIDE);
1279 SetFocus(0);
1280 SetActiveWindow(0);
1281 check_wnd_state(0, 0, 0, 0); <-- This should pass if ShowWindow does it's job!!! As of 10/28/2012 it does!
1282
1283 Now Handle wines Msg.c test_SetActiveWindow( 0 )...
1284 */
1285 TRACE("USAW: Previous active window\n");
1286 if ( gpqForegroundPrev &&
1291 {
1292 TRACE("USAW:PAW hwnd %p\n", UserHMGetHandle(Wnd));
1293 return IntUserSetActiveWindow(Wnd, FALSE, TRUE, FALSE);
1294 }
1295
1296 // Activate anyone but the active window.
1297 if ( pti->MessageQueue->spwndActive &&
1298 (Wnd = VerifyWnd(pti->MessageQueue->spwndActive)) != NULL )
1299 {
1300 //ERR("USAW:AOWM hwnd %p\n", UserHMGetHandle(Wnd));
1301 if (!ActivateOtherWindowMin(Wnd))
1302 {
1303 // Okay, now go find someone else to play with!
1304 //ERR("USAW: Going to WPAOW\n");
1306 }
1307 return TRUE;
1308 }
1309
1310 TRACE("USAW: Nothing\n");
1311 return FALSE;
1312}
1313
1314// Win: PWND xxxSetFocus(Window)
1317{
1318 HWND hWndPrev = 0;
1319 PWND pwndTop;
1320 PTHREADINFO pti;
1321 PUSER_MESSAGE_QUEUE ThreadQueue;
1322
1323 if (Window)
1325
1327 ThreadQueue = pti->MessageQueue;
1328 ASSERT(ThreadQueue != 0);
1329
1330 TRACE("Enter SetFocus hWnd 0x%p pti 0x%p\n",Window ? UserHMGetHandle(Window) : 0, pti );
1331
1332 hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
1333
1334 if (Window != 0)
1335 {
1336 if (hWndPrev == UserHMGetHandle(Window))
1337 {
1338 return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0; /* Nothing to do */
1339 }
1340
1341 if (Window->head.pti->MessageQueue != ThreadQueue)
1342 {
1343 ERR("SetFocus Must have the same Q!\n");
1344 return 0;
1345 }
1346
1347 /* Check if we can set the focus to this window */
1349 for (pwndTop = Window; pwndTop; pwndTop = pwndTop->spwndParent)
1350 {
1351 if (pwndTop->style & (WS_MINIMIZED|WS_DISABLED)) return 0;
1352 if ((pwndTop->style & (WS_POPUP|WS_CHILD)) != WS_CHILD) break;
1353 if (pwndTop->spwndParent == NULL) break;
1354 }
1357 {
1358 ERR("SetFocus 1 WH_CBT Call Hook return!\n");
1359 return 0;
1360 }
1361
1362 /* Activate pwndTop if needed. */
1363 if (pwndTop != ThreadQueue->spwndActive)
1364 {
1365 PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); // Keep it based on desktop.
1366 if (ThreadQueue != ForegroundQueue && IsAllowedFGActive(pti, pwndTop)) // Rule 2 & 3.
1367 {
1368 //ERR("SetFocus: Set Foreground!\n");
1369 if (!(pwndTop->style & WS_VISIBLE))
1370 {
1371 pti->ppi->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE;
1372 }
1374 {
1375 ERR("SetFocus: Set Foreground and Focus Failed!\n");
1376 return 0;
1377 }
1378 }
1379
1380 /* Set Active when it is needed. */
1381 if (pwndTop != ThreadQueue->spwndActive)
1382 {
1383 //ERR("SetFocus: Set Active! %p\n",pwndTop?UserHMGetHandle(pwndTop):0);
1384 if (!co_IntSetActiveWindow(pwndTop, FALSE, FALSE, FALSE))
1385 {
1386 ERR("SetFocus: Set Active Failed!\n");
1387 return 0;
1388 }
1389 }
1390
1391 /* Abort if window destroyed */
1392 if (Window->state2 & WNDS2_INDESTROY) return 0;
1393 /* Do not change focus if the window is no longer active */
1394 if (pwndTop != ThreadQueue->spwndActive)
1395 {
1396 ERR("SetFocus: Top window did not go active!\n");
1397 return 0;
1398 }
1399 }
1400
1401 // Check again! SetActiveWindow could have set the focus via WM_ACTIVATE.
1402 hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
1403
1405
1406 TRACE("Focus: %p -> %p\n", hWndPrev, UserHMGetHandle(Window));
1407 }
1408 else /* NULL hwnd passed in */
1409 {
1410 if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev))
1411 {
1412 ERR("SetFocus: 2 WH_CBT Call Hook return!\n");
1413 return 0;
1414 }
1415 //ERR("SetFocus: Set Focus NULL\n");
1416 /* set the current thread focus window null */
1418 }
1419 return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0;
1420}
1421
1424{
1425 PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
1426 if (!ForegroundQueue)
1427 return NULL;
1428 return (ForegroundQueue->spwndActive ? UserHMGetHandle(ForegroundQueue->spwndActive) : NULL);
1429}
1430
1432{
1434 PUSER_MESSAGE_QUEUE ThreadQueue = pti->MessageQueue;
1435 if (!ThreadQueue)
1436 return NULL;
1437 return (ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : NULL);
1438}
1439
1442{
1443 PTHREADINFO pti;
1444 PUSER_MESSAGE_QUEUE ThreadQueue;
1445 HWND Ret;
1446
1447 TRACE("Enter IntGetCapture\n");
1448
1450 ThreadQueue = pti->MessageQueue;
1451 Ret = ((ThreadQueue && ThreadQueue->spwndCapture) ? UserHMGetHandle(ThreadQueue->spwndCapture) : NULL);
1452
1453 TRACE("Leave IntGetCapture, ret=%p\n", Ret);
1454 return Ret;
1455}
1456
1459{
1460 PTHREADINFO pti;
1461 PUSER_MESSAGE_QUEUE ThreadQueue;
1462 PWND pWnd, Window = NULL;
1463 HWND hWndPrev;
1464
1466 ThreadQueue = pti->MessageQueue;
1467
1468 if (ThreadQueue->QF_flags & QF_CAPTURELOCKED)
1469 return NULL;
1470
1471 if (hWnd && (Window = UserGetWindowObject(hWnd)))
1472 {
1473 if (Window->head.pti->MessageQueue != ThreadQueue)
1474 {
1475 ERR("Window Thread does not match Current!\n");
1476 return NULL;
1477 }
1478 }
1479
1480 hWndPrev = MsqSetStateWindow(pti, MSQ_STATE_CAPTURE, hWnd);
1481
1482 if (hWndPrev)
1483 {
1484 pWnd = UserGetWindowObject(hWndPrev);
1485 if (pWnd)
1486 IntNotifyWinEvent(EVENT_SYSTEM_CAPTUREEND, pWnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
1487 }
1488
1489 if (Window)
1490 IntNotifyWinEvent(EVENT_SYSTEM_CAPTURESTART, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
1491
1492 //
1493 // Only send the message if we have a previous Window!
1494 // Fix msg_menu tracking popup menu and win test_capture_4!!!!
1495 //
1496 if (hWndPrev)
1497 {
1498 if (ThreadQueue->MenuOwner && Window) ThreadQueue->QF_flags |= QF_CAPTURELOCKED;
1499
1501
1502 ThreadQueue->QF_flags &= ~QF_CAPTURELOCKED;
1503 }
1504
1505 if (hWnd == NULL) // Release mode.
1506 {
1507 MOUSEINPUT mi;
1509 /* Also remove other windows if not capturing anymore */
1513 /* Somebody may have missed some mouse movements */
1514 mi.dx = 0;
1515 mi.dy = 0;
1516 mi.mouseData = 0;
1518 mi.time = 0;
1519 mi.dwExtraInfo = 0;
1521 }
1522 return hWndPrev;
1523}
1524
1525/*
1526 API Call
1527*/
1528BOOL
1531{
1532 PTHREADINFO pti;
1533 PUSER_MESSAGE_QUEUE ThreadQueue;
1534
1536 ThreadQueue = pti->MessageQueue;
1537
1538 // Can not release inside WM_CAPTURECHANGED!!
1539 if (ThreadQueue->QF_flags & QF_CAPTURELOCKED) return FALSE;
1540
1542
1543 return TRUE;
1544}
1545
1546/*
1547 API Call
1548*/
1551{
1553
1555}
1556
1557/*
1558 API Call
1559*/
1562{
1564
1566}
1567
1568/*
1569 API Call
1570*/
1573{
1576 switch (uLockCode)
1577 {
1578 case LSFW_LOCK:
1579 if ( CanForceFG(ppi) && !gppiLockSFW )
1580 {
1581 gppiLockSFW = ppi;
1582 return TRUE;
1583 }
1584 break;
1585 case LSFW_UNLOCK:
1586 if ( gppiLockSFW == ppi)
1587 {
1588 gppiLockSFW = NULL;
1589 return TRUE;
1590 }
1591 break;
1592 default:
1594 }
1595 EngSetLastError(Err);
1596 return FALSE;
1597}
1598
1599/*
1600 API Call
1601*/
1604{
1605 PPROCESSINFO ppi, ppiCur;
1607
1608 ppi = NULL;
1609 if (dwProcessId != ASFW_ANY)
1610 {
1612 {
1614 return FALSE;
1615 }
1617 if (!ppi)
1618 {
1620 return FALSE;
1621 }
1622 }
1624 if (!CanForceFG(ppiCur))
1625 {
1628 return FALSE;
1629 }
1630 if (dwProcessId == ASFW_ANY)
1631 { // All processes will be enabled to set the foreground window.
1632 //ERR("ptiLastInput is CLEARED!!\n");
1634 }
1635 else
1636 { // Rule #3, last input event in force.
1637 ERR("ptiLastInput is SET!!\n");
1638 //ptiLastInput = ppi->ptiList; // See CORE-6384 & CORE-7030.
1640 }
1641 return TRUE;
1642}
1643
1644/*
1645 * @implemented
1646 */
1649{
1650 HWND Ret;
1651
1652 TRACE("Enter NtUserGetForegroundWindow\n");
1654
1656
1657 TRACE("Leave NtUserGetForegroundWindow, ret=%p\n", Ret);
1658 UserLeave();
1659 return Ret;
1660}
1661
1664{
1666 HWND hWndPrev;
1667 PWND Window, pwndPrev;
1668 HWND Ret = NULL;
1669
1670 TRACE("Enter NtUserSetActiveWindow(%p)\n", hWnd);
1672
1673 Window = NULL;
1674 if (hWnd)
1675 {
1677 {
1678 ERR("NtUserSetActiveWindow: Invalid handle 0x%p!\n",hWnd);
1679 goto Exit; // Return NULL
1680 }
1681 }
1682
1683 if (!Window ||
1684 Window->head.pti->MessageQueue == gptiCurrent->MessageQueue)
1685 {
1686 pwndPrev = gptiCurrent->MessageQueue->spwndActive;
1687 hWndPrev = (pwndPrev ? UserHMGetHandle(pwndPrev) : NULL);
1688 if (Window) UserRefObjectCo(Window, &Ref);
1691 Ret = ((hWndPrev && IntIsWindow(hWndPrev)) ? hWndPrev : NULL);
1692 }
1693
1694Exit:
1695 TRACE("Leave NtUserSetActiveWindow, ret=%p\n", Ret);
1696 UserLeave();
1697 return Ret;
1698}
1699
1700/*
1701 * @implemented
1702 */
1705{
1706 HWND Ret;
1707
1708 TRACE("Enter NtUserSetCapture(%p)\n", hWnd);
1710
1711 Ret = co_UserSetCapture(hWnd);
1712
1713 TRACE("Leave NtUserSetCapture, ret=%p\n", Ret);
1714 UserLeave();
1715 return Ret;
1716}
1717
1718/*
1719 * @implemented
1720 */
1723{
1724 PWND Window;
1726 HWND ret = NULL;
1727
1728 TRACE("Enter NtUserSetFocus(%p)\n", hWnd);
1730
1731 if (hWnd)
1732 {
1734 {
1735 ERR("NtUserSetFocus: Invalid handle 0x%p!\n",hWnd);
1736 goto Exit; // Return NULL
1737 }
1738
1739 UserRefObjectCo(Window, &Ref);
1742 }
1743 else
1744 {
1746 }
1747
1748Exit:
1749 TRACE("Leave NtUserSetFocus, ret=%p\n", ret);
1750 UserLeave();
1751 return ret;
1752}
1753
1754/* EOF */
Type
Definition: Type.h:7
#define msg(x)
Definition: auth_time.c:54
HWND hWnd
Definition: settings.c:17
#define ERR(fmt,...)
Definition: precomp.h:57
#define UlongToHandle(ul)
Definition: basetsd.h:91
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
struct @1765 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:33
#define APIENTRY
Definition: api.h:79
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
static const WCHAR Message[]
Definition: register.c:74
return ret
Definition: mutex.c:146
@ 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:1663
BOOL FASTCALL co_IntMouseActivateWindow(PWND Wnd)
Definition: focus.c:1252
BOOL FASTCALL FindRemoveEventMsg(PTHREADINFO pti, DWORD Event, DWORD EventLast)
Definition: focus.c:681
BOOL FASTCALL IntDeactivateWindow(PTHREADINFO pti, HANDLE tid)
Definition: focus.c:190
BOOL FASTCALL IntLockSetForegroundWindow(UINT uLockCode)
Definition: focus.c:1572
HWND APIENTRY NtUserSetCapture(HWND hWnd)
Definition: focus.c:1704
BOOL FASTCALL CanForceFG(PPROCESSINFO ppi)
Definition: focus.c:751
BOOL FASTCALL co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd, BOOL Clear)
Definition: focus.c:117
BOOL FASTCALL IntAllowSetForegroundWindow(DWORD dwProcessId)
Definition: focus.c:1603
VOID FASTCALL IntActivateWindow(PWND Wnd, PTHREADINFO pti, HANDLE tid, DWORD Type)
Definition: focus.c:359
HWND ghwndOldFullscreen
Definition: focus.c:19
HWND FASTCALL IntGetThreadFocusWindow(VOID)
Definition: focus.c:43
HWND FASTCALL co_UserSetFocus(PWND Window)
Definition: focus.c:1316
BOOL FASTCALL ToggleFGActivate(PTHREADINFO pti)
Definition: focus.c:712
PPROCESSINFO gppiLockSFW
Definition: focus.c:16
BOOL FASTCALL IntCheckFullscreen(PWND Window)
Definition: focus.c:78
BOOL FASTCALL UserSetActiveWindow(_In_opt_ PWND Wnd)
Definition: focus.c:1262
HWND FASTCALL IntGetCaptureWindow(VOID)
Definition: focus.c:34
BOOL FASTCALL co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOOL Async)
Definition: focus.c:446
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:732
BOOL FASTCALL co_IntMakeWindowActive(PWND Window)
Definition: focus.c:428
PTHREADINFO gptiForeground
Definition: focus.c:15
BOOL FASTCALL IntIsWindowFullscreen(PWND Window)
Definition: focus.c:52
ULONG guSFWLockCount
Definition: focus.c:17
HWND APIENTRY NtUserGetForegroundWindow(VOID)
Definition: focus.c:1648
HWND FASTCALL co_UserSetCapture(HWND hWnd)
Definition: focus.c:1458
HWND APIENTRY IntGetCapture(VOID)
Definition: focus.c:1441
VOID FASTCALL UpdateShellHook(PWND Window)
Definition: focus.c:98
VOID FASTCALL IntSendFocusMessages(PTHREADINFO pti, PWND pWnd)
Definition: focus.c:617
BOOL FASTCALL co_IntSetForegroundWindow(PWND Window)
Definition: focus.c:1550
BOOL FASTCALL co_IntSetForegroundMessageQueue(_In_opt_ PWND Wnd, _In_ PTHREADINFO pti, _In_ BOOL MouseActivate, _In_ DWORD Type)
Definition: focus.c:769
BOOL FASTCALL IntReleaseCapture(VOID)
Definition: focus.c:1530
BOOL FASTCALL co_IntSetForegroundWindowMouse(PWND Window)
Definition: focus.c:1561
HWND APIENTRY NtUserSetFocus(HWND hWnd)
Definition: focus.c:1722
BOOL FASTCALL co_IntSetActiveWindow(_In_ PWND Wnd, _In_ BOOL bMouse, _In_ BOOL bFocus, _In_ BOOL Async)
Definition: focus.c:1026
PTHREADINFO ptiLastInput
Definition: focus.c:18
HWND FASTCALL UserGetActiveWindow(VOID)
Definition: focus.c:1431
static BOOL FASTCALL co_IntSetForegroundAndFocusWindow(_In_opt_ PWND Wnd, _In_ BOOL MouseActivate, _In_ BOOL bFlash)
Definition: focus.c:926
VOID IntFocusSetInputContext(PWND pWnd, BOOL bActivate, BOOL bCallback)
Definition: focus.c:149
PUSER_MESSAGE_QUEUE gpqForegroundPrev
Definition: focus.c:14
HWND FASTCALL UserGetForegroundWindow(VOID)
Definition: focus.c:1423
BOOL FASTCALL IntUserSetActiveWindow(_In_ PWND Wnd, _In_ BOOL bMouse, _In_ BOOL bFocus, _In_ BOOL Async)
Definition: focus.c:1172
_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
PSERVERINFO gpsi
Definition: imm.c:18
#define IMS_IMEACTIVATE
Definition: imm32_undoc.h:46
#define IMS_IMEDEACTIVATE
Definition: imm32_undoc.h:47
#define WM_IME_SYSTEM
Definition: imm32_undoc.h:32
#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:3613
struct _WND * PWND
#define WNDS_NONCPAINT
Definition: ntuser.h:613
#define MSQ_STATE_CAPTURE
Definition: ntuser.h:3609
#define TIF_INACTIVATEAPPMSG
Definition: ntuser.h:272
#define IS_IMM_MODE()
Definition: ntuser.h:1212
#define MSQ_STATE_MENUOWNER
Definition: ntuser.h:3612
#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
static TfClientId tid
#define RtlEqualMemory(dst, src, len)
Definition: kdvm.h:18
LONG_PTR LPARAM
Definition: minwindef.h:175
UINT_PTR WPARAM
Definition: minwindef.h:174
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static void Clear(void)
Definition: treeview.c:388
static MONITORINFO mi
Definition: win.c:7338
VOID FASTCALL ClearMsgBitsMask(PTHREADINFO pti, UINT MessageBits)
Definition: msgqueue.c:445
VOID FASTCALL MsqDestroyMessage(PUSER_MESSAGE Message)
Definition: msgqueue.c:748
VOID FASTCALL MsqReleaseModifierKeys(PUSER_MESSAGE_QUEUE MessageQueue)
Definition: msgqueue.c:2546
HWND FASTCALL MsqSetStateWindow(PTHREADINFO pti, ULONG Type, HWND hWnd)
Definition: msgqueue.c:2507
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 _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#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:1792
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:258
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:249
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:43
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
_In_ DWORD dwProcessId
Definition: shlwapi.h:193
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:3889
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 WS_MINIMIZED
Definition: undocuser.h:20
#define QS_EVENT
Definition: undocuser.h:98
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:124
#define ASSERT_REFS_CO(_obj_)
Definition: userfuncs.h:14
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
#define IntDereferenceThreadInfo(pti)
Definition: win32.h:172
#define W32PF_ALLOWFOREGROUNDACTIVATE
Definition: win32.h:12
#define IntReferenceThreadInfo(pti)
Definition: win32.h:167
#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
#define ValidateHwndNoErr(hwnd)
Definition: precomp.h:100
PWND FASTCALL UserGetDesktopWindow(VOID)
Definition: desktop.c:1403
VOID FASTCALL IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue)
Definition: desktop.c:1336
PUSER_MESSAGE_QUEUE FASTCALL IntGetFocusMessageQueue(VOID)
Definition: desktop.c:1324
VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam)
Definition: desktop.c:1706
PDESKTOP gpdeskInputDesktop
Definition: desktop.c:52
PWND FASTCALL co_GetDesktopWindow(PWND pWnd)
Definition: desktop.c:1383
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:30
LRESULT FASTCALL co_IntSendMessageWithCallBack(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, SENDASYNCPROC CompletionCallback, ULONG_PTR CompletionCallbackContext, ULONG_PTR *uResult)
Definition: message.c:1785
BOOL FASTCALL UserSendNotifyMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:2090
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1495
LONG NTAPI UserGetSystemMetrics(ULONG Index)
Definition: metric.c:210
PMONITOR NTAPI UserGetPrimaryMonitor(VOID)
Definition: monitor.c:102
#define USERTAG_WINDOWLIST
Definition: tags.h:298
HWND *FASTCALL IntWinListChildren(PWND Window)
Definition: window.c:276
PWND FASTCALL VerifyWnd(PWND pWnd)
Definition: window.c:88
BOOL FASTCALL IntIsWindow(HWND hWnd)
Definition: window.c:178
BOOL FASTCALL IntIsWindowVisible(PWND Wnd)
Definition: window.c:191
PWND FASTCALL IntGetNonChildAncestor(PWND pWnd)
Definition: window.c:353
#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
#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
struct _RECTL * LPRECTL
#define WM_QUERYNEWPALETTE
Definition: winuser.h:1906
#define HSHELL_RUDEAPPACTIVATED
Definition: winuser.h:1292
#define MAKEWPARAM(l, h)
Definition: winuser.h:4111
#define SWP_NOACTIVATE
Definition: winuser.h:1253
#define MAKELPARAM(l, h)
Definition: winuser.h:4110
#define SM_CYSCREEN
Definition: winuser.h:971
#define WM_CAPTURECHANGED
Definition: winuser.h:1836
#define WS_EX_APPWINDOW
Definition: winuser.h:383
#define HCBT_ACTIVATE
Definition: winuser.h:60
#define HWND_BROADCAST
Definition: winuser.h:1215
#define WM_CANCELMODE
Definition: winuser.h:1663
#define SWP_NOMOVE
Definition: winuser.h:1255
#define WS_EX_NOACTIVATE
Definition: winuser.h:395
#define WS_EX_TOOLWINDOW
Definition: winuser.h:404
#define WM_SETFOCUS
Definition: winuser.h:1641
#define SWP_NOSIZE
Definition: winuser.h:1256
#define WM_MOUSEMOVE
Definition: winuser.h:1803
#define WA_INACTIVE
Definition: winuser.h:2664
#define WH_CBT
Definition: winuser.h:35
#define WM_ACTIVATE
Definition: winuser.h:1640
#define MOUSEEVENTF_MOVE
Definition: winuser.h:1194
#define WM_NCACTIVATE
Definition: winuser.h:1716
#define HWND_TOP
Definition: winuser.h:1218
#define HCBT_SETFOCUS
Definition: winuser.h:64
#define WA_ACTIVE
Definition: winuser.h:2665
#define WA_CLICKACTIVE
Definition: winuser.h:2666
#define WM_ACTIVATEAPP
Definition: winuser.h:1660
#define SM_CXSCREEN
Definition: winuser.h:970
#define WM_KILLFOCUS
Definition: winuser.h:1642
#define WM_PALETTEISCHANGING
Definition: winuser.h:1904
#define ObDereferenceObject
Definition: obfuncs.h:203