⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wince_ws.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		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 + -