ReactOS  0.4.14-dev-608-gd495a4f
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 DBG_DEFAULT_CHANNEL(UserFocus);
11 
16 ULONG guSFWLockCount = 0; // Rule #8, No menus are active. So should be zero.
18 
19 /*
20  Check locking of a process or one or more menus are active.
21 */
24 {
25  return (gppiLockSFW || guSFWLockCount);
26 }
27 
28 /*
29  Get capture window via foreground Queue.
30 */
33 {
34  PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
35  return ( ForegroundQueue ? (ForegroundQueue->spwndCapture ? UserHMGetHandle(ForegroundQueue->spwndCapture) : 0) : 0);
36 }
37 
40 {
41  PTHREADINFO pti;
42  PUSER_MESSAGE_QUEUE ThreadQueue;
43 
45  ThreadQueue = pti->MessageQueue;
46  if (!ThreadQueue)
47  return NULL;
48  return ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
49 }
50 
53 {
54  if ( Window->spwndParent == UserGetDesktopWindow() &&
55  Window->spwndOwner == NULL &&
56  (!(Window->ExStyle & WS_EX_TOOLWINDOW) ||
57  (Window->ExStyle & WS_EX_APPWINDOW)))
58  {
59  // FIXME lParam; The value is TRUE if the window is in full-screen mode, or FALSE otherwise.
60  co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (WPARAM) UserHMGetHandle(Window), FALSE);
61  }
62  else
63  {
64  co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, 0, FALSE);
65  }
66 }
67 
70 {
71  USER_REFERENCE_ENTRY RefPrev;
72  PWND WndPrev;
73  BOOL Ret = TRUE;
74  LPARAM lParam = hWnd ? (LPARAM)hWnd : 0;
75 
76  if (hWndPrev && (WndPrev = ValidateHwndNoErr(hWndPrev)))
77  {
78  UserRefObjectCo(WndPrev, &RefPrev);
79 
81  {
83  MAKEWPARAM(WA_INACTIVE, (WndPrev->style & WS_MINIMIZE) != 0),
84  (LPARAM)hWnd);
85 
86  if (WndPrev && Clear)
87  WndPrev->state &= ~(WNDS_ACTIVEFRAME|WNDS_HASCAPTION);
88  }
89  else
90  {
91  ERR("Application is keeping itself Active to prevent the change!\n");
92  Ret = FALSE;
93  }
94 
95  UserDerefObjectCo(WndPrev);
96  }
97  return Ret;
98 }
99 
100 //
101 // Deactivating the foreground message queue.
102 //
103 // Release Active, Capture and Focus Windows associated with this message queue.
104 //
107 {
109  PTHREADINFO ptiPrev;
110  PWND pwndPrev;
111  BOOL InAAPM = FALSE;
113 
114  if ( !pti->MessageQueue->spwndActive )
115  {
116  TRACE("IDAW E : Nothing to do, Active is NULL! pti 0x%p tid 0x%p\n",pti,tid);
117  return TRUE;
118  }
119 
120  TRACE("IDAW : pti 0x%p tid 0x%p\n",pti,tid);
121 
122  if (ptiCurrent != pti)
123  {
125  IntReferenceThreadInfo(ptiCurrent);
126  }
127 
128  if (!(pti->TIF_flags & TIF_INACTIVATEAPPMSG) )
129  {
131  InAAPM = TRUE;
132  }
133 
134  //
135  // Check for Capture and release it.
136  //
137  if ( pti->MessageQueue->spwndCapture )
138  {
139  MSG msg;
140  PWND pwndCapture = pti->MessageQueue->spwndCapture;
141 
142  UserRefObjectCo(pwndCapture, &Ref);
143  co_IntSendMessage(UserHMGetHandle(pwndCapture), WM_CANCELMODE, 0, 0);
144  UserDerefObjectCo(pwndCapture);
145 
146  /* Generate mouse move message */
147  msg.message = WM_MOUSEMOVE;
148  msg.wParam = UserGetMouseButtonsState();
149  msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y);
150  msg.pt = gpsi->ptCursor;
152  }
153 
154  //
155  // Check for Active and release it.
156  //
157  if ( pti->MessageQueue->spwndActive )
158  {
159  pwndPrev = pti->MessageQueue->spwndActive;
160  ptiPrev = pwndPrev->head.pti;
161 
163  {
164  if (InAAPM) pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
165  if (ptiCurrent != pti)
166  {
168  IntDereferenceThreadInfo(ptiCurrent);
169  }
170  return FALSE;
171  }
172 
173  if ( pti->MessageQueue->spwndActive == pwndPrev )
174  {
175  pti->MessageQueue->spwndActivePrev = pwndPrev;
176  pti->MessageQueue->spwndActive = NULL;
177  }
178 
179  if (ptiPrev->TIF_flags & TIF_INCLEANUP) ptiPrev = NULL;
180  }
181  else
182  {
183  ptiPrev = pti;
184  pwndPrev = (PWND)-1; // Avoid zero Active window.
185  }
186 
187  if ( ptiPrev )
188  {
189  HANDLE OldTID = PsGetThreadId(ptiPrev->pEThread);
190  PWND cWindow;
191  HWND *List, *phWnd;
192 
194  if ( List )
195  {
196  if ( OldTID )
197  {
198  for (phWnd = List; *phWnd; ++phWnd)
199  {
200  cWindow = ValidateHwndNoErr(*phWnd);
201  if ( cWindow && cWindow->head.pti == ptiPrev )
202  { // FALSE if the window is being deactivated,
203  // ThreadId that owns the window being activated.
204  //ERR("IDW : WM_ACTIVATEAPP(0) hwnd %p tid Old %p New %p\n",UserHMGetHandle(cWindow),OldTID,tid);
205  UserRefObjectCo(cWindow, &Ref);
207  UserDerefObjectCo(cWindow);
208  }
209  }
210  }
212  }
213  }
214 
215  //
216  // Now check for a change (Bounce), if Active same as previous window, release it too.
217  //
218  if ( pti->MessageQueue->spwndActive == pwndPrev )
219  {
221  {
222  if (InAAPM) pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
223  if (ptiCurrent != pti)
224  {
226  IntDereferenceThreadInfo(ptiCurrent);
227  }
228  return FALSE;
229  }
230 
231  if ( pti->MessageQueue->spwndActive == pwndPrev )
232  {
233  pti->MessageQueue->spwndActivePrev = pwndPrev;
234  pti->MessageQueue->spwndActive = NULL;
235  }
236  }
237 
238  //
239  // Check for Focus and release it.
240  //
241  if ( pti->MessageQueue->spwndFocus )
242  {
243  PWND pwndFocus = pti->MessageQueue->spwndFocus;
244 
245  //
246  // Fix win.c:test_SetForegroundWindow:SetActiveWindow(0)!
247  //
248  pti->MessageQueue->spwndFocus = NULL; // Null out Focus.
249 
250  UserRefObjectCo(pwndFocus, &Ref);
252  UserDerefObjectCo(pwndFocus);
253  }
254 
255  if (InAAPM) pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
256  if (ptiCurrent != pti)
257  {
259  IntDereferenceThreadInfo(ptiCurrent);
260  }
261  return TRUE;
262 }
263 
264 //
265 // Activating another threads foreground window after a switch.
266 //
269 {
272 
273  if (Wnd)
274  {
275  Wnd = VerifyWnd(Wnd);
276 
277  if (!Wnd) return;
278 
279  UserRefObjectCo(Wnd, &Ref);
280 
281  if (!gpqForeground)
282  {
283  // No foreground queue set.
284  co_IntSetForegroundMessageQueue( Wnd, pti, (BOOL)Type, 0);
285  }
286  else
287  {
288  // Same Active and Wnd.
289  if ( pmq->spwndActive == Wnd )
290  {
291  WPARAM wParam = (Wnd->head.pti->MessageQueue == gpqForeground);
292 
294 
295  if (wParam)
296  {
297  UpdateShellHook(Wnd);
298 
300  }
301  }
302  else // Not the same, set the active Wnd.
303  {
305  }
306  }
307  UserDerefObjectCo(Wnd);
308  }
309  else // Handle no Wnd!
310  {
311  if ( tid && // TID,
312  pmq->spwndActive && // Active WND not zero,
313  gpqForeground == pmq ) // Same message queues.
314  {
315  Wnd = pmq->spwndActive; // Use active window from current queue.
316 
317  UserRefObjectCo(Wnd, &Ref);
318 
320 
321  UpdateShellHook(Wnd);
322 
324 
325  UserDerefObjectCo(Wnd);
326  }
327  else if (gpqForeground != pmq)
328  {
329  // Not the same message queue so clear flags for foreground switching.
331  pti->ppi->W32PF_flags &= ~W32PF_ALLOWFOREGROUNDACTIVATE;
332  }
333  }
334 }
335 
338 {
339  PWND spwndOwner;
340  if (VerifyWnd(Window))
341  { // Set last active for window and it's owner.
342  spwndOwner = Window;
343  while (spwndOwner->spwndOwner)
344  {
345  spwndOwner = spwndOwner->spwndOwner;
346  }
347  spwndOwner->spwndLastActive = Window;
348  return TRUE;
349  }
350  ERR("MakeWindowActive Failed!\n");
351  return FALSE;
352 }
353 
355 co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOOL Async)
356 {
357  USER_REFERENCE_ENTRY Ref, RefPrev, RefCall;
358  HANDLE OldTID, NewTID;
359  PTHREADINFO pti, ptiOld, ptiNew;
360  BOOL InAAPM = FALSE;
361 
362  //ERR("SendActivateMessages\n");
363 
365 
366  if (Window)
367  {
368  UserRefObjectCo(Window, &Ref);
369 
370  if (WindowPrev) UserRefObjectCo(WindowPrev, &RefPrev);
371 
372  pti->MessageQueue->QF_flags &= ~QF_EVENTDEACTIVATEREMOVED;
373 
374  /* Send palette messages */
375  if (gpsi->PUSIFlags & PUSIF_PALETTEDISPLAY &&
376  //co_IntPostOrSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
378  {
382  0);
383  }
385  if (!(Window->style & WS_CHILD))
386  {
388 
389  while (pwndTemp && !(pwndTemp->style & WS_VISIBLE)) pwndTemp = pwndTemp->spwndNext;
390 
391  if (Window != pwndTemp || (WindowPrev && !IntIsWindowVisible(WindowPrev)))
392  {
393  if (!Async || pti->MessageQueue == gpqForeground)
394  {
396  if (Window == pwndTemp) flags |= SWP_NOACTIVATE;
397  //ERR("co_IntSendActivateMessages SetWindowPos! Async %d pti Q == FGQ %d\n",Async,pti->MessageQueue == gpqForeground);
399  }
400  }
401  }
404  if (Window->spwndPrev)
405  {
406  HWND *phwndTopLevel, *phwndCurrent;
407  PWND pwndCurrent, pwndDesktop;
408 
409  pwndDesktop = co_GetDesktopWindow(Window);//UserGetDesktopWindow();
410  if (Window->spwndParent == pwndDesktop )
411  {
412  phwndTopLevel = IntWinListChildren(pwndDesktop);
413  phwndCurrent = phwndTopLevel;
414  while(*phwndCurrent)
415  {
416  pwndCurrent = UserGetWindowObject(*phwndCurrent);
417 
418  if (pwndCurrent && pwndCurrent->spwndOwner == Window )
419  {
421  }
422  phwndCurrent++;
423  }
424  ExFreePoolWithTag(phwndTopLevel, USERTAG_WINDOWLIST);
425  }
426  }
428  }
429 
430  OldTID = WindowPrev ? IntGetWndThreadId(WindowPrev) : NULL;
431  NewTID = Window ? IntGetWndThreadId(Window) : NULL;
432  ptiOld = WindowPrev ? WindowPrev->head.pti : NULL;
433  ptiNew = Window ? Window->head.pti : NULL;
434 
435  //ERR("SendActivateMessage Old -> %x, New -> %x\n", OldTID, NewTID);
436 
437  if (!(pti->TIF_flags & TIF_INACTIVATEAPPMSG) &&
438  (OldTID != NewTID) )
439  {
440  PWND cWindow;
441  HWND *List, *phWnd;
442 
444  if ( List )
445  {
446  if ( OldTID )
447  {
448  ptiOld->TIF_flags |= TIF_INACTIVATEAPPMSG;
449  // Note: Do not set pci flags, this does crash!
450  for (phWnd = List; *phWnd; ++phWnd)
451  {
452  cWindow = ValidateHwndNoErr(*phWnd);
453  if (cWindow && cWindow->head.pti == ptiOld)
454  { // FALSE if the window is being deactivated,
455  // ThreadId that owns the window being activated.
456  //ERR("SAM : WM_ACTIVATEAPP(0) tid Old %p New %p\n",OldTID,NewTID);
457  UserRefObjectCo(cWindow, &RefCall);
458  co_IntSendMessage(*phWnd, WM_ACTIVATEAPP, FALSE, (LPARAM)NewTID);
459  UserDerefObjectCo(cWindow);
460  }
461  }
462  ptiOld->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
463  }
464  if ( NewTID )
465  {
466  InAAPM = TRUE;
469  for (phWnd = List; *phWnd; ++phWnd)
470  {
471  cWindow = ValidateHwndNoErr(*phWnd);
472  if (cWindow && cWindow->head.pti == ptiNew)
473  { // TRUE if the window is being activated,
474  // ThreadId that owns the window being deactivated.
475  //ERR("SAM : WM_ACTIVATEAPP(1) hwnd %p tid New %p Old %p\n",UserHMGetHandle(cWindow),NewTID,OldTID);
476  UserRefObjectCo(cWindow, &RefCall);
477  co_IntSendMessage(*phWnd, WM_ACTIVATEAPP, TRUE, (LPARAM)OldTID);
478  UserDerefObjectCo(cWindow);
479  }
480  }
481  }
483  }
484  }
485 
486  if (Window)
487  {
488  if (WindowPrev)
489  UserDerefObjectCo(WindowPrev); // Now allow the previous window to die.
490 
491  if (Window->state & WNDS_ACTIVEFRAME)
492  { // If already active frame do not allow NCPaint.
493  //ERR("SendActivateMessage Is Active Frame!\n");
494  Window->state |= WNDS_NONCPAINT;
495  }
496 
497  if (Window->style & WS_MINIMIZE)
498  {
499  TRACE("Widow was minimized\n");
500  }
501 
503 
507  0);
508 
510  WM_ACTIVATE,
511  MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE, (Window->style & WS_MINIMIZE) != 0),
512  (LPARAM)(WindowPrev ? UserHMGetHandle(WindowPrev) : 0));
513 
515 
516  Window->state &= ~WNDS_NONCPAINT;
517 
519  }
520  return InAAPM;
521 }
522 
525 {
526  PWND pWndPrev;
527  PUSER_MESSAGE_QUEUE ThreadQueue = pti->MessageQueue; // Queue can change...
528 
529  ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;
530  if (!pWnd && ThreadQueue->spwndActive)
531  {
532  ThreadQueue->QF_flags |= QF_FOCUSNULLSINCEACTIVE;
533  }
534 
535  pWndPrev = ThreadQueue->spwndFocus;
536 
537  /* check if the specified window can be set in the input data of a given queue */
538  if (!pWnd || ThreadQueue == pWnd->head.pti->MessageQueue)
539  /* set the current thread focus window */
540  ThreadQueue->spwndFocus = pWnd;
541 
542  if (pWnd)
543  {
544  if (pWndPrev)
545  {
547  }
548  if (ThreadQueue->spwndFocus == pWnd)
549  {
550  IntNotifyWinEvent(EVENT_OBJECT_FOCUS, pWnd, OBJID_CLIENT, CHILDID_SELF, 0);
551 
552  co_IntSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)(pWndPrev ? UserHMGetHandle(pWndPrev) : NULL), 0);
553  }
554  }
555  else
556  {
557  if (pWndPrev)
558  {
559  IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
560 
562  }
563  }
564 }
565 
568 {
571  BOOL Ret = FALSE;
572 
574  while (Entry != &pti->PostedMessagesListHead)
575  {
576  // Scan posted queue messages to see if we received async messages.
578  Entry = Entry->Flink;
579 
580  if (Message->dwQEvent == EventLast)
581  {
582  //ERR("Event D/SAW: Last Activate/Deactivate %d\n", EventLast);
583  return Ret;
584  }
585 
586  if (Message->dwQEvent == Event)
587  {
588  //ERR("Event D/SAW: Found one in the Post Msg Queue! Activate/Deactivate %d\n", Event);
589  ClearMsgBitsMask(pti, Message->QS_Flags);
591  Ret = TRUE;
592  }
593  }
594  return Ret;
595 }
596 
599 {
600  BOOL Ret;
601  PPROCESSINFO ppi = pti->ppi;
602 
603  Ret = !!(pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE);
604  if (Ret)
605  {
607  }
608  else
609  Ret = !!(ppi->W32PF_flags & W32PF_ALLOWFOREGROUNDACTIVATE);
610 
611  if (Ret)
612  ppi->W32PF_flags &= ~W32PF_ALLOWFOREGROUNDACTIVATE;
613  //ERR("ToggleFGActivate is %d\n",Ret);
614  return Ret;
615 }
616 
619 {
620  // Not allowed if one or more,,
621  if (!ToggleFGActivate(pti) || // bits not set,
622  pti->rpdesk != gpdeskInputDesktop || // not current Desktop,
623  pti->MessageQueue == gpqForeground || // if already the queue foreground,
624  IsFGLocked() || // foreground is locked,
625  Wnd->ExStyle & WS_EX_NOACTIVATE ) // or,,, does not become the foreground window when the user clicks it.
626  {
627  return FALSE;
628  }
629  //ERR("IsAllowedFGActive is TRUE\n");
630  return TRUE;
631 }
632 
633 /*
634  Can the system force foreground from one or more conditions.
635  */
638 {
639  if (!ptiLastInput ||
640  ptiLastInput->ppi == ppi ||
641  !gptiForeground ||
642  gptiForeground->ppi == ppi ||
644  gppiInputProvider == ppi ||
646  ) return TRUE;
647  //ERR("CanForceFG is FALSE\n");
648  return FALSE;
649 }
650 
651 //
652 // Switching out foreground message queues.
653 //
656  _In_opt_ PWND Wnd,
657  _In_ PTHREADINFO pti,
658  _In_ BOOL MouseActivate,
659  _In_ DWORD Type )
660 {
661  PTHREADINFO ptiChg, ptiPrev;
662  PUSER_MESSAGE_QUEUE pumq, pumqChg, pumqPrev;
663  BOOL Removed, Ret = TRUE;
664 
665  if (Wnd && !VerifyWnd(Wnd))
666  {
667  return FALSE;
668  }
669 
671  ptiPrev = NULL;
672  else
673  ptiPrev = gptiForeground;
674 
675  if (Wnd)
676  {
677  ptiChg = Wnd->head.pti;
678  IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue);
679  gptiForeground = Wnd->head.pti;
680  //ERR("Set Foreground pti 0x%p Q 0x%p hWnd 0x%p\n",Wnd->head.pti, Wnd->head.pti->MessageQueue,Wnd->head.h);
681  }
682  else
683  {
684  ptiChg = NULL;
687  //ERR("Set Foreground pti 0x0 Q 0x0 hWnd 0x0\n");
688  }
689 
690  //
691  // Process the changing out of the message queues.
692  //
694  {
695  pumqPrev = NULL;
696  if ( ptiPrev && !(ptiPrev->TIF_flags & TIF_INCLEANUP) )
697  {
698  pumqPrev = ptiPrev->MessageQueue;
699  }
700 
701  pumq = pti ? pti->MessageQueue : NULL;
702 
703  // Deactivate the previous message queue.
704  if (pumqPrev)
705  {
706  if ( pumq != pumqPrev )
707  {
708  MSG Msg;
709  HWND hWndPrev = pumqPrev->spwndActive ? UserHMGetHandle(pumqPrev->spwndActive) : NULL;
710  HANDLE tid = gptiForeground ? PsGetThreadId(gptiForeground->pEThread) : NULL; // TID from changing Window PTI.
711 
712  Msg.message = WM_ASYNC_SETACTIVEWINDOW;
713  Msg.hwnd = hWndPrev;
714  Msg.wParam = (WPARAM)pumqPrev->spwndActive;
715  Msg.lParam = 0;
716  Msg.time = 0;
717  //ERR("SFWAMQ : DAW P pti 0x%p tid 0x%p hWndPrev 0x%p\n",ptiPrev,tid,hWndPrev);
719  }
720  }
721 
722  pumqChg = NULL;
723  if ( ptiChg && !(ptiChg->TIF_flags & TIF_INCLEANUP) )
724  {
725  pumqChg = ptiChg->MessageQueue;
726  }
727 
728  pumq = pti ? pti->MessageQueue : NULL;
729 
730  // Activate changing message queue.
731  if (pumqChg)
732  {
733  /*
734  Henri Verbeet,
735  What happens is that we get the WM_WINE_SETACTIVEWINDOW message sent by the
736  other thread after we already changed the foreground window back to our own
737  window.
738  */
739  //ERR("SFWAMQ : 1\n");
741 
742  if (pumqChg != pumq)
743  {
744  MSG Msg;
745  HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
746  HANDLE tid = ptiPrev ? PsGetThreadId(ptiPrev->pEThread) : NULL;
747 
748  if (Removed) pumqChg->QF_flags |= QF_EVENTDEACTIVATEREMOVED;
749 
750  Msg.message = WM_ASYNC_SETACTIVEWINDOW;
751  Msg.hwnd = hWnd;
752  Msg.wParam = (WPARAM)Wnd;
753  Msg.lParam = (LPARAM)tid;
754  Msg.time = 0;
755  //ERR("SFWAMQ : SAW P pti 0x%p tid 0x%p hWnd 0x%p\n",ptiChg,tid,hWnd);
756  MsqPostMessage(ptiChg, &Msg, FALSE, QS_EVENT, POSTEVENT_SAW, (LONG_PTR)Type|MouseActivate);
757  }
758  else // Current message queue same as changed message queue.
759  {
760  if (pumq->spwndActive == Wnd)
761  {
763 
764  UpdateShellHook(Wnd);
765 
767  }
768  else
769  {
770  //ERR("SFWAMQ : SAW I pti 0x%p hWnd 0x%p\n",ptiChg,Wnd->head.h);
771  Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE/*Type*/, FALSE);
772  //if (!Ret) ERR("SFWAMQ : ISAW : return error\n");
773  return Ret;
774  }
775  }
776  }
777 
778  // Handle same message queue after switch out.
779  pumqPrev = NULL;
780  if ( ptiPrev && !(ptiPrev->TIF_flags & TIF_INCLEANUP) )
781  {
782  pumqPrev = ptiPrev->MessageQueue;
783  }
784  pumq = pti ? pti->MessageQueue : NULL;
785 
786  if ( pumqPrev && pumq == pumqPrev )
787  {
788  HANDLE tid = Wnd ? PsGetThreadId(Wnd->head.pti->pEThread) : NULL;
789  //ERR("SFWAMQ : DAW I pti 0x%p tid 0x%p hWnd 0x%p\n",ptiPrev,tid,Wnd ? Wnd->head.h : 0);
790  IntDeactivateWindow(pti, tid);
791  }
792  }
793  return Ret;
794 }
795 
796 /*
797  MSDN:
798  The system restricts which processes can set the foreground window. A process
799  can set the foreground window only if one of the following conditions is true:
800 
801  * The process is the foreground process.
802  * The process was started by the foreground process.
803  * The process received the last input event.
804  * There is no foreground process.
805  * The foreground process is being debugged.
806  * The foreground is not locked (see LockSetForegroundWindow).
807  * The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
808  * No menus are active.
809 */
810 static
813  _In_opt_ PWND Wnd,
814  _In_ BOOL MouseActivate,
815  _In_ BOOL bFlash )
816 {
817  HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
818  PUSER_MESSAGE_QUEUE PrevForegroundQueue;
819  PTHREADINFO pti;
820  BOOL Ret = FALSE;
821 
822  if (Wnd) ASSERT_REFS_CO(Wnd);
823 
824  TRACE("SetForegroundAndFocusWindow(%x, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE"));
825 
826  PrevForegroundQueue = IntGetFocusMessageQueue(); // Use this active desktop.
828 
829  if (Wnd && PrevForegroundQueue)
830  { // Same Window Q as foreground just do active.
831  if (Wnd->head.pti->MessageQueue == PrevForegroundQueue)
832  {
833  //ERR("Same Window Q as foreground just do active.\n");
834  if (pti->MessageQueue == PrevForegroundQueue)
835  { // Same WQ and TQ go active.
836  //ERR("Same WQ and TQ go active.\n");
837  Ret = IntUserSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
838  }
839  else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
840  { // Same WQ and it is active.
841  //ERR("Same WQ and it is active.\n");
842  Ret = TRUE;
843  }
844  else
845  { // Same WQ as FG but not the same TQ send active.
846  //ERR("Same WQ as FG but not the same TQ send active.\n");
847  MSG Msg;
848  PTHREADINFO ptiNew = Wnd->head.pti;
849 
850  Msg.message = WM_ASYNC_SETACTIVEWINDOW;
851  Msg.hwnd = hWnd;
852  Msg.wParam = (WPARAM)Wnd;
853  Msg.lParam = 0;
854  Msg.time = 0;
855  //ERR("SFAFW 1 : SAW P pti 0x%p hWnd 0x%p\n",ptiNew,hWnd);
856  MsqPostMessage(ptiNew, &Msg, FALSE, QS_EVENT, POSTEVENT_SAW, (LONG_PTR)MouseActivate);
857 
858  Ret = TRUE;
859  }
860  return Ret;
861  }
862  }
863 
864  if ( (( !IsFGLocked() || pti->ppi == gppiInputProvider ) &&
866  pti->ppi == ppiScrnSaver
867  )
868  {
869 
870  ToggleFGActivate(pti);
871 
872  return co_IntSetForegroundMessageQueue( Wnd, pti, MouseActivate, 0 );
873  }
874 
875  if (!Wnd) return FALSE; // No window, always return FALSE.
876 
878 
879  if (pti->MessageQueue == Wnd->head.pti->MessageQueue)
880  {
881  //ERR("Same PQ and WQ go active.\n");
882  Ret = IntUserSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
883  //if (!Ret) ERR("ISFAFW : IUSAW : return error\n");
884  }
885  else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
886  {
887  TRACE("Same Active and Wnd.\n"); // Leave this for now.
888  }
889  else
890  {
891  //ERR("Activate Not same PQ and WQ and Wnd.\n");
893  MSG Msg;
894  PTHREADINFO ptiNew = Wnd->head.pti;
895 
896  Msg.message = WM_ASYNC_SETACTIVEWINDOW;
897  Msg.hwnd = hWnd;
898  Msg.wParam = (WPARAM)Wnd;
899  Msg.lParam = 0;
900  Msg.time = 0;
901  //ERR("SFAFW 2 : SAW P pti 0x%p hWnd 0x%p\n",ptiNew,hWnd);
902  MsqPostMessage(ptiNew, &Msg, FALSE, QS_EVENT, POSTEVENT_SAW, (LONG_PTR)MouseActivate);
903  }
904  // Always return FALSE.
905  return FALSE;
906 }
907 
908 //
909 // Set the Active Window.
910 //
913  _In_ PWND Wnd,
914  _In_ BOOL bMouse,
915  _In_ BOOL bFocus,
916  _In_ BOOL Async )
917 {
918  PTHREADINFO pti;
919  PUSER_MESSAGE_QUEUE ThreadQueue;
920  PWND pWndChg, WndPrev; // State changes.
921  HWND hWndPrev;
922  HWND hWnd = 0;
923  BOOL InAAPM;
924  CBTACTIVATESTRUCT cbt;
925 
926  //ERR("co_IntSetActiveWindow 1\n");
927 
929  ThreadQueue = pti->MessageQueue;
930  ASSERT(ThreadQueue != 0);
931 
932  hWndPrev = ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : NULL;
933 
934  pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch.
935 
936  if ( !Wnd || Wnd == UserGetDesktopWindow() )
937  {
938  //ERR("ISAW : NULL %p\n",Wnd);
939  return FALSE;
940  }
941 
942  ASSERT_REFS_CO(Wnd);
943  hWnd = UserHMGetHandle(Wnd);
944  //ERR("co_IntSetActiveWindow 2 hWnd 0x%p\n",hWnd);
945 
946  /* check if the specified window can be set in the input data of a given queue */
947  if ( ThreadQueue != Wnd->head.pti->MessageQueue )
948  {
949  //ERR("ISAW : Must have the same Message Queue\n");
950  return FALSE;
951  }
952 
953  if (!VerifyWnd(Wnd))
954  {
955  //ERR("ISAW : Window is in Destroy!\n");
956  return FALSE;
957  }
958 
959  if ( Wnd == pWndChg )
960  {
961  //ERR("ISAW : Nothing to do\n");
962  return TRUE; // Fix CORE-8780 and CORE-11979. See CORE-11324 for breakage.
963  }
964 
965  if ( Wnd->state & WNDS_BEINGACTIVATED ) return TRUE;
966 
967  /* Call CBT hook chain */
968  cbt.fMouse = bMouse;
969  cbt.hWndActive = hWndPrev;
971  {
972  ERR("SetActiveWindow: WH_CBT Call Hook return!\n");
973  return FALSE;
974  }
975 
976  ThreadQueue->QF_flags &= ~QF_EVENTDEACTIVATEREMOVED;
977 
978  if ( ThreadQueue->spwndActive && ThreadQueue->spwndActive->state & WNDS_DESTROYED )
979  ThreadQueue->spwndActive = NULL;
980  else
981  ThreadQueue->spwndActivePrev = ThreadQueue->spwndActive;
982 
983  WndPrev = ThreadQueue->spwndActive; // Keep to save changing active.
984 
985  if (WndPrev)
986  {
987  if (ThreadQueue == gpqForeground) gpqForegroundPrev = ThreadQueue;
989  }
990 
991  WndPrev = ThreadQueue->spwndActive; // Again keep to save changing active.
992 
993  // While in calling message proc or hook:
994  // Fail if a preemptive switch was made, current active not made previous,
995  // focus window is dead or no longer the same thread queue.
996  if ( ThreadQueue->spwndActivePrev != ThreadQueue->spwndActive ||
997  pWndChg != WndPrev ||
998  (Wnd && !VerifyWnd(Wnd)) ||
999  ThreadQueue != pti->MessageQueue )
1000  {
1001  ERR("SetActiveWindow: Summary ERROR, active state changed!\n");
1002  return FALSE;
1003  }
1004 
1005  if (!WndPrev) ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;
1006 
1007  /* set the current thread active window */
1008  ThreadQueue->spwndActive = Wnd;
1009 
1010  // Set state flag to prevent recursions.
1011  Wnd->state |= WNDS_BEINGACTIVATED;
1012 
1013  IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
1014 
1015  // Clear out activate EVENT messages.
1017 
1018  WndPrev = VerifyWnd(ThreadQueue->spwndActivePrev); // Now should be set but verify it again.
1019 
1020  InAAPM = co_IntSendActivateMessages(WndPrev, Wnd, bMouse, Async);
1021 
1022  /* now change focus if necessary */
1024  if (bFocus && !(ThreadQueue->QF_flags & QF_FOCUSNULLSINCEACTIVE))
1025  {
1026  /* Do not change focus if the window is no longer active */
1027  if (pti->MessageQueue->spwndActive != IntGetNonChildAncestor(pti->MessageQueue->spwndFocus))
1028  {
1029  PWND pWndSend = pti->MessageQueue->spwndActive;
1030  // Clear focus if the active window is minimized.
1031  if (pWndSend && pti->MessageQueue->spwndActive->style & WS_MINIMIZE) pWndSend = NULL;
1032  // Send focus messages and if so, set the focus.
1033  IntSendFocusMessages( pti, pWndSend);
1034  }
1035  }
1037  if (InAAPM)
1038  {
1040  }
1041 
1042  // Checked in MENU_TrackMenu
1043  ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE;
1044 
1045  //ERR("co_IntSetActiveWindow Exit\n");
1046  Wnd->state &= ~WNDS_BEINGACTIVATED;
1047  return (ThreadQueue->spwndActive == Wnd);
1048 }
1049 
1050 //
1051 // Set the Active Window.
1052 //
1053 // Window is not optional!
1054 //
1055 BOOL FASTCALL
1057  _In_ PWND Wnd,
1058  _In_ BOOL bMouse,
1059  _In_ BOOL bFocus,
1060  _In_ BOOL Async)
1061 {
1062  PTHREADINFO pti;
1063  PUSER_MESSAGE_QUEUE ThreadQueue;
1064 
1065  //ERR("IntUserSetActiveWindow 1\n");
1066  ASSERT_REFS_CO(Wnd);
1067  if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
1068  //ERR("IntUserSetActiveWindow 1a hWnd 0x%p\n",UserHMGetHandle(Wnd));
1069 
1070  //ERR("IntUserSetActiveWindow 2\n");
1072  ThreadQueue = pti->MessageQueue;
1073  ASSERT(ThreadQueue != 0);
1074 
1075  while (Wnd)
1076  {
1077  BOOL Ret, DoFG, AllowFG;
1078 
1079  if (ThreadQueue == Wnd->head.pti->MessageQueue)
1080  {
1081  if (IsAllowedFGActive(pti, Wnd))
1082  {
1083  DoFG = TRUE;
1084  }
1085  else
1086  {
1087  //ERR("IntUserSetActiveWindow 3 Go Out!\n");
1088  break;
1089  }
1090  AllowFG = !pti->cVisWindows; // Nothing is visable.
1091  //ERR("IntUserSetActiveWindow 3a DoFG = %d AllowFG = %d\n",DoFG,AllowFG);
1092  }
1093  else //if (ThreadQueue != Wnd->head.pti->MessageQueue)
1094  {
1095  //PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
1096  // Rule 1 & 4, We are foreground so set this FG window or NULL foreground....
1097  if (!gpqForeground || gpqForeground == ThreadQueue)
1098  {
1099  DoFG = TRUE;
1100  }
1101  else
1102  DoFG = FALSE;
1103  if (DoFG)
1104  {
1106  AllowFG = TRUE;
1107  else
1108  AllowFG = FALSE;
1109  }
1110  else
1111  AllowFG = FALSE;
1112  //ERR("IntUserSetActiveWindow 3b DoFG = %d AllowFG = %d\n",DoFG,AllowFG);
1113  }
1114  Ret = FALSE;
1115  if (DoFG)
1116  {
1118  //ERR("IntUserSetActiveWindow 3c FG set\n");
1119  Ret = co_IntSetForegroundAndFocusWindow(Wnd, bMouse, TRUE);
1120  if (AllowFG)
1121  {
1123  }
1124  else
1125  {
1127  }
1128  }
1129  return Ret;
1130  }
1131 
1132  return co_IntSetActiveWindow(Wnd, bMouse, bFocus, Async);
1133 }
1134 
1135 BOOL FASTCALL
1137 {
1138  TRACE("Mouse Active\n");
1140 }
1141 
1142 BOOL FASTCALL
1144 {
1146 
1147  if (Wnd)
1148  {
1149  if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
1150 
1151  return IntUserSetActiveWindow(Wnd, FALSE, TRUE, FALSE);
1152  }
1153  /*
1154  Yes your eye are not deceiving you~!
1155 
1156  First part of wines Win.c test_SetActiveWindow:
1157 
1158  flush_events( TRUE );
1159  ShowWindow(hwnd, SW_HIDE);
1160  SetFocus(0);
1161  SetActiveWindow(0);
1162  check_wnd_state(0, 0, 0, 0); <-- This should pass if ShowWindow does it's job!!! As of 10/28/2012 it does!
1163 
1164  Now Handle wines Msg.c test_SetActiveWindow( 0 )...
1165  */
1166  TRACE("USAW: Previous active window\n");
1167  if ( gpqForegroundPrev &&
1172  {
1173  TRACE("USAW:PAW hwnd %p\n",Wnd?Wnd->head.h:NULL);
1174  return IntUserSetActiveWindow(Wnd, FALSE, TRUE, FALSE);
1175  }
1176 
1177  // Activate anyone but the active window.
1178  if ( pti->MessageQueue->spwndActive &&
1179  (Wnd = VerifyWnd(pti->MessageQueue->spwndActive)) != NULL )
1180  {
1181  //ERR("USAW:AOWM hwnd %p\n",Wnd?Wnd->head.h:NULL);
1182  if (!ActivateOtherWindowMin(Wnd))
1183  {
1184  // Okay, now go find someone else to play with!
1185  //ERR("USAW: Going to WPAOW\n");
1187  }
1188  return TRUE;
1189  }
1190 
1191  TRACE("USAW: Nothing\n");
1192  return FALSE;
1193 }
1194 
1195 HWND FASTCALL
1197 {
1198  HWND hWndPrev = 0;
1199  PWND pwndTop;
1200  PTHREADINFO pti;
1201  PUSER_MESSAGE_QUEUE ThreadQueue;
1202 
1203  if (Window)
1205 
1207  ThreadQueue = pti->MessageQueue;
1208  ASSERT(ThreadQueue != 0);
1209 
1210  TRACE("Enter SetFocus hWnd 0x%p pti 0x%p\n",Window ? UserHMGetHandle(Window) : 0, pti );
1211 
1212  hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
1213 
1214  if (Window != 0)
1215  {
1216  if (hWndPrev == UserHMGetHandle(Window))
1217  {
1218  return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0; /* Nothing to do */
1219  }
1220 
1221  if (Window->head.pti->MessageQueue != ThreadQueue)
1222  {
1223  ERR("SetFocus Must have the same Q!\n");
1224  return 0;
1225  }
1226 
1227  /* Check if we can set the focus to this window */
1229  for (pwndTop = Window; pwndTop; pwndTop = pwndTop->spwndParent)
1230  {
1231  if (pwndTop->style & (WS_MINIMIZED|WS_DISABLED)) return 0;
1232  if ((pwndTop->style & (WS_POPUP|WS_CHILD)) != WS_CHILD) break;
1233  if (pwndTop->spwndParent == NULL) break;
1234  }
1236  if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev))
1237  {
1238  ERR("SetFocus 1 WH_CBT Call Hook return!\n");
1239  return 0;
1240  }
1241 
1242  /* Activate pwndTop if needed. */
1243  if (pwndTop != ThreadQueue->spwndActive)
1244  {
1245  PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); // Keep it based on desktop.
1246  if (ThreadQueue != ForegroundQueue && IsAllowedFGActive(pti, pwndTop)) // Rule 2 & 3.
1247  {
1248  //ERR("SetFocus: Set Foreground!\n");
1249  if (!(pwndTop->style & WS_VISIBLE))
1250  {
1251  pti->ppi->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE;
1252  }
1254  {
1255  ERR("SetFocus: Set Foreground and Focus Failed!\n");
1256  return 0;
1257  }
1258  }
1259 
1260  /* Set Active when it is needed. */
1261  if (pwndTop != ThreadQueue->spwndActive)
1262  {
1263  //ERR("SetFocus: Set Active! %p\n",pwndTop?UserHMGetHandle(pwndTop):0);
1264  if (!co_IntSetActiveWindow(pwndTop, FALSE, FALSE, FALSE))
1265  {
1266  ERR("SetFocus: Set Active Failed!\n");
1267  return 0;
1268  }
1269  }
1270 
1271  /* Abort if window destroyed */
1272  if (Window->state2 & WNDS2_INDESTROY) return 0;
1273  /* Do not change focus if the window is no longer active */
1274  if (pwndTop != ThreadQueue->spwndActive)
1275  {
1276  ERR("SetFocus: Top window did not go active!\n");
1277  return 0;
1278  }
1279  }
1280 
1281  // Check again! SetActiveWindow could have set the focus via WM_ACTIVATE.
1282  hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
1283 
1285 
1286  TRACE("Focus: %p -> %p\n", hWndPrev, Window->head.h);
1287  }
1288  else /* NULL hwnd passed in */
1289  {
1290  if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev))
1291  {
1292  ERR("SetFocus: 2 WH_CBT Call Hook return!\n");
1293  return 0;
1294  }
1295  //ERR("SetFocus: Set Focus NULL\n");
1296  /* set the current thread focus window null */
1297  IntSendFocusMessages( pti, NULL);
1298  }
1299  return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0;
1300 }
1301 
1302 HWND FASTCALL
1304 {
1305  PUSER_MESSAGE_QUEUE ForegroundQueue;
1306 
1307  ForegroundQueue = IntGetFocusMessageQueue();
1308  return( ForegroundQueue ? (ForegroundQueue->spwndActive ? UserHMGetHandle(ForegroundQueue->spwndActive) : 0) : 0);
1309 }
1310 
1312 {
1313  PTHREADINFO pti;
1314  PUSER_MESSAGE_QUEUE ThreadQueue;
1315 
1317  ThreadQueue = pti->MessageQueue;
1318  return( ThreadQueue ? (ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : 0) : 0);
1319 }
1320 
1321 HWND APIENTRY
1323 {
1324  PTHREADINFO pti;
1325  PUSER_MESSAGE_QUEUE ThreadQueue;
1327 
1328  TRACE("Enter IntGetCapture\n");
1329 
1331  ThreadQueue = pti->MessageQueue;
1332  RETURN( ThreadQueue ? (ThreadQueue->spwndCapture ? UserHMGetHandle(ThreadQueue->spwndCapture) : 0) : 0);
1333 
1334 CLEANUP:
1335  TRACE("Leave IntGetCapture, ret=%p\n", _ret_);
1336  END_CLEANUP;
1337 }
1338 
1339 HWND FASTCALL
1341 {
1342  PTHREADINFO pti;
1343  PUSER_MESSAGE_QUEUE ThreadQueue;
1344  PWND pWnd, Window = NULL;
1345  HWND hWndPrev;
1346 
1348  ThreadQueue = pti->MessageQueue;
1349 
1350  if (ThreadQueue->QF_flags & QF_CAPTURELOCKED)
1351  return NULL;
1352 
1353  if (hWnd && (Window = UserGetWindowObject(hWnd)))
1354  {
1355  if (Window->head.pti->MessageQueue != ThreadQueue)
1356  {
1357  ERR("Window Thread does not match Current!\n");
1358  return NULL;
1359  }
1360  }
1361 
1362  hWndPrev = MsqSetStateWindow(pti, MSQ_STATE_CAPTURE, hWnd);
1363 
1364  if (hWndPrev)
1365  {
1366  pWnd = UserGetWindowObject(hWndPrev);
1367  if (pWnd)
1368  IntNotifyWinEvent(EVENT_SYSTEM_CAPTUREEND, pWnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
1369  }
1370 
1371  if (Window)
1372  IntNotifyWinEvent(EVENT_SYSTEM_CAPTURESTART, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
1373 
1374  //
1375  // Only send the message if we have a previous Window!
1376  // Fix msg_menu tracking popup menu and win test_capture_4!!!!
1377  //
1378  if (hWndPrev)
1379  {
1380  if (ThreadQueue->MenuOwner && Window) ThreadQueue->QF_flags |= QF_CAPTURELOCKED;
1381 
1383 
1384  ThreadQueue->QF_flags &= ~QF_CAPTURELOCKED;
1385  }
1386 
1387  if (hWnd == NULL) // Release mode.
1388  {
1389  MOUSEINPUT mi;
1391  /* Also remove other windows if not capturing anymore */
1395  /* Somebody may have missed some mouse movements */
1396  mi.dx = 0;
1397  mi.dy = 0;
1398  mi.mouseData = 0;
1400  mi.time = 0;
1401  mi.dwExtraInfo = 0;
1403  }
1404  return hWndPrev;
1405 }
1406 
1407 /*
1408  API Call
1409 */
1410 BOOL
1411 FASTCALL
1413 {
1414  PTHREADINFO pti;
1415  PUSER_MESSAGE_QUEUE ThreadQueue;
1416 
1418  ThreadQueue = pti->MessageQueue;
1419 
1420  // Can not release inside WM_CAPTURECHANGED!!
1421  if (ThreadQueue->QF_flags & QF_CAPTURELOCKED) return FALSE;
1422 
1424 
1425  return TRUE;
1426 }
1427 
1428 /*
1429  API Call
1430 */
1431 BOOL FASTCALL
1433 {
1435 
1437 }
1438 
1439 /*
1440  API Call
1441 */
1442 BOOL FASTCALL
1444 {
1446 
1448 }
1449 
1450 /*
1451  API Call
1452 */
1453 BOOL FASTCALL
1455 {
1456  ULONG Err = ERROR_ACCESS_DENIED;
1458  switch (uLockCode)
1459  {
1460  case LSFW_LOCK:
1461  if ( CanForceFG(ppi) && !gppiLockSFW )
1462  {
1463  gppiLockSFW = ppi;
1464  return TRUE;
1465  }
1466  break;
1467  case LSFW_UNLOCK:
1468  if ( gppiLockSFW == ppi)
1469  {
1470  gppiLockSFW = NULL;
1471  return TRUE;
1472  }
1473  break;
1474  default:
1476  }
1477  EngSetLastError(Err);
1478  return FALSE;
1479 }
1480 
1481 /*
1482  API Call
1483 */
1484 BOOL FASTCALL
1486 {
1487  PPROCESSINFO ppi, ppiCur;
1489 
1490  ppi = NULL;
1491  if (dwProcessId != ASFW_ANY)
1492  {
1494  {
1496  return FALSE;
1497  }
1499  if (!ppi)
1500  {
1502  return FALSE;
1503  }
1504  }
1506  if (!CanForceFG(ppiCur))
1507  {
1510  return FALSE;
1511  }
1512  if (dwProcessId == ASFW_ANY)
1513  { // All processes will be enabled to set the foreground window.
1514  //ERR("ptiLastInput is CLEARED!!\n");
1515  ptiLastInput = NULL;
1516  }
1517  else
1518  { // Rule #3, last input event in force.
1519  ERR("ptiLastInput is SET!!\n");
1520  //ptiLastInput = ppi->ptiList; // See CORE-6384 & CORE-7030.
1522  }
1523  return TRUE;
1524 }
1525 
1526 /*
1527  * @implemented
1528  */
1529 HWND APIENTRY
1531 {
1533 
1534  TRACE("Enter NtUserGetForegroundWindow\n");
1536 
1538 
1539 CLEANUP:
1540  TRACE("Leave NtUserGetForegroundWindow, ret=%p\n",_ret_);
1541  UserLeave();
1542  END_CLEANUP;
1543 }
1544 
1545 HWND APIENTRY
1547 {
1549  HWND hWndPrev;
1550  PWND Window;
1552 
1553  TRACE("Enter NtUserSetActiveWindow(%p)\n", hWnd);
1555 
1556  Window = NULL;
1557  if (hWnd)
1558  {
1559  if (!(Window = UserGetWindowObject(hWnd)))
1560  {
1561  ERR("NtUserSetActiveWindow: Invalid handle 0x%p!\n",hWnd);
1562  RETURN( NULL);
1563  }
1564  }
1565 
1566  if (!Window ||
1567  Window->head.pti->MessageQueue == gptiCurrent->MessageQueue)
1568  {
1569  hWndPrev = gptiCurrent->MessageQueue->spwndActive ? UserHMGetHandle(gptiCurrent->MessageQueue->spwndActive) : NULL;
1570  if (Window) UserRefObjectCo(Window, &Ref);
1573  RETURN( hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0 );
1574  }
1575  RETURN( NULL);
1576 
1577 CLEANUP:
1578  TRACE("Leave NtUserSetActiveWindow, ret=%p\n",_ret_);
1579  UserLeave();
1580  END_CLEANUP;
1581 }
1582 
1583 /*
1584  * @implemented
1585  */
1586 HWND APIENTRY
1588 {
1590 
1591  TRACE("Enter NtUserSetCapture(%p)\n", hWnd);
1593 
1595 
1596 CLEANUP:
1597  TRACE("Leave NtUserSetCapture, ret=%p\n", _ret_);
1598  UserLeave();
1599  END_CLEANUP;
1600 }
1601 
1602 /*
1603  * @implemented
1604  */
1605 HWND APIENTRY
1607 {
1608  PWND Window;
1611  HWND ret;
1612 
1613  TRACE("Enter NtUserSetFocus(%p)\n", hWnd);
1615 
1616  if (hWnd)
1617  {
1618  if (!(Window = UserGetWindowObject(hWnd)))
1619  {
1620  ERR("NtUserSetFocus: Invalid handle 0x%p!\n",hWnd);
1621  RETURN(NULL);
1622  }
1623 
1624  UserRefObjectCo(Window, &Ref);
1627 
1628  RETURN(ret);
1629  }
1630  else
1631  {
1632  RETURN( co_UserSetFocus(0));
1633  }
1634 
1635 CLEANUP:
1636  TRACE("Leave NtUserSetFocus, ret=%p\n",_ret_);
1637  UserLeave();
1638  END_CLEANUP;
1639 }
1640 
1641 /* EOF */
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
PUSER_MESSAGE_QUEUE gpqForeground
Definition: focus.c:12
#define WS_DISABLED
Definition: pedump.c:621
#define MSQ_STATE_MOVESIZE
Definition: ntuser.h:3548
PTHREADINFO gptiForeground
Definition: focus.c:14
DWORD ExStyle
Definition: ntuser.h:668
PPROCESSINFO ppiScrnSaver
Definition: main.c:30
#define TRUE
Definition: types.h:120
VOID FASTCALL co_MsqInsertMouseMessage(MSG *Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook)
Definition: msgqueue.c:580
#define MAKEWPARAM(l, h)
Definition: winuser.h:3984
PWND FASTCALL ValidateHwndNoErr(HWND hWnd)
Definition: window.c:96
HWND FASTCALL IntGetThreadFocusWindow(VOID)
Definition: focus.c:39
#define CLEANUP
Definition: ntuser.h:5
BOOL FASTCALL co_IntSetActiveWindow(_In_ PWND Wnd, _In_ BOOL bMouse, _In_ BOOL bFocus, _In_ BOOL Async)
Definition: focus.c:912
BOOL NTAPI UserSendMouseInput(MOUSEINPUT *pMouseInput, BOOL bInjected)
Definition: mouse.c:168
Type
Definition: Type.h:6
#define RETURN(value)
Definition: ntuser.h:4
struct _Entry Entry
Definition: kefuncs.h:640
HWND FASTCALL co_UserSetFocus(PWND Window)
Definition: focus.c:1196
BOOL FASTCALL FindRemoveEventMsg(PTHREADINFO pti, DWORD Event, DWORD EventLast)
Definition: focus.c:567
#define QF_FOCUSNULLSINCEACTIVE
Definition: msgqueue.h:105
#define QF_EVENTDEACTIVATEREMOVED
Definition: msgqueue.h:107
#define WNDS2_BOTTOMMOST
Definition: ntuser.h:614
BOOL FASTCALL IntReleaseCapture(VOID)
Definition: focus.c:1412
VOID FASTCALL IntSendFocusMessages(PTHREADINFO pti, PWND pWnd)
Definition: focus.c:524
BOOL FASTCALL IntUserSetActiveWindow(_In_ PWND Wnd, _In_ BOOL bMouse, _In_ BOOL bFocus, _In_ BOOL Async)
Definition: focus.c:1056
PDESKTOP gpdeskInputDesktop
Definition: desktop.c:35
HWND FASTCALL UserGetActiveWindow(VOID)
Definition: focus.c:1311
#define POSTEVENT_NONE
Definition: msgqueue.h:126
#define ASSERT_REFS_CO(_obj_)
Definition: userfuncs.h:13
BOOL FASTCALL IsFGLocked(VOID)
Definition: focus.c:23
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
FLONG TIF_flags
Definition: win32.h:94
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
VOID FASTCALL IntNotifyWinEvent(DWORD Event, PWND pWnd, LONG idObject, LONG idChild, DWORD flags)
Definition: event.c:179
#define MAKELPARAM(l, h)
Definition: winuser.h:3983
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
BOOLEAN FASTCALL co_WinPosSetWindowPos(PWND Window, HWND WndInsertAfter, INT x, INT y, INT cx, INT cy, UINT flags)
Definition: winpos.c:1720
struct @1591 Msg[]
#define WM_CAPTURECHANGED
Definition: winuser.h:1790
BOOL FASTCALL UserSendNotifyMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1874
#define OBJID_WINDOW
Definition: winable.h:15
HWND hWnd
Definition: settings.c:17
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Definition: object.h:25
BOOL FASTCALL UserSetActiveWindow(_In_opt_ PWND Wnd)
Definition: focus.c:1143
#define HWND_TOP
Definition: winuser.h:1193
static MONITORINFO mi
Definition: win.c:7339
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
DBG_DEFAULT_CHANNEL(UserFocus)
UINT_PTR WPARAM
Definition: windef.h:207
#define WS_CHILD
Definition: pedump.c:617
#define HCBT_SETFOCUS
Definition: winuser.h:64
HWND APIENTRY NtUserSetActiveWindow(HWND hWnd)
Definition: focus.c:1546
HWND FASTCALL IntGetCaptureWindow(VOID)
Definition: focus.c:32
VOID FASTCALL co_WinPosActivateOtherWindow(PWND Wnd)
Definition: winpos.c:395
#define FASTCALL
Definition: nt_native.h:50
#define TIF_SYSTEMTHREAD
Definition: ntuser.h:242
#define WS_EX_TOOLWINDOW
Definition: winuser.h:404
PUSER_MESSAGE_QUEUE FASTCALL IntGetFocusMessageQueue(VOID)
Definition: desktop.c:1271
struct _DESKTOP * rpdesk
Definition: win32.h:91
#define W32PF_SETFOREGROUNDALLOWED
Definition: win32.h:20
PSERVERINFO gpsi
Definition: main.c:27
WPARAM wParam
Definition: combotst.c:138
WORD FASTCALL UserGetMouseButtonsState(VOID)
Definition: mouse.c:22
PPROCESSINFO gppiLockSFW
Definition: focus.c:15
#define _In_opt_
Definition: no_sal2.h:213
#define WNDS_BEINGACTIVATED
Definition: ntuser.h:593
PPROCESSINFO ppi
Definition: win32.h:87
VOID FASTCALL MsqDestroyMessage(PUSER_MESSAGE Message)
Definition: msgqueue.c:748
Definition: window.c:28
#define W32PF_ALLOWFOREGROUNDACTIVATE
Definition: win32.h:12
#define WM_NCACTIVATE
Definition: winuser.h:1670
#define TIF_CSRSSTHREAD
Definition: ntuser.h:243
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
#define WS_MINIMIZE
Definition: pedump.c:622
unsigned int BOOL
Definition: ntddk_ex.h:94
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:38
#define QF_CAPTURELOCKED
Definition: msgqueue.h:111
BOOL FASTCALL co_IntMouseActivateWindow(PWND Wnd)
Definition: focus.c:1136
#define CHILDID_SELF
Definition: winable.h:14
struct _WND * spwndOwner
Definition: ntuser.h:679
THRDESKHEAD head
Definition: ntuser.h:659
Definition: object.h:3
PPROCESSINFO gppiInputProvider
Definition: ntuser.c:16
smooth NULL
Definition: ftsmooth.c:416
ULONG guSFWLockCount
Definition: focus.c:16
LONG_PTR LPARAM
Definition: windef.h:208
PWND FASTCALL co_GetDesktopWindow(PWND pWnd)
Definition: desktop.c:1330
#define WH_CBT
Definition: winuser.h:35
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
PTHREADINFO ptiLastInput
Definition: focus.c:17
#define WS_EX_NOACTIVATE
Definition: winuser.h:395
struct _WND * spwndNext
Definition: ntuser.h:675
#define WEF_SETBYWNDPTI
Definition: ntuser.h:213
#define WM_PALETTEISCHANGING
Definition: winuser.h:1858
VOID FASTCALL IntActivateWindow(PWND Wnd, PTHREADINFO pti, HANDLE tid, DWORD Type)
Definition: focus.c:268
HWND APIENTRY NtUserSetFocus(HWND hWnd)
Definition: focus.c:1606
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:103
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
HWND FASTCALL UserGetForegroundWindow(VOID)
Definition: focus.c:1303
HWND APIENTRY NtUserGetForegroundWindow(VOID)
Definition: focus.c:1530
#define TIF_ALLOWFOREGROUNDACTIVATE
Definition: ntuser.h:245
#define IntReferenceThreadInfo(pti)
Definition: win32.h:162
BOOL FASTCALL co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd, BOOL Clear)
Definition: focus.c:69
#define WS_MINIMIZED
Definition: undocuser.h:18
static BOOL FASTCALL co_IntSetForegroundAndFocusWindow(_In_opt_ PWND Wnd, _In_ BOOL MouseActivate, _In_ BOOL bFlash)
Definition: focus.c:812
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
#define UserHMGetHandle(obj)
Definition: ntuser.h:208
#define WM_QUERYNEWPALETTE
Definition: winuser.h:1860
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define OBJID_CLIENT
Definition: winable.h:19
HWND FASTCALL MsqSetStateWindow(PTHREADINFO pti, ULONG Type, HWND hWnd)
Definition: msgqueue.c:2533
#define TRACE(s)
Definition: solgame.cpp:4
HWND FASTCALL co_UserSetCapture(HWND hWnd)
Definition: focus.c:1340
#define WM_KILLFOCUS
Definition: winuser.h:1596
VOID FASTCALL ClearMsgBitsMask(PTHREADINFO pti, UINT MessageBits)
Definition: msgqueue.c:445
BOOL FASTCALL co_IntMakeWindowActive(PWND Window)
Definition: focus.c:337
LIST_ENTRY List
Definition: psmgr.c:57
HWND APIENTRY NtUserSetCapture(HWND hWnd)
Definition: focus.c:1587
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SWP_NOACTIVATE
Definition: winuser.h:1227
#define TIF_INACTIVATEAPPMSG
Definition: ntuser.h:249
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define WA_ACTIVE
Definition: winuser.h:2598
BOOL FASTCALL IntLockSetForegroundWindow(UINT uLockCode)
Definition: focus.c:1454
#define QS_EVENT
Definition: undocuser.h:95
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DECLARE_RETURN(type)
Definition: ntuser.h:3
#define WA_CLICKACTIVE
Definition: winuser.h:2599
VOID FASTCALL MsqPostMessage(PTHREADINFO pti, MSG *Msg, BOOLEAN HardwareMessage, DWORD MessageBits, DWORD dwQEvent, LONG_PTR ExtraInfo)
Definition: msgqueue.c:1338
BOOL FASTCALL IntIsWindow(HWND hWnd)
Definition: window.c:157
int Window
Definition: x11stubs.h:26
GLbitfield flags
Definition: glext.h:7161
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
CHAR Message[80]
Definition: alive.c:5
LRESULT APIENTRY co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:1103
BOOL FASTCALL co_IntSetForegroundMessageQueue(_In_opt_ PWND Wnd, _In_ PTHREADINFO pti, _In_ BOOL MouseActivate, _In_ DWORD Type)
Definition: focus.c:655
PWND FASTCALL UserGetDesktopWindow(VOID)
Definition: desktop.c:1349
NTSTATUS NTAPI PsLookupProcessByProcessId(IN HANDLE ProcessId, OUT PEPROCESS *Process)
Definition: process.c:919
int ret
BOOL FASTCALL IntIsWindowVisible(PWND Wnd)
Definition: window.c:170
BOOL FASTCALL co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOOL Async)
Definition: focus.c:355
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1281
#define WM_CANCELMODE
Definition: winuser.h:1617
HWND *FASTCALL IntWinListChildren(PWND Window)
Definition: window.c:255
#define WNDS_ACTIVEFRAME
Definition: ntuser.h:579
Definition: typedefs.h:117
HANDLE NTAPI PsGetThreadId(IN PETHREAD Thread)
Definition: thread.c:705
HWND APIENTRY IntGetCapture(VOID)
Definition: focus.c:1322
BOOL FASTCALL ActivateOtherWindowMin(PWND Wnd)
Definition: winpos.c:284
#define SWP_NOSIZE
Definition: winuser.h:1230
#define ERR(fmt,...)
Definition: debug.h:109
#define _In_
Definition: no_sal2.h:204
Definition: ntuser.h:657
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:88
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
BOOL FASTCALL ToggleFGActivate(PTHREADINFO pti)
Definition: focus.c:598
VOID FASTCALL IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue)
Definition: desktop.c:1283
struct _WND * PWND
#define WM_ACTIVATEAPP
Definition: winuser.h:1614
#define WM_ACTIVATE
Definition: winuser.h:1594
#define MSQ_STATE_CAPTURE
Definition: ntuser.h:3544
LIST_ENTRY PostedMessagesListHead
Definition: win32.h:131
struct _WND * spwndLastActive
Definition: ntuser.h:703
#define IntGetWndThreadId(WndObj)
Definition: window.h:34
#define QF_ACTIVATIONCHANGE
Definition: msgqueue.h:100
#define MOUSEEVENTF_MOVE
Definition: winuser.h:1169
DWORD state
Definition: ntuser.h:665
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define WS_POPUP
Definition: pedump.c:616
unsigned int UINT
Definition: ndis.h:50
#define WM_MOUSEMOVE
Definition: winuser.h:1757
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
#define WNDS_NONCPAINT
Definition: ntuser.h:581
VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam)
Definition: desktop.c:1656
#define POSTEVENT_DAW
Definition: msgqueue.h:123
DWORD dwFlags
Definition: winuser.h:3762
#define msg(x)
Definition: auth_time.c:54
PWND FASTCALL IntGetNonChildAncestor(PWND pWnd)
Definition: window.c:323
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define PUSIF_PALETTEDISPLAY
Definition: ntuser.h:954
BOOL FASTCALL CanForceFG(PPROCESSINFO ppi)
Definition: focus.c:637
PUSER_MESSAGE_QUEUE gpqForegroundPrev
Definition: focus.c:13
UINT cVisWindows
Definition: win32.h:135
struct _WND * spwndParent
Definition: ntuser.h:677
BOOL FASTCALL IntAllowSetForegroundWindow(DWORD dwProcessId)
Definition: focus.c:1485
BOOL FASTCALL IntDeactivateWindow(PTHREADINFO pti, HANDLE tid)
Definition: focus.c:106
unsigned int ULONG
Definition: retypes.h:1
DWORD state2
Definition: ntuser.h:666
#define HCBT_ACTIVATE
Definition: winuser.h:60
#define SWP_NOMOVE
Definition: winuser.h:1229
#define WA_INACTIVE
Definition: winuser.h:2597
BOOL FASTCALL co_IntSetForegroundWindowMouse(PWND Window)
Definition: focus.c:1443
Definition: fbtusb.h:86
#define WS_EX_APPWINDOW
Definition: winuser.h:383
void Clear(USHORT Window)
Definition: hardware.c:705
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define WM_SETFOCUS
Definition: winuser.h:1595
PWND FASTCALL VerifyWnd(PWND pWnd)
Definition: window.c:64
#define USERTAG_WINDOWLIST
Definition: tags.h:297
BOOL FASTCALL IsAllowedFGActive(PTHREADINFO pti, PWND Wnd)
Definition: focus.c:618
BOOL FASTCALL co_IntSetForegroundWindow(PWND Window)
Definition: focus.c:1432
struct _WND * spwndChild
Definition: ntuser.h:678
#define WS_VISIBLE
Definition: pedump.c:620
#define MSQ_STATE_MENUOWNER
Definition: ntuser.h:3547
#define HWND_BROADCAST
Definition: winuser.h:1190
#define IntDereferenceThreadInfo(pti)
Definition: win32.h:167
#define WNDS_DESTROYED
Definition: ntuser.h:604
#define POSTEVENT_SAW
Definition: msgqueue.h:124
static TfClientId tid
LPARAM lParam
Definition: combotst.c:139
VOID FASTCALL UpdateShellHook(PWND Window)
Definition: focus.c:52
#define TIF_INCLEANUP
Definition: ntuser.h:240
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
base of all file and directory entries
Definition: entries.h:82
#define WNDS_HASCAPTION
Definition: ntuser.h:576
#define APIENTRY
Definition: api.h:79
#define END_CLEANUP
Definition: ntuser.h:6
#define WNDS2_INDESTROY
Definition: ntuser.h:616
DWORD style
Definition: ntuser.h:670