📄 wince_ws.c
字号:
ClientToScreen( hWnd, &pt );
MainRect.i32Left=pt.x;
MainRect.i32Top=pt.y;
pt.x=MainRect.i32Right;
pt.y=MainRect.i32Bottom;
ClientToScreen( hWnd, &pt );
MainRect.i32Right=pt.x;
MainRect.i32Bottom=pt.y;
// if the mainrect is not the same as rc then we have changed position so set bPosChanged
hRgn = CreateRectRgn(0, 0, 5, 5);
while(hwCur)
{
hwCur=GetWindow(hwCur,GW_HWNDPREV);
if(!hwCur)
{
break;
}
if(hwCur==psSurface->u.window.ws.hShadowWnd)
{
continue;
}
if(IsWindowVisible(hwCur)==FALSE)
{
continue;
}
dwAboveCount++;
GetWindowRect(hwCur,(RECT*)&rc);
nHorizontalOffset = rc.i32Left;
nVerticalOffset = rc.i32Top;
#ifdef DISPLAYMESSAGES
wsprintf(wszMessageBuf,TEXT("(%d,%d),(%d,%d)"),rc.i32Left,rc.i32Top,rc.right,rc.bottom);
OutputDebugString(wszMessageBuf);
#endif
nRgn = GetWindowRgn(hwCur, hRgn);
if(nRgn == COMPLEXREGION)
{
dwSize = GetRegionData(hRgn, sizeof(RGNDATA), NULL);
RgnData = (RGNDATA*) malloc(dwSize);
GetRegionData(hRgn, dwSize, RgnData);
psRect=(RECT*)(RgnData->Buffer);
for(dwIndex=0;dwIndex<RgnData->rdh.nCount;dwIndex++,psRect++)
{
rc.i32Right=nHorizontalOffset + (psRect->right-1);
rc.i32Left=nHorizontalOffset + psRect->left;
rc.i32Top=nVerticalOffset + psRect->top;
rc.i32Bottom=nVerticalOffset + (psRect->bottom-1);
psRects=CreateRect(&rc,psRects);
}
free(RgnData);
}
else
{
rc.i32Right--;
rc.i32Bottom--;
psRects=CreateRect(&rc,psRects);
}
psSurface->u.window.ws.psOverlappedWindowList=CreateListItem((IMG_UINT32)hwCur, psSurface->u.window.ws.psOverlappedWindowList);
}
// as Child windows will have the same z-order as our display window we need to enumerate these as well.
// but as this will stop us displaying anything if we have a menu, lets not do this for now
hwCur=hWnd;
while(hwCur)
{
hwCur=GetWindow(hWnd,GW_CHILD);
if(!hwCur)
{
break;
}
if(hwCur==psSurface->u.window.ws.hShadowWnd)
{
continue;
}
if(IsWindowVisible(hwCur)==FALSE)
{
continue;
}
dwAboveCount++;
GetWindowRect(hwCur,(RECT*)&rc);
#ifdef DISPLAYMESSAGES
wsprintf(wszMessageBuf,TEXT("(%d,%d),(%d,%d)"),rc.i32Left,rc.i32Top,rc.right,rc.bottom);
OutputDebugString(wszMessageBuf);
#endif
nRgn = GetWindowRgn(hwCur, hRgn);
if(nRgn == COMPLEXREGION)
{
dwSize = GetRegionData(hRgn, sizeof(RGNDATA), NULL);
RgnData = (RGNDATA*) malloc(dwSize);
GetRegionData(hRgn, dwSize, RgnData);
psRect=(RECT*)(RgnData->Buffer);
for(dwIndex=0;dwIndex<RgnData->rdh.nCount;dwIndex++,psRect++)
{
rc.i32Right=nHorizontalOffset + (psRect->right-1);
rc.i32Left=nHorizontalOffset + psRect->left;
rc.i32Top=nVerticalOffset + psRect->top;
rc.i32Bottom=nVerticalOffset + (psRect->bottom-1);
psRects=CreateRect(&rc,psRects);
}
free(RgnData);
}
else
{
rc.i32Right--;
rc.i32Bottom--;
psRects=CreateRect(&rc,psRects);
}
psSurface->u.window.ws.psOverlappedWindowList=CreateListItem((IMG_UINT32)hwCur, psSurface->u.window.ws.psOverlappedWindowList);
}
DeleteObject((HGDIOBJ)hRgn);
}
else
{
if (psSurface->u.window.ws.psClippedBlits)
{
FreeRegions(psSurface->u.window.ws.psClippedBlits);
psSurface->u.window.ws.psClippedBlits=NULL;
}
if (psSurface->u.window.ws.psOverlappingRects)
{
FreeRegions(psSurface->u.window.ws.psOverlappingRects);
psSurface->u.window.ws.psOverlappingRects=NULL;
}
if(psSurface->u.window.ws.psOverlappedWindowList)
{
FreeItems(psSurface->u.window.ws.psOverlappedWindowList);
psSurface->u.window.ws.psOverlappedWindowList=NULL;
}
return FALSE;
}
// compare this list of rectangles with the previous list.
// If they are different we need to recalculate our clipping rectangles, flush the queue and move our shadow window to the front and then the back.
//
if(dwAboveCount==0)
{
if (psSurface->u.window.ws.psOverlappingRects)
{
FreeRegions(psSurface->u.window.ws.psOverlappingRects);
psSurface->u.window.ws.psOverlappingRects=NULL;
}
if (psSurface->u.window.ws.psClippedBlits)
{
FreeRegions(psSurface->u.window.ws.psClippedBlits);
psSurface->u.window.ws.psClippedBlits=NULL;
}
MainRect.i32Right--;
MainRect.i32Bottom--;
psSurface->u.window.ws.psClippedBlits=CreateRect(&MainRect,NULL);
return FALSE;
}
if((!RegionsIdentical(psRects,psSurface->u.window.ws.psOverlappingRects))||(psRects,psSurface->u.window.ws.bPosChanged))
{
if(psSurface->u.window.ws.psOverlappingRects)
{
FreeRegions(psSurface->u.window.ws.psOverlappingRects);
}
psSurface->u.window.ws.psOverlappingRects=psRects;
MainRect.i32Right--;
MainRect.i32Bottom--;
if(psSurface->u.window.ws.psClippedBlits)
{
FreeRegions(psSurface->u.window.ws.psClippedBlits);
}
psSurface->u.window.ws.psClippedBlits=SubtractRects(psSurface->u.window.ws.psOverlappingRects,&MainRect);
psSurface->u.window.ws.bPosChanged=FALSE;
// we still need to clear our queue and then send our shadow window to the front and then the back.
return IMG_TRUE;
}
else
{
if(psRects)
{
FreeRegions(psRects);
psRects=NULL;
FreeItems(psSurface->u.window.ws.psOverlappedWindowList);
psSurface->u.window.ws.psOverlappedWindowList=NULL;
}
}
return FALSE;
}
/*****************************************************************************
FUNCTION : SubtractRects
DESCRIPTION: Create a list of blit regions by subtracting the overlapping regions from the
Source rectangle
PARAMETERS : PWSREGION psRegion
WSRECT *psRect
RETURNS : PWSREGION, a pointer to a list of blit rectangles
*****************************************************************************/
PWSREGION SubtractRects(PWSREGION psRegion, WSRECT *psRect)
{
PWSREGION psCur;
PWSREGION psPrev;
PWSREGION psFirst;
PWSREGION psNext;
WSRECT sCreateRect;
psFirst=CreateRect(psRect,NULL);
// For each region in our input list, we want to test it's intersection/occludion of the recangle and split it up into an unoccluded section and a untested section
while(psRegion)
{
psCur=psFirst;
psPrev=NULL;
while(psCur)
{
psNext=psCur->psNext;
if((psRegion->sRect.i32Left>psCur->sRect.i32Left)&&(psRegion->sRect.i32Left<=psCur->sRect.i32Right))
{
sCreateRect.i32Right=psRegion->sRect.i32Left-1;
sCreateRect.i32Left=psCur->sRect.i32Left;
sCreateRect.i32Top=psCur->sRect.i32Top;
sCreateRect.i32Bottom=psCur->sRect.i32Bottom;
psFirst=CreateRect(&sCreateRect,psFirst);
if(!psPrev)
{
psPrev=psFirst;
}
psCur->sRect.i32Left=psRegion->sRect.i32Left;
}
if((psRegion->sRect.i32Right >= psCur->sRect.i32Left)&&(psRegion->sRect.i32Right < psCur->sRect.i32Right))
{
sCreateRect.i32Left=psRegion->sRect.i32Right+1;
sCreateRect.i32Right=psCur->sRect.i32Right;
sCreateRect.i32Top=psCur->sRect.i32Top;
sCreateRect.i32Bottom=psCur->sRect.i32Bottom;
psFirst=CreateRect(&sCreateRect,psFirst);
if(!psPrev)
{
psPrev=psFirst;
}
psCur->sRect.i32Right=psRegion->sRect.i32Right;
}
if((psRegion->sRect.i32Top > psCur->sRect.i32Top)&&(psRegion->sRect.i32Top<=psCur->sRect.i32Bottom))
{
sCreateRect.i32Bottom=psRegion->sRect.i32Top-1;
sCreateRect.i32Left=psCur->sRect.i32Left;
sCreateRect.i32Right=psCur->sRect.i32Right;
sCreateRect.i32Top=psCur->sRect.i32Top;
psFirst=CreateRect(&sCreateRect,psFirst);
if(!psPrev)
{
psPrev=psFirst;
}
psCur->sRect.i32Top=psRegion->sRect.i32Top;
}
if((psRegion->sRect.i32Bottom >= psCur->sRect.i32Top)&&(psRegion->sRect.i32Bottom<psCur->sRect.i32Bottom))
{
sCreateRect.i32Top=psRegion->sRect.i32Bottom+1;
sCreateRect.i32Left=psCur->sRect.i32Left;
sCreateRect.i32Right=psCur->sRect.i32Right;
sCreateRect.i32Bottom=psCur->sRect.i32Bottom;
psFirst=CreateRect(&sCreateRect,psFirst);
if(!psPrev)
{
psPrev=psFirst;
}
psCur->sRect.i32Bottom=psRegion->sRect.i32Bottom;
}
// if we are occluded then free this rectangle and remove it from the list.
if( (BETWEEN(psRegion->sRect.i32Left,psCur->sRect.i32Left,psRegion->sRect.i32Right)) &&
(BETWEEN(psRegion->sRect.i32Left,psCur->sRect.i32Right,psRegion->sRect.i32Right)) &&
(BETWEEN(psRegion->sRect.i32Top,psCur->sRect.i32Top,psRegion->sRect.i32Bottom)) &&
(BETWEEN(psRegion->sRect.i32Top,psCur->sRect.i32Bottom,psRegion->sRect.i32Bottom)))
{
if(psPrev)
{
psPrev->psNext=psCur->psNext;
free(psCur);
psCur=psPrev;
}
//
else
{
free(psCur);
psCur=NULL;
psFirst=psNext;
}
}
psPrev=psCur;
psCur=psNext;
}
psRegion=psRegion->psNext;
}
return psFirst;
}
/*****************************************************************************
FUNCTION : CreateRect
DESCRIPTION: Create a WSRegion with the specified Rectangle dimensions, pointing to the next specified element
PARAMETERS : PWSREGION psNext
WSRECT *psRect
RETURNS : PWSREGION, a pointer to a list of WSREGIONS
*****************************************************************************/
PWSREGION CreateRect(WSRECT *psRect, PWSREGION psNext)
{
PWSREGION psCur;
psCur=(PWSREGION)malloc(sizeof(WSREGION));
if(psCur)
{
psCur->sRect=*psRect;
psCur->psNext=psNext;
}
return psCur;
}
/*****************************************************************************
FUNCTION : CreateListItem
DESCRIPTION: Create a Listitem item value, pointing to the next specified element
PARAMETERS : PLISTITEM psNext
WSRECT *psRect
RETURNS : PLISTITEM, a pointer to a list of PLISTITEM
*****************************************************************************/
PLISTITEM CreateListItem(IMG_UINT32 ui32Item, PLISTITEM psNext)
{
PLISTITEM psCur;
psCur=(PLISTITEM)malloc(sizeof(LISTITEM));
if(psCur)
{
psCur->ui32Item=ui32Item;
psCur->psNext=psNext;
}
return psCur;
}
/*****************************************************************************
FUNCTION : RegionsIdentical
DESCRIPTION: Compare the two regions, to see if they are identical
PARAMETERS : PWSREGION psRegionA
PWSREGION psRegionB
RETURNS : TRUE if they are the same
*****************************************************************************/
BOOL RegionsIdentical(PWSREGION psRegionA, PWSREGION psRegionB)
{
BOOL bIdentical=TRUE;
if((psRegionA==NULL)&&(psRegionB==NULL))
{
return TRUE;
}
if((psRegionA==NULL)||(psRegionB==NULL))
{
return FALSE;
}
while((psRegionA)&&(psRegionB))
{
if(
(psRegionA->sRect.i32Top!=psRegionB->sRect.i32Top)||
(psRegionA->sRect.i32Left!=psRegionB->sRect.i32Left)||
(psRegionA->sRect.i32Right!=psRegionB->sRect.i32Right)||
(psRegionA->sRect.i32Bottom!=psRegionB->sRect.i32Bottom) )
{
bIdentical=FALSE;
break;
}
if((psRegionA->psNext) && (psRegionB->psNext))
{
psRegionA=psRegionA->psNext;
psRegionB=psRegionB->psNext;
}
else
{
break;
}
}
if(psRegionA->psNext!=NULL)
bIdentical=FALSE;
if(psRegionB->psNext!=NULL)
bIdentical=FALSE;
return bIdentical;
}
/*****************************************************************************
FUNCTION : FreeRegions
DESCRIPTION: Free the specified region list
PARAMETERS : PWSREGION psRegion
RETURNS : None
*****************************************************************************/
void FreeRegions(PWSREGION psRegion)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -