2 * ReactOS Win32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 IntGetCaptureWindow(VOID
)
29 PUSER_MESSAGE_QUEUE ForegroundQueue
= IntGetFocusMessageQueue();
30 return ForegroundQueue
!= NULL
? ForegroundQueue
->CaptureWindow
: 0;
34 IntGetFocusWindow(VOID
)
36 PUSER_MESSAGE_QUEUE ForegroundQueue
= IntGetFocusMessageQueue();
37 return ForegroundQueue
!= NULL
? ForegroundQueue
->FocusWindow
: 0;
41 IntGetThreadFocusWindow(VOID
)
44 PUSER_MESSAGE_QUEUE ThreadQueue
;
46 pti
= PsGetCurrentThreadWin32Thread();
47 ThreadQueue
= pti
->MessageQueue
;
48 return ThreadQueue
!= NULL
? ThreadQueue
->FocusWindow
: 0;
52 co_IntSendDeactivateMessages(HWND hWndPrev
, HWND hWnd
)
56 co_IntPostOrSendMessage(hWndPrev
, WM_NCACTIVATE
, FALSE
, 0);
57 co_IntPostOrSendMessage(hWndPrev
, WM_ACTIVATE
,
58 MAKEWPARAM(WA_INACTIVE
, UserGetWindowLong(hWndPrev
, GWL_STYLE
, FALSE
) & WS_MINIMIZE
),
64 co_IntSendActivateMessages(HWND hWndPrev
, HWND hWnd
, BOOL MouseActivate
)
66 USER_REFERENCE_ENTRY Ref
, RefPrev
;
67 PWINDOW_OBJECT Window
, WindowPrev
= NULL
;
69 if ((Window
= UserGetWindowObject(hWnd
)))
71 UserRefObjectCo(Window
, &Ref
);
73 WindowPrev
= UserGetWindowObject(hWndPrev
);
75 if (WindowPrev
) UserRefObjectCo(WindowPrev
, &RefPrev
);
77 /* Send palette messages */
78 if (co_IntPostOrSendMessage(hWnd
, WM_QUERYNEWPALETTE
, 0, 0))
80 UserPostMessage( HWND_BROADCAST
,
86 if (UserGetWindow(hWnd
, GW_HWNDPREV
) != NULL
)
87 co_WinPosSetWindowPos(Window
, HWND_TOP
, 0, 0, 0, 0,
88 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOSENDCHANGING
);
90 if (!IntGetOwner(Window
) && !IntGetParent(Window
))
92 co_IntShellHookNotify(HSHELL_WINDOWACTIVATED
, (LPARAM
) hWnd
);
96 { // Set last active for window and it's owner.
97 Window
->Wnd
->hWndLastActive
= hWnd
;
98 if (Window
->Wnd
->spwndOwner
)
99 Window
->Wnd
->spwndOwner
->hWndLastActive
= hWnd
;
100 Window
->Wnd
->state
|= WNDS_ACTIVEFRAME
;
103 if (WindowPrev
&& WindowPrev
->Wnd
)
104 WindowPrev
->Wnd
->state
&= ~WNDS_ACTIVEFRAME
;
106 if (Window
&& WindowPrev
)
108 PWINDOW_OBJECT cWindow
;
110 HANDLE OldTID
= IntGetWndThreadId(WindowPrev
);
111 HANDLE NewTID
= IntGetWndThreadId(Window
);
113 DPRINT("SendActiveMessage Old -> %x, New -> %x\n", OldTID
, NewTID
);
115 if (OldTID
!= NewTID
)
117 List
= IntWinListChildren(UserGetWindowObject(IntGetDesktopWindow()));
120 for (phWnd
= List
; *phWnd
; ++phWnd
)
122 cWindow
= UserGetWindowObject(*phWnd
);
123 if (cWindow
&& (IntGetWndThreadId(cWindow
) == OldTID
))
124 { // FALSE if the window is being deactivated,
125 // ThreadId that owns the window being activated.
126 co_IntPostOrSendMessage(*phWnd
, WM_ACTIVATEAPP
, FALSE
, (LPARAM
)NewTID
);
129 for (phWnd
= List
; *phWnd
; ++phWnd
)
131 cWindow
= UserGetWindowObject(*phWnd
);
132 if (cWindow
&& (IntGetWndThreadId(cWindow
) == NewTID
))
133 { // TRUE if the window is being activated,
134 // ThreadId that owns the window being deactivated.
135 co_IntPostOrSendMessage(*phWnd
, WM_ACTIVATEAPP
, TRUE
, (LPARAM
)OldTID
);
141 UserDerefObjectCo(WindowPrev
); // Now allow the previous window to die.
144 UserDerefObjectCo(Window
);
146 /* FIXME: IntIsWindow */
148 co_IntPostOrSendMessage(hWnd
, WM_NCACTIVATE
, (WPARAM
)(hWnd
== UserGetForegroundWindow()), 0);
149 /* FIXME: WA_CLICKACTIVE */
150 co_IntPostOrSendMessage(hWnd
, WM_ACTIVATE
,
151 MAKEWPARAM(MouseActivate
? WA_CLICKACTIVE
: WA_ACTIVE
,
152 UserGetWindowLong(hWnd
, GWL_STYLE
, FALSE
) & WS_MINIMIZE
),
158 co_IntSendKillFocusMessages(HWND hWndPrev
, HWND hWnd
)
162 co_IntPostOrSendMessage(hWndPrev
, WM_KILLFOCUS
, (WPARAM
)hWnd
, 0);
167 co_IntSendSetFocusMessages(HWND hWndPrev
, HWND hWnd
)
171 co_IntPostOrSendMessage(hWnd
, WM_SETFOCUS
, (WPARAM
)hWndPrev
, 0);
176 IntFindChildWindowToOwner(PWINDOW_OBJECT Root
, PWINDOW_OBJECT Owner
)
179 PWINDOW_OBJECT Child
, OwnerWnd
;
181 for(Child
= Root
->spwndChild
; Child
; Child
= Child
->spwndNext
)
183 OwnerWnd
= UserGetWindowObject(Child
->hOwner
);
187 if(OwnerWnd
== Owner
)
198 co_IntSetForegroundAndFocusWindow(PWINDOW_OBJECT Window
, PWINDOW_OBJECT FocusWindow
, BOOL MouseActivate
)
200 HWND hWnd
= Window
->hSelf
;
201 HWND hWndPrev
= NULL
;
202 HWND hWndFocus
= FocusWindow
->hSelf
;
203 HWND hWndFocusPrev
= NULL
;
204 PUSER_MESSAGE_QUEUE PrevForegroundQueue
;
207 ASSERT_REFS_CO(Window
);
209 DPRINT("IntSetForegroundAndFocusWindow(%x, %x, %s)\n", hWnd
, hWndFocus
, MouseActivate
? "TRUE" : "FALSE");
213 if ((Wnd
->style
& (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
215 DPRINT("Failed - Child\n");
219 if (0 == (Wnd
->style
& WS_VISIBLE
) &&
220 Window
->pti
->pEThread
->ThreadsProcess
!= CsrProcess
)
222 DPRINT("Failed - Invisible\n");
226 PrevForegroundQueue
= IntGetFocusMessageQueue();
227 if (PrevForegroundQueue
!= 0)
229 hWndPrev
= PrevForegroundQueue
->ActiveWindow
;
232 if (hWndPrev
== hWnd
)
234 DPRINT("Failed - Same\n");
238 hWndFocusPrev
= (PrevForegroundQueue
== FocusWindow
->pti
->MessageQueue
239 ? FocusWindow
->pti
->MessageQueue
->FocusWindow
: NULL
);
241 /* FIXME: Call hooks. */
243 co_IntSendDeactivateMessages(hWndPrev
, hWnd
);
244 co_IntSendKillFocusMessages(hWndFocusPrev
, hWndFocus
);
246 IntSetFocusMessageQueue(Window
->pti
->MessageQueue
);
247 if (Window
->pti
->MessageQueue
)
249 Window
->pti
->MessageQueue
->ActiveWindow
= hWnd
;
252 if (FocusWindow
->pti
->MessageQueue
)
254 FocusWindow
->pti
->MessageQueue
->FocusWindow
= hWndFocus
;
257 if (PrevForegroundQueue
!= Window
->pti
->MessageQueue
)
259 /* FIXME: Send WM_ACTIVATEAPP to all thread windows. */
262 co_IntSendSetFocusMessages(hWndFocusPrev
, hWndFocus
);
263 co_IntSendActivateMessages(hWndPrev
, hWnd
, MouseActivate
);
269 co_IntSetForegroundWindow(PWINDOW_OBJECT Window
)//FIXME: can Window be NULL??
271 /*if (Window)*/ ASSERT_REFS_CO(Window
);
273 return co_IntSetForegroundAndFocusWindow(Window
, Window
, FALSE
);
277 co_IntMouseActivateWindow(PWINDOW_OBJECT Window
)
280 PWINDOW_OBJECT TopWindow
;
281 USER_REFERENCE_ENTRY Ref
;
284 ASSERT_REFS_CO(Window
);
287 if(Wnd
->style
& WS_DISABLED
)
290 PWINDOW_OBJECT TopWnd
;
291 PWINDOW_OBJECT DesktopWindow
= UserGetWindowObject(IntGetDesktopWindow());
294 Top
= IntFindChildWindowToOwner(DesktopWindow
, Window
);
295 if((TopWnd
= UserGetWindowObject(Top
)))
297 UserRefObjectCo(TopWnd
, &Ref
);
298 Ret
= co_IntMouseActivateWindow(TopWnd
);
299 UserDerefObjectCo(TopWnd
);
308 TopWindow
= UserGetAncestor(Window
, GA_ROOT
);
309 if (!TopWindow
) return FALSE
;
311 /* TMN: Check return valud from this function? */
312 UserRefObjectCo(TopWindow
, &Ref
);
314 co_IntSetForegroundAndFocusWindow(TopWindow
, Window
, TRUE
);
316 UserDerefObjectCo(TopWindow
);
322 co_IntSetActiveWindow(PWINDOW_OBJECT Window OPTIONAL
)
325 PUSER_MESSAGE_QUEUE ThreadQueue
;
329 CBTACTIVATESTRUCT cbt
;
332 ASSERT_REFS_CO(Window
);
334 pti
= PsGetCurrentThreadWin32Thread();
335 ThreadQueue
= pti
->MessageQueue
;
336 ASSERT(ThreadQueue
!= 0);
341 if ((!(Wnd
->style
& WS_VISIBLE
) &&
342 Window
->pti
->pEThread
->ThreadsProcess
!= CsrProcess
) ||
343 (Wnd
->style
& (WS_POPUP
| WS_CHILD
)) == WS_CHILD
)
345 return ThreadQueue
? 0 : ThreadQueue
->ActiveWindow
;
347 hWnd
= Window
->hSelf
;
350 hWndPrev
= ThreadQueue
->ActiveWindow
;
351 if (hWndPrev
== hWnd
)
356 /* call CBT hook chain */
358 cbt
.hWndActive
= hWndPrev
;
359 if (co_HOOK_CallHooks( WH_CBT
, HCBT_ACTIVATE
, (WPARAM
)hWnd
, (LPARAM
)&cbt
))
362 ThreadQueue
->ActiveWindow
= hWnd
;
364 co_IntSendDeactivateMessages(hWndPrev
, hWnd
);
365 co_IntSendActivateMessages(hWndPrev
, hWnd
, FALSE
);
368 /* return IntIsWindow(hWndPrev) ? hWndPrev : 0;*/
374 co_IntSetFocusWindow(PWINDOW_OBJECT Window OPTIONAL
)
378 PUSER_MESSAGE_QUEUE ThreadQueue
;
381 ASSERT_REFS_CO(Window
);
383 pti
= PsGetCurrentThreadWin32Thread();
384 ThreadQueue
= pti
->MessageQueue
;
385 ASSERT(ThreadQueue
!= 0);
387 hWndPrev
= ThreadQueue
->FocusWindow
;
391 if (hWndPrev
== Window
->hSelf
)
396 if (co_HOOK_CallHooks( WH_CBT
, HCBT_SETFOCUS
, (WPARAM
)Window
->hSelf
, (LPARAM
)hWndPrev
))
399 ThreadQueue
->FocusWindow
= Window
->hSelf
;
401 co_IntSendKillFocusMessages(hWndPrev
, Window
->hSelf
);
402 co_IntSendSetFocusMessages(hWndPrev
, Window
->hSelf
);
406 ThreadQueue
->FocusWindow
= 0;
408 if (co_HOOK_CallHooks( WH_CBT
, HCBT_SETFOCUS
, (WPARAM
)0, (LPARAM
)hWndPrev
))
411 co_IntSendKillFocusMessages(hWndPrev
, 0);
421 UserGetForegroundWindow(VOID
)
423 PUSER_MESSAGE_QUEUE ForegroundQueue
;
425 ForegroundQueue
= IntGetFocusMessageQueue();
426 return( ForegroundQueue
!= NULL
? ForegroundQueue
->ActiveWindow
: 0);
434 NtUserGetForegroundWindow(VOID
)
436 DECLARE_RETURN(HWND
);
438 DPRINT("Enter NtUserGetForegroundWindow\n");
439 UserEnterExclusive();
441 RETURN( UserGetForegroundWindow());
444 DPRINT("Leave NtUserGetForegroundWindow, ret=%i\n",_ret_
);
450 HWND FASTCALL
UserGetActiveWindow(VOID
)
453 PUSER_MESSAGE_QUEUE ThreadQueue
;
455 pti
= PsGetCurrentThreadWin32Thread();
456 ThreadQueue
= pti
->MessageQueue
;
457 return( ThreadQueue
? ThreadQueue
->ActiveWindow
: 0);
462 NtUserSetActiveWindow(HWND hWnd
)
464 USER_REFERENCE_ENTRY Ref
;
465 DECLARE_RETURN(HWND
);
467 DPRINT("Enter NtUserSetActiveWindow(%x)\n", hWnd
);
468 UserEnterExclusive();
472 PWINDOW_OBJECT Window
;
474 PUSER_MESSAGE_QUEUE ThreadQueue
;
477 if (!(Window
= UserGetWindowObject(hWnd
)))
482 pti
= PsGetCurrentThreadWin32Thread();
483 ThreadQueue
= pti
->MessageQueue
;
485 if (Window
->pti
->MessageQueue
!= ThreadQueue
)
487 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
491 UserRefObjectCo(Window
, &Ref
);
492 hWndPrev
= co_IntSetActiveWindow(Window
);
493 UserDerefObjectCo(Window
);
499 RETURN( co_IntSetActiveWindow(0));
503 DPRINT("Leave NtUserSetActiveWindow, ret=%i\n",_ret_
);
515 PUSER_MESSAGE_QUEUE ThreadQueue
;
516 DECLARE_RETURN(HWND
);
518 DPRINT("Enter IntGetCapture\n");
520 pti
= PsGetCurrentThreadWin32Thread();
521 ThreadQueue
= pti
->MessageQueue
;
522 RETURN( ThreadQueue
? ThreadQueue
->CaptureWindow
: 0);
525 DPRINT("Leave IntGetCapture, ret=%i\n",_ret_
);
533 NtUserSetCapture(HWND hWnd
)
536 PUSER_MESSAGE_QUEUE ThreadQueue
;
537 PWINDOW_OBJECT Window
;
539 DECLARE_RETURN(HWND
);
541 DPRINT("Enter NtUserSetCapture(%x)\n", hWnd
);
542 UserEnterExclusive();
544 pti
= PsGetCurrentThreadWin32Thread();
545 ThreadQueue
= pti
->MessageQueue
;
547 if((Window
= UserGetWindowObject(hWnd
)))
549 if(Window
->pti
->MessageQueue
!= ThreadQueue
)
555 hWndPrev
= MsqSetStateWindow(ThreadQueue
, MSQ_STATE_CAPTURE
, hWnd
);
557 /* also remove other windows if not capturing anymore */
560 MsqSetStateWindow(ThreadQueue
, MSQ_STATE_MENUOWNER
, NULL
);
561 MsqSetStateWindow(ThreadQueue
, MSQ_STATE_MOVESIZE
, NULL
);
564 co_IntPostOrSendMessage(hWndPrev
, WM_CAPTURECHANGED
, 0, (LPARAM
)hWnd
);
565 ThreadQueue
->CaptureWindow
= hWnd
;
570 DPRINT("Leave NtUserSetCapture, ret=%i\n",_ret_
);
577 HWND FASTCALL
co_UserSetFocus(PWINDOW_OBJECT Window OPTIONAL
)
582 PUSER_MESSAGE_QUEUE ThreadQueue
;
584 PWINDOW_OBJECT TopWnd
;
585 USER_REFERENCE_ENTRY Ref
;
588 ASSERT_REFS_CO(Window
);
590 pti
= PsGetCurrentThreadWin32Thread();
591 ThreadQueue
= pti
->MessageQueue
;
594 if (Wnd
->style
& (WS_MINIMIZE
| WS_DISABLED
))
596 return( (ThreadQueue
? ThreadQueue
->FocusWindow
: 0));
599 if (Window
->pti
->MessageQueue
!= ThreadQueue
)
601 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
605 TopWnd
= UserGetAncestor(Window
, GA_ROOT
);
606 if (TopWnd
&& TopWnd
->hSelf
!= UserGetActiveWindow())
608 // PWINDOW_OBJECT WndTops = UserGetWindowObject(hWndTop);
609 UserRefObjectCo(TopWnd
, &Ref
);
610 co_IntSetActiveWindow(TopWnd
);
611 UserDerefObjectCo(TopWnd
);
614 hWndPrev
= co_IntSetFocusWindow(Window
);
620 return( co_IntSetFocusWindow(NULL
));
630 NtUserSetFocus(HWND hWnd
)
632 PWINDOW_OBJECT Window
;
633 USER_REFERENCE_ENTRY Ref
;
634 DECLARE_RETURN(HWND
);
637 DPRINT("Enter NtUserSetFocus(%x)\n", hWnd
);
638 UserEnterExclusive();
642 if (!(Window
= UserGetWindowObject(hWnd
)))
647 UserRefObjectCo(Window
, &Ref
);
648 ret
= co_UserSetFocus(Window
);
649 UserDerefObjectCo(Window
);
655 RETURN( co_UserSetFocus(0));
659 DPRINT("Leave NtUserSetFocus, ret=%i\n",_ret_
);