📄 basesite.cpp
字号:
); //Find out what part intersects us. HXREGION* pTemp = Transition( pPosition->x, pPosition->y, pPosition->x + m_size.cx, pPosition->y + m_size.cy ); HXIntersectRegion( pTemp, pReg, pReg ); if( !HXEmptyRegion(pReg) ) { HXUnionRegion( pReg, m_pDirtyRegion, m_pDirtyRegion); // We must call _DamageRect to give windows a chance to see if // we are occluded by a drop down menu. If we are, then we // have to invalidate the OS rect so Windows does not do a // save under. HXxRect rectTmp = {pTemp->extents.x1, pTemp->extents.y1, pTemp->extents.x2, pTemp->extents.y2}; _DamageRect(rectTmp); } HXDestroyRegion( pReg ); HXDestroyRegion( pTemp );}/************************************************************************ * Method: * IHXSite::DamageRegion */STDMETHODIMP CHXBaseSite::DamageRegion(HXxRegion region){ HX_ASSERT( "Depricated method, do not use. Use the new damage region." == NULL ); //This was never used and it was not defined what a HXxRegion was. //So, we just have to invalidate the whole site. //Users should use the new damage region that takes the cross platform //region that actually works. HXxRect rect; HXREGION* reg = (HXREGION*)region; rect.left = 0; rect.top = 0; rect.right = m_size.cx; rect.bottom = m_size.cy; return DamageRect( rect );}// Method:// IHXSite::ForceRedrawSTDMETHODIMP CHXBaseSite::ForceRedraw(){ HXxEvent event; HXxWindow* hxxWin = GetWindow(); if( IsCompositionLocked() && m_pVideoSurface->m_nBltMode!=HX_OVERLAY_BLT ) { return HXR_OK; } // make sure we have a visible window event though this should be // computed from the list of rects. if (!_ShouldEnterForceRedraw()) { return HXR_OK; } _TLSLock(); AddRef(); memset(&m_UpdateBltStatsRect, 0, sizeof(m_UpdateBltStatsRect)); if(m_pTopLevelSite->m_bDisableForceRedraw) { m_pTopLevelSite->m_bDisableForceRedraw = TRUE; } else { BOOL bDoIt = ((m_bIsVisible && m_pUser && m_Region && !HXEmptyRegion(m_Region)) || (m_AlphaBlendNotifiers.GetCount()!=0 || m_AlphaBlendSites.GetCount()!=0)); if( bDoIt ) { AboutToBlt(); event.handled = 0; if( m_bUserWantsSubRects ) { if( !HXEmptyRegion(m_pDirtyRegion) ) { HXxExposeInfo exposeInfo; HXxBoxRegion dirtRegion; //Construct a dirty rect that is relative to the //site's topleft corner. HXREGION* pTmpReg = HXCreateRegion(); HXUnionRegion( pTmpReg, m_pDirtyRegion, pTmpReg ); HXOffsetRegion( pTmpReg, -m_topleft.x, -m_topleft.y ); // adjust for scrolling; essentially turning off // subrect blitting while scrolling if (GetXSliderPos() || GetYSliderPos()) { HXREGION* pMe = HXCreateRectRegion( 0, 0, m_size.cx, m_size.cy ); HXUnionRegion(pMe, pTmpReg, pTmpReg); HXDestroyRegion(pMe); } //Set up the cross platform region. dirtRegion.numRects = pTmpReg->numRects; dirtRegion.rects = pTmpReg->rects; exposeInfo.extents.left = pTmpReg->extents.x1; exposeInfo.extents.right = pTmpReg->extents.x2; exposeInfo.extents.top = pTmpReg->extents.y1; exposeInfo.extents.bottom = pTmpReg->extents.y2; exposeInfo.pRegion = & dirtRegion; exposeInfo.pWindow = GetWindow(); exposeInfo.pParam1 = NULL; exposeInfo.pParam2 = NULL; event.event = HX_SURFACE_UPDATE2; event.window = hxxWin?hxxWin->window : NULL; event.param1 = m_pVideoSurface; event.param2 = &exposeInfo; event.result = 0; event.handled = 0; // Clear the dirty region HXZeroOutRegion( m_pDirtyRegion ); if( m_pUser ) { if (!m_bDoNotGenerateWMPPaint) { m_bInForceRedraw = m_bSiteRefresh; m_pUser->HandleEvent(&event); m_bInForceRedraw = FALSE; } } HXDestroyRegion( pTmpReg ); } } else {//XXXgfw OK, this is screwed up. Windows renders want a rectangle in//XXXgfw param2 while the unix renderers want a Window there. To clean this//XXXgfw up we need to clean up and unify the renderers.....#if defined(_UNIX) && !defined(_MAC_UNIX) event.event = HX_SURFACE_UPDATE; event.window = hxxWin?hxxWin->window : NULL; event.param1 = m_pVideoSurface; event.param2 = GetWindow(); event.result = 0; event.handled = 0;#else event.event = HX_SURFACE_UPDATE; event.window = m_pWindow? m_pWindow->window : NULL; event.param1 = m_pVideoSurface; event.param2 = NULL; event.result = 0; event.handled = 0;#endif // Clear the dirty region HXZeroOutRegion( m_pDirtyRegion ); if( m_pUser ) { if (!m_bDoNotGenerateWMPPaint) { // Distinguishes between a new frame and a repaint of a prior frame m_bInForceRedraw = m_bSiteRefresh; m_pUser->HandleEvent(&event); m_bInForceRedraw = FALSE; } } } // If blt has never been called, then blt black to the // background. Do not do this if we are a windowed // renderer. if (!event.handled && !m_bBltHasBeenCalled && !m_pWindow && m_pVideoSurface->m_nBltMode!=HX_OVERLAY_BLT ) { // Get the current size of the site The source rect is // just a 1 by 1 black pixel that gets stretched to // fit the destination HXxRect rDestRect = { 0, 0, m_size.cx, m_size.cy}; HXxRect rSrcRect = { 0, 0, 1, 1}; HXBitmapInfoHeader bih; memset(&bih, 0, sizeof(HXBitmapInfoHeader)); bih.biSize = sizeof(HXBitmapInfoHeader); bih.biWidth = 1; bih.biHeight = 1; bih.biPlanes = 1; bih.biBitCount = 32; bih.biCompression = HX_RGB; UCHAR pBuffer[4] = { 0,0,0,0 }; m_pVideoSurface->Blt(pBuffer, &bih, rDestRect, rSrcRect); m_bBltHasBeenCalled = FALSE; } //Stupid Windowed renderers! if(!m_bDoNotGenerateWMPPaint && !event.handled && m_pWindow && m_pWindow->window ) { _SendOSUpdateMessage(); } } m_pVideoSurface->UpdateBltStats(&m_UpdateBltStatsRect); } _TLSUnlock(); _ExitForceRedraw(); Release(); return HXR_OK;}/************************************************************************ * Method: * IHXSite2::UpdateSiteWindow * * Not used on Windows platform */STDMETHODIMP CHXBaseSite::UpdateSiteWindow( HXxWindow* /*IN*/ pWindow ){ return HXR_NOTIMPL;}/************************************************************************ * Method: * IHXSite2::ShowSite */STDMETHODIMP CHXBaseSite::ShowSite(BOOL bShow){ _TLSLock(); if(m_bIsVisible != bShow) { m_bIsVisible = bShow; //Invalidate the rect.... HXxRect pTmp = { m_topleft.x, m_topleft.y, m_topleft.x+m_size.cx, m_topleft.y+m_size.cy}; m_pTopLevelSite->_RecursiveDamageRect( &pTmp, TRUE ); if( this == m_pTopLevelSite ) { RecomputeClip(); } else { if(m_pTopLevelSite) m_pTopLevelSite->ScheduleCallback(CLIP, 0); } } _ShowSite(bShow); SizeSliders(); _TLSUnlock(); return HXR_OK;}void CHXBaseSite::_ForceRedrawAll(){ if( (IsSiteVisible() && m_Region && !HXEmptyRegion(m_Region)) || (m_AlphaBlendSites.GetCount()||m_AlphaBlendNotifiers.GetCount() ) ) {// HXREGION* pReg = NULL;// if( pDirtyRect)// {// pReg = HXCreateRectRegion( pDirtyRect->left,// pDirtyRect->top,// pDirtyRect->right-pDirtyRect->left,// pDirtyRect->bottom-pDirtyRect->top );// HXIntersectRegion( m_Region, pReg, pReg );// HXUnionRegion( m_pDirtyRegion, pReg, m_pDirtyRegion );// HXDestroyRegion( pReg );// }// else// {// HXUnionRegion( m_pDirtyRegion, m_Region, m_pDirtyRegion );// } InternalForceRedraw(); } //Now do all the children in z-order LISTPOSITION pos = m_ChildrenInZOrder.GetHeadPosition(); while(pos) { CHXBaseSite* pSite = (CHXBaseSite*)m_ChildrenInZOrder.GetNext(pos); pSite->_ForceRedrawAll(); }}BOOL CHXBaseSite::_CheckForVisibleChild(){ BOOL retVal = FALSE; if( m_bIsVisible && !m_bSiteNeverBlts ) { retVal = TRUE; } else { LISTPOSITION pos = m_ChildrenInZOrder.GetHeadPosition(); while(pos) { CHXBaseSite* pSite = (CHXBaseSite*)m_ChildrenInZOrder.GetNext(pos); if( pSite->_CheckForVisibleChild() ) { retVal = TRUE; break; } } } return retVal;}/************************************************************************ * Method: * IHXSite2::IsSiteVisible */STDMETHODIMP_(BOOL) CHXBaseSite::IsSiteVisible(){ BOOL bIsVisible = m_bIsVisible; if(m_pParentSite) { bIsVisible &= m_pParentSite->IsSiteVisible(); } if( bIsVisible ) { //If we are a m_bSiteNeverBlts then it doesn't matter if we are //visible or not, we must have at least one child that is //visible and not m_bSiteNeverBlts. Otherwise we really aren't //visible at all. This distinction is needed because of our //favorite logic in computesubrecs not that we have transparent //regions. if(!_CheckForVisibleChild()) { bIsVisible = FALSE; } } return bIsVisible;}/************************************************************************ * Method: * IHXSite2::UpdateZOrder * This method updates the Z order of its child sites since one of its * child sites' Z order is being updated. */voidCHXBaseSite::UpdateZOrder( CHXBaseSite* pUpdatedChildSite, INT32 lOldZOrder, INT32 lNewZOrder){ HX_ASSERT(pUpdatedChildSite); LISTPOSITION pos = m_ChildrenInZOrder.Find((void*)pUpdatedChildSite); if (!pos) { return; } m_ChildrenInZOrder.RemoveAt(pos); BOOL bHasReinsertedChild = FALSE; INT32 zOrder = 0; INT32 newZOrder = 0; LISTPOSITION posNext = m_ChildrenInZOrder.GetHeadPosition(); while (posNext) { pos = posNext; CHXBaseSite* pSite = (CHXBaseSite*)m_ChildrenInZOrder.GetNext(posNext); if (!bHasReinsertedChild) { pSite->GetZOrder(zOrder); if (zOrder > lNewZOrder) { m_ChildrenInZOrder.InsertBefore(pos, (void*)pUpdatedChildSite); bHasReinsertedChild = TRUE; pUpdatedChildSite->SetInternalZOrder(newZOrder++); } } pSite->SetInternalZOrder(newZOrder++); } if (!bHasReinsertedChild) { m_ChildrenInZOrder.AddTail((void*)pUpdatedChildSite); pUpdatedChildSite->SetInternalZOrder(newZOrder++); } HX_ASSERT((newZOrder == m_ChildrenInZOrder.GetCount()) && (m_ChildrenInZOrder.GetCount() == m_ChildrenMap.GetCount()));}/************************************************************************ * Method: * IHXSite2::SetZOrder */STDMETHODIMP CHXBaseSite::SetZOrder(INT32 lZOrder){ if(!m_pParentSite) { return HXR_UNEXPECTED; } _TLSLock(); if (lZOrder == -1) { lZOrder = m_pParentSite->GetNumberOfChildSites() - 1; } if (lZOrder >= (INT32) m_pParentSite->GetNumberOfChildSites()) { lZOrder = m_pParentSite->GetNumberOfChildSites() - 1; } if (m_lZOrder != lZOrder) { m_pParentSite->UpdateZOrder(this, m_lZOrder, lZOrder); //Invalidate the rect....
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -