📄 basesite.cpp
字号:
HXUnionRectWithRegion( &rectTmp, m_pDirtyRegion, m_pDirtyRegion);
//Do OS specific stuff here.
_DamageRect(rect);
#if defined(_MACINTOSH) || defined(_MAC_UNIX)
_TLSUnlock();
#endif
return HXR_OK;
}
//This is the same as DamageRect except that the coordinates are in
//Window relative coords and we don't do the OS specific stuff (like
//no invalidateRect.
void CHXBaseSite::DamageRectWindowRel(HXxRect rect)
{
HXxPoint* pPosition = GetOrigin();
//Crop
HXREGION* pReg = HXCreateRectRegion( rect.left,
rect.top,
rect.right-rect.left,
rect.bottom-rect.top
);
//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::ForceRedraw
STDMETHODIMP 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.
*/
void
CHXBaseSite::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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -