继承MFC CRectTracker使得橡皮条只能在规定范围变化和限制大小

#include "stdafx.h"
#include "RectTrackerEx.h"

/
// CRectTracker global state

// various GDI objects we need to draw
AFX_STATIC_DATA HCURSOR _afxCursors[10] = { 0, };
AFX_STATIC_DATA HBRUSH _afxHatchBrush = 0;
AFX_STATIC_DATA HPEN _afxBlackDottedPen = 0;
AFX_STATIC_DATA int _afxHandleSize = 0;

struct AFX_HANDLEINFO
{
	size_t nOffsetX;    // offset within RECT for X coordinate
	size_t nOffsetY;    // offset within RECT for Y coordinate
	int nCenterX;       // adjust X by Width()/2 * this number
	int nCenterY;       // adjust Y by Height()/2 * this number
	int nHandleX;       // adjust X by handle size * this number
	int nHandleY;       // adjust Y by handle size * this number
	int nInvertX;       // handle converts to this when X inverted
	int nInvertY;       // handle converts to this when Y inverted
};

// this array describes all 8 handles (clock-wise)
AFX_STATIC_DATA const AFX_HANDLEINFO _afxHandleInfo[] =
{
	// corner handles (top-left, top-right, bottom-right, bottom-left
	{ offsetof(RECT, left), offsetof(RECT, top),        0, 0,  0,  0, 1, 3 },
	{ offsetof(RECT, right), offsetof(RECT, top),       0, 0, -1,  0, 0, 2 },
	{ offsetof(RECT, right), offsetof(RECT, bottom),    0, 0, -1, -1, 3, 1 },
	{ offsetof(RECT, left), offsetof(RECT, bottom),     0, 0,  0, -1, 2, 0 },

	// side handles (top, right, bottom, left)
	{ offsetof(RECT, left), offsetof(RECT, top),        1, 0,  0,  0, 4, 6 },
	{ offsetof(RECT, right), offsetof(RECT, top),       0, 1, -1,  0, 7, 5 },
	{ offsetof(RECT, left), offsetof(RECT, bottom),     1, 0,  0, -1, 6, 4 },
	{ offsetof(RECT, left), offsetof(RECT, top),        0, 1,  0,  0, 5, 7 }
};

// the struct below gives us information on the layout of a RECT struct and
//  the relationship between its members
struct AFX_RECTINFO
{
	size_t nOffsetAcross;   // offset of opposite point (ie. left->right)
	int nSignAcross;        // sign relative to that point (ie. add/subtract)
};

// this array is indexed by the offset of the RECT member / sizeof(int)
AFX_STATIC_DATA const AFX_RECTINFO _afxRectInfo[] =
{
	{ offsetof(RECT, right), +1 },
	{ offsetof(RECT, bottom), +1 },
	{ offsetof(RECT, left), -1 },
	{ offsetof(RECT, top), -1 },
};

CRectTrackerEx::CRectTrackerEx(void)
{
	
}


CRectTrackerEx::~CRectTrackerEx(void)
{
}


