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

📄 draw.cpp

📁 Viaual C++实战演练一书的源代码,对于C++程序员有实际的借鉴意义.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	double cx, cy;

	a = abs(m_x1 - m_x2) * 0.5;//椭圆X轴长度
	b = abs(m_y1 - m_y2) * 0.5;//椭圆Y轴长度
	cx = (m_x1 + m_x2) * 0.5;//椭圆中心点X坐标
	cy = (m_y1 + m_y2) * 0.5;//椭圆中心点Y坐标

	if(a > b)
	{//椭圆长轴为X轴
		c = sqrt(a*a - b*b);
		fx1 = cx - c;
		fx2 = cx + c;
		fy1 = fy2 = cy;
	}
	else
	{
		c = sqrt(b*b - a*a);
		fx1 = fx2 = cx;
		fy1 = cy - c;
		fy2 = cy + c;
		a = b;
	}
	b = sqrt((fx1 - x)*(fx1 - x) + (fy1 - y)*(fy1 - y));//指定点到第一焦点的距离
	b += sqrt((fx2 - x)*(fx2 - x) + (fy2 - y)*(fy2 - y));//指定点到第二焦点的距离

	a = fabs(2*a - b);//指定点到两焦点的距离和

	return(a < MAXOFFSET);
}


//-----------------------------------
// 以下为CDrawCircle(绘圆)类方法实现
//-----------------------------------

IMPLEMENT_SERIAL(CDrawCircle, CDrawObject, 1);

void CDrawCircle::Serialize(CArchive& ar)
{
	COLORREF color;

	if(ar.IsLoading())
	{
		ar >> m_nStyle >> color >> m_x >> m_y >> m_r;
		SetPenColor(color);
	}
	else
	{
		color = GetPenColor();
		ar << m_nStyle << color << m_x << m_y << m_r;
	}
}

CDrawCircle::CDrawCircle(COLORREF color)
{
	m_x=m_y=m_r=0;
	SetPenColor(color);
	m_nStyle = IDT_CIRCLE;
}

void CDrawCircle::Draw(CDC* pDC)
{
	if(!this)
	{//当前类为空,既无效类指针
		return;
	}

	COLORREF CopyColor = GetPenColor();
	CPen pen(PS_SOLID, 1, CopyColor);
	int oldmode = pDC->GetROP2();
	CPen* oldpen = pDC->SelectObject(&pen);//指定绘制笔;
	//设置为“空”刷,既不填充。
	CBrush* oldbrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);;
	pDC->SetROP2(R2_COPYPEN);//指定绘制模式

	pDC->Ellipse(m_x-m_r, m_y-m_r, m_x+m_r, m_y+m_r);//绘圆

	//恢复DC
	pDC->SetROP2(oldmode);
	pDC->SelectObject(oldpen);
	pDC->SelectObject(oldbrush);
	pen.DeleteObject();//释放笔资源
}

int CDrawCircle::NewPoint(long x, long y)
{
	m_x = x;
	m_y = y;

	return 4;
}

int CDrawCircle::SelectAt(long x, long y)
{
	if(AtPoint(m_x-m_r, m_y, x, y))
	{//指针靠近左点
		return 1;
	}
	else if(AtPoint(m_x, m_y-m_r, x, y))
	{//指针靠近上点
		return 2;
	}
	else if(AtPoint(m_x+m_r, m_y, x, y))
	{//指针靠近右点
		return 3;
	}
	else if(AtPoint(m_x, m_y+m_r, x, y))
	{//指针靠近右下角点
		return 4;
	}
	else if(AtPoint(m_x, m_y, x, y))
	{
		return 5;
	}
	else if(AtCurve(x, y))
	{//指针在圆上
		m_oldx = x;
		m_oldy = y;
		return 6;
	}
	else 
		return 0;
}

void CDrawCircle::MoveAt(CDC *pDC, int flags, long x, long y)
{
	//以下设置DC
	COLORREF XorColor = pDC->GetBkColor() ^ GetPenColor();
	CPen pen(PS_SOLID, 1, XorColor);
	int oldmode = pDC->GetROP2();
	CPen* oldpen = pDC->SelectObject(&pen);
	//设置为“空”刷,既不填充。
	CBrush* oldbrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
	pDC->SetROP2(R2_XORPEN);

	if(m_bSelected)
	{//以前已经选择了,取消热点
		HotPoints(pDC);
	}
	//删除原图形
	pDC->Ellipse(m_x-m_r, m_y-m_r, m_x+m_r, m_y+m_r);//绘圆

	//修改新图形坐标
	switch(flags)
	{
	case 1:
	case 2:
	case 3:
	case 4:
		m_r = (long)sqrt((m_x-x)*(m_x-x) + (m_y-y)*(m_y-y));
		break;
	case 5:
		m_x = x;
		m_y = y;
		break;
	case 6:
		m_x += x-m_oldx;
		m_y += y-m_oldy;
		m_oldx = x;
		m_oldy = y;
		break;
	}

	//绘新图形
	pDC->Ellipse(m_x-m_r, m_y-m_r, m_x+m_r, m_y+m_r);//绘圆

	if(m_bSelected)
	{//以前已经选择了,设置热点
		HotPoints(pDC);
	}
	//以下恢复DC
	pDC->SetROP2(oldmode);
	pDC->SelectObject(oldpen);
	pDC->SelectObject(oldbrush);
	pen.DeleteObject();
}

void CDrawCircle::HotPoints(CDC* pDC)
{
	HotPoint(pDC, m_x-m_r, m_y);// 1
	HotPoint(pDC, m_x, m_y-m_r);// 2
	HotPoint(pDC, m_x+m_r, m_y);// 3
	HotPoint(pDC, m_x, m_y+m_r);// 4
	HotPoint(pDC, m_x, m_y);// 圆心
}

void CDrawCircle::Selected(CDC *pDC, bool select)
{
	if(!this)
	{//如果类指针无效,直接返回
		return;
	}

	if(select)
	{
		if(!m_bSelected)
		{//以前未选择,绘热点并设置选择标志
			HotPoints(pDC);
			m_bSelected = true;
		}
	}
	else
	{
		if(m_bSelected)
		{//以前已经选择了,取消热点设置并清选择标志
			HotPoints(pDC);
			m_bSelected = false;
		}
	}
}

bool CDrawCircle::AtCurve(long x, long y)
{
	double l;

	l = fabs(sqrt((m_x - x)*(m_x - x) + (m_y - y)*(m_y - y)) - m_r);

	return(l < MAXOFFSET);
}


//-----------------------------------
// 以下为CDrawPLine(绘折线)类方法实现
//-----------------------------------

IMPLEMENT_SERIAL(CDrawPLine, CDrawObject, 1);

void CDrawPLine::Serialize(CArchive& ar)
{
	COLORREF color;
	int i;

	if(ar.IsLoading())
	{
		ar >> m_nStyle >> color >> m_nNumber;
		SetPenColor(color);
		for(i=0;i<m_nNumber;i++)
		{
			ar >> m_aPoints[i].x >> m_aPoints[i].y;
		}
	}
	else
	{
		color = GetPenColor();
		ar << m_nStyle << color << m_nNumber;
		for(i=0;i<m_nNumber;i++)
		{
			ar << m_aPoints[i].x << m_aPoints[i].y;
		}
	}
}

CDrawPLine::CDrawPLine(COLORREF color)
{
	m_nNumber = 0;
	SetPenColor(color);
	m_nStyle = IDT_PLINE;
}

void CDrawPLine::Draw(CDC* pDC)
{
	if(!this)
	{//当前类为空,既无效类指针
		return;
	}

	COLORREF CopyColor = GetPenColor();
	CPen pen(PS_SOLID, 1, CopyColor);
	int oldmode = pDC->GetROP2();
	CPen* oldpen = pDC->SelectObject(&pen);//指定绘制笔;
	pDC->SetROP2(R2_COPYPEN);//指定绘制模式

	int i;
	pDC->MoveTo(m_aPoints[0].x, m_aPoints[0].y);
	for(i=1; i<m_nNumber; i++)
	{
		pDC->LineTo(m_aPoints[i].x, m_aPoints[i].y);//绘折线
	}

	//恢复DC
	pDC->SetROP2(oldmode);
	pDC->SelectObject(oldpen);
	pen.DeleteObject();//释放笔资源
}

int CDrawPLine::NewPoint(long x, long y)
{
	m_nNumber = 1;
	m_aPoints[0].x = x;
	m_aPoints[0].y = y;
	m_oldx = x;
	m_oldy = y;

	return 2;
}

int CDrawPLine::AddPoint(long x, long y)
{
	if(m_nNumber < MAXPLINEPOINT)
	{
		m_aPoints[m_nNumber].x = x;
		m_aPoints[m_nNumber].y = y;
		m_nNumber++;
	}

	//判断是否可继续绘折线
	if(m_nNumber != MAXPLINEPOINT)
	{//可继续下一点
		return m_nNumber+1;
	}
	else
		return 0;
}

int CDrawPLine::SelectAt(long x, long y)
{
	int i;

	if(AtPoint(m_aPoints[0].x, m_aPoints[0].y, x, y))
	{//检查是否选择第一点
		return 1;
	}
	for(i=1;i<m_nNumber; i++)
	{
		if(AtPoint(m_aPoints[i].x, m_aPoints[i].y, x, y))
		{
			return i+1;
		}
		if(AtLine(m_aPoints[i-1].x, m_aPoints[i-1].y, m_aPoints[i].x, m_aPoints[i].y, x, y))
		{
			m_oldx = x;
			m_oldy = y;
			return -1;//指针在直线上
		}
	}
	return 0;
}

void CDrawPLine::MoveAt(CDC *pDC, int flags, long x, long y)
{
	//以下设置DC
	COLORREF XorColor = pDC->GetBkColor() ^ GetPenColor();
	CPen pen(PS_SOLID, 1, XorColor);
	int i;
	int oldmode = pDC->GetROP2();
	CPen* oldpen = pDC->SelectObject(&pen);
	//设置为“空”刷,既不填充。
	CBrush* oldbrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
	pDC->SetROP2(R2_XORPEN);

	if(m_bSelected)
	{//以前已经选择了,取消热点
		HotPoints(pDC);
	}

	//修改新图形坐标
	if(flags == 1)
	{//移动折线第一端点
		pDC->MoveTo(m_aPoints[0].x, m_aPoints[0].y);
		pDC->LineTo(m_aPoints[1].x, m_aPoints[1].y);
		m_aPoints[0].x = x;
		m_aPoints[0].y = y;
		pDC->MoveTo(m_aPoints[0].x, m_aPoints[0].y);
		pDC->LineTo(m_aPoints[1].x, m_aPoints[1].y);
	}
	else if(flags == m_nNumber)
	{//移动折线最后端点
		pDC->MoveTo(m_aPoints[m_nNumber-2].x, m_aPoints[m_nNumber-2].y);
		pDC->LineTo(m_aPoints[m_nNumber-1].x, m_aPoints[m_nNumber-1].y);
		m_aPoints[m_nNumber-1].x = x;
		m_aPoints[m_nNumber-1].y = y;
		pDC->MoveTo(m_aPoints[m_nNumber-2].x, m_aPoints[m_nNumber-2].y);
		pDC->LineTo(m_aPoints[m_nNumber-1].x, m_aPoints[m_nNumber-1].y);
	}
	else if(flags == m_nNumber +1)
	{//移动点超出范围,只有增加端点时出现
		pDC->MoveTo(m_aPoints[m_nNumber-1].x, m_aPoints[m_nNumber-1].y);
		pDC->LineTo(m_oldx, m_oldy);
		m_oldx = x;
		m_oldy = y;
		pDC->MoveTo(m_aPoints[m_nNumber-1].x, m_aPoints[m_nNumber-1].y);
		pDC->LineTo(m_oldx, m_oldy);
	}
	else if(flags > 1 && flags < m_nNumber)
	{//移动折线中间端点
		pDC->MoveTo(m_aPoints[flags-2].x, m_aPoints[flags-2].y);
		pDC->LineTo(m_aPoints[flags-1].x, m_aPoints[flags-1].y);
		pDC->LineTo(m_aPoints[flags].x, m_aPoints[flags].y);
		m_aPoints[flags-1].x = x;
		m_aPoints[flags-1].y = y;
		pDC->MoveTo(m_aPoints[flags-2].x, m_aPoints[flags-2].y);
		pDC->LineTo(m_aPoints[flags-1].x, m_aPoints[flags-1].y);
		pDC->LineTo(m_aPoints[flags].x, m_aPoints[flags].y);
	}
	else if(flags == -1)
	{//移动整个折线
		pDC->MoveTo(m_aPoints[0].x, m_aPoints[0].y);
		m_aPoints[0].x += x-m_oldx;
		m_aPoints[0].y += y-m_oldy;
		for(i=1;i<m_nNumber;i++)
		{
			pDC->LineTo(m_aPoints[i].x, m_aPoints[i].y);//删折线
			m_aPoints[i].x += x-m_oldx;
			m_aPoints[i].y += y-m_oldy;
		}
		pDC->MoveTo(m_aPoints[0].x, m_aPoints[0].y);
		for(i=1; i<m_nNumber; i++)
		{//绘折线
			pDC->LineTo(m_aPoints[i].x, m_aPoints[i].y);
		}
		m_oldx = x;
		m_oldy = y;
	}

	if(m_bSelected)
	{//以前已经选择了,设置热点
		HotPoints(pDC);
	}
	//以下恢复DC
	pDC->SetROP2(oldmode);
	pDC->SelectObject(oldpen);
	pDC->SelectObject(oldbrush);
	pen.DeleteObject();
}

