VOID FASTCALL co_VIS_WindowLayoutChanged( PWND Wnd, PREGION NewlyExposed) { PWND Parent; USER_REFERENCE_ENTRY Ref; ASSERT_REFS_CO(Wnd); Parent = Wnd->spwndParent; if(Parent) { PREGION TempRgn = IntSysCreateRectpRgn(0, 0, 0, 0); if (!TempRgn) return; IntGdiCombineRgn(TempRgn, NewlyExposed, NULL, RGN_COPY); REGION_bOffsetRgn(TempRgn, Wnd->rcWindow.left - Parent->rcClient.left, Wnd->rcWindow.top - Parent->rcClient.top); UserRefObjectCo(Parent, &Ref); co_UserRedrawWindow(Parent, NULL, TempRgn, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN); UserDerefObjectCo(Parent); REGION_Delete(TempRgn); } }
BOOL FASTCALL co_UserHideCaret(PWND Window OPTIONAL) { PTHREADINFO pti; PUSER_MESSAGE_QUEUE ThreadQueue; if (Window) ASSERT_REFS_CO(Window); if(Window && Window->head.pti->pEThread != PsGetCurrentThread()) { EngSetLastError(ERROR_ACCESS_DENIED); return FALSE; } pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; if(Window && ThreadQueue->CaretInfo->hWnd != Window->head.h) { EngSetLastError(ERROR_ACCESS_DENIED); return FALSE; } if(ThreadQueue->CaretInfo->Visible) { PWND pwnd = UserGetWindowObject(ThreadQueue->CaretInfo->hWnd); IntKillTimer(pwnd, IDCARETTIMER, TRUE); co_IntHideCaret(ThreadQueue->CaretInfo); ThreadQueue->CaretInfo->Visible = 0; ThreadQueue->CaretInfo->Showing = 0; } return TRUE; }
BOOL FASTCALL co_IntMouseActivateWindow(PWND Wnd) { HWND Top; USER_REFERENCE_ENTRY Ref; ASSERT_REFS_CO(Wnd); if (Wnd->style & WS_DISABLED) { BOOL Ret; PWND TopWnd; PWND DesktopWindow = UserGetDesktopWindow(); if (DesktopWindow) { ERR("Window Diabled\n"); Top = IntFindChildWindowToOwner(DesktopWindow, Wnd); if ((TopWnd = ValidateHwndNoErr(Top))) { UserRefObjectCo(TopWnd, &Ref); Ret = co_IntMouseActivateWindow(TopWnd); UserDerefObjectCo(TopWnd); return Ret; } } return FALSE; } TRACE("Mouse Active\n"); co_IntSetForegroundAndFocusWindow(Wnd, TRUE); return TRUE; }
/* API Call */ BOOL FASTCALL co_IntSetForegroundWindow(PWND Window) { ASSERT_REFS_CO(Window); return co_IntSetForegroundAndFocusWindow(Window, FALSE); }
BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL) { PTHREADINFO pti; PUSER_MESSAGE_QUEUE ThreadQueue; PWND pWnd = NULL; if (Window) ASSERT_REFS_CO(Window); if(Window && Window->head.pti->pEThread != PsGetCurrentThread()) { EngSetLastError(ERROR_ACCESS_DENIED); return FALSE; } pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; if(Window && ThreadQueue->CaretInfo->hWnd != Window->head.h) { EngSetLastError(ERROR_ACCESS_DENIED); return FALSE; } if (!ThreadQueue->CaretInfo->Visible) { ThreadQueue->CaretInfo->Visible = 1; pWnd = ValidateHwndNoErr(ThreadQueue->CaretInfo->hWnd); if (!ThreadQueue->CaretInfo->Showing && pWnd) { IntNotifyWinEvent(EVENT_OBJECT_SHOW, pWnd, OBJID_CARET, OBJID_CARET, 0); } IntSetTimer(pWnd, IDCARETTIMER, gpsi->dtCaretBlink, CaretSystemTimerProc, TMRF_SYSTEM); } return TRUE; }
BOOL FASTCALL co_IntSetScrollBarInfo(PWND Window, LONG idObject, PSETSCROLLBARINFO psbi) { INT Bar; PSCROLLBARINFO sbi; LPSCROLLINFO psi; ASSERT_REFS_CO(Window); Bar = SBOBJ_TO_SBID(idObject); if(!SBID_IS_VALID(Bar)) { EngSetLastError(ERROR_INVALID_PARAMETER); ERR("Trying to get scrollinfo for unknown scrollbar type %d\n", Bar); return FALSE; } if(!co_IntCreateScrollBars(Window)) { ERR("Failed to create scrollbars for window.\n"); return FALSE; } sbi = IntGetScrollbarInfoFromWindow(Window, Bar); psi = IntGetScrollInfoFromWindow(Window, Bar); psi->nTrackPos = psbi->nTrackPos; sbi->reserved = psbi->reserved; RtlCopyMemory(&sbi->rgstate, &psbi->rgstate, sizeof(psbi->rgstate)); return TRUE; }
VOID FASTCALL co_VIS_WindowLayoutChanged( PWND Wnd, HRGN NewlyExposed) { HRGN Temp; PWND Parent; USER_REFERENCE_ENTRY Ref; ASSERT_REFS_CO(Wnd); Parent = Wnd->spwndParent; if(Parent) { Temp = IntSysCreateRectRgn(0, 0, 0, 0); NtGdiCombineRgn(Temp, NewlyExposed, NULL, RGN_COPY); NtGdiOffsetRgn(Temp, Wnd->rcWindow.left - Parent->rcClient.left, Wnd->rcWindow.top - Parent->rcClient.top); UserRefObjectCo(Parent, &Ref); co_UserRedrawWindow(Parent, NULL, Temp, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN); UserDerefObjectCo(Parent); GreDeleteObject(Temp); } }
BOOL FASTCALL co_IntGetScrollBarInfo(PWND Window, LONG idObject, PSCROLLBARINFO psbi) { INT Bar; PSCROLLBARINFO sbi; PSBDATA pSBData; ASSERT_REFS_CO(Window); Bar = SBOBJ_TO_SBID(idObject); if(!SBID_IS_VALID(Bar)) { EngSetLastError(ERROR_INVALID_PARAMETER); ERR("Trying to get scrollinfo for unknown scrollbar type %d\n", Bar); return FALSE; } if(!co_IntCreateScrollBars(Window)) { ERR("Failed to create scrollbars for window.\n"); return FALSE; } sbi = IntGetScrollbarInfoFromWindow(Window, Bar); pSBData = IntGetSBData(Window, Bar); IntGetScrollBarRect(Window, Bar, &(sbi->rcScrollBar)); IntCalculateThumb(Window, Bar, sbi, pSBData); RtlCopyMemory(psbi, sbi, sizeof(SCROLLBARINFO)); return TRUE; }
/* API Call */ BOOL FASTCALL co_IntSetForegroundWindowMouse(PWND Window) { if (Window) ASSERT_REFS_CO(Window); return co_IntSetForegroundAndFocusWindow(Window, TRUE); }
BOOL FASTCALL co_IntSetForegroundWindow(PWND Window)//FIXME: can Window be NULL?? { /*if (Window)*/ ASSERT_REFS_CO(Window); return co_IntSetForegroundAndFocusWindow(Window, Window, FALSE); }
BOOL FASTCALL co_IntCreateScrollBars(PWND Window) { PSCROLLBARINFO psbi; PSBDATA pSBData; ULONG Size, s; INT i; ASSERT_REFS_CO(Window); if (Window->pSBInfo && Window->pSBInfoex) { /* No need to create it anymore */ return TRUE; } /* Allocate memory for all scrollbars (HORZ, VERT, CONTROL) */ Size = 3 * (sizeof(SBINFOEX)); if(!(Window->pSBInfoex = ExAllocatePoolWithTag(PagedPool, Size, TAG_SBARINFO))) { ERR("Unable to allocate memory for scrollbar information for window %p\n", Window->head.h); return FALSE; } RtlZeroMemory(Window->pSBInfoex, Size); if(!(Window->pSBInfo = DesktopHeapAlloc( Window->head.rpdesk, sizeof(SBINFO)))) { ERR("Unable to allocate memory for scrollbar information for window %p\n", Window->head.h); return FALSE; } RtlZeroMemory(Window->pSBInfo, sizeof(SBINFO)); Window->pSBInfo->Vert.posMax = 100; Window->pSBInfo->Horz.posMax = 100; co_WinPosGetNonClientSize(Window, &Window->rcWindow, &Window->rcClient); for(s = SB_HORZ; s <= SB_VERT; s++) { psbi = IntGetScrollbarInfoFromWindow(Window, s); psbi->cbSize = sizeof(SCROLLBARINFO); for (i = 0; i < CCHILDREN_SCROLLBAR + 1; i++) psbi->rgstate[i] = 0; pSBData = IntGetSBData(Window, s); IntGetScrollBarRect(Window, s, &(psbi->rcScrollBar)); IntCalculateThumb(Window, s, psbi, pSBData); } return TRUE; }
/* static VOID FASTCALL IntUpdateSBInfo(PWND Window, int wBar) { PSCROLLBARINFO sbi; PSBDATA pSBData; ASSERT(Window); ASSERT(Window->pSBInfo); ASSERT(Window->pSBInfoex); sbi = IntGetScrollbarInfoFromWindow(Window, wBar); pSBData = IntGetSBData(Window, wBar); IntGetScrollBarRect(Window, wBar, &(sbi->rcScrollBar)); IntCalculateThumb(Window, wBar, sbi, pSBData); } */ static BOOL FASTCALL co_IntGetScrollInfo(PWND Window, INT nBar, PSBDATA pSBData, LPSCROLLINFO lpsi) { UINT Mask; LPSCROLLINFO psi; ASSERT_REFS_CO(Window); if(!SBID_IS_VALID(nBar)) { EngSetLastError(ERROR_INVALID_PARAMETER); ERR("Trying to get scrollinfo for unknown scrollbar type %d\n", nBar); return FALSE; } if (!Window->pSBInfo) { ERR("IntGetScrollInfo No window scrollbar info!\n"); return FALSE; } psi = IntGetScrollInfoFromWindow(Window, nBar); if (lpsi->fMask == SIF_ALL) { Mask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS; } else { Mask = lpsi->fMask; } if (0 != (Mask & SIF_PAGE)) { lpsi->nPage = psi->nPage; } if (0 != (Mask & SIF_POS)) { lpsi->nPos = psi->nPos; } if (0 != (Mask & SIF_RANGE)) { lpsi->nMin = psi->nMin; lpsi->nMax = psi->nMax; } if (0 != (Mask & SIF_TRACKPOS)) { lpsi->nTrackPos = psi->nTrackPos; } return TRUE; }
HWND FASTCALL co_IntSetActiveWindow(PWND Wnd OPTIONAL) { PTHREADINFO pti; PUSER_MESSAGE_QUEUE ThreadQueue; HWND hWndPrev; HWND hWnd = 0; CBTACTIVATESTRUCT cbt; if (Wnd) ASSERT_REFS_CO(Wnd); pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; ASSERT(ThreadQueue != 0); if (Wnd != 0) { if ((!(Wnd->style & WS_VISIBLE) && Wnd->head.pti->pEThread->ThreadsProcess != CsrProcess) || (Wnd->style & (WS_POPUP | WS_CHILD)) == WS_CHILD) { return ThreadQueue ? 0 : ThreadQueue->ActiveWindow; } hWnd = Wnd->head.h; } hWndPrev = ThreadQueue->ActiveWindow; if (hWndPrev == hWnd) { return hWndPrev; } /* call CBT hook chain */ cbt.fMouse = FALSE; cbt.hWndActive = hWndPrev; if (co_HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hWnd, (LPARAM)&cbt)) { ERR("SetActiveWindow WH_CBT Call Hook return!\n"); return 0; } ThreadQueue->ActiveWindow = hWnd; co_IntSendDeactivateMessages(hWndPrev, hWnd); co_IntSendActivateMessages(hWndPrev, hWnd, FALSE); /* FIXME */ /* return IntIsWindow(hWndPrev) ? hWndPrev : 0;*/ return hWndPrev; }
static HWND FASTCALL co_IntSetFocusWindow(PWND Window OPTIONAL) { HWND hWndPrev = 0; PTHREADINFO pti; PUSER_MESSAGE_QUEUE ThreadQueue; if (Window) ASSERT_REFS_CO(Window); pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; ASSERT(ThreadQueue != 0); hWndPrev = ThreadQueue->FocusWindow; if (Window != 0) { if (hWndPrev == Window->head.h) { return hWndPrev; } if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev)) { ERR("SetFocusWindow 1 WH_CBT Call Hook return!\n"); return 0; } ThreadQueue->FocusWindow = Window->head.h; TRACE("Focus: %d -> %d\n", hWndPrev, Window->head.h); co_IntSendKillFocusMessages(hWndPrev, Window->head.h); co_IntSendSetFocusMessages(hWndPrev, Window->head.h); } else { ThreadQueue->FocusWindow = 0; if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev)) { ERR("SetFocusWindow 2 WH_CBT Call Hook return!\n"); return 0; } co_IntSendKillFocusMessages(hWndPrev, 0); } return hWndPrev; }
/* Ported from WINE20020904 (SCROLL_ShowScrollBar) */ DWORD FASTCALL co_UserShowScrollBar(PWND Wnd, int nBar, BOOL fShowH, BOOL fShowV) { ULONG old_style, set_bits = 0, clear_bits = 0; ASSERT_REFS_CO(Wnd); switch(nBar) { case SB_CTL: { //IntUpdateSBInfo(Wnd, SB_CTL); // Is this needed? Was tested w/o! co_WinPosShowWindow(Wnd, fShowH ? SW_SHOW : SW_HIDE); return TRUE; } case SB_BOTH: case SB_HORZ: if (fShowH) set_bits |= WS_HSCROLL; else clear_bits |= WS_HSCROLL; if( nBar == SB_HORZ ) break; /* Fall through */ case SB_VERT: if (fShowV) set_bits |= WS_VSCROLL; else clear_bits |= WS_VSCROLL; break; default: EngSetLastError(ERROR_INVALID_PARAMETER); return FALSE; } old_style = IntSetStyle( Wnd, set_bits, clear_bits ); if ((old_style & clear_bits) != 0 || (old_style & set_bits) != set_bits) { ///// Is this needed? Was tested w/o! //if (Wnd->style & WS_HSCROLL) IntUpdateSBInfo(Wnd, SB_HORZ); //if (Wnd->style & WS_VSCROLL) IntUpdateSBInfo(Wnd, SB_VERT); ///// /* Frame has been changed, let the window redraw itself */ co_WinPosSetWindowPos(Wnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING); return TRUE; } return FALSE; }
HWND FASTCALL co_UserSetFocus(PWND Wnd OPTIONAL) { if (Wnd) { PTHREADINFO pti; PUSER_MESSAGE_QUEUE ThreadQueue; HWND hWndPrev; PWND TopWnd; USER_REFERENCE_ENTRY Ref; ASSERT_REFS_CO(Wnd); pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; if (Wnd->style & (WS_MINIMIZE | WS_DISABLED)) { return( (ThreadQueue ? ThreadQueue->FocusWindow : 0)); } if (Wnd->head.pti->MessageQueue != ThreadQueue) { EngSetLastError(ERROR_INVALID_WINDOW_HANDLE); return( 0); } TopWnd = UserGetAncestor(Wnd, GA_ROOT); if (TopWnd && TopWnd->head.h != UserGetActiveWindow()) { // PWND WndTops = UserGetWindowObject(hWndTop); UserRefObjectCo(TopWnd, &Ref); co_IntSetActiveWindow(TopWnd); UserDerefObjectCo(TopWnd); } hWndPrev = co_IntSetFocusWindow(Wnd); return( hWndPrev); } else { return( co_IntSetFocusWindow(NULL)); } }
BOOL FASTCALL co_IntMouseActivateWindow(PWND Wnd) { HWND Top; PWND TopWindow; USER_REFERENCE_ENTRY Ref; ASSERT_REFS_CO(Wnd); if(Wnd->style & WS_DISABLED) { BOOL Ret; PWND TopWnd; PWND DesktopWindow = UserGetWindowObject(IntGetDesktopWindow()); if(DesktopWindow) { Top = IntFindChildWindowToOwner(DesktopWindow, Wnd); if((TopWnd = UserGetWindowObject(Top))) { UserRefObjectCo(TopWnd, &Ref); Ret = co_IntMouseActivateWindow(TopWnd); UserDerefObjectCo(TopWnd); return Ret; } } return FALSE; } TopWindow = UserGetAncestor(Wnd, GA_ROOT); if (!TopWindow) return FALSE; /* TMN: Check return valud from this function? */ UserRefObjectCo(TopWindow, &Ref); co_IntSetForegroundAndFocusWindow(TopWindow, Wnd, TRUE); UserDerefObjectCo(TopWindow); return TRUE; }
BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL) { PTHREADINFO pti; PWND pWnd; PUSER_MESSAGE_QUEUE ThreadQueue; if (Window) ASSERT_REFS_CO(Window); if(Window && Window->head.pti->pEThread != PsGetCurrentThread()) { EngSetLastError(ERROR_ACCESS_DENIED); return FALSE; } pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; if(Window && ThreadQueue->CaretInfo->hWnd != Window->head.h) { EngSetLastError(ERROR_ACCESS_DENIED); return FALSE; } if(!ThreadQueue->CaretInfo->Visible) { ThreadQueue->CaretInfo->Visible = 1; if(!ThreadQueue->CaretInfo->Showing) { pWnd = UserGetWindowObject(ThreadQueue->CaretInfo->hWnd); co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0); IntNotifyWinEvent(EVENT_OBJECT_SHOW, pWnd, OBJID_CARET, OBJID_CARET, 0); } IntSetTimer(UserGetWindowObject(ThreadQueue->CaretInfo->hWnd), IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TMRF_SYSTEM); } return TRUE; }
/* 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; }
static DWORD FASTCALL co_IntSetScrollInfo(PWND Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw) { /* * Update the scrollbar state and set action flags according to * what has to be done graphics wise. */ LPSCROLLINFO Info; PSCROLLBARINFO psbi; UINT new_flags; INT action = 0; PSBDATA pSBData; DWORD OldPos = 0; BOOL bChangeParams = FALSE; /* Don't show/hide scrollbar if params don't change */ UINT MaxPage; int MaxPos; ASSERT_REFS_CO(Window); if(!SBID_IS_VALID(nBar)) { EngSetLastError(ERROR_INVALID_PARAMETER); ERR("Trying to set scrollinfo for unknown scrollbar type %d", nBar); return FALSE; } if(!co_IntCreateScrollBars(Window)) { return FALSE; } if (lpsi->cbSize != sizeof(SCROLLINFO) && lpsi->cbSize != (sizeof(SCROLLINFO) - sizeof(lpsi->nTrackPos))) { EngSetLastError(ERROR_INVALID_PARAMETER); return 0; } if (lpsi->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL | SIF_PREVIOUSPOS)) { EngSetLastError(ERROR_INVALID_PARAMETER); return 0; } psbi = IntGetScrollbarInfoFromWindow(Window, nBar); Info = IntGetScrollInfoFromWindow(Window, nBar); pSBData = IntGetSBData(Window, nBar); /* Set the page size */ if (lpsi->fMask & SIF_PAGE) { if (Info->nPage != lpsi->nPage) { Info->nPage = lpsi->nPage; pSBData->page = lpsi->nPage; bChangeParams = TRUE; } } /* Set the scroll pos */ if (lpsi->fMask & SIF_POS) { if (Info->nPos != lpsi->nPos) { OldPos = Info->nPos; Info->nPos = lpsi->nPos; pSBData->pos = lpsi->nPos; bChangeParams = TRUE; } } /* Set the scroll range */ if (lpsi->fMask & SIF_RANGE) { if (lpsi->nMin > lpsi->nMax) { Info->nMin = lpsi->nMin; Info->nMax = lpsi->nMin; pSBData->posMin = lpsi->nMin; pSBData->posMax = lpsi->nMin; bChangeParams = TRUE; } else if (Info->nMin != lpsi->nMin || Info->nMax != lpsi->nMax) { Info->nMin = lpsi->nMin; Info->nMax = lpsi->nMax; pSBData->posMin = lpsi->nMin; pSBData->posMax = lpsi->nMax; bChangeParams = TRUE; } } /* Make sure the page size is valid */ MaxPage = abs(Info->nMax - Info->nMin) + 1; if (Info->nPage > MaxPage) { pSBData->page = Info->nPage = MaxPage; } /* Make sure the pos is inside the range */ MaxPos = Info->nMax + 1 - (int)max(Info->nPage, 1); ASSERT(MaxPos >= Info->nMin); if (Info->nPos < Info->nMin) { pSBData->pos = Info->nPos = Info->nMin; } else if (Info->nPos > MaxPos) { pSBData->pos = Info->nPos = MaxPos; } /* * Don't change the scrollbar state if SetScrollInfo is just called * with SIF_DISABLENOSCROLL */ if (!(lpsi->fMask & SIF_ALL)) { //goto done; return lpsi->fMask & SIF_PREVIOUSPOS ? OldPos : pSBData->pos; } /* Check if the scrollbar should be hidden or disabled */ if (lpsi->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL)) { new_flags = Window->pSBInfo->WSBflags; if (Info->nMin >= (int)(Info->nMax - max(Info->nPage - 1, 0))) { /* Hide or disable scroll-bar */ if (lpsi->fMask & SIF_DISABLENOSCROLL) { new_flags = ESB_DISABLE_BOTH; bChangeParams = TRUE; } else if ((nBar != SB_CTL) && bChangeParams) { action = SA_SSI_HIDE; } } else /* Show and enable scroll-bar only if no page only changed. */ if (lpsi->fMask != SIF_PAGE) { new_flags = ESB_ENABLE_BOTH; if ((nBar != SB_CTL) && bChangeParams) { action |= SA_SSI_SHOW; } } if (Window->pSBInfo->WSBflags != new_flags) /* Check arrow flags */ { Window->pSBInfo->WSBflags = new_flags; action |= SA_SSI_REPAINT_ARROWS; } } //done: if ( action & SA_SSI_HIDE ) { co_UserShowScrollBar(Window, nBar, FALSE, FALSE); } else { if ( action & SA_SSI_SHOW ) if ( co_UserShowScrollBar(Window, nBar, TRUE, TRUE) ) return lpsi->fMask & SIF_PREVIOUSPOS ? OldPos : pSBData->pos; /* SetWindowPos() already did the painting */ if (bRedraw) { // FIXME: Arrows and interior. RECTL UpdateRect = psbi->rcScrollBar; UpdateRect.left -= Window->rcClient.left - Window->rcWindow.left; UpdateRect.right -= Window->rcClient.left - Window->rcWindow.left; UpdateRect.top -= Window->rcClient.top - Window->rcWindow.top; UpdateRect.bottom -= Window->rcClient.top - Window->rcWindow.top; co_UserRedrawWindow(Window, &UpdateRect, 0, RDW_INVALIDATE | RDW_FRAME); } // FIXME: Arrows /* else if( action & SA_SSI_REPAINT_ARROWS ) { RECTL UpdateRect = psbi->rcScrollBar; UpdateRect.left -= Window->rcClient.left - Window->rcWindow.left; UpdateRect.right -= Window->rcClient.left - Window->rcWindow.left; UpdateRect.top -= Window->rcClient.top - Window->rcWindow.top; UpdateRect.bottom -= Window->rcClient.top - Window->rcWindow.top; co_UserRedrawWindow(Window, &UpdateRect, 0, RDW_INVALIDATE | RDW_FRAME); } */ } /* Return current position */ return lpsi->fMask & SIF_PREVIOUSPOS ? OldPos : pSBData->pos; }
BOOL FASTCALL co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus, BOOL Async) { PTHREADINFO pti; PUSER_MESSAGE_QUEUE ThreadQueue; PWND pWndChg, WndPrev; // State changes. HWND hWndPrev; HWND hWnd = 0; BOOL InAAPM; CBTACTIVATESTRUCT cbt; if (Wnd) { ASSERT_REFS_CO(Wnd); hWnd = UserHMGetHandle(Wnd); if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE; if (Wnd == UserGetDesktopWindow()) return FALSE; } pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; ASSERT(ThreadQueue != 0); hWndPrev = ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : NULL; if (Prev) *Prev = hWndPrev; if (hWndPrev == hWnd) return TRUE; pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch. if (Wnd) { if (ThreadQueue != Wnd->head.pti->MessageQueue) { PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); // Rule 1 & 4, We are foreground so set this FG window or NULL foreground.... if (!ForegroundQueue || ForegroundQueue == ThreadQueue) { return co_IntSetForegroundAndFocusWindow(Wnd, bMouse); } } if (Wnd->state & WNDS_BEINGACTIVATED) return TRUE; } /* Call CBT hook chain */ cbt.fMouse = bMouse; cbt.hWndActive = hWndPrev; if (co_HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hWnd, (LPARAM)&cbt)) { ERR("SetActiveWindow: WH_CBT Call Hook return!\n"); return FALSE; } if ( ThreadQueue->spwndActive && ThreadQueue->spwndActive->state & WNDS_DESTROYED ) ThreadQueue->spwndActive = NULL; else ThreadQueue->spwndActivePrev = ThreadQueue->spwndActive; WndPrev = ThreadQueue->spwndActive; // Keep to save changing active. if (WndPrev) { if (ThreadQueue == gpqForeground) gpqForegroundPrev = ThreadQueue; if (!co_IntSendDeactivateMessages(hWndPrev, hWnd)) return FALSE; } // While in calling message proc or hook: // Fail if a preemptive switch was made, current active not made previous, // focus window is dead or no longer the same thread queue. if ( ThreadQueue->spwndActivePrev != ThreadQueue->spwndActive || pWndChg != ThreadQueue->spwndActive || (Wnd && !VerifyWnd(Wnd)) || ThreadQueue != pti->MessageQueue ) { ERR("SetActiveWindow: Summery ERROR, active state changed!\n"); return FALSE; } if (!WndPrev) ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE; if (Wnd) Wnd->state |= WNDS_BEINGACTIVATED; IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); /* check if the specified window can be set in the input data of a given queue */ if ( !Wnd || ThreadQueue == Wnd->head.pti->MessageQueue) { /* set the current thread active window */ ThreadQueue->spwndActive = Wnd; } InAAPM = co_IntSendActivateMessages(WndPrev, Wnd, bMouse, Async); /* now change focus if necessary */ if (bFocus && !(ThreadQueue->QF_flags & QF_FOCUSNULLSINCEACTIVE)) { /* Do not change focus if the window is no longer active */ if (ThreadQueue->spwndActive == Wnd) { if (!ThreadQueue->spwndFocus || !Wnd || UserGetAncestor(ThreadQueue->spwndFocus, GA_ROOT) != Wnd) { co_UserSetFocus(Wnd); } } } if (InAAPM) { pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG; pti->pClientInfo->dwTIFlags = pti->TIF_flags; } // FIXME: Used in the menu loop!!! //ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE; if (Wnd) Wnd->state &= ~WNDS_BEINGACTIVATED; return (ThreadQueue->spwndActive == Wnd); }
static BOOLEAN FASTCALL co_IntTranslateAccelerator( PWND Window, CONST MSG *pMsg, CONST ACCEL *pAccel) { BOOL bFound = FALSE; UINT Mask = 0, nPos; HWND hWnd; HMENU hMenu, hSubMenu; PMENU MenuObject; ASSERT_REFS_CO(Window); hWnd = Window->head.h; TRACE("IntTranslateAccelerator(hwnd %p, message %x, wParam %x, lParam %x, fVirt 0x%x, key %x, cmd %x)\n", hWnd, pMsg->message, pMsg->wParam, pMsg->lParam, pAccel->fVirt, pAccel->key, pAccel->cmd); if (UserGetKeyState(VK_CONTROL) & 0x8000) Mask |= FCONTROL; if (UserGetKeyState(VK_MENU) & 0x8000) Mask |= FALT; // FIXME: VK_LMENU (msg winetest!) if (UserGetKeyState(VK_SHIFT) & 0x8000) Mask |= FSHIFT; TRACE("Mask 0x%x\n", Mask); if (pAccel->fVirt & FVIRTKEY) { /* This is a virtual key. Process WM_(SYS)KEYDOWN messages. */ if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN) { /* Check virtual key and SHIFT, CTRL, LALT state */ if (pMsg->wParam == pAccel->key && Mask == (pAccel->fVirt & (FSHIFT | FCONTROL | FALT))) { bFound = TRUE; } } } else { /* This is a char code. Process WM_(SYS)CHAR messages. */ if (pMsg->message == WM_CHAR || pMsg->message == WM_SYSCHAR) { /* Check char code and LALT state only */ if (pMsg->wParam == pAccel->key && (Mask & FALT) == (pAccel->fVirt & FALT)) { bFound = TRUE; } } } if (!bFound) { /* Don't translate this msg */ TRACE("IntTranslateAccelerator returns FALSE\n"); return FALSE; } /* Check if accelerator is associated with menu command */ hMenu = (Window->style & WS_CHILD) ? 0 : (HMENU)Window->IDMenu; hSubMenu = NULL; MenuObject = UserGetMenuObject(hMenu); nPos = pAccel->cmd; if (MenuObject) { if ((MENU_FindItem (&MenuObject, &nPos, MF_BYPOSITION))) hSubMenu = MenuObject->head.h; else hMenu = NULL; } if (!hMenu) { /* Check system menu now */ hMenu = Window->SystemMenu; hSubMenu = hMenu; /* system menu is a popup menu */ MenuObject = UserGetMenuObject(hMenu); nPos = pAccel->cmd; if (MenuObject) { if ((MENU_FindItem (&MenuObject, &nPos, MF_BYPOSITION))) hSubMenu = MenuObject->head.h; else hMenu = NULL; } } /* If this is a menu item, there is no capturing enabled and window is not disabled, send WM_INITMENU */ if (hMenu && !IntGetCaptureWindow()) { co_IntSendMessage(hWnd, WM_INITMENU, (WPARAM)hMenu, 0L); if (hSubMenu) { nPos = IntFindSubMenu(&hMenu, hSubMenu); TRACE("hSysMenu = %p, hSubMenu = %p, nPos = %u\n", hMenu, hSubMenu, nPos); co_IntSendMessage(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, TRUE)); } } /* Don't send any message if: - window is disabled - menu item is disabled - this is window menu and window is minimized */ if (!(Window->style & WS_DISABLED) && !(hMenu && IntGetMenuState(hMenu, pAccel->cmd, MF_BYCOMMAND) & (MF_DISABLED | MF_GRAYED)) && !(hMenu && hMenu == (HMENU)Window->IDMenu && (Window->style & WS_MINIMIZED))) { /* If this is system menu item, send WM_SYSCOMMAND, otherwise send WM_COMMAND */ if (hMenu && hMenu == Window->SystemMenu) { TRACE("Sending WM_SYSCOMMAND, wParam=%0x\n", pAccel->cmd); co_IntSendMessage(hWnd, WM_SYSCOMMAND, pAccel->cmd, 0x00010000L); } else { TRACE("Sending WM_COMMAND, wParam=%0x\n", 0x10000 | pAccel->cmd); co_IntSendMessage(hWnd, WM_COMMAND, 0x10000 | pAccel->cmd, 0L); } } TRACE("IntTranslateAccelerator returns TRUE\n"); return TRUE; }
static BOOL FASTCALL co_IntSetForegroundAndFocusWindow(PWND Wnd, PWND FocusWindow, BOOL MouseActivate) { HWND hWnd = Wnd->head.h; HWND hWndPrev = NULL; HWND hWndFocus = FocusWindow->head.h; HWND hWndFocusPrev = NULL; PUSER_MESSAGE_QUEUE PrevForegroundQueue; ASSERT_REFS_CO(Wnd); TRACE("IntSetForegroundAndFocusWindow(%x, %x, %s)\n", hWnd, hWndFocus, MouseActivate ? "TRUE" : "FALSE"); if ((Wnd->style & (WS_CHILD | WS_POPUP)) == WS_CHILD) { TRACE("Failed - Child\n"); return FALSE; } if (0 == (Wnd->style & WS_VISIBLE) && Wnd->head.pti->pEThread->ThreadsProcess != CsrProcess) { TRACE("Failed - Invisible\n"); return FALSE; } PrevForegroundQueue = IntGetFocusMessageQueue(); if (PrevForegroundQueue != 0) { hWndPrev = PrevForegroundQueue->ActiveWindow; hWndFocusPrev = PrevForegroundQueue->FocusWindow; } if (hWndPrev == hWnd) { TRACE("Failed - Same\n"); return TRUE; } /* FIXME: Call hooks. */ co_IntSendDeactivateMessages(hWndPrev, hWnd); co_IntSendKillFocusMessages(hWndFocusPrev, hWndFocus); IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue); if (Wnd->head.pti->MessageQueue) { Wnd->head.pti->MessageQueue->ActiveWindow = hWnd; } if (FocusWindow->head.pti->MessageQueue) { FocusWindow->head.pti->MessageQueue->FocusWindow = hWndFocus; } if (PrevForegroundQueue != Wnd->head.pti->MessageQueue) { /* FIXME: Send WM_ACTIVATEAPP to all thread windows. */ } co_IntSendSetFocusMessages(hWndFocusPrev, hWndFocus); co_IntSendActivateMessages(hWndPrev, hWnd, MouseActivate); return TRUE; }
BOOL FASTCALL co_IntSetActiveWindow(PWND Wnd OPTIONAL, BOOL bMouse, BOOL bFocus, BOOL Async) { PTHREADINFO pti; PUSER_MESSAGE_QUEUE ThreadQueue; PWND pWndChg, WndPrev; // State changes. HWND hWndPrev; HWND hWnd = 0; BOOL InAAPM; CBTACTIVATESTRUCT cbt; //ERR("co_IntSetActiveWindow 1\n"); if (Wnd) { ASSERT_REFS_CO(Wnd); hWnd = UserHMGetHandle(Wnd); if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE; if (Wnd == UserGetDesktopWindow()) return FALSE; //ERR("co_IntSetActiveWindow 1a hWnd 0x%p\n",hWnd); } //ERR("co_IntSetActiveWindow 2\n"); pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; ASSERT(ThreadQueue != 0); hWndPrev = ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : NULL; pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch. while (Wnd) { BOOL Ret, DoFG, AllowFG; if (Wnd->state & WNDS_BEINGACTIVATED) return TRUE; if (ThreadQueue == Wnd->head.pti->MessageQueue) { if (IsAllowedFGActive(pti, Wnd)) { DoFG = TRUE; } else { //ERR("co_IntSetActiveWindow 3 Go Out!\n"); break; } AllowFG = !pti->cVisWindows; // Nothing is visable. //ERR("co_IntSetActiveWindow 3a DoFG = %d AllowFG = %d\n",DoFG,AllowFG); } else //if (ThreadQueue != Wnd->head.pti->MessageQueue) { //PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); // Rule 1 & 4, We are foreground so set this FG window or NULL foreground.... //if (!ForegroundQueue || ForegroundQueue == ThreadQueue) if (!gpqForeground || gpqForeground == ThreadQueue) { DoFG = TRUE; } else DoFG = FALSE; if (DoFG) { if (pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE || pti->cVisWindows) AllowFG = TRUE; else AllowFG = FALSE; } else AllowFG = FALSE; //ERR("co_IntSetActiveWindow 3b DoFG = %d AllowFG = %d\n",DoFG,AllowFG); } Ret = FALSE; if (DoFG) { pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE; //ERR("co_IntSetActiveWindow 3c FG set\n"); Ret = co_IntSetForegroundAndFocusWindow(Wnd, bMouse); if (AllowFG) { pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE; } else { pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE; } } return Ret; } /* Call CBT hook chain */ cbt.fMouse = bMouse; cbt.hWndActive = hWndPrev; if (co_HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hWnd, (LPARAM)&cbt)) { ERR("SetActiveWindow: WH_CBT Call Hook return!\n"); return FALSE; } if ( ThreadQueue->spwndActive && ThreadQueue->spwndActive->state & WNDS_DESTROYED ) ThreadQueue->spwndActive = NULL; else ThreadQueue->spwndActivePrev = ThreadQueue->spwndActive; WndPrev = ThreadQueue->spwndActive; // Keep to save changing active. if (WndPrev) { if (ThreadQueue == gpqForeground) gpqForegroundPrev = ThreadQueue; if (!co_IntSendDeactivateMessages(UserHMGetHandle(WndPrev), hWnd)) return FALSE; } WndPrev = ThreadQueue->spwndActive; // Again keep to save changing active. // While in calling message proc or hook: // Fail if a preemptive switch was made, current active not made previous, // focus window is dead or no longer the same thread queue. if ( ThreadQueue->spwndActivePrev != ThreadQueue->spwndActive || pWndChg != WndPrev || (Wnd && !VerifyWnd(Wnd)) || ThreadQueue != pti->MessageQueue ) { ERR("SetActiveWindow: Summery ERROR, active state changed!\n"); return FALSE; } if (!WndPrev) ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE; if (Wnd) Wnd->state |= WNDS_BEINGACTIVATED; IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); //// Breaks Atl-Esc/Tab via User32. ////FindRemoveAsyncMsg(Wnd,(WPARAM)Wnd); // Clear out activate ASYNC messages. /* check if the specified window can be set in the input data of a given queue */ if ( !Wnd || ThreadQueue == Wnd->head.pti->MessageQueue) { /* set the current thread active window */ ThreadQueue->spwndActive = Wnd; } WndPrev = VerifyWnd(ThreadQueue->spwndActivePrev); // Now should be set but verify it again. InAAPM = co_IntSendActivateMessages(WndPrev, Wnd, bMouse, Async); /* now change focus if necessary */ if (bFocus && !(ThreadQueue->QF_flags & QF_FOCUSNULLSINCEACTIVE)) { /* Do not change focus if the window is no longer active */ if (ThreadQueue->spwndActive == Wnd) { if (!ThreadQueue->spwndFocus || !Wnd || UserGetAncestor(ThreadQueue->spwndFocus, GA_ROOT) != Wnd) { co_UserSetFocus(Wnd); } } } if (InAAPM) { pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG; } // FIXME: Used in the menu loop!!! //ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE; //ERR("co_IntSetActiveWindow Exit\n"); if (Wnd) Wnd->state &= ~WNDS_BEINGACTIVATED; return (ThreadQueue->spwndActive == Wnd); }
/* Ported from WINE20020904 (SCROLL_ShowScrollBar) */ DWORD FASTCALL co_UserShowScrollBar(PWND Wnd, int wBar, DWORD bShow) { DWORD Style, OldStyle; ASSERT_REFS_CO(Wnd); switch(wBar) { case SB_HORZ: Style = WS_HSCROLL; break; case SB_VERT: Style = WS_VSCROLL; break; case SB_BOTH: Style = WS_HSCROLL | WS_VSCROLL; break; case SB_CTL: Style = 0; break; default: EngSetLastError(ERROR_INVALID_PARAMETER); return( FALSE); } if(!co_IntCreateScrollBars(Wnd)) { return( FALSE); } if (wBar == SB_CTL) { IntUpdateSBInfo(Wnd, SB_CTL); co_WinPosShowWindow(Wnd, bShow ? SW_SHOW : SW_HIDE); return( TRUE); } OldStyle = Wnd->style; if(bShow) Wnd->style |= Style; else Wnd->style &= ~Style; if(Wnd->style != OldStyle) { if(Wnd->style & WS_HSCROLL) IntUpdateSBInfo(Wnd, SB_HORZ); if(Wnd->style & WS_VSCROLL) IntUpdateSBInfo(Wnd, SB_VERT); if(Wnd->style & WS_VISIBLE) { /* Frame has been changed, let the window redraw itself */ co_WinPosSetWindowPos(Wnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING); } } return( TRUE); }
HWND FASTCALL co_UserSetFocus(PWND Window) { HWND hWndPrev = 0; PWND pwndTop; PTHREADINFO pti; PUSER_MESSAGE_QUEUE ThreadQueue; if (Window) ASSERT_REFS_CO(Window); pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; ASSERT(ThreadQueue != 0); TRACE("Enter SetFocus hWnd 0x%p pti 0x%p\n",Window ? UserHMGetHandle(Window) : 0, pti ); hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0; if (Window != 0) { if (hWndPrev == UserHMGetHandle(Window)) { return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0; /* Nothing to do */ } if (Window->head.pti->MessageQueue != ThreadQueue) { ERR("SetFocus Must have the same Q!\n"); return 0; } /* Check if we can set the focus to this window */ for (pwndTop = Window; pwndTop != NULL; pwndTop = pwndTop->spwndParent) { if (pwndTop->style & (WS_MINIMIZED|WS_DISABLED)) return 0; if ((pwndTop->style & (WS_POPUP|WS_CHILD)) != WS_CHILD) break; } if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev)) { ERR("SetFocus 1 WH_CBT Call Hook return!\n"); return 0; } /* Activate pwndTop if needed. */ if (pwndTop != ThreadQueue->spwndActive) { PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); // Keep it based on desktop. if (ThreadQueue != ForegroundQueue && IsAllowedFGActive(pti, pwndTop)) // Rule 2 & 3. { //ERR("SetFocus: Set Foreground!\n"); if (!(pwndTop->style & WS_VISIBLE)) { pti->ppi->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE; } if (!co_IntSetForegroundAndFocusWindow(pwndTop, FALSE)) { ERR("SetFocus: Set Foreground and Focus Failed!\n"); return 0; } } /* Set Active when it is needed. */ if (pwndTop != ThreadQueue->spwndActive) { //ERR("SetFocus: Set Active!\n"); if (!co_IntSetActiveWindow(pwndTop, FALSE, FALSE, FALSE)) { ERR("SetFocus: Set Active Failed!\n"); return 0; } } /* Abort if window destroyed */ if (Window->state2 & WNDS2_INDESTROY) return 0; /* Do not change focus if the window is no longer active */ if (pwndTop != ThreadQueue->spwndActive) { ERR("SetFocus: Top window did not go active!\n"); return 0; } } // Check again! SetActiveWindow could have set the focus via WM_ACTIVATE. hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0; IntSendFocusMessages( pti, Window); TRACE("Focus: %p -> %p\n", hWndPrev, Window->head.h); } else /* NULL hwnd passed in */ { if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev)) { ERR("SetFocus: 2 WH_CBT Call Hook return!\n"); return 0; } /* set the current thread focus window null */ IntSendFocusMessages( pti, NULL); } return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0; }
static DWORD FASTCALL co_IntSetScrollInfo(PWND Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw) { /* * Update the scrollbar state and set action flags according to * what has to be done graphics wise. */ LPSCROLLINFO Info; PSCROLLBARINFO psbi; /* UINT new_flags;*/ BOOL bChangeParams = FALSE; /* don't show/hide scrollbar if params don't change */ ASSERT_REFS_CO(Window); if(!SBID_IS_VALID(nBar)) { EngSetLastError(ERROR_INVALID_PARAMETER); ERR("Trying to set scrollinfo for unknown scrollbar type %d", nBar); return FALSE; } if(!co_IntCreateScrollBars(Window)) { return FALSE; } if (lpsi->cbSize != sizeof(SCROLLINFO) && lpsi->cbSize != (sizeof(SCROLLINFO) - sizeof(lpsi->nTrackPos))) { EngSetLastError(ERROR_INVALID_PARAMETER); return 0; } if (lpsi->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL)) { EngSetLastError(ERROR_INVALID_PARAMETER); return 0; } psbi = IntGetScrollbarInfoFromWindow(Window, nBar); Info = IntGetScrollInfoFromWindow(Window, nBar); /* Set the page size */ if (0 != (lpsi->fMask & SIF_PAGE)) { if (Info->nPage != lpsi->nPage) { Info->nPage = lpsi->nPage; bChangeParams = TRUE; } } /* Set the scroll pos */ if (0 != (lpsi->fMask & SIF_POS)) { if (Info->nPos != lpsi->nPos) { Info->nPos = lpsi->nPos; } } /* Set the scroll range */ if (0 != (lpsi->fMask & SIF_RANGE)) { /* Invalid range -> range is set to (0,0) */ if (lpsi->nMin > lpsi->nMax || 0x80000000 <= (UINT)(lpsi->nMax - lpsi->nMin)) { Info->nMin = 0; Info->nMax = 0; bChangeParams = TRUE; } else if (Info->nMin != lpsi->nMin || Info->nMax != lpsi->nMax) { Info->nMin = lpsi->nMin; Info->nMax = lpsi->nMax; bChangeParams = TRUE; } } /* Make sure the page size is valid */ if (Info->nMax - Info->nMin + 1 < Info->nPage) { Info->nPage = Info->nMax - Info->nMin + 1; } /* Make sure the pos is inside the range */ if (Info->nPos < Info->nMin) { Info->nPos = Info->nMin; } else if (Info->nPos > Info->nMax - max(Info->nPage - 1, 0)) { Info->nPos = Info->nMax - max(Info->nPage - 1, 0); } /* * Don't change the scrollbar state if SetScrollInfo is just called * with SIF_DISABLENOSCROLL */ if (0 == (lpsi->fMask & SIF_ALL)) { return Info->nPos; } /* Check if the scrollbar should be hidden or disabled */ if (0 != (lpsi->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL))) { if (Info->nMin >= (int)(Info->nMax - max(Info->nPage - 1, 0))) { /* Hide or disable scroll-bar */ if (0 != (lpsi->fMask & SIF_DISABLENOSCROLL)) { /* new_flags = ESB_DISABLE_BOTH;*/ } else if ((nBar != SB_CTL) && bChangeParams) { co_UserShowScrollBar(Window, nBar, FALSE); return Info->nPos; } } else /* Show and enable scroll-bar */ { /* new_flags = 0;*/ if ((nBar != SB_CTL) && bChangeParams) { co_UserShowScrollBar(Window, nBar, TRUE); } } #if 0 if (infoPtr->flags != new_flags) /* check arrow flags */ { infoPtr->flags = new_flags; *Action |= SA_SSI_REPAINT_ARROWS; } #endif } if (bRedraw) { RECTL UpdateRect = psbi->rcScrollBar; UpdateRect.left -= Window->rcClient.left - Window->rcWindow.left; UpdateRect.right -= Window->rcClient.left - Window->rcWindow.left; UpdateRect.top -= Window->rcClient.top - Window->rcWindow.top; UpdateRect.bottom -= Window->rcClient.top - Window->rcWindow.top; co_UserRedrawWindow(Window, &UpdateRect, 0, RDW_INVALIDATE | RDW_FRAME); } /* Return current position */ return Info->nPos; }