BOOL FASTCALL co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd) { USER_REFERENCE_ENTRY RefPrev; PWND WndPrev; BOOL Ret = TRUE; if (hWndPrev && (WndPrev = ValidateHwndNoErr(hWndPrev))) { UserRefObjectCo(WndPrev, &RefPrev); if (co_IntSendMessageNoWait(hWndPrev, WM_NCACTIVATE, FALSE, 0)) //(LPARAM)hWnd)) { co_IntSendMessageNoWait(hWndPrev, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, WndPrev->style & WS_MINIMIZE), (LPARAM)hWnd); if (WndPrev) WndPrev->state &= ~WNDS_ACTIVEFRAME; } else { ERR("Application is keeping itself Active to prevent the change!\n"); Ret = FALSE; } UserDerefObjectCo(WndPrev); } return Ret; }
VOID FASTCALL co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd) { PWND WndPrev ; if (hWndPrev && (WndPrev = UserGetWindowObject(hWndPrev))) { co_IntSendMessageNoWait(hWndPrev, WM_NCACTIVATE, FALSE, 0); co_IntSendMessageNoWait(hWndPrev, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, WndPrev->style & WS_MINIMIZE), (LPARAM)hWnd); } }
DWORD APIENTRY NtUserEmptyClipboard(VOID) { BOOL ret = FALSE; UserEnterExclusive(); if (intIsClipboardOpenByMe()) { if (ClipboardData) { IntEmptyClipboardData(); } ClipboardOwnerWindow = ClipboardWindow; ClipboardOwnerThread = ClipboardThread; IntIncrementSequenceNumber(); ret = TRUE; } else { EngSetLastError(ERROR_CLIPBOARD_NOT_OPEN); } if (ret && ClipboardOwnerWindow) { TRACE("Clipboard: WM_DESTROYCLIPBOARD to %p", ClipboardOwnerWindow->head.h); co_IntSendMessageNoWait( ClipboardOwnerWindow->head.h, WM_DESTROYCLIPBOARD, 0, 0); } UserLeave(); return ret; }
BOOL NTAPI UserEmptyClipboard(VOID) { BOOL bRet = FALSE; PWINSTATION_OBJECT pWinStaObj; pWinStaObj = IntGetWinStaForCbAccess(); if (!pWinStaObj) return FALSE; if (IntIsClipboardOpenByMe(pWinStaObj)) { UserEmptyClipboardData(pWinStaObj); if (pWinStaObj->spwndClipOwner) { TRACE("Clipboard: WM_DESTROYCLIPBOARD to %p\n", pWinStaObj->spwndClipOwner->head.h); co_IntSendMessageNoWait(pWinStaObj->spwndClipOwner->head.h, WM_DESTROYCLIPBOARD, 0, 0); } pWinStaObj->spwndClipOwner = pWinStaObj->spwndClipOpen; pWinStaObj->iClipSequenceNumber++; bRet = TRUE; } else { EngSetLastError(ERROR_CLIPBOARD_NOT_OPEN); ERR("Access denied!\n"); } ObDereferenceObject(pWinStaObj); return bRet; }
BOOL FASTCALL co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOOL Async) { USER_REFERENCE_ENTRY Ref, RefPrev; HANDLE OldTID, NewTID; PTHREADINFO pti, ptiOld, ptiNew; BOOL InAAPM = FALSE; if (Window) { pti = PsGetCurrentThreadWin32Thread(); UserRefObjectCo(Window, &Ref); if (WindowPrev) UserRefObjectCo(WindowPrev, &RefPrev); /* Send palette messages */ if (gpsi->PUSIFlags & PUSIF_PALETTEDISPLAY && //co_IntPostOrSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0)) co_IntSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0)) { UserSendNotifyMessage( HWND_BROADCAST, WM_PALETTEISCHANGING, (WPARAM)UserHMGetHandle(Window), 0); } //// Fixes bug 7089. if (!(Window->style & WS_CHILD)) { PWND pwndTemp = co_GetDesktopWindow(Window)->spwndChild; while (pwndTemp && !(pwndTemp->style & WS_VISIBLE)) pwndTemp = pwndTemp->spwndNext; if (Window != pwndTemp || (WindowPrev && !IntIsWindowVisible(WindowPrev))) { if (!Async || pti->MessageQueue == gpqForeground) { UINT flags = SWP_NOSIZE | SWP_NOMOVE; if (Window == pwndTemp) flags |= SWP_NOACTIVATE; //ERR("co_IntSendActivateMessages SetWindowPos! Async %d pti Q == FGQ %d\n",Async,pti->MessageQueue == gpqForeground); co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, flags); } } } //// //// CORE-1161 and CORE-6651 if (Window->spwndPrev) { HWND *phwndTopLevel, *phwndCurrent; PWND pwndCurrent, pwndDesktop; pwndDesktop = UserGetDesktopWindow(); if (Window->spwndParent == pwndDesktop ) { phwndTopLevel = IntWinListChildren(pwndDesktop); phwndCurrent = phwndTopLevel; while(*phwndCurrent) { pwndCurrent = UserGetWindowObject(*phwndCurrent); if (pwndCurrent && pwndCurrent->spwndOwner == Window ) { co_WinPosSetWindowPos(pwndCurrent, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE); } phwndCurrent++; } ExFreePool(phwndTopLevel); } } //// OldTID = WindowPrev ? IntGetWndThreadId(WindowPrev) : NULL; NewTID = IntGetWndThreadId(Window); ptiOld = WindowPrev ? WindowPrev->head.pti : NULL; ptiNew = Window->head.pti; //ERR("SendActivateMessage Old -> %x, New -> %x\n", OldTID, NewTID); if (!(pti->TIF_flags & TIF_INACTIVATEAPPMSG) && (!WindowPrev || OldTID != NewTID) ) { PWND cWindow; HWND *List, *phWnd; List = IntWinListChildren(UserGetDesktopWindow()); if ( List ) { if ( OldTID ) { ptiOld->TIF_flags |= TIF_INACTIVATEAPPMSG; // Note: Do not set pci flags, this does crash! for (phWnd = List; *phWnd; ++phWnd) { cWindow = ValidateHwndNoErr(*phWnd); if (cWindow && cWindow->head.pti == ptiOld) { // FALSE if the window is being deactivated, // ThreadId that owns the window being activated. co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, FALSE, (LPARAM)NewTID); } } ptiOld->TIF_flags &= ~TIF_INACTIVATEAPPMSG; } if ( NewTID ) { //// Prevents a resource crash due to reentrance! InAAPM = TRUE; pti->TIF_flags |= TIF_INACTIVATEAPPMSG; //// for (phWnd = List; *phWnd; ++phWnd) { cWindow = ValidateHwndNoErr(*phWnd); if (cWindow && cWindow->head.pti == ptiNew) { // TRUE if the window is being activated, // ThreadId that owns the window being deactivated. co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, TRUE, (LPARAM)OldTID); } } } ExFreePoolWithTag(List, USERTAG_WINDOWLIST); } } if (WindowPrev) UserDerefObjectCo(WindowPrev); // Now allow the previous window to die. if (Window->state & WNDS_ACTIVEFRAME) { // If already active frame do not allow NCPaint. //ERR("SendActivateMessage Is Active Frame!\n"); Window->state |= WNDS_NONCPAINT; } if (Window->style & WS_MINIMIZE) { TRACE("Widow was minimized\n"); } co_IntMakeWindowActive(Window); /* FIXME: IntIsWindow */ co_IntSendMessageNoWait( UserHMGetHandle(Window), WM_NCACTIVATE, (WPARAM)(Window == (gpqForeground ? gpqForeground->spwndActive : NULL)), 0); //(LPARAM)hWndPrev); co_IntSendMessageNoWait( UserHMGetHandle(Window), WM_ACTIVATE, MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE, Window->style & WS_MINIMIZE), (LPARAM)(WindowPrev ? UserHMGetHandle(WindowPrev) : 0)); if (!Window->spwndOwner && !IntGetParent(Window)) { // FIXME lParam; The value is TRUE if the window is in full-screen mode, or FALSE otherwise. co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (WPARAM) UserHMGetHandle(Window), FALSE); } Window->state &= ~WNDS_NONCPAINT; UserDerefObjectCo(Window); } return InAAPM; }
/* MSDN: The system restricts which processes can set the foreground window. A process can set the foreground window only if one of the following conditions is true: * The process is the foreground process. * The process was started by the foreground process. * The process received the last input event. * There is no foreground process. * The foreground process is being debugged. * The foreground is not locked (see LockSetForegroundWindow). * The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo). * No menus are active. */ static BOOL FASTCALL co_IntSetForegroundAndFocusWindow( _In_ PWND Wnd, _In_ BOOL MouseActivate) { HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL; HWND hWndPrev = NULL; PWND pWndPrev = NULL; PUSER_MESSAGE_QUEUE PrevForegroundQueue; PTHREADINFO pti; BOOL fgRet = FALSE, Ret = FALSE; if (Wnd) ASSERT_REFS_CO(Wnd); //ERR("SetForegroundAndFocusWindow(%x, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE")); PrevForegroundQueue = IntGetFocusMessageQueue(); // Use this active desktop. pti = PsGetCurrentThreadWin32Thread(); if (PrevForegroundQueue) { // Same Window Q as foreground just do active. if (Wnd && Wnd->head.pti->MessageQueue == PrevForegroundQueue) { //ERR("Same Window Q as foreground just do active.\n"); if (pti->MessageQueue == PrevForegroundQueue) { // Same WQ and TQ go active. //ERR("Same WQ and TQ go active.\n"); Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE); } else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd) { // Same WQ and it is active. //ERR("Same WQ and it is active.\n"); Ret = TRUE; } else { // Same WQ as FG but not the same TQ send active. //ERR("Same WQ as FG but not the same TQ send active.\n"); co_IntSendMessage(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate ); Ret = TRUE; } return Ret; } hWndPrev = PrevForegroundQueue->spwndActive ? UserHMGetHandle(PrevForegroundQueue->spwndActive) : 0; pWndPrev = PrevForegroundQueue->spwndActive; } if ( (( !IsFGLocked() || pti->ppi == gppiInputProvider ) && ( CanForceFG(pti->ppi) || pti->TIF_flags & (TIF_SYSTEMTHREAD|TIF_CSRSSTHREAD|TIF_ALLOWFOREGROUNDACTIVATE) )) || pti->ppi == ppiScrnSaver ) { //ToggleFGActivate(pti); // win.c line 2662 fail if (Wnd) { IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue); gptiForeground = Wnd->head.pti; //ERR("Set Foreground pti 0x%p Q 0x%p hWnd 0x%p\n",Wnd->head.pti, Wnd->head.pti->MessageQueue,Wnd->head.h); } else { IntSetFocusMessageQueue(NULL); gptiForeground = NULL; //ERR("Set Foreground pti 0x0 Q 0x0 hWnd 0x0\n"); } /* Henri Verbeet, What happens is that we get the WM_WINE_SETACTIVEWINDOW message sent by the other thread after we already changed the foreground window back to our own window. */ //ERR("SFAFW: 1\n"); FindRemoveAsyncMsg(Wnd, 0); // Do this to fix test_SFW todos! fgRet = TRUE; } // Fix FG Bounce with regedit. if (hWndPrev != hWnd ) { if (PrevForegroundQueue && fgRet && PrevForegroundQueue->spwndActive) { //ERR("SFGW: Send NULL to 0x%x\n",hWndPrev); if (pti->MessageQueue == PrevForegroundQueue) { //ERR("SFGW: TI same as Prev TI\n"); co_IntSetActiveWindow(NULL, FALSE, TRUE, FALSE); } else if (pWndPrev) { //ERR("SFGW Deactivate: TI not same as Prev TI\n"); // No real reason to wait here. co_IntSendMessageNoWait(hWndPrev, WM_ASYNC_SETACTIVEWINDOW, 0, 0 ); } } } if (!Wnd) return FALSE; // Always return false. if (pti->MessageQueue == Wnd->head.pti->MessageQueue) { //ERR("Same PQ and WQ go active.\n"); Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE); } else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd) { //ERR("Same Active and Wnd.\n"); Ret = TRUE; } else { //ERR("Activate Not same PQ and WQ and Wnd.\n"); co_IntSendMessageNoWait(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate ); Ret = TRUE; } return Ret && fgRet; }
VOID FASTCALL co_IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate) { USER_REFERENCE_ENTRY Ref, RefPrev; PWND Window, WindowPrev = NULL; if ((Window = UserGetWindowObject(hWnd))) { UserRefObjectCo(Window, &Ref); WindowPrev = UserGetWindowObject(hWndPrev); if (WindowPrev) UserRefObjectCo(WindowPrev, &RefPrev); /* Send palette messages */ if (co_IntPostOrSendMessage(hWnd, WM_QUERYNEWPALETTE, 0, 0)) { UserSendNotifyMessage( HWND_BROADCAST, WM_PALETTEISCHANGING, (WPARAM)hWnd, 0); } if (Window->spwndPrev != NULL) co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSENDCHANGING); if (!Window->spwndOwner && !IntGetParent(Window)) { co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (LPARAM) hWnd); } if (Window) { // Set last active for window and it's owner. Window->hWndLastActive = hWnd; if (Window->spwndOwner) Window->spwndOwner->hWndLastActive = hWnd; Window->state |= WNDS_ACTIVEFRAME; } if (WindowPrev) WindowPrev->state &= ~WNDS_ACTIVEFRAME; if (Window && WindowPrev) { PWND cWindow; HWND *List, *phWnd; HANDLE OldTID = IntGetWndThreadId(WindowPrev); HANDLE NewTID = IntGetWndThreadId(Window); TRACE("SendActiveMessage Old -> %x, New -> %x\n", OldTID, NewTID); if (Window->style & WS_MINIMIZE) { TRACE("Widow was minimized\n"); } if (OldTID != NewTID) { List = IntWinListChildren(UserGetWindowObject(IntGetDesktopWindow())); if (List) { for (phWnd = List; *phWnd; ++phWnd) { cWindow = UserGetWindowObject(*phWnd); if (cWindow && (IntGetWndThreadId(cWindow) == OldTID)) { // FALSE if the window is being deactivated, // ThreadId that owns the window being activated. co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, FALSE, (LPARAM)NewTID); } } for (phWnd = List; *phWnd; ++phWnd) { cWindow = UserGetWindowObject(*phWnd); if (cWindow && (IntGetWndThreadId(cWindow) == NewTID)) { // TRUE if the window is being activated, // ThreadId that owns the window being deactivated. co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, TRUE, (LPARAM)OldTID); } } ExFreePool(List); } } UserDerefObjectCo(WindowPrev); // Now allow the previous window to die. } UserDerefObjectCo(Window); /* FIXME: IntIsWindow */ co_IntSendMessageNoWait(hWnd, WM_NCACTIVATE, (WPARAM)(hWnd == UserGetForegroundWindow()), 0); /* FIXME: WA_CLICKACTIVE */ co_IntSendMessageNoWait(hWnd, WM_ACTIVATE, MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE, Window->style & WS_MINIMIZE), (LPARAM)hWndPrev); } }