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 if (hWndPrev
&& (WndPrev
= UserGetWindowObject(hWndPrev
)))
58 co_IntSendMessageNoWait(hWndPrev
, WM_NCACTIVATE
, FALSE
, 0);
59 co_IntSendMessageNoWait(hWndPrev
, WM_ACTIVATE
,
60 MAKEWPARAM(WA_INACTIVE
, WndPrev
->style
& WS_MINIMIZE
),
66 co_IntSendActivateMessages(HWND hWndPrev
, HWND hWnd
, BOOL MouseActivate
)
68 USER_REFERENCE_ENTRY Ref
, RefPrev
;
69 PWND Window
, WindowPrev
= NULL
;
71 if ((Window
= UserGetWindowObject(hWnd
)))
73 UserRefObjectCo(Window
, &Ref
);
75 WindowPrev
= UserGetWindowObject(hWndPrev
);
77 if (WindowPrev
) UserRefObjectCo(WindowPrev
, &RefPrev
);
79 /* Send palette messages */
80 if (co_IntPostOrSendMessage(hWnd
, WM_QUERYNEWPALETTE
, 0, 0))
82 UserPostMessage( HWND_BROADCAST
,
88 if (Window
->spwndPrev
!= NULL
)
89 co_WinPosSetWindowPos(Window
, HWND_TOP
, 0, 0, 0, 0,
90 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOSENDCHANGING
);
92 if (!Window
->spwndOwner
&& !IntGetParent(Window
))
94 co_IntShellHookNotify(HSHELL_WINDOWACTIVATED
, (LPARAM
) hWnd
);
98 { // Set last active for window and it's owner.
99 Window
->hWndLastActive
= hWnd
;
100 if (Window
->spwndOwner
)
101 Window
->spwndOwner
->hWndLastActive
= hWnd
;
102 Window
->state
|= WNDS_ACTIVEFRAME
;
106 WindowPrev
->state
&= ~WNDS_ACTIVEFRAME
;
108 if (Window
&& WindowPrev
)
112 HANDLE OldTID
= IntGetWndThreadId(WindowPrev
);
113 HANDLE NewTID
= IntGetWndThreadId(Window
);
115 DPRINT("SendActiveMessage Old -> %x, New -> %x\n", OldTID
, NewTID
);
116 if (Window
->style
& WS_MINIMIZE
)
118 DPRINT("Widow was minimized\n");
121 if (OldTID
!= NewTID
)
123 List
= IntWinListChildren(UserGetWindowObject(IntGetDesktopWindow()));
126 for (phWnd
= List
; *phWnd
; ++phWnd
)
128 cWindow
= UserGetWindowObject(*phWnd
);
130 if (cWindow
&& (IntGetWndThreadId(cWindow
) == OldTID
))
131 { // FALSE if the window is being deactivated,
132 // ThreadId that owns the window being activated.
133 co_IntSendMessageNoWait(*phWnd
, WM_ACTIVATEAPP
, FALSE
, (LPARAM
)NewTID
);
136 for (phWnd
= List
; *phWnd
; ++phWnd
)
138 cWindow
= UserGetWindowObject(*phWnd
);
139 if (cWindow
&& (IntGetWndThreadId(cWindow
) == NewTID
))
140 { // TRUE if the window is being activated,
141 // ThreadId that owns the window being deactivated.
142 co_IntSendMessageNoWait(*phWnd
, WM_ACTIVATEAPP
, TRUE
, (LPARAM
)OldTID
);
148 UserDerefObjectCo(WindowPrev
); // Now allow the previous window to die.
151 UserDerefObjectCo(Window
);
153 /* FIXME: IntIsWindow */
154 co_IntSendMessageNoWait(hWnd
, WM_NCACTIVATE
, (WPARAM
)(hWnd
== UserGetForegroundWindow()), 0);
155 /* FIXME: WA_CLICKACTIVE */
156 co_IntSendMessageNoWait(hWnd
, WM_ACTIVATE
,
157 MAKEWPARAM(MouseActivate
? WA_CLICKACTIVE
: WA_ACTIVE
,
158 Window
->style
& WS_MINIMIZE
),
164 co_IntSendKillFocusMessages(HWND hWndPrev
, HWND hWnd
)
168 IntNotifyWinEvent(EVENT_OBJECT_FOCUS
, NULL
, OBJID_CLIENT
, CHILDID_SELF
, 0);
169 co_IntPostOrSendMessage(hWndPrev
, WM_KILLFOCUS
, (WPARAM
)hWnd
, 0);
174 co_IntSendSetFocusMessages(HWND hWndPrev
, HWND hWnd
)
178 PWND pWnd
= UserGetWindowObject(hWnd
);
179 IntNotifyWinEvent(EVENT_OBJECT_FOCUS
, pWnd
, OBJID_CLIENT
, CHILDID_SELF
, 0);
180 co_IntPostOrSendMessage(hWnd
, WM_SETFOCUS
, (WPARAM
)hWndPrev
, 0);
185 IntFindChildWindowToOwner(PWND Root
, PWND Owner
)
188 PWND Child
, OwnerWnd
;
190 for(Child
= Root
->spwndChild
; Child
; Child
= Child
->spwndNext
)
192 OwnerWnd
= Child
->spwndOwner
;
196 if(OwnerWnd
== Owner
)
207 co_IntSetForegroundAndFocusWindow(PWND Wnd
, PWND FocusWindow
, BOOL MouseActivate
)
209 HWND hWnd
= Wnd
->head
.h
;
210 HWND hWndPrev
= NULL
;
211 HWND hWndFocus
= FocusWindow
->head
.h
;
212 HWND hWndFocusPrev
= NULL
;
213 PUSER_MESSAGE_QUEUE PrevForegroundQueue
;
217 DPRINT("IntSetForegroundAndFocusWindow(%x, %x, %s)\n", hWnd
, hWndFocus
, MouseActivate
? "TRUE" : "FALSE");
219 if ((Wnd
->style
& (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
221 DPRINT("Failed - Child\n");
225 if (0 == (Wnd
->style
& WS_VISIBLE
) &&
226 Wnd
->head
.pti
->pEThread
->ThreadsProcess
!= CsrProcess
)
228 DPRINT("Failed - Invisible\n");
232 PrevForegroundQueue
= IntGetFocusMessageQueue();
233 if (PrevForegroundQueue
!= 0)
235 hWndPrev
= PrevForegroundQueue
->ActiveWindow
;
236 hWndFocusPrev
= PrevForegroundQueue
->FocusWindow
;
239 if (hWndPrev
== hWnd
)
241 DPRINT("Failed - Same\n");
245 /* FIXME: Call hooks. */
247 co_IntSendDeactivateMessages(hWndPrev
, hWnd
);
248 co_IntSendKillFocusMessages(hWndFocusPrev
, hWndFocus
);
251 IntSetFocusMessageQueue(Wnd
->head
.pti
->MessageQueue
);
253 if (Wnd
->head
.pti
->MessageQueue
)
255 Wnd
->head
.pti
->MessageQueue
->ActiveWindow
= hWnd
;
258 if (FocusWindow
->head
.pti
->MessageQueue
)
260 FocusWindow
->head
.pti
->MessageQueue
->FocusWindow
= hWndFocus
;
263 if (PrevForegroundQueue
!= Wnd
->head
.pti
->MessageQueue
)
265 /* FIXME: Send WM_ACTIVATEAPP to all thread windows. */
268 co_IntSendSetFocusMessages(hWndFocusPrev
, hWndFocus
);
269 co_IntSendActivateMessages(hWndPrev
, hWnd
, MouseActivate
);
275 co_IntSetForegroundWindow(PWND Window
)//FIXME: can Window be NULL??
277 /*if (Window)*/ ASSERT_REFS_CO(Window
);
279 return co_IntSetForegroundAndFocusWindow(Window
, Window
, FALSE
);
283 co_IntMouseActivateWindow(PWND Wnd
)
287 USER_REFERENCE_ENTRY Ref
;
291 if(Wnd
->style
& WS_DISABLED
)
295 PWND DesktopWindow
= UserGetWindowObject(IntGetDesktopWindow());
298 Top
= IntFindChildWindowToOwner(DesktopWindow
, Wnd
);
299 if((TopWnd
= UserGetWindowObject(Top
)))
301 UserRefObjectCo(TopWnd
, &Ref
);
302 Ret
= co_IntMouseActivateWindow(TopWnd
);
303 UserDerefObjectCo(TopWnd
);
312 TopWindow
= UserGetAncestor(Wnd
, GA_ROOT
);
313 if (!TopWindow
) return FALSE
;
315 /* TMN: Check return valud from this function? */
316 UserRefObjectCo(TopWindow
, &Ref
);
318 co_IntSetForegroundAndFocusWindow(TopWindow
, Wnd
, TRUE
);
320 UserDerefObjectCo(TopWindow
);
326 co_IntSetActiveWindow(PWND Wnd OPTIONAL
)
329 PUSER_MESSAGE_QUEUE ThreadQueue
;
332 CBTACTIVATESTRUCT cbt
;
337 pti
= PsGetCurrentThreadWin32Thread();
338 ThreadQueue
= pti
->MessageQueue
;
339 ASSERT(ThreadQueue
!= 0);
343 if ((!(Wnd
->style
& WS_VISIBLE
) &&
344 Wnd
->head
.pti
->pEThread
->ThreadsProcess
!= CsrProcess
) ||
345 (Wnd
->style
& (WS_POPUP
| WS_CHILD
)) == WS_CHILD
)
347 return ThreadQueue
? 0 : ThreadQueue
->ActiveWindow
;
352 hWndPrev
= ThreadQueue
->ActiveWindow
;
353 if (hWndPrev
== hWnd
)
358 /* call CBT hook chain */
360 cbt
.hWndActive
= hWndPrev
;
361 if (co_HOOK_CallHooks( WH_CBT
, HCBT_ACTIVATE
, (WPARAM
)hWnd
, (LPARAM
)&cbt
))
363 DPRINT1("SetActiveWindow WH_CBT Call Hook return!\n");
366 ThreadQueue
->ActiveWindow
= hWnd
;
368 co_IntSendDeactivateMessages(hWndPrev
, hWnd
);
369 co_IntSendActivateMessages(hWndPrev
, hWnd
, FALSE
);
372 /* return IntIsWindow(hWndPrev) ? hWndPrev : 0;*/
378 co_IntSetFocusWindow(PWND Window OPTIONAL
)
382 PUSER_MESSAGE_QUEUE ThreadQueue
;
385 ASSERT_REFS_CO(Window
);
387 pti
= PsGetCurrentThreadWin32Thread();
388 ThreadQueue
= pti
->MessageQueue
;
389 ASSERT(ThreadQueue
!= 0);
391 hWndPrev
= ThreadQueue
->FocusWindow
;
395 if (hWndPrev
== Window
->head
.h
)
400 if (co_HOOK_CallHooks( WH_CBT
, HCBT_SETFOCUS
, (WPARAM
)Window
->head
.h
, (LPARAM
)hWndPrev
))
402 DPRINT1("SetFocusWindow 1 WH_CBT Call Hook return!\n");
405 ThreadQueue
->FocusWindow
= Window
->head
.h
;
407 co_IntSendKillFocusMessages(hWndPrev
, Window
->head
.h
);
408 co_IntSendSetFocusMessages(hWndPrev
, Window
->head
.h
);
412 ThreadQueue
->FocusWindow
= 0;
413 if (co_HOOK_CallHooks( WH_CBT
, HCBT_SETFOCUS
, (WPARAM
)0, (LPARAM
)hWndPrev
))
415 DPRINT1("SetFocusWindow 2 WH_CBT Call Hook return!\n");
419 co_IntSendKillFocusMessages(hWndPrev
, 0);
429 UserGetForegroundWindow(VOID
)
431 PUSER_MESSAGE_QUEUE ForegroundQueue
;
433 ForegroundQueue
= IntGetFocusMessageQueue();
434 return( ForegroundQueue
!= NULL
? ForegroundQueue
->ActiveWindow
: 0);
442 NtUserGetForegroundWindow(VOID
)
444 DECLARE_RETURN(HWND
);
446 DPRINT("Enter NtUserGetForegroundWindow\n");
447 UserEnterExclusive();
449 RETURN( UserGetForegroundWindow());
452 DPRINT("Leave NtUserGetForegroundWindow, ret=%i\n",_ret_
);
458 HWND FASTCALL
UserGetActiveWindow(VOID
)
461 PUSER_MESSAGE_QUEUE ThreadQueue
;
463 pti
= PsGetCurrentThreadWin32Thread();
464 ThreadQueue
= pti
->MessageQueue
;
465 return( ThreadQueue
? ThreadQueue
->ActiveWindow
: 0);
470 NtUserSetActiveWindow(HWND hWnd
)
472 USER_REFERENCE_ENTRY Ref
;
473 DECLARE_RETURN(HWND
);
475 DPRINT("Enter NtUserSetActiveWindow(%x)\n", hWnd
);
476 UserEnterExclusive();
482 PUSER_MESSAGE_QUEUE ThreadQueue
;
485 if (!(Window
= UserGetWindowObject(hWnd
)))
490 pti
= PsGetCurrentThreadWin32Thread();
491 ThreadQueue
= pti
->MessageQueue
;
493 if (Window
->head
.pti
->MessageQueue
!= ThreadQueue
)
495 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
499 UserRefObjectCo(Window
, &Ref
);
500 hWndPrev
= co_IntSetActiveWindow(Window
);
501 UserDerefObjectCo(Window
);
507 RETURN( co_IntSetActiveWindow(0));
511 DPRINT("Leave NtUserSetActiveWindow, ret=%i\n",_ret_
);
523 PUSER_MESSAGE_QUEUE ThreadQueue
;
524 DECLARE_RETURN(HWND
);
526 DPRINT("Enter IntGetCapture\n");
528 pti
= PsGetCurrentThreadWin32Thread();
529 ThreadQueue
= pti
->MessageQueue
;
530 RETURN( ThreadQueue
? ThreadQueue
->CaptureWindow
: 0);
533 DPRINT("Leave IntGetCapture, ret=%i\n",_ret_
);
541 NtUserSetCapture(HWND hWnd
)
544 PUSER_MESSAGE_QUEUE ThreadQueue
;
547 DECLARE_RETURN(HWND
);
549 DPRINT("Enter NtUserSetCapture(%x)\n", hWnd
);
550 UserEnterExclusive();
552 pti
= PsGetCurrentThreadWin32Thread();
553 ThreadQueue
= pti
->MessageQueue
;
555 if((Window
= UserGetWindowObject(hWnd
)))
557 if(Window
->head
.pti
->MessageQueue
!= ThreadQueue
)
563 hWndPrev
= MsqSetStateWindow(ThreadQueue
, MSQ_STATE_CAPTURE
, hWnd
);
567 pWnd
= UserGetWindowObject(hWndPrev
);
569 IntNotifyWinEvent(EVENT_SYSTEM_CAPTUREEND
, pWnd
, OBJID_WINDOW
, CHILDID_SELF
, WEF_SETBYWNDPTI
);
572 /* also remove other windows if not capturing anymore */
575 MsqSetStateWindow(ThreadQueue
, MSQ_STATE_MENUOWNER
, NULL
);
576 MsqSetStateWindow(ThreadQueue
, MSQ_STATE_MOVESIZE
, NULL
);
580 IntNotifyWinEvent(EVENT_SYSTEM_CAPTURESTART
, Window
, OBJID_WINDOW
, CHILDID_SELF
, WEF_SETBYWNDPTI
);
582 co_IntPostOrSendMessage(hWndPrev
, WM_CAPTURECHANGED
, 0, (LPARAM
)hWnd
);
583 ThreadQueue
->CaptureWindow
= hWnd
;
588 DPRINT("Leave NtUserSetCapture, ret=%i\n",_ret_
);
595 HWND FASTCALL
co_UserSetFocus(PWND Wnd OPTIONAL
)
600 PUSER_MESSAGE_QUEUE ThreadQueue
;
603 USER_REFERENCE_ENTRY Ref
;
607 pti
= PsGetCurrentThreadWin32Thread();
608 ThreadQueue
= pti
->MessageQueue
;
610 if (Wnd
->style
& (WS_MINIMIZE
| WS_DISABLED
))
612 return( (ThreadQueue
? ThreadQueue
->FocusWindow
: 0));
615 if (Wnd
->head
.pti
->MessageQueue
!= ThreadQueue
)
617 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
621 TopWnd
= UserGetAncestor(Wnd
, GA_ROOT
);
622 if (TopWnd
&& TopWnd
->head
.h
!= UserGetActiveWindow())
624 // PWND WndTops = UserGetWindowObject(hWndTop);
625 UserRefObjectCo(TopWnd
, &Ref
);
626 co_IntSetActiveWindow(TopWnd
);
627 UserDerefObjectCo(TopWnd
);
630 hWndPrev
= co_IntSetFocusWindow(Wnd
);
636 return( co_IntSetFocusWindow(NULL
));
646 NtUserSetFocus(HWND hWnd
)
649 USER_REFERENCE_ENTRY Ref
;
650 DECLARE_RETURN(HWND
);
653 DPRINT("Enter NtUserSetFocus(%x)\n", hWnd
);
654 UserEnterExclusive();
658 if (!(Window
= UserGetWindowObject(hWnd
)))
663 UserRefObjectCo(Window
, &Ref
);
664 ret
= co_UserSetFocus(Window
);
665 UserDerefObjectCo(Window
);
671 RETURN( co_UserSetFocus(0));
675 DPRINT("Leave NtUserSetFocus, ret=%i\n",_ret_
);