Click here to Skip to main content
15,887,746 members
Articles / Programming Languages / C++

CGrid Control

Rate me:
Please Sign up or sign in to vote.
4.14/5 (18 votes)
8 May 2007CPOL1 min read 68.7K   5.2K   48  
An article on a grid control built with Windows API. Also includes an MFC class
#include "rectrgn.h"


CMyRect::CMyRect()
{
	x = y = 0;
	cx = cy = 0;
}

CMyRect::~CMyRect()
{
}

void CMyRect::Set(RECT_TYPE left, RECT_TYPE top, RECT_TYPE width, RECT_TYPE height)
{
	x = left;
	y = top;
	cx = width;
	cy = height;
}

const RECT_TYPE CMyRect::Left()
{
	return x;
}

const RECT_TYPE CMyRect::Top()
{
	return y;
}

const RECT_TYPE CMyRect::Right()
{
	return x + cx;
}

const RECT_TYPE CMyRect::Bottom()
{
	return y + cy;
}

const RECT_TYPE CMyRect::Width()
{
	return cx;
}

const RECT_TYPE CMyRect::Height()
{
	return cy;
}

bool CMyRect::operator == (const CMyRect& e)
{
	if(x == e.x && y == e.y && cx == e.cx && cy == e.cy) return true;
	return false;
}

void CMyRect::SetWidth(RECT_TYPE width)
{
	cx = width;
}

void CMyRect::SetHeight(RECT_TYPE height)
{
	cy = height;
}

bool CMyRect::IsCellIn(int xPos, int yPos)
{
	if(xPos < x || yPos < y || 
		xPos >= Right() || yPos >= Bottom())
		return false;
	else
		return true;
}




void DivideRect(CMyRect *prc1, CMyRect *prc2, CMyRect *pBound, CMyArray<CMyRect>* pRectArray)
{
	CMyRect tmp;
	if((*prc1 == (*prc2))) {
		if(pRectArray) pRectArray->RemoveAll();
		if(pBound) pBound->Set(0, 0, 0, 0);
		return ;
	}
	
	RECT_TYPE l = min(prc1->Left(), prc2->Left());
	RECT_TYPE t = min(prc1->Top(), prc2->Top());
	RECT_TYPE r = max(prc1->Right(), prc2->Right());
	RECT_TYPE b = max(prc1->Bottom(), prc2->Bottom());

	if( 
		(r - l >= prc1->Width() + prc2->Width()) || 
		(b - t >= prc1->Height() + prc2->Height())) {

		if(pRectArray) {
			pRectArray->SetSize(1);
			pRectArray->SetAt(0, *prc1);
		}
		if(pBound) {
			*pBound = *prc1;
		}
		return ;
	}
	else if((r - l <= prc1->Width() + prc2->Width()) && (b - t <= prc1->Height() + prc2->Height())) {
		if( (prc1->Left() <= prc2->Left()) && 
			(prc1->Top() <= prc2->Top()) && 
			(prc1->Right() >= prc2->Right()) && 
			(prc1->Bottom() >= prc2->Bottom()) ) {
			// prc2 is in prc1    cover
			if(pRectArray) {
				pRectArray->SetSize(4);
				tmp.Set(prc1->Left(), prc1->Top(), prc1->Width(), prc2->Top() - prc1->Top());
				if(tmp.Width() != 0 && tmp.Height() != 0)
					pRectArray->SetAt(0, tmp);
				tmp.Set(prc1->Left(), prc2->Top(), prc2->Left() - prc1->Left(), prc2->Height());
				if(tmp.Width() != 0 && tmp.Height() != 0)
					pRectArray->SetAt(1, tmp);
				tmp.Set(prc2->Right(), prc2->Top(), prc1->Right() - prc2->Right(), prc2->Height());
				if(tmp.Width() != 0 && tmp.Height() != 0)
					pRectArray->SetAt(2, tmp);
				tmp.Set(prc1->Left(), prc2->Bottom(), prc1->Width(), prc1->Bottom() - prc2->Bottom());
				if(tmp.Width() != 0 && tmp.Height() != 0)
					pRectArray->SetAt(3, tmp);
			}
			if(pBound) {
				*pBound = *prc1;
			}
			return ;
		}
		else if( (prc1->Left() >= prc2->Left()) && 
			(prc1->Top() >= prc2->Top()) && 
			(prc1->Right() <= prc2->Right()) && 
			(prc1->Bottom() <= prc2->Bottom()) ) {
			// prc1 is in prc2    cover
			if(pRectArray) pRectArray->RemoveAll();
			if(pBound) pBound->Set(0, 0, 0, 0);
			return ;
		}
		else {
			if(prc1->Left() < prc2->Left() && 
				prc1->Right() > prc2->Right() && 
				prc1->Top() >= prc2->Top() && 
				prc1->Bottom() <= prc2->Bottom() ) {
				// prc1 is through prc2 in x direction   through
				if(pRectArray) {
					pRectArray->SetSize(2);
					tmp.Set(prc1->Left(), prc1->Top(), prc2->Left() - prc1->Left(), prc1->Height());
					pRectArray->SetAt(0, tmp);
					tmp.Set(prc2->Right(), prc1->Top(), prc1->Right() - prc2->Right(), prc1->Height());
					pRectArray->SetAt(1, tmp);
				}
				if(pBound) {
					*pBound = *prc1;
				}
				return ;
			}
			else if(prc1->Left() >= prc2->Left() && 
				prc1->Right() <= prc2->Right() && 
				prc1->Top() < prc2->Top() && 
				prc1->Bottom() > prc2->Bottom() ) {
				// prc2 is through prc1 in x direction   through
				if(pRectArray) {
					pRectArray->SetSize(2);
					tmp.Set(prc1->Left(), prc1->Top(), prc1->Width(), prc2->Top() - prc1->Top());
					pRectArray->SetAt(0, tmp);
					tmp.Set(prc1->Left(), prc2->Bottom(), prc1->Width(), prc1->Bottom() - prc2->Bottom());
					pRectArray->SetAt(1, tmp);
				}
				if(pBound) {
					*pBound = *prc1;
				}
				return ;
			}
			else {
				if(prc1->Left() < prc2->Left() && prc1->Right() > prc2->Right() && 
					prc1->Top() < prc2->Bottom() && prc1->Bottom() < prc2->Bottom()) {
					// prc1 cut prc2 in prc2's top
					if(pRectArray) {
						pRectArray->SetSize(3);
						tmp.Set(prc1->Left(), prc1->Top(), prc2->Left() - prc1->Left(), prc1->Height());
						pRectArray->SetAt(0, tmp);
						tmp.Set(prc2->Left(), prc1->Top(), prc2->Width(), prc2->Top() - prc1->Top());
						pRectArray->SetAt(1, tmp);
						tmp.Set(prc2->Right(), prc1->Top(), prc1->Right() - prc2->Right(), prc1->Height());
						pRectArray->SetAt(2, tmp);
					}
					if(pBound) {
						*pBound = *prc1;
					}
					return ;
				}
				else if(prc1->Left() < prc2->Right() && prc1->Right() < prc2->Right() && 
					prc1->Top() < prc2->Top() && prc1->Bottom() > prc2->Bottom()) {
					// prc1 cut prc2 in prc2's left
					if(pRectArray) {
						pRectArray->SetSize(3);
						tmp.Set(prc1->Left(), prc1->Top(), prc1->Width(), prc2->Top() - prc1->Top());
						pRectArray->SetAt(0, tmp);
						tmp.Set(prc1->Left(), prc2->Top(), prc2->Left() - prc1->Left(), prc2->Height());
						pRectArray->SetAt(1, tmp);
						tmp.Set(prc1->Left(), prc2->Bottom(), prc1->Width(), prc1->Bottom() - prc2->Bottom());
						pRectArray->SetAt(2, tmp);
					}
					if(pBound) {
						*pBound = *prc1;
					}
					return ;
				}
				else if(prc1->Left() < prc2->Left() && prc1->Right() > prc2->Right() && 
					prc1->Top() > prc2->Top() && prc1->Bottom() > prc2->Top()) {
					// prc1 cut prc2 in prc2's bottom
					if(pRectArray) {
						pRectArray->SetSize(3);
						tmp.Set(prc1->Left(), prc1->Top(), prc2->Left() - prc1->Left(), prc1->Height());
						pRectArray->SetAt(0, tmp);
						tmp.Set(prc2->Left(), prc2->Bottom(), prc2->Width(), prc1->Bottom() - prc2->Bottom());
						pRectArray->SetAt(1, tmp);
						tmp.Set(prc2->Right(), prc1->Top(), prc1->Right() - prc2->Right(), prc1->Height());
						pRectArray->SetAt(2, tmp);
					}
					if(pBound) {
						*pBound = *prc1;
					}
					return ;
				}
				else if(prc1->Left() > prc2->Left() && prc1->Right() > prc2->Left() && 
					prc1->Top() < prc2->Top() && prc1->Bottom() > prc2->Bottom()) {
					// prc1 cut prc2 in prc2's right
					if(pRectArray) {
						pRectArray->SetSize(3);
						tmp.Set(prc1->Left(), prc1->Top(), prc1->Width(), prc2->Top() - prc1->Top());
						pRectArray->SetAt(0, tmp);
						tmp.Set(prc2->Right(), prc2->Top(), prc1->Right() - prc2->Right(), prc2->Height());
						pRectArray->SetAt(1, tmp);
						tmp.Set(prc1->Left(), prc2->Bottom(), prc1->Height(), prc1->Bottom() - prc2->Bottom());
						pRectArray->SetAt(2, tmp);
					}
					if(pBound) {
						*pBound = *prc1;
					}
					return ;
				}
				if(prc1->Left() >= prc2->Left() && prc1->Right() <= prc2->Right() && 
					prc1->Top() >= prc2->Top() && prc2->Bottom() > prc1->Top()) {
					// prc2 cut prc1 in prc1's top
					tmp.Set(prc1->Left(), prc2->Bottom(), prc1->Width(), prc1->Bottom() - prc2->Bottom());
					if(pRectArray) {
						pRectArray->SetSize(1);
						pRectArray->SetAt(0, tmp);
					}
					if(pBound) {
						*pBound = tmp;
					}
					return ;
				}
				else if(prc1->Left() >= prc2->Left() && prc2->Right() > prc1->Left() && 
					prc1->Top() >= prc2->Top() && prc1->Bottom() <= prc2->Bottom()) {
					// prc2 cut prc1 in prc1's left
					tmp.Set(prc2->Right(), prc1->Top(), prc1->Right() - prc2->Right(), prc1->Height());
					if(pRectArray) {
						pRectArray->SetSize(1);
						pRectArray->SetAt(0, tmp);
					}
					if(pBound) {
						*pBound = tmp;
					}
					return ;
				}
				else if(prc1->Left() >= prc2->Left() && prc1->Right() <= prc2->Right() && 
					prc2->Top() < prc1->Bottom() && prc1->Bottom() <= prc2->Bottom()) {
					// prc2 cut prc1 in prc1's bottom
					tmp.Set(prc1->Left(), prc1->Top(), prc1->Width(), prc2->Top() - prc1->Top());
					if(pRectArray) {
						pRectArray->SetSize(1);
						pRectArray->SetAt(0, tmp);
					}
					if(pBound) {
						*pBound = tmp;
					}
					return ;
				}
				else if(prc2->Left() < prc1->Right() && prc1->Right() <= prc2->Right() && 
					prc1->Top() >= prc2->Top() && prc1->Bottom() <= prc2->Bottom()) {
					// prc2 cut prc1 in prc1's right
					tmp.Set(prc1->Left(), prc1->Top(), prc2->Left() - prc1->Left(), prc1->Height());
					if(pRectArray) {
						pRectArray->SetSize(1);
						pRectArray->SetAt(0, tmp);
					}
					if(pBound) {
						*pBound = tmp;
					}
					return ;
				}
				else {
					if(prc1->Left() < prc2->Left() && prc1->Right() < prc2->Right() && 
						prc1->Top() < prc2->Top() && prc1->Bottom() < prc2->Bottom()) {
						// prc1 cut prc2 in prc2's top left
						if(pRectArray) {
							pRectArray->SetSize(2);
							tmp.Set(prc1->Left(), prc1->Top(), prc1->Width(), prc2->Top() - prc1->Top());
							pRectArray->SetAt(0, tmp);
							tmp.Set(prc1->Left(), prc2->Top(), prc2->Left() - prc1->Left(), prc1->Bottom() - prc2->Top());
							pRectArray->SetAt(1, tmp);
						}
						if(pBound) {
							*pBound = *prc1;
						}
						return ;
					}
					else if(prc1->Left() < prc2->Left() && prc1->Right() < prc2->Right() && 
						prc1->Top() > prc2->Top() && prc1->Bottom() > prc2->Bottom()) {
						// prc1 cut prc2 in prc2's bottom left
						if(pRectArray) {
							pRectArray->SetSize(2);
							tmp.Set(prc1->Left(), prc1->Top(), prc2->Left() - prc1->Left(), prc2->Bottom() - prc1->Top());
							pRectArray->SetAt(0, tmp);
							tmp.Set(prc1->Left(), prc2->Bottom(), prc1->Width(), prc1->Bottom() - prc2->Bottom());
							pRectArray->SetAt(1, tmp);
						}
						if(pBound) {
							*pBound = *prc1;
						}
						return ;
					}
					else if(prc1->Left() > prc2->Left() && prc1->Left() < prc2->Right() && 
						prc1->Top() > prc2->Top() && prc1->Top() < prc2->Bottom()) {
						// prc1 cut prc2 in prc2's bottom right
						if(pRectArray) {
							pRectArray->SetSize(2);
							tmp.Set(prc2->Right(), prc1->Top(), prc1->Right() - prc2->Right(), prc2->Bottom() - prc1->Top());
							pRectArray->SetAt(0, tmp);
							tmp.Set(prc1->Left(), prc2->Bottom(), prc1->Width(), prc1->Bottom() - prc2->Bottom());
							pRectArray->SetAt(1, tmp);
						}
						if(pBound) {
							*pBound = *prc1;
						}
						return ;
					}
					else if(prc1->Left() > prc2->Left() && prc1->Right() > prc2->Right() && 
						prc1->Top() < prc2->Top() && prc1->Bottom() < prc2->Bottom()) {
						// prc1 cut prc2 in prc2's top right
						if(pRectArray) {
							pRectArray->SetSize(2);
							tmp.Set(prc1->Left(), prc1->Top(), prc1->Width(), prc2->Top() - prc1->Top());
							pRectArray->SetAt(0, tmp);
							tmp.Set(prc2->Right(), prc2->Top(), prc1->Right() - prc2->Right(), prc1->Bottom() - prc2->Top());
							pRectArray->SetAt(1, tmp);
						}
						if(pBound) {
							*pBound = *prc1;
						}
						return ;
					}
					else if(prc1->Left() >= prc2->Left() && prc1->Left() < prc2->Right() && 
						prc1->Top() >= prc2->Top() && prc1->Top() < prc2->Bottom()) {
						// prc2 cut prc1 in prc1's top left
						if(pRectArray) {
							pRectArray->SetSize(2);
							tmp.Set(prc2->Right(), prc1->Top(), prc1->Right() - prc2->Right(), prc2->Bottom() - prc1->Top());
							pRectArray->SetAt(0, tmp);
							tmp.Set(prc1->Left(), prc2->Bottom(), prc1->Width(), prc1->Bottom() - prc2->Bottom());
							pRectArray->SetAt(1, tmp);
						}
						if(pBound) {
							*pBound = *prc1;
						}
						return ;
					}
					else if(prc1->Left() >= prc2->Left() && prc1->Left() < prc2->Right() && 
						prc1->Top() < prc2->Top() && prc1->Bottom() <= prc2->Bottom()) {
						// prc2 cut prc1 in prc1's bottom left
						if(pRectArray) {
							pRectArray->SetSize(2);
							tmp.Set(prc1->Left(), prc1->Top(), prc1->Width(), prc2->Top() - prc1->Top());
							pRectArray->SetAt(0, tmp);
							tmp.Set(prc2->Right(), prc2->Top(), prc1->Right() - prc2->Right(), prc1->Bottom() - prc2->Top());
							pRectArray->SetAt(1, tmp);
						}
						if(pBound) {
							*pBound = *prc1;
						}
						return ;
					}
					else if(prc1->Left() < prc2->Left() && prc1->Right() <= prc2->Right() && 
						prc1->Top() < prc2->Top() && prc1->Bottom() <= prc2->Bottom()) {
						// prc2 cut prc1 in prc1's bottom right
						if(pRectArray) {
							pRectArray->SetSize(2);
							tmp.Set(prc1->Left(), prc1->Top(), prc1->Width(), prc2->Top() - prc1->Top());
							pRectArray->SetAt(0, tmp);
							tmp.Set(prc1->Left(), prc2->Top(), prc2->Left() - prc1->Left(), prc1->Bottom() - prc2->Top());
							pRectArray->SetAt(1, tmp);
						}
						if(pBound) {
							*pBound = *prc1;
						}
						return ;
					}
					else if(prc1->Left() < prc2->Left() && prc1->Right() <= prc2->Right() && 
						prc1->Top() >= prc2->Top() && prc1->Bottom() > prc2->Bottom()) {
						// prc2 cut prc1 in prc1's top right
						if(pRectArray) {
							pRectArray->SetSize(2);
							tmp.Set(prc1->Left(), prc1->Top(), prc2->Left() - prc1->Left(), prc2->Bottom() - prc1->Top());
							pRectArray->SetAt(0, tmp);
							tmp.Set(prc1->Left(), prc2->Bottom(), prc1->Width(), prc1->Bottom() - prc2->Bottom());
							pRectArray->SetAt(1, tmp);
						}
						if(pBound) {
							*pBound = *prc1;
						}
						return ;
					}
				}
			}
		}
	}
}

// return cut or not
bool MergeRect(CMyRect *prc1, CMyRect *prc2, CMyRect *pBound, CMyArray<CMyRect>* pRectArray)
{
	if((*prc1 == (*prc2)))
		return true;
	
	CMyRect tmp;
	RECT_TYPE l = min(prc1->Left(), prc2->Left());
	RECT_TYPE t = min(prc1->Top(), prc2->Top());
	RECT_TYPE r = max(prc1->Right(), prc2->Right());
	RECT_TYPE b = max(prc1->Bottom(), prc2->Bottom());

	if(
		(r - l > prc1->Width() + prc2->Width()) || 
		(b - t > prc1->Height() + prc2->Height())
		) {
		// away
		if(pRectArray) {
			pRectArray->SetSize(2);
			tmp = *prc1;
			pRectArray->SetAt(0, tmp);
			tmp = *prc2;
			pRectArray->SetAt(1, tmp);
		}

		if(pBound)
			pBound->Set(l, t, r - l, b - t);
		return false;
	}
	else if(
		(r - l == prc1->Width() + prc2->Width()) && 
		!(prc1->Height() == prc2->Height() && 
		prc1->Top() == prc2->Top())
		) {
		// away
		if(pRectArray) {
			pRectArray->SetSize(2);
			tmp = *prc1;
			pRectArray->SetAt(0, tmp);
			tmp = *prc2;
			pRectArray->SetAt(1, tmp);
		}

		if(pBound)
			pBound->Set(l, t, r - l, b - t);
		return false;
	}
	else if(
		(b - t == prc1->Height() + prc2->Height()) && 
		!(prc1->Width() == prc2->Width() && 
		prc1->Left() == prc2->Left())
		) {
		// away
		if(pRectArray) {
			pRectArray->SetSize(2);
			tmp = *prc1;
			pRectArray->SetAt(0, tmp);
			tmp = *prc2;
			pRectArray->SetAt(1, tmp);
		}

		if(pBound)
			pBound->Set(l, t, r - l, b - t);
		return false;
	}
	else {

		if(
			(prc1->Width() == prc2->Width()) && 
			(prc1->Left() == prc2->Left()) && 
			((b - t) <= (prc1->Height() + prc2->Height()))
			) {
			// join in vert
			tmp.Set(l, t, r - l, b - t);
			if(pRectArray) {
				pRectArray->SetSize(1);
				pRectArray->SetAt(0, tmp);
			}
			if(pBound)
				*pBound = tmp;
			return true;
		}
		else if(
			(prc1->Height() == prc2->Height()) && 
			(prc1->Top() == prc2->Top()) && 
			((r - l) <= (prc1->Width() + prc2->Width()))
			) {
			// join in horz
			tmp.Set(l, t, r - l, b - t);
			if(pRectArray) {
				pRectArray->SetSize(1);
				pRectArray->SetAt(0, tmp);
			}
			if(pBound)
				*pBound = tmp;
			return true;
		}
		else if( 
			(r - l < prc1->Width() + prc2->Width()) && 
			(b - t < prc1->Height() + prc2->Height())
			) {
			// cut
			if( (prc1->Left() <= prc2->Left()) && 
				(prc1->Top() <= prc2->Top()) && 
				(prc1->Right() >= prc2->Right()) && 
				(prc1->Bottom() >= prc2->Bottom()) ) {
				// prc2 is in prc1    cover
				if(pRectArray) {
					pRectArray->SetSize(1);
					pRectArray->SetAt(0, *prc1);
				}
				if(pBound)
					*pBound = *prc1;
				return true;
			}
			else if( (prc1->Left() >= prc2->Left()) && 
				(prc1->Top() >= prc2->Top()) && 
				(prc1->Right() <= prc2->Right()) && 
				(prc1->Bottom() <= prc2->Bottom()) ) {
				// prc1 is in prc2    cover
				if(pRectArray) {
					pRectArray->SetSize(1);
					pRectArray->SetAt(0, *prc2);
				}
				if(pBound)
					*pBound = *prc2;
				return true;
			}
			else {
				if(prc1->Left() <= prc2->Left() && 
					prc1->Right() >= prc2->Right() && 
					prc1->Top() >= prc2->Top() && 
					prc1->Bottom() <= prc2->Bottom() ) {
					// prc1 is through prc2 in x direction   through
					if(pRectArray) {
						pRectArray->SetSize(3);
						tmp.Set(prc1->Left(), prc1->Top(), prc2->Left() - prc1->Left(), prc1->Height());
						pRectArray->SetAt(0, tmp);
						tmp = *prc2;
						pRectArray->SetAt(1, tmp);
						tmp.Set(prc2->Right(), prc1->Top(), prc1->Right() - prc2->Right(), prc1->Height());
						pRectArray->SetAt(2, tmp);
					}
					
					if(pBound)
						pBound->Set(prc1->Left(), prc2->Top(), prc1->Width(), prc2->Height());
					return true;
				}
				else if(prc1->Left() >= prc2->Left() && 
					prc1->Right() <= prc2->Right() && 
					prc1->Top() <= prc2->Top() && 
					prc1->Bottom() >= prc2->Bottom() ) {
					// prc2 is through prc1 in x direction   through
					if(pRectArray) {
						pRectArray->SetSize(3);
						tmp.Set(prc2->Left(), prc2->Top(), prc1->Left() - prc2->Left(), prc2->Height());
						pRectArray->SetAt(0, tmp);
						tmp = *prc1;
						pRectArray->SetAt(1, tmp);
						tmp.Set(prc1->Right(), prc2->Top(), prc2->Right() - prc1->Right(), prc2->Height());
						pRectArray->SetAt(2, tmp);
					}
					
					if(pBound)
						pBound->Set(prc2->Left(), prc1->Top(), prc2->Width(), prc1->Height());
					
					return true;
				}
				else {
					if(prc1->Left() <= prc2->Left() && prc1->Right() >= prc2->Right() && 
						prc1->Top() <= prc2->Top() && prc1->Bottom() <= prc2->Bottom()) {
						// prc1 cut prc2 in prc2's top
						if(pRectArray) {
							pRectArray->SetSize(2);
							tmp = *prc1;
							pRectArray->SetAt(0, tmp);
							tmp.Set(prc2->Left(), prc1->Bottom(), prc2->Width(), prc2->Bottom() - prc1->Bottom());
							pRectArray->SetAt(1, tmp);
						}
						
						if(pBound)
							pBound->Set(prc1->Left(), prc1->Top(), prc1->Width(), prc2->Bottom() - prc1->Top());
						return true;
					}
					else if(prc1->Left() <= prc2->Left() && prc1->Right() <= prc2->Right() && 
						prc1->Top() <= prc2->Top() && prc1->Bottom() >= prc2->Bottom()) {
						// prc1 cut prc2 in prc2's left
						if(pRectArray) {
							pRectArray->SetSize(2);
							tmp = *prc1;
							pRectArray->SetAt(0, tmp);
							tmp.Set(prc1->Right(), prc2->Top(), prc2->Right() - prc1->Right(), prc2->Height());
							pRectArray->SetAt(1, tmp);
						}
						
						if(pBound)
							pBound->Set(prc1->Left(), prc1->Top(), prc2->Right() - prc1->Left(), prc1->Height());
						return true;
					}
					else if(prc1->Left() <= prc2->Left() && prc1->Right() >= prc2->Right() && 
						prc1->Top() >= prc2->Top() && prc1->Bottom() >= prc2->Bottom()) {
						// prc1 cut prc2 in prc2's bottom
						if(pRectArray) {
							pRectArray->SetSize(2);
							tmp = *prc1;
							pRectArray->SetAt(0, tmp);
							tmp.Set(prc2->Left(), prc2->Top(), prc2->Width(), prc1->Top() - prc2->Top());
							pRectArray->SetAt(1, tmp);
						}
						
						if(pBound)
							pBound->Set(prc1->Left(), prc2->Top(), prc1->Width(), prc1->Bottom() - prc2->Top());
						return true;
					}
					else if(prc1->Left() >= prc2->Left() && prc1->Right() >= prc2->Right() && 
						prc1->Top() <= prc2->Top() && prc1->Bottom() >= prc2->Bottom()) {
						// prc1 cut prc2 in prc2's right
						if(pRectArray) {
							pRectArray->SetSize(2);
							tmp = *prc1;
							pRectArray->SetAt(0, tmp);
							tmp.Set(prc2->Left(), prc2->Top(), prc1->Left() - prc2->Left(), prc2->Height());
							pRectArray->SetAt(1, tmp);
						}
						
						if(pBound)
							pBound->Set(prc2->Left(), prc1->Top(), prc1->Right() - prc2->Left(), prc1->Height());
						return true;
					}
					if(prc1->Left() >= prc2->Left() && prc1->Right() <= prc2->Right() && 
						prc1->Top() >= prc2->Top() && prc1->Bottom() >= prc2->Bottom()) {
						// prc2 cut prc1 in prc1's top
						if(pRectArray) {
							pRectArray->SetSize(2);
							tmp = *prc2;
							pRectArray->SetAt(0, tmp);
							tmp.Set(prc1->Left(), prc2->Bottom(), prc1->Width(), prc1->Bottom() - prc2->Bottom());
							pRectArray->SetAt(1, tmp);
						}
						
						if(pBound)
							pBound->Set(prc2->Left(), prc2->Top(), prc2->Width(), prc1->Bottom() - prc2->Top());
						return true;
					}
					else if(prc1->Left() >= prc2->Left() && prc1->Right() >= prc2->Right() && 
						prc1->Top() >= prc2->Top() && prc1->Bottom() <= prc2->Bottom()) {
						// prc2 cut prc1 in prc1's left
						if(pRectArray) {
							pRectArray->SetSize(2);
							tmp = *prc2;
							pRectArray->SetAt(0, tmp);
							tmp.Set(prc2->Right(), prc1->Top(), prc1->Right() - prc2->Right(), prc1->Height());
							pRectArray->SetAt(1, tmp);
						}
						
						if(pBound)
							pBound->Set(prc2->Left(), prc2->Top(), prc1->Right() - prc2->Left(), prc2->Height());
						return true;
					}
					else if(prc1->Left() >= prc2->Left() && prc1->Right() <= prc2->Right() && 
						prc1->Top() <= prc2->Top() && prc1->Bottom() <= prc2->Bottom()) {
						// prc2 cut prc1 in prc1's bottom
						if(pRectArray) {
							pRectArray->SetSize(2);
							tmp = *prc2;
							pRectArray->SetAt(0, tmp);
							tmp.Set(prc1->Left(), prc1->Top(), prc1->Width(), prc2->Top() - prc1->Top());
							pRectArray->SetAt(1, tmp);
						}
						
						if(pBound)
							pBound->Set(prc2->Left(), prc1->Top(), prc2->Width(), prc2->Bottom() - prc1->Top());
						return true;
					}
					else if(prc1->Left() <= prc2->Left() && prc1->Right() <= prc2->Right() && 
						prc1->Top() >= prc2->Top() && prc1->Bottom() <= prc2->Bottom()) {
						// prc2 cut prc1 in prc1's right
						if(pRectArray) {
							pRectArray->SetSize(2);
							tmp = *prc2;
							pRectArray->SetAt(0, tmp);
							tmp.Set(prc1->Left(), prc1->Top(), prc2->Left() - prc1->Left(), prc1->Height());
							pRectArray->SetAt(1, tmp);
						}
						
						if(pBound)
							pBound->Set(prc1->Left(), prc2->Top(), prc2->Right() - prc1->Left(), prc2->Height());
						return true;
					}
					else {
						if(prc1->Left() <= prc2->Left() && prc1->Right() <= prc2->Right() && 
							prc1->Top() <= prc2->Top() && prc1->Bottom() <= prc2->Bottom()) {
							// prc1 cut prc2 in prc2's top left
							if(pRectArray) {
								pRectArray->SetSize(3);
								tmp = *prc2;
								pRectArray->SetAt(0, tmp);
								tmp.Set(prc1->Left(), prc1->Top(), prc2->Left() - prc1->Left(), prc1->Height());
								pRectArray->SetAt(1, tmp);
								tmp.Set(prc2->Left(), prc1->Top(), prc1->Right() - prc2->Left(), prc2->Top() - prc1->Top());
								pRectArray->SetAt(2, tmp);
							}
							
							if(pBound)
								pBound->Set(prc1->Left(), prc1->Top(), prc2->Right() - prc1->Left(), prc2->Bottom() - prc1->Top());
							return true;
						}
						else if(prc1->Left() <= prc2->Left() && prc1->Right() <= prc2->Right() && 
							prc1->Top() >= prc2->Top() && prc1->Bottom() >= prc2->Bottom()) {
							// prc1 cut prc2 in prc2's bottom left
							if(pRectArray) {
								pRectArray->SetSize(3);
								tmp = *prc2;
								pRectArray->SetAt(0, tmp);
								tmp.Set(prc1->Left(), prc1->Top(), prc2->Left() - prc1->Left(), prc1->Height());
								pRectArray->SetAt(1, tmp);
								tmp.Set(prc2->Left(), prc2->Bottom(), prc1->Right() - prc2->Left(), prc1->Bottom() - prc2->Bottom());
								pRectArray->SetAt(2, tmp);
							}
							
							if(pBound)
								pBound->Set(prc1->Left(), prc2->Top(), prc2->Right() - prc1->Left(), prc1->Bottom() - prc2->Top());
							return true;
						}
						else if(prc1->Left() >= prc2->Left() && prc1->Left() <= prc2->Right() && 
							prc1->Top() >= prc2->Top() && prc1->Top() <= prc2->Bottom()) {
							// prc1 cut prc2 in prc2's bottom right
							if(pRectArray) {
								pRectArray->SetSize(3);
								tmp = *prc2;
								pRectArray->SetAt(0, tmp);
								tmp.Set(prc1->Left(), prc2->Bottom(), prc1->Width(), prc1->Bottom() - prc2->Bottom());
								pRectArray->SetAt(1, tmp);
								tmp.Set(prc2->Right(), prc1->Top(), prc1->Right() - prc2->Right(), prc2->Bottom() - prc1->Top());
								pRectArray->SetAt(2, tmp);
							}
							
							if(pBound)
								pBound->Set(prc2->Left(), prc2->Top(), prc1->Right() - prc2->Left(), prc1->Bottom() - prc2->Top());
							return true;
						}
						else if(prc1->Left() >= prc2->Left() && prc1->Right() >= prc2->Right() && 
							prc1->Top() <= prc2->Top() && prc1->Bottom() <= prc2->Bottom()) {
							// prc1 cut prc2 in prc2's top right
							if(pRectArray) {
								pRectArray->SetSize(3);
								tmp = *prc2;
								pRectArray->SetAt(0, tmp);
								tmp.Set(prc1->Left(), prc1->Top(), prc1->Width(), prc2->Top() - prc1->Top());
								pRectArray->SetAt(1, tmp);
								tmp.Set(prc2->Right(), prc2->Top(), prc1->Right() - prc2->Right(), prc1->Bottom() - prc2->Top());
								pRectArray->SetAt(2, tmp);
							}
							
							if(pBound)
								pBound->Set(prc2->Left(), prc1->Top(), prc1->Right() - prc2->Left(), prc2->Bottom() - prc1->Top());
							return true;
						}
						else if(prc1->Left() >= prc2->Left() && prc1->Left() <= prc2->Right() && 
							prc1->Top() >= prc2->Top() && prc1->Top() <= prc2->Bottom()) {
							// prc2 cut prc1 in prc1's top left
							if(pRectArray) {
								pRectArray->SetSize(3);
								tmp = *prc1;
								pRectArray->SetAt(0, tmp);
								tmp.Set(prc2->Left(), prc2->Top(), prc1->Left() - prc2->Left(), prc2->Height());
								pRectArray->SetAt(1, tmp);
								tmp.Set(prc1->Left(), prc2->Top(), prc2->Right() - prc1->Left(), prc1->Top() - prc2->Top());
								pRectArray->SetAt(2, tmp);
							}
							
							if(pBound)
								pBound->Set(prc2->Left(), prc2->Top(), prc1->Right() - prc2->Left(), prc1->Bottom() - prc2->Top());
							return true;
						}
						else if(prc1->Left() >= prc2->Left() && prc1->Right() >= prc2->Right() && 
							prc1->Top() <= prc2->Top() && prc1->Bottom() <= prc2->Bottom()) {
							// prc2 cut prc1 in prc1's bottom left
							if(pRectArray) {
								pRectArray->SetSize(3);
								tmp = *prc1;
								pRectArray->SetAt(0, tmp);
								tmp.Set(prc2->Left(), prc2->Top(), prc1->Left() - prc2->Left(), prc2->Height());
								pRectArray->SetAt(1, tmp);
								tmp.Set(prc1->Left(), prc1->Bottom(), prc2->Right() - prc1->Left(), prc2->Bottom() - prc1->Bottom());
								pRectArray->SetAt(2, tmp);
							}
							
							if(pBound)
								pBound->Set(prc2->Left(), prc1->Top(), prc1->Right() - prc2->Left(), prc2->Bottom() - prc1->Top());
							return true;
						}
						else if(prc1->Left() <= prc2->Left() && prc1->Right() <= prc2->Right() && 
							prc1->Top() <= prc2->Top() && prc1->Bottom() <= prc2->Bottom()) {
							// prc2 cut prc1 in prc1's bottom right
							if(pRectArray) {
								pRectArray->SetSize(3);
								tmp = *prc1;
								pRectArray->SetAt(0, tmp);
								tmp.Set(prc2->Left(), prc1->Bottom(), prc2->Width(), prc2->Bottom() - prc1->Bottom());
								pRectArray->SetAt(1, tmp);
								tmp.Set(prc1->Right(), prc2->Top(), prc2->Right() - prc1->Right(), prc1->Bottom() - prc2->Top());
								pRectArray->SetAt(2, tmp);
							}
							
							if(pBound)
								pBound->Set(prc1->Left(), prc1->Top(), prc2->Right() - prc1->Left(), prc2->Bottom() - prc1->Top());
							return true;
						}
						else if(prc1->Left() <= prc2->Left() && prc1->Right() <= prc2->Right() && 
							prc1->Top() >= prc2->Top() && prc1->Bottom() >= prc2->Bottom()) {
							// prc2 cut prc1 in prc1's top right
							if(pRectArray) {
								pRectArray->SetSize(3);
								tmp = *prc1;
								pRectArray->SetAt(0, tmp);
								tmp.Set(prc2->Left(), prc2->Top(), prc2->Width(), prc1->Top() - prc2->Top());
								pRectArray->SetAt(1, tmp);
								tmp.Set(prc1->Right(), prc1->Top(), prc2->Right() - prc1->Right(), prc2->Bottom() - prc1->Top());
								pRectArray->SetAt(2, tmp);
							}
							
							if(pBound)
								pBound->Set(prc1->Left(), prc2->Top(), prc2->Right() - prc1->Left(), prc1->Bottom() - prc2->Top());
							return true;
						}
					}
				}
			}
		}

	}
	return false;
}

























CRectRgn::CRectRgn()
{
}

CRectRgn::~CRectRgn()
{
}

void CRectRgn::Merge(CMyRect* pRect)
{
	int i;
	CMyRect					rcBound;
	CMyArray<CMyRect>		rcMerge, rcCut, tmp;
	bool					bMerged = false;
	for(i = 0; i < m_array.GetSize(); ++ i) {
		if(MergeRect(&m_array[i], pRect, NULL, &tmp)) {

			rcMerge.SetSize(i);
			for(int j = 0; j < i; ++ j)
				rcMerge[j] = m_array[j];
			rcMerge.Append(tmp);
			++ i;
			bMerged = true;
			break;
		}
	}

	if(!bMerged) {
		m_array.Add(*pRect);
		m_array.FreeExtra();
	}
	else {
		for(; i < m_array.GetSize(); ++ i) {
			DivideRect(&m_array[i], pRect, NULL, &tmp);
			rcCut.Append(tmp);
		}
		rcMerge.Append(rcCut);
		m_array = rcMerge;
	}

	MergeRect(&m_rect, pRect, &rcBound, NULL);
	m_rect = rcBound;
}

void CRectRgn::Divide(CMyRect* pRect)
{
	int i;
	CMyArray<CMyRect>		rects, tmp;
	for(i = 0; i < m_array.GetSize(); ++ i) {
		DivideRect(&m_array[i], pRect, NULL, &tmp);
		rects.Append(tmp);
	}
	m_array = rects;

	RECT_TYPE l, t, r, b;
	l = t = 0xfffffff;
	r = b = 0;
	for(i = 0; i < m_array.GetSize(); ++ i) {
		if(m_array[i].Left() < l) l = m_array[i].Left();
		if(m_array[i].Top() < t) t = m_array[i].Top();

		if(m_array[i].Right() > r) r = m_array[i].Right();
		if(m_array[i].Bottom() > b) b = m_array[i].Bottom();
	}
	m_rect.Set(l, t, r - l, b - t);
}

CMyRect* CRectRgn::GetBoundRect()
{
	return &m_rect;
}

int CRectRgn::GetSubRectCount()
{
	return m_array.GetSize();
}

CMyRect* CRectRgn::GetSubRect(int nIndex)
{
	return &m_array[nIndex];
}

void CRectRgn::Clear()
{
	m_array.RemoveAll();
	m_rect.Set(0, 0, 0, 0);
}

void CRectRgn::Init(CMyRect* pRect)
{
	m_rect = *pRect;
	m_array.SetSize(1);
	m_array.SetAt(0, m_rect);
}

void CRectRgn::Init(RECT_TYPE left, RECT_TYPE top, RECT_TYPE width, RECT_TYPE height)
{
	CMyRect rect;
	rect.Set(left, top, width, height);
	Init(&rect);
}

bool CRectRgn::PtInRgn(int x, int y)
{
	if(m_rect.IsCellIn(x, y)) {
		for(int i = 0; i < m_array.GetSize(); ++ i) {
			if(m_array[i].IsCellIn(x, y)) return true;
		}
		return false;
	}
	else
		return false;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
China China
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions