ReactOS 0.4.17-dev-37-g0bfb40d
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
148VOID IntFocusSetInputContext(PWND pWnd, BOOL bActivate, BOOL bCallback)
149{
150 PTHREADINFO pti;
151 PWND pImeWnd;
153 HWND hImeWnd;
156
157 if (!pWnd || !pWnd->pcls || IS_WND_IMELIKE(pWnd))
158 return;
159
160 pti = pWnd->head.pti;
161 if (!pti || (pti->TIF_flags & TIF_INCLEANUP))
162 return;
163
164 pImeWnd = pti->spwndDefaultIme;
165 if (!pImeWnd)
166 return;
167
168 UserRefObjectCo(pImeWnd, &Ref);
169
170 hImeWnd = UserHMGetHandle(pImeWnd);
171 wParam = (bActivate ? IMS_IMEACTIVATE : IMS_IMEDEACTIVATE);
173
174 if (bCallback)
176 else
178
179 UserDerefObjectCo(pImeWnd);
180}
181
182//
183// Deactivating the foreground message queue.
184//
185// Release Active, Capture and Focus Windows associated with this message queue.
186//
189{
191 PTHREADINFO ptiPrev;
192 PWND pwndPrev;
193 BOOL InAAPM = FALSE;
195
196 if ( !pti->MessageQueue->spwndActive )
197 {
198 TRACE("IDAW E : Nothing to do, Active is NULL! pti 0x%p tid 0x%p\n",pti,tid);
199 return TRUE;
200 }
201
202 TRACE("IDAW : pti 0x%p tid 0x%p\n",pti,tid);
203
204 if (ptiCurrent != pti)
205 {
207 IntReferenceThreadInfo(ptiCurrent);
208 }
209
210 if (!(pti->TIF_flags & TIF_INACTIVATEAPPMSG) )
211 {
213 InAAPM = TRUE;
214 }
215
216 //
217 // Check for Capture and release it.
218 //
219 if ( pti->MessageQueue->spwndCapture )
220 {
221 MSG msg;
222 PWND pwndCapture = pti->MessageQueue->spwndCapture;
223
224 UserRefObjectCo(pwndCapture, &Ref);
226 UserDerefObjectCo(pwndCapture);
227
228 /* Generate mouse move message */
229 msg.message = WM_MOUSEMOVE;
230 msg.wParam = UserGetMouseButtonsState();
231 msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y);
232 msg.pt = gpsi->ptCursor;
234 }
235
236 //
237 // Check for Active and release it.
238 //
239 if ( pti->MessageQueue->spwndActive )
240 {
241 pwndPrev = pti->MessageQueue->spwndActive;
242 ptiPrev = pwndPrev->head.pti;
243
245 {
246 if (InAAPM) pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
247 if (ptiCurrent != pti)
248 {
250 IntDereferenceThreadInfo(ptiCurrent);
251 }
252 return FALSE;
253 }
254
255 if ( pti->MessageQueue->spwndActive == pwndPrev )
256 {
257 pti->MessageQueue->spwndActivePrev = pwndPrev;
258 pti->MessageQueue->spwndActive = NULL;
259 }
260
261 if (ptiPrev->TIF_flags & TIF_INCLEANUP) ptiPrev = NULL;
262 }
263 else
264 {
265 ptiPrev = pti;
266 pwndPrev = (PWND)-1; // Avoid zero Active window.
267 }
268
269 if ( ptiPrev )
270 {
271 HANDLE OldTID = PsGetThreadId(ptiPrev->pEThread);
272 PWND cWindow;
273 HWND *List, *phWnd;
274
276 if ( List )
277 {
278 if ( OldTID )
279 {
280 for (phWnd = List; *phWnd; ++phWnd)
281 {
282 cWindow = ValidateHwndNoErr(*phWnd);
283 if ( cWindow && cWindow->head.pti == ptiPrev )
284 { // FALSE if the window is being deactivated,
285 // ThreadId that owns the window being activated.
286 //ERR("IDW : WM_ACTIVATEAPP(0) hwnd %p tid Old %p New %p\n",UserHMGetHandle(cWindow),OldTID,tid);
287 UserRefObjectCo(cWindow, &Ref);
289 UserDerefObjectCo(cWindow);
290 }
291 }
292 }
294 }
295 }
296
297 //
298 // Now check for a change (Bounce), if Active same as previous window, release it too.
299 //
300 if ( pti->MessageQueue->spwndActive == pwndPrev )
301 {
303 {
304 if (InAAPM) pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
305 if (ptiCurrent != pti)
306 {
308 IntDereferenceThreadInfo(ptiCurrent);
309 }
310 return FALSE;
311 }
312
313 if ( pti->MessageQueue->spwndActive == pwndPrev )
314 {
315 pti->MessageQueue->spwndActivePrev = pwndPrev;
316 pti->MessageQueue->spwndActive = NULL;
317 }
318 }
319
320 //
321 // Check for Focus and release it.
322 //
323 if ( pti->MessageQueue->spwndFocus )
324 {
325 PWND pwndFocus = pti->MessageQueue->spwndFocus;
326
327 //
328 // Fix win.c:test_SetForegroundWindow:SetActiveWindow(0)!
329 //
330 pti->MessageQueue->spwndFocus = NULL; // Null out Focus.
331
332 UserRefObjectCo(pwndFocus, &Ref);
334 if (IS_IMM_MODE())
335 {
337 }
338 UserDerefObjectCo(pwndFocus);
339 }
340
341 /* Check for keyboard modifiers and release them (CORE-14768) */
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
615{
616 PWND pWndPrev;
617 PUSER_MESSAGE_QUEUE ThreadQueue = pti->MessageQueue; // Queue can change...
618 HWND hwndPrev;
620
621 ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;
622 if (!pWnd && ThreadQueue->spwndActive)
623 {
624 ThreadQueue->QF_flags |= QF_FOCUSNULLSINCEACTIVE;
625 }
626
627 pWndPrev = ThreadQueue->spwndFocus;
628 if (pWndPrev)
629 UserRefObjectCo(pWndPrev, &Ref);
630
631 /* check if the specified window can be set in the input data of a given queue */
632 if (!pWnd || ThreadQueue == pWnd->head.pti->MessageQueue)
633 /* set the current thread focus window */
634 ThreadQueue->spwndFocus = pWnd;
635
636 if (pWnd)
637 {
638 if (pWndPrev)
639 {
641 if (IS_IMM_MODE())
642 {
644 }
645 }
646 if (ThreadQueue->spwndFocus == pWnd)
647 {
648 if (IS_IMM_MODE())
649 {
651 }
652
653 IntNotifyWinEvent(EVENT_OBJECT_FOCUS, pWnd, OBJID_CLIENT, CHILDID_SELF, 0);
654
655 hwndPrev = (pWndPrev ? UserHMGetHandle(pWndPrev) : NULL);
657 }
658 }
659 else
660 {
661 if (pWndPrev)
662 {
663 IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
664
666 if (IS_IMM_MODE())
667 {
669 }
670 }
671 }
672
673 if (pWndPrev)
674 UserDerefObjectCo(pWndPrev);
675}
676
679{
682 BOOL Ret = FALSE;
683
685 while (Entry != &pti->PostedMessagesListHead)
686 {
687 // Scan posted queue messages to see if we received async messages.
689 Entry = Entry->Flink;
690
691 if (Message->dwQEvent == EventLast)
692 {
693 //ERR("Event D/SAW: Last Activate/Deactivate %d\n", EventLast);
694 return Ret;
695 }
696
697 if (Message->dwQEvent == Event)
698 {
699 //ERR("Event D/SAW: Found one in the Post Msg Queue! Activate/Deactivate %d\n", Event);
700 ClearMsgBitsMask(pti, Message->QS_Flags);
702 Ret = TRUE;
703 }
704 }
705 return Ret;
706}
707
710{
711 BOOL Ret;
712 PPROCESSINFO ppi = pti->ppi;
713
714 Ret = !!(pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE);
715 if (Ret)
716 {
717 pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE;
718 }
719 else
720 Ret = !!(ppi->W32PF_flags & W32PF_ALLOWFOREGROUNDACTIVATE);
721
722 if (Ret)
723 ppi->W32PF_flags &= ~W32PF_ALLOWFOREGROUNDACTIVATE;
724 //ERR("ToggleFGActivate is %d\n",Ret);
725 return Ret;
726}
727
730{
731 // Not allowed if one or more,,
732 if (!ToggleFGActivate(pti) || // bits not set,
733 pti->rpdesk != gpdeskInputDesktop || // not current Desktop,
734 pti->MessageQueue == gpqForeground || // if already the queue foreground,
735 IsFGLocked() || // foreground is locked,
736 (Wnd->ExStyle & WS_EX_NOACTIVATE)) // or, does not become the foreground window when the user clicks it.
737 {
738 return FALSE;
739 }
740 //ERR("IsAllowedFGActive is TRUE\n");
741 return TRUE;
742}
743
744/*
745 Can the system force foreground from one or more conditions.
746 */
749{
750 if (!ptiLastInput ||
751 ptiLastInput->ppi == ppi ||
753 gptiForeground->ppi == ppi ||
755 gppiInputProvider == ppi ||
757 ) return TRUE;
758 //ERR("CanForceFG is FALSE\n");
759 return FALSE;
760}
761
762//
763// Switching out foreground message queues.
764//
767 _In_opt_ PWND Wnd,
768 _In_ PTHREADINFO pti,
769 _In_ BOOL MouseActivate,
770 _In_ DWORD Type )
771{
772 PTHREADINFO ptiChg, ptiPrev;
773 PUSER_MESSAGE_QUEUE pumq, pumqChg, pumqPrev;
774 BOOL Removed, Ret = TRUE;
775
776 if (Wnd && !VerifyWnd(Wnd))
777 {
778 return FALSE;
779 }
780
782 ptiPrev = NULL;
783 else
784 ptiPrev = gptiForeground;
785
786 if (Wnd)
787 {
788 ptiChg = Wnd->head.pti;
789 IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue);
790 gptiForeground = Wnd->head.pti;
791 //ERR("Set Foreground pti 0x%p Q 0x%p hWnd 0x%p\n", Wnd->head.pti, Wnd->head.pti->MessageQueue, UserHMGetHandle(Wnd));
792 }
793 else
794 {
795 ptiChg = NULL;
798 //ERR("Set Foreground pti 0x0 Q 0x0 hWnd 0x0\n");
799 }
800
801 //
802 // Process the changing out of the message queues.
803 //
805 {
806 pumqPrev = NULL;
807 if ( ptiPrev && !(ptiPrev->TIF_flags & TIF_INCLEANUP) )
808 {
809 pumqPrev = ptiPrev->MessageQueue;
810 }
811
812 pumq = pti ? pti->MessageQueue : NULL;
813
814 // Deactivate the previous message queue.
815 if (pumqPrev)
816 {
817 if ( pumq != pumqPrev )
818 {
819 MSG Msg;
820 HWND hWndPrev = pumqPrev->spwndActive ? UserHMGetHandle(pumqPrev->spwndActive) : NULL;
821 HANDLE tid = gptiForeground ? PsGetThreadId(gptiForeground->pEThread) : NULL; // TID from changing Window PTI.
822
824 Msg.hwnd = hWndPrev;
825 Msg.wParam = (WPARAM)pumqPrev->spwndActive;
826 Msg.lParam = 0;
827 Msg.time = 0;
828 //ERR("SFWAMQ : DAW P pti 0x%p tid 0x%p hWndPrev 0x%p\n",ptiPrev,tid,hWndPrev);
830 }
831 }
832
833 pumqChg = NULL;
834 if ( ptiChg && !(ptiChg->TIF_flags & TIF_INCLEANUP) )
835 {
836 pumqChg = ptiChg->MessageQueue;
837 }
838
839 pumq = pti ? pti->MessageQueue : NULL;
840
841 // Activate changing message queue.
842 if (pumqChg)
843 {
844 /*
845 Henri Verbeet,
846 What happens is that we get the WM_WINE_SETACTIVEWINDOW message sent by the
847 other thread after we already changed the foreground window back to our own
848 window.
849 */
850 //ERR("SFWAMQ : 1\n");
852
853 if (pumqChg != pumq)
854 {
855 MSG Msg;
856 HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
857 HANDLE tid = ptiPrev ? PsGetThreadId(ptiPrev->pEThread) : NULL;
858
860
862 Msg.hwnd = hWnd;
863 Msg.wParam = (WPARAM)Wnd;
864 Msg.lParam = (LPARAM)tid;
865 Msg.time = 0;
866 //ERR("SFWAMQ : SAW P pti 0x%p tid 0x%p hWnd 0x%p\n",ptiChg,tid,hWnd);
867 MsqPostMessage(ptiChg, &Msg, FALSE, QS_EVENT, POSTEVENT_SAW, (LONG_PTR)Type|MouseActivate);
868 }
869 else // Current message queue same as changed message queue.
870 {
871 if (pumq->spwndActive == Wnd)
872 {
874
875 UpdateShellHook(Wnd);
876
878 }
879 else
880 {
881 //ERR("SFWAMQ : SAW I pti 0x%p hWnd 0x%p\n", ptiChg, Wnd ? UserHMGetHandle(Wnd) : NULL);
882 Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE/*Type*/, FALSE);
883 //if (!Ret) ERR("SFWAMQ : ISAW : return error\n");
884 return Ret;
885 }
886 }
887 }
888
889 // Handle same message queue after switch out.
890 pumqPrev = NULL;
891 if ( ptiPrev && !(ptiPrev->TIF_flags & TIF_INCLEANUP) )
892 {
893 pumqPrev = ptiPrev->MessageQueue;
894 }
895 pumq = pti ? pti->MessageQueue : NULL;
896
897 if ( pumqPrev && pumq == pumqPrev )
898 {
899 HANDLE tid = Wnd ? PsGetThreadId(Wnd->head.pti->pEThread) : NULL;
900 //ERR("SFWAMQ : DAW I pti 0x%p tid 0x%p hWnd 0x%p\n", ptiPrev, tid, Wnd ? UserHMGetHandle(Wnd) : NULL);
902 }
903 }
904 return Ret;
905}
906
907/*
908 MSDN:
909 The system restricts which processes can set the foreground window. A process
910 can set the foreground window only if one of the following conditions is true:
911
912 * The process is the foreground process.
913 * The process was started by the foreground process.
914 * The process received the last input event.
915 * There is no foreground process.
916 * The foreground process is being debugged.
917 * The foreground is not locked (see LockSetForegroundWindow).
918 * The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
919 * No menus are active.
920*/
921static
924 _In_opt_ PWND Wnd,
925 _In_ BOOL MouseActivate,
926 _In_ BOOL bFlash )
927{
928 HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
929 PUSER_MESSAGE_QUEUE PrevForegroundQueue;
930 PTHREADINFO pti;
931 BOOL Ret = FALSE;
932
933 if (Wnd) ASSERT_REFS_CO(Wnd);
934
935 TRACE("SetForegroundAndFocusWindow(%x, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE"));
936
937 PrevForegroundQueue = IntGetFocusMessageQueue(); // Use this active desktop.
939
940 if (Wnd && PrevForegroundQueue)
941 { // Same Window Q as foreground just do active.
942 if (Wnd->head.pti->MessageQueue == PrevForegroundQueue)
943 {
944 //ERR("Same Window Q as foreground just do active.\n");
945 if (pti->MessageQueue == PrevForegroundQueue)
946 { // Same WQ and TQ go active.
947 //ERR("Same WQ and TQ go active.\n");
948 Ret = IntUserSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
949 }
950 else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
951 { // Same WQ and it is active.
952 //ERR("Same WQ and it is active.\n");
953 Ret = TRUE;
954 }
955 else
956 { // Same WQ as FG but not the same TQ send active.
957 //ERR("Same WQ as FG but not the same TQ send active.\n");
958 MSG Msg;
959 PTHREADINFO ptiNew = Wnd->head.pti;
960
962 Msg.hwnd = hWnd;
963 Msg.wParam = (WPARAM)Wnd;
964 Msg.lParam = 0;
965 Msg.time = 0;
966 //ERR("SFAFW 1 : SAW P pti 0x%p hWnd 0x%p\n",ptiNew,hWnd);
967 MsqPostMessage(ptiNew, &Msg, FALSE, QS_EVENT, POSTEVENT_SAW, (LONG_PTR)MouseActivate);
968
969 Ret = TRUE;
970 }
971 return Ret;
972 }
973 }
974
975 if ( (( !IsFGLocked() || pti->ppi == gppiInputProvider ) &&
977 pti->ppi == ppiScrnSaver
978 )
979 {
980
981 ToggleFGActivate(pti);
982
983 return co_IntSetForegroundMessageQueue( Wnd, pti, MouseActivate, 0 );
984 }
985
986 if (!Wnd) return FALSE; // No window, always return FALSE.
987
989
990 if (pti->MessageQueue == Wnd->head.pti->MessageQueue)
991 {
992 //ERR("Same PQ and WQ go active.\n");
993 Ret = IntUserSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
994 //if (!Ret) ERR("ISFAFW : IUSAW : return error\n");
995 }
996 else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
997 {
998 TRACE("Same Active and Wnd.\n"); // Leave this for now.
999 }
1000 else
1001 {
1002 //ERR("Activate Not same PQ and WQ and Wnd.\n");
1004 MSG Msg;
1005 PTHREADINFO ptiNew = Wnd->head.pti;
1006
1007 Msg.message = WM_ASYNC_SETACTIVEWINDOW;
1008 Msg.hwnd = hWnd;
1009 Msg.wParam = (WPARAM)Wnd;
1010 Msg.lParam = 0;
1011 Msg.time = 0;
1012 //ERR("SFAFW 2 : SAW P pti 0x%p hWnd 0x%p\n",ptiNew,hWnd);
1013 MsqPostMessage(ptiNew, &Msg, FALSE, QS_EVENT, POSTEVENT_SAW, (LONG_PTR)MouseActivate);
1014 }
1015 // Always return FALSE.
1016 return FALSE;
1017}
1018
1019//
1020// Set the Active Window.
1021//
1024 _In_ PWND Wnd,
1025 _In_ BOOL bMouse,
1026 _In_ BOOL bFocus,
1027 _In_ BOOL Async )
1028{
1029 PTHREADINFO pti;
1030 PUSER_MESSAGE_QUEUE ThreadQueue;
1031 PWND pWndChg, WndPrev; // State changes.
1032 HWND hWndPrev;
1033 HWND hWnd = 0;
1034 BOOL InAAPM;
1036
1037 //ERR("co_IntSetActiveWindow 1\n");
1038
1040 ThreadQueue = pti->MessageQueue;
1041 ASSERT(ThreadQueue != 0);
1042
1043 pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch.
1044 hWndPrev = (pWndChg ? UserHMGetHandle(pWndChg) : NULL);
1045
1046 if ( !Wnd || Wnd == UserGetDesktopWindow() )
1047 {
1048 //ERR("ISAW : NULL %p\n",Wnd);
1049 return FALSE;
1050 }
1051
1052 ASSERT_REFS_CO(Wnd);
1053 hWnd = UserHMGetHandle(Wnd);
1054 //ERR("co_IntSetActiveWindow 2 hWnd 0x%p\n",hWnd);
1055
1056 if (Wnd->ExStyle & WS_EX_NOACTIVATE)
1057 return TRUE;
1058
1059 /* check if the specified window can be set in the input data of a given queue */
1060 if ( ThreadQueue != Wnd->head.pti->MessageQueue )
1061 {
1062 //ERR("ISAW : Must have the same Message Queue\n");
1063 return FALSE;
1064 }
1065
1066 if (!VerifyWnd(Wnd))
1067 {
1068 //ERR("ISAW : Window is in Destroy!\n");
1069 return FALSE;
1070 }
1071
1072 if ( Wnd == pWndChg )
1073 {
1074 //ERR("ISAW : Nothing to do\n");
1075 return TRUE; // Fix CORE-8780 and CORE-11979. See CORE-11324 for breakage.
1076 }
1077
1078 if ( Wnd->state & WNDS_BEINGACTIVATED ) return TRUE;
1079
1080 /* Call CBT hook chain */
1081 cbt.fMouse = bMouse;
1082 cbt.hWndActive = hWndPrev;
1084 {
1085 ERR("SetActiveWindow: WH_CBT Call Hook return!\n");
1086 return FALSE;
1087 }
1088
1089 ThreadQueue->QF_flags &= ~QF_EVENTDEACTIVATEREMOVED;
1090
1091 if ( ThreadQueue->spwndActive && ThreadQueue->spwndActive->state & WNDS_DESTROYED )
1092 ThreadQueue->spwndActive = NULL;
1093 else
1094 ThreadQueue->spwndActivePrev = ThreadQueue->spwndActive;
1095
1096 WndPrev = ThreadQueue->spwndActive; // Keep to save changing active.
1097
1098 if (WndPrev)
1099 {
1100 if (ThreadQueue == gpqForeground) gpqForegroundPrev = ThreadQueue;
1102 }
1103
1104 WndPrev = ThreadQueue->spwndActive; // Again keep to save changing active.
1105
1106 // While in calling message proc or hook:
1107 // Fail if a preemptive switch was made, current active not made previous,
1108 // focus window is dead or no longer the same thread queue.
1109 if ( ThreadQueue->spwndActivePrev != ThreadQueue->spwndActive ||
1110 pWndChg != WndPrev ||
1111 (Wnd && !VerifyWnd(Wnd)) ||
1112 ThreadQueue != pti->MessageQueue )
1113 {
1114 ERR("SetActiveWindow: Summary ERROR, active state changed!\n");
1115 return FALSE;
1116 }
1117
1118 if (!WndPrev) ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;
1119
1120 /* set the current thread active window */
1121 ThreadQueue->spwndActive = Wnd;
1122
1123 // Set state flag to prevent recursions.
1124 Wnd->state |= WNDS_BEINGACTIVATED;
1125
1126 IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
1127
1128 // Clear out activate EVENT messages.
1130
1131 WndPrev = VerifyWnd(ThreadQueue->spwndActivePrev); // Now should be set but verify it again.
1132
1133 InAAPM = co_IntSendActivateMessages(WndPrev, Wnd, bMouse, Async);
1134
1135 /* now change focus if necessary */
1137 if (bFocus && !(ThreadQueue->QF_flags & QF_FOCUSNULLSINCEACTIVE))
1138 {
1139 /* Do not change focus if the window is no longer active */
1140 if (pti->MessageQueue->spwndActive != IntGetNonChildAncestor(pti->MessageQueue->spwndFocus))
1141 {
1142 PWND pWndSend = pti->MessageQueue->spwndActive;
1143 // Clear focus if the active window is minimized.
1144 if (pWndSend && pti->MessageQueue->spwndActive->style & WS_MINIMIZE) pWndSend = NULL;
1145 // Send focus messages and if so, set the focus.
1146 IntSendFocusMessages( pti, pWndSend);
1147 }
1148 }
1150 if (InAAPM)
1151 {
1152 pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
1153 }
1154
1155 // Checked in MENU_TrackMenu
1156 ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE;
1157
1158 //ERR("co_IntSetActiveWindow Exit\n");
1159 Wnd->state &= ~WNDS_BEINGACTIVATED;
1160 return (ThreadQueue->spwndActive == Wnd);
1161}
1162
1163//
1164// Set the Active Window.
1165//
1166// Window is not optional!
1167//
1170 _In_ PWND Wnd,
1171 _In_ BOOL bMouse,
1172 _In_ BOOL bFocus,
1173 _In_ BOOL Async)
1174{
1175 PTHREADINFO pti;
1176 PUSER_MESSAGE_QUEUE ThreadQueue;
1177
1178 //ERR("IntUserSetActiveWindow 1\n");
1179 ASSERT_REFS_CO(Wnd);
1180 if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
1181 //ERR("IntUserSetActiveWindow 1a hWnd 0x%p\n",UserHMGetHandle(Wnd));
1182
1183 //ERR("IntUserSetActiveWindow 2\n");
1185 ThreadQueue = pti->MessageQueue;
1186 ASSERT(ThreadQueue != 0);
1187
1188 while (Wnd)
1189 {
1190 BOOL Ret, DoFG, AllowFG;
1191
1192 if (ThreadQueue == Wnd->head.pti->MessageQueue)
1193 {
1194 if (IsAllowedFGActive(pti, Wnd))
1195 {
1196 DoFG = TRUE;
1197 }
1198 else
1199 {
1200 //ERR("IntUserSetActiveWindow 3 Go Out!\n");
1201 break;
1202 }
1203 AllowFG = !pti->cVisWindows; // Nothing is visable.
1204 //ERR("IntUserSetActiveWindow 3a DoFG = %d AllowFG = %d\n",DoFG,AllowFG);
1205 }
1206 else //if (ThreadQueue != Wnd->head.pti->MessageQueue)
1207 {
1208 //PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
1209 // Rule 1 & 4, We are foreground so set this FG window or NULL foreground....
1210 if (!gpqForeground || gpqForeground == ThreadQueue)
1211 {
1212 DoFG = TRUE;
1213 }
1214 else
1215 DoFG = FALSE;
1216 if (DoFG)
1217 {
1219 AllowFG = TRUE;
1220 else
1221 AllowFG = FALSE;
1222 }
1223 else
1224 AllowFG = FALSE;
1225 //ERR("IntUserSetActiveWindow 3b DoFG = %d AllowFG = %d\n",DoFG,AllowFG);
1226 }
1227 Ret = FALSE;
1228 if (DoFG)
1229 {
1231 //ERR("IntUserSetActiveWindow 3c FG set\n");
1232 Ret = co_IntSetForegroundAndFocusWindow(Wnd, bMouse, TRUE);
1233 if (AllowFG)
1234 {
1236 }
1237 else
1238 {
1239 pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE;
1240 }
1241 }
1242 return Ret;
1243 }
1244
1245 return co_IntSetActiveWindow(Wnd, bMouse, bFocus, Async);
1246}
1247
1250{
1251 TRACE("Mouse Active\n");
1252 if (Wnd && (Wnd->ExStyle & WS_EX_NOACTIVATE))
1253 return TRUE;
1255}
1256
1259{
1261
1262 if (Wnd)
1263 {
1264 if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
1265
1266 return IntUserSetActiveWindow(Wnd, FALSE, TRUE, FALSE);
1267 }
1268 /*
1269 Yes your eye are not deceiving you~!
1270
1271 First part of wines Win.c test_SetActiveWindow:
1272
1273 flush_events( TRUE );
1274 ShowWindow(hwnd, SW_HIDE);
1275 SetFocus(0);
1276 SetActiveWindow(0);
1277 check_wnd_state(0, 0, 0, 0); <-- This should pass if ShowWindow does it's job!!! As of 10/28/2012 it does!
1278
1279 Now Handle wines Msg.c test_SetActiveWindow( 0 )...
1280 */
1281 TRACE("USAW: Previous active window\n");
1282 if ( gpqForegroundPrev &&
1287 {
1288 TRACE("USAW:PAW hwnd %p\n", UserHMGetHandle(Wnd));
1289 return IntUserSetActiveWindow(Wnd, FALSE, TRUE, FALSE);
1290 }
1291
1292 // Activate anyone but the active window.
1293 if ( pti->MessageQueue->spwndActive &&
1294 (Wnd = VerifyWnd(pti->MessageQueue->spwndActive)) != NULL )
1295 {
1296 //ERR("USAW:AOWM hwnd %p\n", UserHMGetHandle(Wnd));
1297 if (!ActivateOtherWindowMin(Wnd))
1298 {
1299 // Okay, now go find someone else to play with!
1300 //ERR("USAW: Going to WPAOW\n");
1302 }
1303 return TRUE;
1304 }
1305
1306 TRACE("USAW: Nothing\n");
1307 return FALSE;
1308}
1309
1312{
1313 HWND hWndPrev = 0;
1314 PWND pwndTop;
1315 PTHREADINFO pti;
1316 PUSER_MESSAGE_QUEUE ThreadQueue;
1317
1318 if (Window)
1320
1322 ThreadQueue = pti->MessageQueue;
1323 ASSERT(ThreadQueue != 0);
1324
1325 TRACE("Enter SetFocus hWnd 0x%p pti 0x%p\n",Window ? UserHMGetHandle(Window) : 0, pti );
1326
1327 hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
1328
1329 if (Window != 0)
1330 {
1331 if (hWndPrev == UserHMGetHandle(Window))
1332 {
1333 return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0; /* Nothing to do */
1334 }
1335
1336 if (Window->head.pti->MessageQueue != ThreadQueue)
1337 {
1338 ERR("SetFocus Must have the same Q!\n");
1339 return 0;
1340 }
1341
1342 /* Check if we can set the focus to this window */
1344 for (pwndTop = Window; pwndTop; pwndTop = pwndTop->spwndParent)
1345 {
1346 if (pwndTop->style & (WS_MINIMIZED|WS_DISABLED)) return 0;
1347 if ((pwndTop->style & (WS_POPUP|WS_CHILD)) != WS_CHILD) break;
1348 if (pwndTop->spwndParent == NULL) break;
1349 }
1352 {
1353 ERR("SetFocus 1 WH_CBT Call Hook return!\n");
1354 return 0;
1355 }
1356
1357 /* Activate pwndTop if needed. */
1358 if (pwndTop != ThreadQueue->spwndActive)
1359 {
1360 PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); // Keep it based on desktop.
1361 if (ThreadQueue != ForegroundQueue && IsAllowedFGActive(pti, pwndTop)) // Rule 2 & 3.
1362 {
1363 //ERR("SetFocus: Set Foreground!\n");
1364 if (!(pwndTop->style & WS_VISIBLE))
1365 {
1366 pti->ppi->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE;
1367 }
1369 {
1370 ERR("SetFocus: Set Foreground and Focus Failed!\n");
1371 return 0;
1372 }
1373 }
1374
1375 /* Set Active when it is needed. */
1376 if (pwndTop != ThreadQueue->spwndActive)
1377 {
1378 //ERR("SetFocus: Set Active! %p\n",pwndTop?UserHMGetHandle(pwndTop):0);
1379 if (!co_IntSetActiveWindow(pwndTop, FALSE, FALSE, FALSE))
1380 {
1381 ERR("SetFocus: Set Active Failed!\n");
1382 return 0;
1383 }
1384 }
1385
1386 /* Abort if window destroyed */
1387 if (Window->state2 & WNDS2_INDESTROY) return 0;
1388 /* Do not change focus if the window is no longer active */
1389 if (pwndTop != ThreadQueue->spwndActive)
1390 {
1391 ERR("SetFocus: Top window did not go active!\n");
1392 return 0;
1393 }
1394 }
1395
1396 // Check again! SetActiveWindow could have set the focus via WM_ACTIVATE.
1397 hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
1398
1400
1401 TRACE("Focus: %p -> %p\n", hWndPrev, UserHMGetHandle(Window));
1402 }
1403 else /* NULL hwnd passed in */
1404 {
1405 if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev))
1406 {
1407 ERR("SetFocus: 2 WH_CBT Call Hook return!\n");
1408 return 0;
1409 }
1410 //ERR("SetFocus: Set Focus NULL\n");
1411 /* set the current thread focus window null */
1413 }
1414 return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0;
1415}
1416
1419{
1420 PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
1421 if (!ForegroundQueue)
1422 return NULL;
1423 return (ForegroundQueue->spwndActive ? UserHMGetHandle(ForegroundQueue->spwndActive) : NULL);
1424}
1425
1427{
1429 PUSER_MESSAGE_QUEUE ThreadQueue = pti->MessageQueue;
1430 if (!ThreadQueue)
1431 return NULL;
1432 return (ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : NULL);
1433}
1434
1437{
1438 PTHREADINFO pti;
1439 PUSER_MESSAGE_QUEUE ThreadQueue;
1440 HWND Ret;
1441
1442 TRACE("Enter IntGetCapture\n");
1443
1445 ThreadQueue = pti->MessageQueue;
1446 Ret = ((ThreadQueue && ThreadQueue->spwndCapture) ? UserHMGetHandle(ThreadQueue->spwndCapture) : NULL);
1447
1448 TRACE("Leave IntGetCapture, ret=%p\n", Ret);
1449 return Ret;
1450}
1451
1454{
1455 PTHREADINFO pti;
1456 PUSER_MESSAGE_QUEUE ThreadQueue;
1457 PWND pWnd, Window = NULL;
1458 HWND hWndPrev;
1459
1461 ThreadQueue = pti->MessageQueue;
1462
1463 if (ThreadQueue->QF_flags & QF_CAPTURELOCKED)
1464 return NULL;
1465
1466 if (hWnd && (Window = UserGetWindowObject(hWnd)))
1467 {
1468 if (Window->head.pti->MessageQueue != ThreadQueue)
1469 {
1470 ERR("Window Thread does not match Current!\n");
1471 return NULL;
1472 }
1473 }
1474
1475 hWndPrev = MsqSetStateWindow(pti, MSQ_STATE_CAPTURE, hWnd);
1476
1477 if (hWndPrev)
1478 {
1479 pWnd = UserGetWindowObject(hWndPrev);
1480 if (pWnd)
1481 IntNotifyWinEvent(EVENT_SYSTEM_CAPTUREEND, pWnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
1482 }
1483
1484 if (Window)
1485 IntNotifyWinEvent(EVENT_SYSTEM_CAPTURESTART, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
1486
1487 //
1488 // Only send the message if we have a previous Window!
1489 // Fix msg_menu tracking popup menu and win test_capture_4!!!!
1490 //
1491 if (hWndPrev)
1492 {
1493 if (ThreadQueue->MenuOwner && Window) ThreadQueue->QF_flags |= QF_CAPTURELOCKED;
1494
1496
1497 ThreadQueue->QF_flags &= ~QF_CAPTURELOCKED;
1498 }
1499
1500 if (hWnd == NULL) // Release mode.
1501 {
1502 MOUSEINPUT mi;
1504 /* Also remove other windows if not capturing anymore */
1508 /* Somebody may have missed some mouse movements */
1509 mi.dx = 0;
1510 mi.dy = 0;
1511 mi.mouseData = 0;
1513 mi.time = 0;
1514 mi.dwExtraInfo = 0;
1516 }
1517 return hWndPrev;
1518}
1519
1520/*
1521 API Call
1522*/
1523BOOL
1526{
1527 PTHREADINFO pti;
1528 PUSER_MESSAGE_QUEUE ThreadQueue;
1529
1531 ThreadQueue = pti->MessageQueue;
1532
1533 // Can not release inside WM_CAPTURECHANGED!!
1534 if (ThreadQueue->QF_flags & QF_CAPTURELOCKED) return FALSE;
1535
1537
1538 return TRUE;
1539}
1540
1541/*
1542 API Call
1543*/
1546{
1548
1550}
1551
1552/*
1553 API Call
1554*/
1557{
1559
1561}
1562
1563/*
1564 API Call
1565*/
1568{
1571 switch (uLockCode)
1572 {
1573 case LSFW_LOCK:
1574 if ( CanForceFG(ppi) && !gppiLockSFW )
1575 {
1576 gppiLockSFW = ppi;
1577 return TRUE;
1578 }
1579 break;
1580 case LSFW_UNLOCK:
1581 if ( gppiLockSFW == ppi)
1582 {
1583 gppiLockSFW = NULL;
1584 return TRUE;
1585 }
1586 break;
1587 default:
1589 }
1590 EngSetLastError(Err);
1591 return FALSE;
1592}
1593
1594/*
1595 API Call
1596*/
1599{
1600 PPROCESSINFO ppi, ppiCur;
1602
1603 ppi = NULL;
1604 if (dwProcessId != ASFW_ANY)
1605 {
1607 {
1609 return FALSE;
1610 }
1612 if (!ppi)
1613 {
1615 return FALSE;
1616 }
1617 }
1619 if (!CanForceFG(ppiCur))
1620 {
1623 return FALSE;
1624 }
1625 if (dwProcessId == ASFW_ANY)
1626 { // All processes will be enabled to set the foreground window.
1627 //ERR("ptiLastInput is CLEARED!!\n");
1629 }
1630 else
1631 { // Rule #3, last input event in force.
1632 ERR("ptiLastInput is SET!!\n");
1633 //ptiLastInput = ppi->ptiList; // See CORE-6384 & CORE-7030.
1635 }
1636 return TRUE;
1637}
1638
1639/*
1640 * @implemented
1641 */
1644{
1645 HWND Ret;
1646
1647 TRACE("Enter NtUserGetForegroundWindow\n");
1649
1651
1652 TRACE("Leave NtUserGetForegroundWindow, ret=%p\n", Ret);
1653 UserLeave();
1654 return Ret;
1655}
1656
1659{
1661 HWND hWndPrev;
1662 PWND Window, pwndPrev;
1663 HWND Ret = NULL;
1664
1665 TRACE("Enter NtUserSetActiveWindow(%p)\n", hWnd);
1667
1668 Window = NULL;
1669 if (hWnd)
1670 {
1672 {
1673 ERR("NtUserSetActiveWindow: Invalid handle 0x%p!\n",hWnd);
1674 goto Exit; // Return NULL
1675 }
1676 }
1677
1678 if (!Window ||
1679 Window->head.pti->MessageQueue == gptiCurrent->MessageQueue)
1680 {
1681 pwndPrev = gptiCurrent->MessageQueue->spwndActive;
1682 hWndPrev = (pwndPrev ? UserHMGetHandle(pwndPrev) : NULL);
1683 if (Window) UserRefObjectCo(Window, &Ref);
1686 Ret = ((hWndPrev && IntIsWindow(hWndPrev)) ? hWndPrev : NULL);
1687 }
1688
1689Exit:
1690 TRACE("Leave NtUserSetActiveWindow, ret=%p\n", Ret);
1691 UserLeave();
1692 return Ret;
1693}
1694
1695/*
1696 * @implemented
1697 */
1700{
1701 HWND Ret;
1702
1703 TRACE("Enter NtUserSetCapture(%p)\n", hWnd);
1705
1706 Ret = co_UserSetCapture(hWnd);
1707
1708 TRACE("Leave NtUserSetCapture, ret=%p\n", Ret);
1709 UserLeave();
1710 return Ret;
1711}
1712
1713/*
1714 * @implemented
1715 */
1718{
1719 PWND Window;
1721 HWND ret = NULL;
1722
1723 TRACE("Enter NtUserSetFocus(%p)\n", hWnd);
1725
1726 if (hWnd)
1727 {
1729 {
1730 ERR("NtUserSetFocus: Invalid handle 0x%p!\n",hWnd);
1731 goto Exit; // Return NULL
1732 }
1733
1734 UserRefObjectCo(Window, &Ref);
1737 }
1738 else
1739 {
1741 }
1742
1743Exit:
1744 TRACE("Leave NtUserSetFocus, ret=%p\n", ret);
1745 UserLeave();
1746 return ret;
1747}
1748
1749/* 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
struct @1767 Msg[]
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#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:1658
BOOL FASTCALL co_IntMouseActivateWindow(PWND Wnd)
Definition: focus.c:1249
BOOL FASTCALL FindRemoveEventMsg(PTHREADINFO pti, DWORD Event, DWORD EventLast)
Definition: focus.c:678
BOOL FASTCALL IntDeactivateWindow(PTHREADINFO pti, HANDLE tid)
Definition: focus.c:188
BOOL FASTCALL IntLockSetForegroundWindow(UINT uLockCode)
Definition: focus.c:1567
HWND APIENTRY NtUserSetCapture(HWND hWnd)
Definition: focus.c:1699
BOOL FASTCALL CanForceFG(PPROCESSINFO ppi)
Definition: focus.c:748
BOOL FASTCALL co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd, BOOL Clear)
Definition: focus.c:117
BOOL FASTCALL IntAllowSetForegroundWindow(DWORD dwProcessId)
Definition: focus.c:1598
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:43
HWND FASTCALL co_UserSetFocus(PWND Window)
Definition: focus.c:1311
BOOL FASTCALL ToggleFGActivate(PTHREADINFO pti)
Definition: focus.c:709
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:1258
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:729
BOOL FASTCALL co_IntMakeWindowActive(PWND Window)
Definition: focus.c:426
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:1643
HWND FASTCALL co_UserSetCapture(HWND hWnd)
Definition: focus.c:1453
HWND APIENTRY IntGetCapture(VOID)
Definition: focus.c:1436
VOID FASTCALL UpdateShellHook(PWND Window)
Definition: focus.c:98
VOID FASTCALL IntSendFocusMessages(PTHREADINFO pti, PWND pWnd)
Definition: focus.c:614
BOOL FASTCALL co_IntSetForegroundWindow(PWND Window)
Definition: focus.c:1545
BOOL FASTCALL co_IntSetForegroundMessageQueue(_In_opt_ PWND Wnd, _In_ PTHREADINFO pti, _In_ BOOL MouseActivate, _In_ DWORD Type)
Definition: focus.c:766
BOOL FASTCALL IntReleaseCapture(VOID)
Definition: focus.c:1525
BOOL FASTCALL co_IntSetForegroundWindowMouse(PWND Window)
Definition: focus.c:1556
HWND APIENTRY NtUserSetFocus(HWND hWnd)
Definition: focus.c:1717
BOOL FASTCALL co_IntSetActiveWindow(_In_ PWND Wnd, _In_ BOOL bMouse, _In_ BOOL bFocus, _In_ BOOL Async)
Definition: focus.c:1023
PTHREADINFO ptiLastInput
Definition: focus.c:18
HWND FASTCALL UserGetActiveWindow(VOID)
Definition: focus.c:1426
static BOOL FASTCALL co_IntSetForegroundAndFocusWindow(_In_opt_ PWND Wnd, _In_ BOOL MouseActivate, _In_ BOOL bFlash)
Definition: focus.c:923
VOID IntFocusSetInputContext(PWND pWnd, BOOL bActivate, BOOL bCallback)
Definition: focus.c:148
PUSER_MESSAGE_QUEUE gpqForegroundPrev
Definition: focus.c:14
HWND FASTCALL UserGetForegroundWindow(VOID)
Definition: focus.c:1418
BOOL FASTCALL IntUserSetActiveWindow(_In_ PWND Wnd, _In_ BOOL bMouse, _In_ BOOL bFocus, _In_ BOOL Async)
Definition: focus.c:1169
_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:58
#define IMS_IMEDEACTIVATE
Definition: imm32_undoc.h:59
#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:9400
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:255
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
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
Entry
Definition: section.c:5210
static void Exit(void)
Definition: sock.c:1330
#define TRACE(s)
Definition: solgame.cpp:4
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:3895
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:123
#define ASSERT_REFS_CO(_obj_)
Definition: userfuncs.h:13
_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:97
PWND FASTCALL UserGetDesktopWindow(VOID)
Definition: desktop.c:1402
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:1704
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:209
PMONITOR NTAPI UserGetPrimaryMonitor(VOID)
Definition: monitor.c:102
#define USERTAG_WINDOWLIST
Definition: tags.h:298
HWND *FASTCALL IntWinListChildren(PWND Window)
Definition: window.c:275
PWND FASTCALL VerifyWnd(PWND pWnd)
Definition: window.c:88
BOOL FASTCALL IntIsWindow(HWND hWnd)
Definition: window.c:177
BOOL FASTCALL IntIsWindowVisible(PWND Wnd)
Definition: window.c:190
PWND FASTCALL IntGetNonChildAncestor(PWND pWnd)
Definition: window.c:352
#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:21
struct _RECTL * LPRECTL
#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 WM_QUERYNEWPALETTE
Definition: winuser.h:1906
#define HSHELL_RUDEAPPACTIVATED
Definition: winuser.h:1292
#define MAKEWPARAM(l, h)
Definition: winuser.h:4117
#define SWP_NOACTIVATE
Definition: winuser.h:1253
#define MAKELPARAM(l, h)
Definition: winuser.h:4116
#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