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_IntSendMessageNoWait(hWndPrev
, WM_NCACTIVATE
, FALSE
, 0);
57 co_IntSendMessageNoWait(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 HANDLE OldTID
= IntGetWndThreadId(WindowPrev
);
109 HANDLE NewTID
= IntGetWndThreadId(Window
);
111 DPRINT1("SendActiveMessage Old -> %x, New -> %x\n", OldTID
, NewTID
);
112 if (Window
->Wnd
->style
& WS_MINIMIZE
)
114 DPRINT1("Widow was nminimized\n");
117 if (OldTID
!= NewTID
)
119 co_IntSendMessageNoWait(hWndPrev
, WM_ACTIVATEAPP
, FALSE
, (LPARAM
)NewTID
);
120 co_IntSendMessageNoWait(hWnd
, WM_ACTIVATEAPP
, TRUE
, (LPARAM
)OldTID
);
122 UserDerefObjectCo(WindowPrev
); // Now allow the previous window to die.
125 UserDerefObjectCo(Window
);
127 /* FIXME: IntIsWindow */
128 co_IntSendMessageNoWait(hWnd
, WM_NCACTIVATE
, (WPARAM
)(hWnd
== UserGetForegroundWindow()), 0);
129 /* FIXME: WA_CLICKACTIVE */
130 co_IntSendMessageNoWait(hWnd
, WM_ACTIVATE
,
131 MAKEWPARAM(MouseActivate
? WA_CLICKACTIVE
: WA_ACTIVE
,
132 UserGetWindowLong(hWnd
, GWL_STYLE
, FALSE
) & WS_MINIMIZE
),
138 co_IntSendKillFocusMessages(HWND hWndPrev
, HWND hWnd
)
142 co_IntPostOrSendMessage(hWndPrev
, WM_KILLFOCUS
, (WPARAM
)hWnd
, 0);
147 co_IntSendSetFocusMessages(HWND hWndPrev
, HWND hWnd
)
151 co_IntPostOrSendMessage(hWnd
, WM_SETFOCUS
, (WPARAM
)hWndPrev
, 0);
156 IntFindChildWindowToOwner(PWINDOW_OBJECT Root
, PWINDOW_OBJECT Owner
)
159 PWINDOW_OBJECT Child
, OwnerWnd
;
161 for(Child
= Root
->spwndChild
; Child
; Child
= Child
->spwndNext
)
163 OwnerWnd
= UserGetWindowObject(Child
->hOwner
);
167 if(OwnerWnd
== Owner
)
178 co_IntSetForegroundAndFocusWindow(PWINDOW_OBJECT Window
, PWINDOW_OBJECT FocusWindow
, BOOL MouseActivate
)
180 HWND hWnd
= Window
->hSelf
;
181 HWND hWndPrev
= NULL
;
182 HWND hWndFocus
= FocusWindow
->hSelf
;
183 HWND hWndFocusPrev
= NULL
;
184 PUSER_MESSAGE_QUEUE PrevForegroundQueue
;
187 ASSERT_REFS_CO(Window
);
189 DPRINT("IntSetForegroundAndFocusWindow(%x, %x, %s)\n", hWnd
, hWndFocus
, MouseActivate
? "TRUE" : "FALSE");
193 if ((Wnd
->style
& (WS_CHILD
| WS_POPUP
)) == WS_CHILD
)
195 DPRINT("Failed - Child\n");
199 if (0 == (Wnd
->style
& WS_VISIBLE
) &&
200 Window
->pti
->pEThread
->ThreadsProcess
!= CsrProcess
)
202 DPRINT("Failed - Invisible\n");
206 PrevForegroundQueue
= IntGetFocusMessageQueue();
207 if (PrevForegroundQueue
!= 0)
209 hWndPrev
= PrevForegroundQueue
->ActiveWindow
;
210 hWndFocusPrev
= PrevForegroundQueue
->FocusWindow
;
213 if (hWndPrev
== hWnd
)
215 DPRINT("Failed - Same\n");
219 /* FIXME: Call hooks. */
221 co_IntSendDeactivateMessages(hWndPrev
, hWnd
);
222 co_IntSendKillFocusMessages(hWndFocusPrev
, hWndFocus
);
225 IntSetFocusMessageQueue(Window
->pti
->MessageQueue
);
227 if (Window
->pti
->MessageQueue
)
229 Window
->pti
->MessageQueue
->ActiveWindow
= hWnd
;
232 if (FocusWindow
->pti
->MessageQueue
)
234 FocusWindow
->pti
->MessageQueue
->FocusWindow
= hWndFocus
;
237 if (PrevForegroundQueue
!= Window
->pti
->MessageQueue
)
239 /* FIXME: Send WM_ACTIVATEAPP to all thread windows. */
242 co_IntSendSetFocusMessages(hWndFocusPrev
, hWndFocus
);
243 co_IntSendActivateMessages(hWndPrev
, hWnd
, MouseActivate
);
249 co_IntSetForegroundWindow(PWINDOW_OBJECT Window
)//FIXME: can Window be NULL??
251 /*if (Window)*/ ASSERT_REFS_CO(Window
);
253 return co_IntSetForegroundAndFocusWindow(Window
, Window
, FALSE
);
257 co_IntMouseActivateWindow(PWINDOW_OBJECT Window
)
260 PWINDOW_OBJECT TopWindow
;
261 USER_REFERENCE_ENTRY Ref
;
264 ASSERT_REFS_CO(Window
);
267 if(Wnd
->style
& WS_DISABLED
)
270 PWINDOW_OBJECT TopWnd
;
271 PWINDOW_OBJECT DesktopWindow
= UserGetWindowObject(IntGetDesktopWindow());
274 Top
= IntFindChildWindowToOwner(DesktopWindow
, Window
);
275 if((TopWnd
= UserGetWindowObject(Top
)))
277 UserRefObjectCo(TopWnd
, &Ref
);
278 Ret
= co_IntMouseActivateWindow(TopWnd
);
279 UserDerefObjectCo(TopWnd
);
288 TopWindow
= UserGetAncestor(Window
, GA_ROOT
);
289 if (!TopWindow
) return FALSE
;
291 /* TMN: Check return valud from this function? */
292 UserRefObjectCo(TopWindow
, &Ref
);
294 co_IntSetForegroundAndFocusWindow(TopWindow
, Window
, TRUE
);
296 UserDerefObjectCo(TopWindow
);
302 co_IntSetActiveWindow(PWINDOW_OBJECT Window OPTIONAL
)
305 PUSER_MESSAGE_QUEUE ThreadQueue
;
309 CBTACTIVATESTRUCT cbt
;
312 ASSERT_REFS_CO(Window
);
314 pti
= PsGetCurrentThreadWin32Thread();
315 ThreadQueue
= pti
->MessageQueue
;
316 ASSERT(ThreadQueue
!= 0);
321 if ((!(Wnd
->style
& WS_VISIBLE
) &&
322 Window
->pti
->pEThread
->ThreadsProcess
!= CsrProcess
) ||
323 (Wnd
->style
& (WS_POPUP
| WS_CHILD
)) == WS_CHILD
)
325 return ThreadQueue
? 0 : ThreadQueue
->ActiveWindow
;
327 hWnd
= Window
->hSelf
;
330 hWndPrev
= ThreadQueue
->ActiveWindow
;
331 if (hWndPrev
== hWnd
)
336 /* call CBT hook chain */
338 cbt
.hWndActive
= hWndPrev
;
339 if (co_HOOK_CallHooks( WH_CBT
, HCBT_ACTIVATE
, (WPARAM
)hWnd
, (LPARAM
)&cbt
))
342 ThreadQueue
->ActiveWindow
= hWnd
;
344 co_IntSendDeactivateMessages(hWndPrev
, hWnd
);
345 co_IntSendActivateMessages(hWndPrev
, hWnd
, FALSE
);
348 /* return IntIsWindow(hWndPrev) ? hWndPrev : 0;*/
354 co_IntSetFocusWindow(PWINDOW_OBJECT Window OPTIONAL
)
358 PUSER_MESSAGE_QUEUE ThreadQueue
;
361 ASSERT_REFS_CO(Window
);
363 pti
= PsGetCurrentThreadWin32Thread();
364 ThreadQueue
= pti
->MessageQueue
;
365 ASSERT(ThreadQueue
!= 0);
367 hWndPrev
= ThreadQueue
->FocusWindow
;
371 if (hWndPrev
== Window
->hSelf
)
376 if (co_HOOK_CallHooks( WH_CBT
, HCBT_SETFOCUS
, (WPARAM
)Window
->hSelf
, (LPARAM
)hWndPrev
))
379 ThreadQueue
->FocusWindow
= Window
->hSelf
;
381 co_IntSendKillFocusMessages(hWndPrev
, Window
->hSelf
);
382 co_IntSendSetFocusMessages(hWndPrev
, Window
->hSelf
);
386 ThreadQueue
->FocusWindow
= 0;
388 if (co_HOOK_CallHooks( WH_CBT
, HCBT_SETFOCUS
, (WPARAM
)0, (LPARAM
)hWndPrev
))
391 co_IntSendKillFocusMessages(hWndPrev
, 0);
401 UserGetForegroundWindow(VOID
)
403 PUSER_MESSAGE_QUEUE ForegroundQueue
;
405 ForegroundQueue
= IntGetFocusMessageQueue();
406 return( ForegroundQueue
!= NULL
? ForegroundQueue
->ActiveWindow
: 0);
414 NtUserGetForegroundWindow(VOID
)
416 DECLARE_RETURN(HWND
);
418 DPRINT("Enter NtUserGetForegroundWindow\n");
419 UserEnterExclusive();
421 RETURN( UserGetForegroundWindow());
424 DPRINT("Leave NtUserGetForegroundWindow, ret=%i\n",_ret_
);
430 HWND FASTCALL
UserGetActiveWindow(VOID
)
433 PUSER_MESSAGE_QUEUE ThreadQueue
;
435 pti
= PsGetCurrentThreadWin32Thread();
436 ThreadQueue
= pti
->MessageQueue
;
437 return( ThreadQueue
? ThreadQueue
->ActiveWindow
: 0);
442 NtUserSetActiveWindow(HWND hWnd
)
444 USER_REFERENCE_ENTRY Ref
;
445 DECLARE_RETURN(HWND
);
447 DPRINT("Enter NtUserSetActiveWindow(%x)\n", hWnd
);
448 UserEnterExclusive();
452 PWINDOW_OBJECT Window
;
454 PUSER_MESSAGE_QUEUE ThreadQueue
;
457 if (!(Window
= UserGetWindowObject(hWnd
)))
462 pti
= PsGetCurrentThreadWin32Thread();
463 ThreadQueue
= pti
->MessageQueue
;
465 if (Window
->pti
->MessageQueue
!= ThreadQueue
)
467 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
471 UserRefObjectCo(Window
, &Ref
);
472 hWndPrev
= co_IntSetActiveWindow(Window
);
473 UserDerefObjectCo(Window
);
479 RETURN( co_IntSetActiveWindow(0));
483 DPRINT("Leave NtUserSetActiveWindow, ret=%i\n",_ret_
);
495 PUSER_MESSAGE_QUEUE ThreadQueue
;
496 DECLARE_RETURN(HWND
);
498 DPRINT("Enter IntGetCapture\n");
500 pti
= PsGetCurrentThreadWin32Thread();
501 ThreadQueue
= pti
->MessageQueue
;
502 RETURN( ThreadQueue
? ThreadQueue
->CaptureWindow
: 0);
505 DPRINT("Leave IntGetCapture, ret=%i\n",_ret_
);
513 NtUserSetCapture(HWND hWnd
)
516 PUSER_MESSAGE_QUEUE ThreadQueue
;
517 PWINDOW_OBJECT Window
;
519 DECLARE_RETURN(HWND
);
521 DPRINT("Enter NtUserSetCapture(%x)\n", hWnd
);
522 UserEnterExclusive();
524 pti
= PsGetCurrentThreadWin32Thread();
525 ThreadQueue
= pti
->MessageQueue
;
527 if((Window
= UserGetWindowObject(hWnd
)))
529 if(Window
->pti
->MessageQueue
!= ThreadQueue
)
535 hWndPrev
= MsqSetStateWindow(ThreadQueue
, MSQ_STATE_CAPTURE
, hWnd
);
537 /* also remove other windows if not capturing anymore */
540 MsqSetStateWindow(ThreadQueue
, MSQ_STATE_MENUOWNER
, NULL
);
541 MsqSetStateWindow(ThreadQueue
, MSQ_STATE_MOVESIZE
, NULL
);
544 co_IntPostOrSendMessage(hWndPrev
, WM_CAPTURECHANGED
, 0, (LPARAM
)hWnd
);
545 ThreadQueue
->CaptureWindow
= hWnd
;
550 DPRINT("Leave NtUserSetCapture, ret=%i\n",_ret_
);
557 HWND FASTCALL
co_UserSetFocus(PWINDOW_OBJECT Window OPTIONAL
)
562 PUSER_MESSAGE_QUEUE ThreadQueue
;
564 PWINDOW_OBJECT TopWnd
;
565 USER_REFERENCE_ENTRY Ref
;
568 ASSERT_REFS_CO(Window
);
570 pti
= PsGetCurrentThreadWin32Thread();
571 ThreadQueue
= pti
->MessageQueue
;
574 if (Wnd
->style
& (WS_MINIMIZE
| WS_DISABLED
))
576 return( (ThreadQueue
? ThreadQueue
->FocusWindow
: 0));
579 if (Window
->pti
->MessageQueue
!= ThreadQueue
)
581 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
585 TopWnd
= UserGetAncestor(Window
, GA_ROOT
);
586 if (TopWnd
&& TopWnd
->hSelf
!= UserGetActiveWindow())
588 // PWINDOW_OBJECT WndTops = UserGetWindowObject(hWndTop);
589 UserRefObjectCo(TopWnd
, &Ref
);
590 co_IntSetActiveWindow(TopWnd
);
591 UserDerefObjectCo(TopWnd
);
594 hWndPrev
= co_IntSetFocusWindow(Window
);
600 return( co_IntSetFocusWindow(NULL
));
610 NtUserSetFocus(HWND hWnd
)
612 PWINDOW_OBJECT Window
;
613 USER_REFERENCE_ENTRY Ref
;
614 DECLARE_RETURN(HWND
);
617 DPRINT("Enter NtUserSetFocus(%x)\n", hWnd
);
618 UserEnterExclusive();
622 if (!(Window
= UserGetWindowObject(hWnd
)))
627 UserRefObjectCo(Window
, &Ref
);
628 ret
= co_UserSetFocus(Window
);
629 UserDerefObjectCo(Window
);
635 RETURN( co_UserSetFocus(0));
639 DPRINT("Leave NtUserSetFocus, ret=%i\n",_ret_
);