void CRectTrackerEx::AdjustRect(int nHandle, LPRECT lpRect)
{
	if (nHandle == hitMiddle)
	{
		int nNewWidth = m_rect.Width();
		int nNewHeight = m_rect.Height();
		if(nNewHeight>0)
		{
			if(m_rect.top<m_limitRect.top)
			{
				m_rect.top = m_limitRect.top;
				m_rect.bottom = m_rect.top + nNewHeight;
			}			
			if(m_rect.bottom>m_limitRect.bottom)
			{
				m_rect.bottom = m_limitRect.bottom;
				m_rect.top = m_rect.bottom - nNewHeight;
			}
		}
		else
		{
			if(m_rect.bottom<m_limitRect.top)
			{
				m_rect.bottom = m_limitRect.top;
				m_rect.top = m_rect.bottom - nNewHeight;
			}
			if(m_rect.top>m_limitRect.bottom)
			{
				m_rect.top = m_limitRect.bottom;
				m_rect.bottom = m_rect.top + nNewHeight;
			}
		}
		if(nNewWidth>0)
		{

			if(m_rect.left<m_limitRect.left)
			{
				m_rect.left = m_limitRect.left;
				m_rect.right = m_rect.left + nNewWidth;
			}
			if(m_rect.right> m_limitRect.right)
			{
				m_rect.right = m_limitRect.right;
				m_rect.left = m_rect.right - nNewWidth;
			}	
		}
		else
		{			
			if(m_rect.right<m_limitRect.left)
			{
				m_rect.right = m_limitRect.left;
				m_rect.left = m_rect.right - nNewWidth;
			}
			
			if(m_rect.left> m_limitRect.right)
			{
				m_rect.left = m_limitRect.right;
				m_rect.right = m_rect.left + nNewWidth;
			}
		}		
		return;
	}

	// convert the handle into locations within m_rect
	int *px, *py;
	GetModifyPointers(nHandle, &px, &py, NULL, NULL);

	// enforce minimum width
	int nNewWidth = m_rect.Width();
	int nAbsWidth = m_bAllowInvert ? abs(nNewWidth) : nNewWidth;
	if (px != NULL && nAbsWidth < m_sizeMin.cx)
	{
		nNewWidth = nAbsWidth != 0 ? nNewWidth / nAbsWidth : 1;
		ptrdiff_t iRectInfo = (int*)px - (int*)&m_rect;
		ENSURE(0 <= iRectInfo && iRectInfo < _countof(_afxRectInfo));
		const AFX_RECTINFO* pRectInfo = &_afxRectInfo[iRectInfo];
		*px = *(int*)((BYTE*)&m_rect + pRectInfo->nOffsetAcross) +
			nNewWidth * m_sizeMin.cx * -pRectInfo->nSignAcross;
	}

	// enforce max width
	if (px != NULL && nAbsWidth > m_sizeMax.cx)
	{
		nNewWidth = nAbsWidth != 0 ? nNewWidth / nAbsWidth : 1;
		ptrdiff_t iRectInfo = (int*)px - (int*)&m_rect;
		ENSURE(0 <= iRectInfo && iRectInfo < _countof(_afxRectInfo));
		const AFX_RECTINFO* pRectInfo = &_afxRectInfo[iRectInfo];
		*px = *(int*)((BYTE*)&m_rect + pRectInfo->nOffsetAcross) +
			nNewWidth * m_sizeMax.cx * -pRectInfo->nSignAcross;
	}

	// enforce minimum height
	int nNewHeight = m_rect.Height();
	int nAbsHeight = m_bAllowInvert ? abs(nNewHeight) : nNewHeight;
	if (py != NULL && nAbsHeight < m_sizeMin.cy)
	{
		nNewHeight = nAbsHeight != 0 ? nNewHeight / nAbsHeight : 1;
		ptrdiff_t iRectInfo = (int*)py - (int*)&m_rect;
		ENSURE(0 <= iRectInfo && iRectInfo < _countof(_afxRectInfo));
		const AFX_RECTINFO* pRectInfo = &_afxRectInfo[iRectInfo];
		*py = *(int*)((BYTE*)&m_rect + pRectInfo->nOffsetAcross) +
			nNewHeight * m_sizeMin.cy * -pRectInfo->nSignAcross;
	}

	// enforce max height
	if (py != NULL && nAbsHeight > m_sizeMax.cy)
	{
		nNewHeight = nAbsHeight != 0 ? nNewHeight / nAbsHeight : 1;
		ptrdiff_t iRectInfo = (int*)py - (int*)&m_rect;
		ENSURE(0 <= iRectInfo && iRectInfo < _countof(_afxRectInfo));
		const AFX_RECTINFO* pRectInfo = &_afxRectInfo[iRectInfo];
		*py = *(int*)((BYTE*)&m_rect + pRectInfo->nOffsetAcross) +
			nNewHeight * m_sizeMax.cy * -pRectInfo->nSignAcross;
	}
	
	nNewWidth = m_rect.Width();
	nNewHeight = m_rect.Height();
	if(nNewHeight>0)
	{
		if(m_rect.top<m_limitRect.top)
		{
			m_rect.top = m_limitRect.top;
		}
		
		if(m_rect.bottom>m_limitRect.bottom)
		{
			m_rect.bottom = m_limitRect.bottom;
		}
	
	}
	else
	{
		if(m_rect.bottom<m_limitRect.top)
		{
			m_rect.bottom = m_limitRect.top;
		}
		
		if(m_rect.top>m_limitRect.bottom)
		{
			m_rect.top = m_limitRect.bottom;
		}
		
	}

	if(nNewWidth>0)
	{

		if(m_rect.left<m_limitRect.left)
		{
			m_rect.left = m_limitRect.left;
		}
		if(m_rect.right> m_limitRect.right)
		{
			m_rect.right = m_limitRect.right;
		}	
	}
	else
	{			
		if(m_rect.right<m_limitRect.left)
		{
			m_rect.right = m_limitRect.left;
		}
		if(m_rect.left> m_limitRect.right)
		{
			m_rect.left = m_limitRect.right;
		}	
	}		

}


void CRectTrackerEx::Draw(CDC *pDC)const   
{
	const int space=3;
	CPoint pt;
	CPen pen(PS_SOLID,1,RGB(147,147,147));
	pDC->SetTextColor(RGB(147,147,147));
	CFont font;
	font.CreatePointFont(90,L"宋体");
	pDC->SelectObject(&font);

	//得到字体宽度和高度
	GetCursorPos(&pt);
	pDC->SetBkMode(TRANSPARENT);

	//创建空画刷画矩形
	pDC->SelectObject((HBRUSH)GetStockObject(NULL_BRUSH));
	CString string=L"";
	string.Format(L"[%d:%d]",abs(m_rect.Width()), abs(m_rect.Height()));

	int x =0;
	int y =0;
	x = m_rect.left< m_rect.right ?m_rect.left:m_rect.right;
	y = m_rect.top < m_rect.bottom?m_rect.bottom:m_rect.top;

	pDC->TextOut(x,y+2,string);

	CRectTracker::Draw(pDC);

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值