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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 PUSER_MESSAGE_QUEUE ForegroundQueue
= IntGetFocusMessageQueue();
30 return ForegroundQueue
!= NULL
? ForegroundQueue
->CaptureWindow
: 0;
36 PUSER_MESSAGE_QUEUE ForegroundQueue
= IntGetFocusMessageQueue();
37 return ForegroundQueue
!= NULL
? ForegroundQueue
->FocusWindow
: 0;
41 IntGetThreadFocusWindow()
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 co_IntPostOrSendMessage(HWND_BROADCAST
, WM_PALETTEISCHANGING
,
84 if (UserGetWindow(hWnd
, GW_HWNDPREV
) != NULL
)
85 co_WinPosSetWindowPos(Window
, HWND_TOP
, 0, 0, 0, 0,
86 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
| SWP_NOSENDCHANGING
);
88 if (!IntGetOwner(Window
) && !IntGetParent(Window
))
90 co_IntShellHookNotify(HSHELL_WINDOWACTIVATED
, (LPARAM
) hWnd
);
94 { // Set last active for window and it's owner.
95 Window
->Wnd
->hWndLastActive
= hWnd
;
96 if (Window
->Wnd
->Owner
)
97 Window
->Wnd
->Owner
->hWndLastActive
= hWnd
;
100 if (Window
&& WindowPrev
)
102 PWINDOW_OBJECT cWindow
;
104 HANDLE OldTID
= IntGetWndThreadId(WindowPrev
);
105 HANDLE NewTID
= IntGetWndThreadId(Window
);
107 DPRINT("SendActiveMessage Old -> %x, New -> %x\n", OldTID
, NewTID
);
109 if (OldTID
!= NewTID
)
111 List
= IntWinListChildren(UserGetWindowObject(IntGetDesktopWindow()));
114 for (phWnd
= List
; *phWnd
; ++phWnd
)
116 cWindow
= UserGetWindowObject(*phWnd
);
117 if (cWindow
&& (IntGetWndThreadId(cWindow
) == OldTID
))
118 { // FALSE if the window is being deactivated,
119 // ThreadId that owns the window being activated.
120 co_IntPostOrSendMessage(*phWnd
, WM_ACTIVATEAPP
, FALSE
, (LPARAM
)NewTID
);
123 for (phWnd
= List
; *phWnd
; ++phWnd
)
125 cWindow
= UserGetWindowObject(*phWnd
);
126 if (cWindow
&& (IntGetWndThreadId(cWindow
) == NewTID
))
127 { // TRUE if the window is being activated,
128 // ThreadId that owns the window being deactivated.
129 co_IntPostOrSendMessage(*phWnd
, WM_ACTIVATEAPP
, TRUE
, (LPARAM
)OldTID
);
135 UserDerefObjectCo(WindowPrev
); // Now allow the previous window to die.
138 UserDerefObjectCo(Window
);
140 /* FIXME: IntIsWindow */
142 co_IntPostOrSendMessage(hWnd
, WM_NCACTIVATE
, (WPARAM
)(hWnd
== UserGetForegroundWindow()), 0);
143 /* FIXME: WA_CLICKACTIVE */
144 co_IntPostOrSendMessage(hWnd
, WM_ACTIVATE
,
145 MAKEWPARAM(MouseActivate
? WA_CLICKACTIVE
: WA_ACTIVE
,
146 UserGetWindowLong(hWnd
, GWL_STYLE
, FALSE
) & WS_MINIMIZE
),
152 co_IntSendKillFocusMessages(HWND hWndPrev
, HWND hWnd
)
156 co_IntPostOrSendMessage(hWndPrev
, WM_KILLFOCUS
, (WPARAM
)hWnd
, 0);
161 co_IntSendSetFocusMessages(HWND hWndPrev
, HWND hWnd
)
165 co_IntPostOrSendMessage(hWnd
, WM_SETFOCUS
, (WPARAM
)hWndPrev
, 0);
170 IntFindChildWindowToOwner(PWINDOW_OBJECT Root
, PWINDOW_OBJECT Owner
)
173 PWINDOW_OBJECT Child
, OwnerWnd
;
175 for(Child
= Root
->FirstChild
; Child
; Child
= Child
->NextSibling
)
177 OwnerWnd
= UserGetWindowObject(Child
->hOwner
);
181 if(OwnerWnd
== Owner
)
192 co_IntSetForegroundAndFocusWindow(PWINDOW_OBJECT Window
, PWINDOW_OBJECT FocusWindow
, BOOL MouseActivate
)
194 HWND hWnd
= Window
->hSelf
;
195 HWND hWndPrev
= NULL
;
196 HWND hWndFocus
= FocusWindow
->hSelf
;
197 HWND hWndFocusPrev
= NULL
;
198 PUSER_MESSAGE_QUEUE PrevForegroundQueue
;
201 ASSERT_REFS_CO(Window
);
203 DPRINT("IntSetForegroundAndFocusWindow(%x, %x, %s)\n", hWnd
, hWndFocus
, MouseActivate
? "TRUE" : "FALSE");
207 if ((Wnd
->Style
& (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
209 DPRINT("Failed - Child\n");
213 if (0 == (Wnd
->Style
& WS_VISIBLE
) &&
214 Window
->OwnerThread
->ThreadsProcess
!= CsrProcess
)
216 DPRINT("Failed - Invisible\n");
220 PrevForegroundQueue
= IntGetFocusMessageQueue();
221 if (PrevForegroundQueue
!= 0)
223 hWndPrev
= PrevForegroundQueue
->ActiveWindow
;
226 if (hWndPrev
== hWnd
)
228 DPRINT("Failed - Same\n");
232 hWndFocusPrev
= (PrevForegroundQueue
== FocusWindow
->MessageQueue
233 ? FocusWindow
->MessageQueue
->FocusWindow
: NULL
);
235 /* FIXME: Call hooks. */
237 co_IntSendDeactivateMessages(hWndPrev
, hWnd
);
238 co_IntSendKillFocusMessages(hWndFocusPrev
, hWndFocus
);
240 IntSetFocusMessageQueue(Window
->MessageQueue
);
241 if (Window
->MessageQueue
)
243 Window
->MessageQueue
->ActiveWindow
= hWnd
;
246 if (FocusWindow
->MessageQueue
)
248 FocusWindow
->MessageQueue
->FocusWindow
= hWndFocus
;
251 if (PrevForegroundQueue
!= Window
->MessageQueue
)
253 /* FIXME: Send WM_ACTIVATEAPP to all thread windows. */
256 co_IntSendSetFocusMessages(hWndFocusPrev
, hWndFocus
);
257 co_IntSendActivateMessages(hWndPrev
, hWnd
, MouseActivate
);
263 co_IntSetForegroundWindow(PWINDOW_OBJECT Window
)//FIXME: can Window be NULL??
265 /*if (Window)*/ ASSERT_REFS_CO(Window
);
267 return co_IntSetForegroundAndFocusWindow(Window
, Window
, FALSE
);
271 co_IntMouseActivateWindow(PWINDOW_OBJECT Window
)
274 PWINDOW_OBJECT TopWindow
;
275 USER_REFERENCE_ENTRY Ref
;
278 ASSERT_REFS_CO(Window
);
281 if(Wnd
->Style
& WS_DISABLED
)
284 PWINDOW_OBJECT TopWnd
;
285 PWINDOW_OBJECT DesktopWindow
= UserGetWindowObject(IntGetDesktopWindow());
288 Top
= IntFindChildWindowToOwner(DesktopWindow
, Window
);
289 if((TopWnd
= UserGetWindowObject(Top
)))
291 UserRefObjectCo(TopWnd
, &Ref
);
292 Ret
= co_IntMouseActivateWindow(TopWnd
);
293 UserDerefObjectCo(TopWnd
);
302 TopWindow
= UserGetAncestor(Window
, GA_ROOT
);
303 if (!TopWindow
) return FALSE
;
305 /* TMN: Check return valud from this function? */
306 UserRefObjectCo(TopWindow
, &Ref
);
308 co_IntSetForegroundAndFocusWindow(TopWindow
, Window
, TRUE
);
310 UserDerefObjectCo(TopWindow
);
316 co_IntSetActiveWindow(PWINDOW_OBJECT Window OPTIONAL
)
319 PUSER_MESSAGE_QUEUE ThreadQueue
;
325 ASSERT_REFS_CO(Window
);
327 pti
= PsGetCurrentThreadWin32Thread();
328 ThreadQueue
= pti
->MessageQueue
;
329 ASSERT(ThreadQueue
!= 0);
334 if ((!(Wnd
->Style
& WS_VISIBLE
) &&
335 Window
->OwnerThread
->ThreadsProcess
!= CsrProcess
) ||
336 (Wnd
->Style
& (WS_POPUP
| WS_CHILD
)) == WS_CHILD
)
338 return ThreadQueue
? 0 : ThreadQueue
->ActiveWindow
;
340 hWnd
= Window
->hSelf
;
343 hWndPrev
= ThreadQueue
->ActiveWindow
;
344 if (hWndPrev
== hWnd
)
349 /* FIXME: Call hooks. */
351 ThreadQueue
->ActiveWindow
= hWnd
;
353 co_IntSendDeactivateMessages(hWndPrev
, hWnd
);
354 co_IntSendActivateMessages(hWndPrev
, hWnd
, FALSE
);
357 /* return IntIsWindow(hWndPrev) ? hWndPrev : 0;*/
363 co_IntSetFocusWindow(PWINDOW_OBJECT Window OPTIONAL
)
367 PUSER_MESSAGE_QUEUE ThreadQueue
;
370 ASSERT_REFS_CO(Window
);
372 pti
= PsGetCurrentThreadWin32Thread();
373 ThreadQueue
= pti
->MessageQueue
;
374 ASSERT(ThreadQueue
!= 0);
376 hWndPrev
= ThreadQueue
->FocusWindow
;
380 if (hWndPrev
== Window
->hSelf
)
385 ThreadQueue
->FocusWindow
= Window
->hSelf
;
387 co_IntSendKillFocusMessages(hWndPrev
, Window
->hSelf
);
388 co_IntSendSetFocusMessages(hWndPrev
, Window
->hSelf
);
392 ThreadQueue
->FocusWindow
= 0;
394 co_IntSendKillFocusMessages(hWndPrev
, 0);
404 UserGetForegroundWindow(VOID
)
406 PUSER_MESSAGE_QUEUE ForegroundQueue
;
408 ForegroundQueue
= IntGetFocusMessageQueue();
409 return( ForegroundQueue
!= NULL
? ForegroundQueue
->ActiveWindow
: 0);
417 NtUserGetForegroundWindow(VOID
)
419 DECLARE_RETURN(HWND
);
421 DPRINT("Enter NtUserGetForegroundWindow\n");
422 UserEnterExclusive();
424 RETURN( UserGetForegroundWindow());
427 DPRINT("Leave NtUserGetForegroundWindow, ret=%i\n",_ret_
);
433 HWND FASTCALL
UserGetActiveWindow()
436 PUSER_MESSAGE_QUEUE ThreadQueue
;
438 pti
= PsGetCurrentThreadWin32Thread();
439 ThreadQueue
= pti
->MessageQueue
;
440 return( ThreadQueue
? ThreadQueue
->ActiveWindow
: 0);
445 NtUserSetActiveWindow(HWND hWnd
)
447 USER_REFERENCE_ENTRY Ref
;
448 DECLARE_RETURN(HWND
);
450 DPRINT("Enter NtUserSetActiveWindow(%x)\n", hWnd
);
451 UserEnterExclusive();
455 PWINDOW_OBJECT Window
;
457 PUSER_MESSAGE_QUEUE ThreadQueue
;
460 if (!(Window
= UserGetWindowObject(hWnd
)))
465 pti
= PsGetCurrentThreadWin32Thread();
466 ThreadQueue
= pti
->MessageQueue
;
468 if (Window
->MessageQueue
!= ThreadQueue
)
470 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
474 UserRefObjectCo(Window
, &Ref
);
475 hWndPrev
= co_IntSetActiveWindow(Window
);
476 UserDerefObjectCo(Window
);
482 RETURN( co_IntSetActiveWindow(0));
486 DPRINT("Leave NtUserSetActiveWindow, ret=%i\n",_ret_
);
498 PUSER_MESSAGE_QUEUE ThreadQueue
;
499 DECLARE_RETURN(HWND
);
501 DPRINT("Enter IntGetCapture\n");
503 pti
= PsGetCurrentThreadWin32Thread();
504 ThreadQueue
= pti
->MessageQueue
;
505 RETURN( ThreadQueue
? ThreadQueue
->CaptureWindow
: 0);
508 DPRINT("Leave IntGetCapture, ret=%i\n",_ret_
);
516 NtUserSetCapture(HWND hWnd
)
519 PUSER_MESSAGE_QUEUE ThreadQueue
;
520 PWINDOW_OBJECT Window
;
522 DECLARE_RETURN(HWND
);
524 DPRINT("Enter NtUserSetCapture(%x)\n", hWnd
);
525 UserEnterExclusive();
527 pti
= PsGetCurrentThreadWin32Thread();
528 ThreadQueue
= pti
->MessageQueue
;
530 if((Window
= UserGetWindowObject(hWnd
)))
532 if(Window
->MessageQueue
!= ThreadQueue
)
538 hWndPrev
= MsqSetStateWindow(ThreadQueue
, MSQ_STATE_CAPTURE
, hWnd
);
540 /* also remove other windows if not capturing anymore */
543 MsqSetStateWindow(ThreadQueue
, MSQ_STATE_MENUOWNER
, NULL
);
544 MsqSetStateWindow(ThreadQueue
, MSQ_STATE_MOVESIZE
, NULL
);
547 co_IntPostOrSendMessage(hWndPrev
, WM_CAPTURECHANGED
, 0, (LPARAM
)hWnd
);
548 ThreadQueue
->CaptureWindow
= hWnd
;
553 DPRINT("Leave NtUserSetCapture, ret=%i\n",_ret_
);
560 HWND FASTCALL
co_UserSetFocus(PWINDOW_OBJECT Window OPTIONAL
)
565 PUSER_MESSAGE_QUEUE ThreadQueue
;
567 PWINDOW_OBJECT TopWnd
;
568 USER_REFERENCE_ENTRY Ref
;
571 ASSERT_REFS_CO(Window
);
573 pti
= PsGetCurrentThreadWin32Thread();
574 ThreadQueue
= pti
->MessageQueue
;
577 if (Wnd
->Style
& (WS_MINIMIZE
| WS_DISABLED
))
579 return( (ThreadQueue
? ThreadQueue
->FocusWindow
: 0));
582 if (Window
->MessageQueue
!= ThreadQueue
)
584 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
588 TopWnd
= UserGetAncestor(Window
, GA_ROOT
);
589 if (TopWnd
&& TopWnd
->hSelf
!= UserGetActiveWindow())
591 // PWINDOW_OBJECT WndTops = UserGetWindowObject(hWndTop);
592 UserRefObjectCo(TopWnd
, &Ref
);
593 co_IntSetActiveWindow(TopWnd
);
594 UserDerefObjectCo(TopWnd
);
597 hWndPrev
= co_IntSetFocusWindow(Window
);
603 return( co_IntSetFocusWindow(NULL
));
613 NtUserSetFocus(HWND hWnd
)
615 PWINDOW_OBJECT Window
;
616 USER_REFERENCE_ENTRY Ref
;
617 DECLARE_RETURN(HWND
);
620 DPRINT("Enter NtUserSetFocus(%x)\n", hWnd
);
621 UserEnterExclusive();
625 if (!(Window
= UserGetWindowObject(hWnd
)))
630 UserRefObjectCo(Window
, &Ref
);
631 ret
= co_UserSetFocus(Window
);
632 UserDerefObjectCo(Window
);
638 RETURN( co_UserSetFocus(0));
642 DPRINT("Leave NtUserSetFocus, ret=%i\n",_ret_
);