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