void CDrawPLine::HotPoints(CDC* pDC)
{
	int i;

	for(i=0; i<m_nNumber; i++)
	{
		HotPoint(pDC, m_aPoints[i].x, m_aPoints[i].y);
	}
}

void CDrawPLine::Selected(CDC *pDC, bool select)
{
	if(!this)
	{//如果类指针无效,直接返回
		return;
	}

	if(select)
	{
		if(!m_bSelected)
		{//以前未选择,绘热点并设置选择标志
			HotPoints(pDC);
			m_bSelected = true;
		}
	}
	else
	{
		if(m_bSelected)
		{//以前已经选择了,取消热点设置并清选择标志
			HotPoints(pDC);
			m_bSelected = false;
		}
	}
}


//-----------------------------------
// 以下为CDrawFont(绘标记)类方法实现
//-----------------------------------

IMPLEMENT_SERIAL(CDrawFont, CDrawObject, 1);

void CDrawFont::Serialize(CArchive& ar)
{
	COLORREF color;

	if(ar.IsLoading())
	{
		ar >> m_nStyle >> color >> m_x >> m_y;
		SetPenColor(color);
	}
	else
	{
		color = GetPenColor();
		ar << m_nStyle << color << m_x << m_y;
	}
}

CDrawFont::CDrawFont(COLORREF color)
{
	m_x=m_y=0;
	SetPenColor(color);
	m_nStyle = IDT_FONT;
}

void CDrawFont::Draw(CDC* pDC)
{
	if(!this)
	{//当前类为空,既无效类指针
		return;
	}

	COLORREF CopyColor = GetPenColor();
	CPen pen(PS_SOLID, 1, CopyColor), *oldpen;
	int oldmode = pDC->GetROP2();
	oldpen = pDC->SelectObject(&pen);//指定绘制笔
	pDC->SetROP2(R2_COPYPEN);//指定绘制模式

	DrawFont(pDC);

	pDC->SelectObject(oldpen);//恢复DC
	pDC->SetROP2(oldmode);
	pen.DeleteObject();//释放笔资源
}

int CDrawFont::NewPoint(long x, long y)
{
	m_x = x;
	m_y = y;

	return 1;
}

int CDrawFont::SelectAt(long x, long y)
{
	if(AtPoint(m_x, m_y, x, y))
	{//指针靠近端点
		return 1;
	}
	else
	{
		return 0;
	}
}

void CDrawFont::MoveAt(CDC *pDC, int flags, long x, long y)
{
	//以下设置DC
	COLORREF XorColor = pDC->GetBkColor() ^ GetPenColor();
	CPen pen(PS_SOLID, 1, XorColor), *oldpen;
	int oldmode = pDC->GetROP2();
	oldpen = pDC->SelectObject(&pen);
	pDC->SetROP2(R2_XORPEN);

	if(m_bSelected)
	{//以前已经选择了,取消热点
		HotPoints(pDC);
	}
	//删除原标记
	DrawFont(pDC);

	//修改新图形坐标
	if(flags == 1)
	{//移动左上角
		m_x = x, m_y = y;
	}

	//绘新图形
	DrawFont(pDC);

	if(m_bSelected)
	{//以前已经选择了,设置热点
		HotPoints(pDC);
	}
	//以下恢复DC
	pDC->SetROP2(oldmode);
	pDC->SelectObject(oldpen);
	pen.DeleteObject();//释放笔资源
}

void CDrawFont::HotPoints(CDC* pDC)
{
	HotPoint(pDC, m_x, m_y);// 端点
}

void CDrawFont::Selected(CDC *pDC, bool select)
{
	if(!this)
	{//如果类指针无效,直接返回
		return;
	}

	if(select)
	{
		if(!m_bSelected)
		{//以前未选择,绘热点并设置选择标志
			HotPoints(pDC);
			m_bSelected = true;
		}
	}
	else
	{
		if(m_bSelected)
		{//以前已经选择了,取消热点设置并清选择标志
			HotPoints(pDC);
			m_bSelected = false;
		}
	}
}

void CDrawFont::DrawFont(CDC* pDC)
{
	int fontsize = 6;
	int dsize = fontsize * 0.7 + 0.5;

	pDC->MoveTo(m_x-fontsize, m_y);
	pDC->LineTo(m_x+fontsize+1, m_y);
	pDC->MoveTo(m_x, m_y-fontsize);
	pDC->LineTo(m_x, m_y+fontsize+1);
	pDC->MoveTo(m_x-dsize, m_y-dsize);
	pDC->LineTo(m_x+dsize+1, m_y+dsize+1);
	pDC->MoveTo(m_x-dsize, m_y+dsize);
	pDC->LineTo(m_x+dsize+1, m_y-dsize-1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -