栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

2021-10-07

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2021-10-07

Entity类成员变量

public:
	COLORREF    m_brushcolor;//填充颜色

实现方法:

public:
void Fill(COLORREF color){ m_brushcolor = color; };

派生类实现:

void MRectangle::Draw(CDC * pDC, int drawMode )
{…
CBrush* pOldBrush = pDC->SelectObject(&brush);
pDC->Rectangle(rect);
…}
1.填充消息响应

VCadView.h

protected:
	//{{AFX_MSG(CVCadView)
	afx_msg void OnModifyEntity(UINT m_nID);
	afx_msg void OnUpdateModifyCommand(CCmdUI* pCmdUI);

VCadView.cpp

BEGIN_MESSAGE_MAP(CVCadView, CView)
ON_COMMAND_RANGE(ID_MODIFY_MOVE, 
	                 ID_MODIFY_FILL, OnModifyEntity)
	ON_UPDATE_COMMAND_UI_RANGE(ID_MODIFY_MOVE, 
					ID_MODIFY_FILL, OnUpdateModifyCommand)
END_MESSAGE_MAP()

消息响应

void CVCadView::OnModifyEntity(UINT m_nID)
{
switch(m_nID)
	{
		case ID_MODIFY_MIRROR: 
		{// 镜像
			m_pCmd = new CMirror();
			break;
		}
		case ID_MODIFY_FILL:
		{// 填充
			m_pCmd = new CFill();
			break;
		}
		default:
			//删除
			Erase() ;
			break;
	}
}

填充操作类实现

CFill::CFill() 
{
	CColorDialog ccd(SeedClr, CC_SOLIDCOLOR);
	if (IDOK == ccd.DoModal())//调用颜色对话框选取填充色
		SeedClr = ccd.GetColor();
	//::prompt("请输入移动的目标点:单击鼠标右键取消");
	CDC*	pDC = g_pView->GetDC(); // 获得视类的设备环境指针

	// 将选择集中的图元移动到目标位置并进行绘制
	int i, n;
	for (n = g_pDoc->m_selectArray.GetSize(), i = 0; i < n; i++)
	{
		MEntity*	pEntity = (MEntity*)g_pDoc->m_selectArray[i];
		pEntity->Draw(pDC, dmInvalid); // 清除原来位置上的图元
	
		MEntity * pNewEnt = pEntity->Copy();
		pNewEnt->Fill(SeedClr);
		pNewEnt->Draw(pDC, dmNormal); // 在目标位置上绘制图元
		g_pDoc->SetModifiedFlag(TRUE); // 标志文档数据已被修改
		pNewEnt->m_nOperationNum = g_pView->m_nCurrentOperation;
		pEntity->Append(pNewEnt);
	}

	g_pDoc->m_selectArray.RemoveAll(); //  清空选择集
	//			g_pDoc->SetModifiedFlag(TRUE); // 标志文档数据已被修改
	g_pView->ReleaseDC(pDC); // 释放视类的设备环境指针
	
}
2.选中后拖拽

拖拽后松开左键响应

void CVCadView::OnLButtonUp(UINT nFlags, CPoint point) 
{
if(m_bDragging) 
   {
for(n = g_pDoc->m_selectArray.GetSize(), i = 0; i < n; i++)
		{
//都是对基类MEntity在操作!!
			MEntity* pNewEnt = pEntity->Copy();
			pNewEnt->Move(basePos, desPos); // 将图元移动到目标位置
			pNewEnt->m_brushcolor = pEntity->m_brushcolor;
			pEntity->m_brushcolor = RGB(255, 255, 255);
			pEntity->Draw(pDC, dmInvalid); // 清除原来位置上的图元

			pNewEnt->Draw(pDC, dmNormal); // 在目标位置上绘制图元
			g_pDoc->SetModifiedFlag(TRUE); // 标志文档数据已被修改
			pNewEnt->m_nOperationNum = g_pView->m_nCurrentOperation;
			pEntity->Append(pNewEnt);
		}
		g_pDoc->m_selectArray.RemoveAll(); //  清空选择集
//		g_pDoc->SetModifiedFlag(TRUE); // 标志文档数据已被修改
		g_pView->ReleaseDC(pDC); // 释放视类的设备环境指针
   }
}
3.平移、旋转、镜像
int	CMove::OnLButtonDown(UINT nFlags, const Position& pos) 
{
	m_nStep ++ ;
	switch(m_nStep)
	{
		case 1:
			// 第一次单击鼠标左键时得到基点位置,并初步设定目标位置
			m_basePos = m_desPos = pos;
			::prompt("请输入移动的目标点:单击鼠标右键取消") ;
			break;
		case 2:
		{
			m_desPos = pos;
			CDC*	pDC = g_pView->GetDC(); // 获得视类的设备环境指针
			// 清除鼠标移动时最后遗留下的橡皮线
			MLines*	pTempLine = new MLines(m_basePos, m_desPos);
			pTempLine->Draw(pDC, dmDrag);
			delete pTempLine;
			// 将选择集中的图元移动到目标位置并进行绘制
			int i, n;
			for(n = g_pDoc->m_selectArray.GetSize(), i = 0; i < n; i++)
			{
				MEntity*	pEntity = (MEntity*)g_pDoc->m_selectArray[i];
				pEntity->Draw(pDC,dmInvalid); // 清除原来位置上的图元
				//Move
				//Draw
				
				MEntity * pNewEnt = pEntity->Copy();
				pNewEnt->Move(m_basePos, m_desPos); // 将图元移动到目标位置
				pNewEnt->m_brushcolor = pEntity->m_brushcolor;
				pEntity->m_brushcolor = RGB(255, 255, 255);
				pEntity->Draw(pDC, dmInvalid); // 清除原来位置上的图元
				
				pNewEnt->Draw(pDC,dmNormal); // 在目标位置上绘制图元
				g_pDoc->SetModifiedFlag(TRUE); // 标志文档数据已被修改
				pNewEnt->m_nOperationNum = g_pView->m_nCurrentOperation;
				pEntity->Append(pNewEnt);
			}
			g_pDoc->m_selectArray.RemoveAll(); //  清空选择集
			g_pView->ReleaseDC(pDC); // 释放视类的设备环境指针
			m_nStep = 0; 

			g_pView->SendMessage(WM_COMMAND, ID_PICK);
			break;
		}
		default:
			break;
	}
	
	return 0;
}

种子填充

VCadView类设计

protected: // create from serialization only
	CRect rect; //定义客户区
	CP2 Seed;//种子及其四个相邻点	
	COLORREF SeedClr;//种子色
	BOOL bFill;//填充标志
public:
	void SeedFill(CDC *pDC);//字符填充函数

填充相应

void CVCadView::OnSeedFill()
{
	// TODO: Add your command handler code here
	CColorDialog ccd(SeedClr, CC_SOLIDCOLOR);
	if (IDOK == ccd.DoModal())//调用颜色对话框选取填充色
		SeedClr = ccd.GetColor();
	else
		return;
	if (IDOK == MessageBox(CString("请在区域内部选取种子点"), CString("提示"), MB_OKCANCEL))
	{
		bFill = TRUE;
	}
	else
		return;
}

选择种子

void CVCadView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	if(!m_bEditable)
		return;

	CDC * pDC = GetDC();
	m_basePos = m_desPos = point;
	if (bFill == TRUE)
	{
		GetClientRect(&rect);
		pDC->SetMapMode(MM_ANISOTROPIC);//显示DC自定义坐标系
		pDC->SetWindowExt(rect.Width(), rect.Height());
		pDC->SetViewportExt(rect.Width(), -rect.Height());
		pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2);
		Seed = CP2(point.x - rect.Width() / 2, rect.Height() / 2 - point.y);//选择种子位置
		SeedFill(pDC);//填充空心汉字
		bFill = FALSE;
		ReleaseDC(pDC);//释放pDC
		return;
	}

种子算法

void CVCadView::SeedFill(CDC *pDC)//文字填充函数
{
	COLORREF BoundaryClr = g_CurColor;//边界色
	BOOL bSpanFill;
	Stack PStakeU, PStakeD;
	PStakeU.Push(Seed); PStakeD.Push(Seed);
	int x, y, x0 = Round(Seed.x), y0 = Round(Seed.y);//x,y用于判断种子与图形的位置关系
	x = x0 - 1;
	while (pDC->GetPixel(x, y0) != BoundaryClr && pDC->GetPixel(x, y0) != SeedClr)//左方判断
	{
		x--;
		if (x <= -rect.Width() / 2)
		{
			MessageBox(CString("种子不在图形之内"), CString("警告"));//到达客户区最左端
			return;
		}
	}
	y = y0 + 1;
	while (pDC->GetPixel(x0, y) != BoundaryClr && pDC->GetPixel(x0, y) != SeedClr)//上方判断
	{
		y++;
		if (y >= rect.Height() / 2)//到达客户区最上端
		{
			MessageBox(CString("种子不在图形之内"), CString("警告"));//到达客户区最左端
			return;
		}
	}
	x = x0 + 1;
	while (pDC->GetPixel(x, y0) != BoundaryClr && pDC->GetPixel(x, y0) != SeedClr)//右方判断
	{
		x++;
		if (x >= rect.Width() / 2)//到达客户区最右端
		{
			MessageBox(CString("种子不在图形之内"), CString("警告"));//到达客户区最左端
			return;
		}
	}
	y = y0 - 1;
	while (pDC->GetPixel(x0, y) != BoundaryClr && pDC->GetPixel(x0, y) != SeedClr)//下方判断
	{
		y--;
		if (y <= -rect.Height() / 2)//到达客户区最下端
		{
			MessageBox(CString("种子不在图形之内"), CString("警告"));//到达客户区最左端
			return;
		}
	}
			
			double xleft, xright;//区间最左端与最右端像素
			CP2 PopPoint, PointTemp;
			while (!PStakeU.Empty())//如果栈不为空
			{
				PopPoint = PStakeU.GetTop()->data; PStakeU.Pop();
				if (pDC->GetPixel(Round(PopPoint.x), Round(PopPoint.y)) == SeedClr)
					continue;
				PointTemp = PopPoint;
				//像素不为边界色,不为种子色,此时在画一条横线
				//向右
				while (pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y)) != BoundaryClr && pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y)) != SeedClr)
				{
					pDC->SetPixelV(Round(PointTemp.x), Round(PointTemp.y), SeedClr);
					PointTemp.x++;
				}
				xright = PointTemp.x - 1;//右边界
				PointTemp.x = PopPoint.x - 1;
				//向左
				while (pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y)) != BoundaryClr && pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y)) != SeedClr)
				{
					pDC->SetPixelV(Round(PointTemp.x), Round(PointTemp.y), SeedClr);
					PointTemp.x--;
				}
				xleft = PointTemp.x + 1;
				//处理上一条扫描线
				PointTemp.x = xleft;
				PointTemp.y = PointTemp.y + 1;
				while (PointTemp.x < xright)
				{
					bSpanFill = FALSE;
					while (pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y)) != BoundaryClr && pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y)) != SeedClr)
					{
						bSpanFill = TRUE;
						PointTemp.x++;
					}
					if (bSpanFill)
					{
						if (PointTemp.x == xright && pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y)) != BoundaryClr && pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y)) != SeedClr)
						{
							PopPoint = PointTemp;
						}
						else
						{
							PopPoint.x = PointTemp.x - 1;
							PopPoint.y = PointTemp.y;
						}
						PStakeU.Push(PopPoint);
						bSpanFill = FALSE;
					}
					while ((pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y)) == BoundaryClr && PointTemp.x < xright) || (pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y)) == SeedClr && PointTemp.x < xright))
						PointTemp.x++;
				}
				//处理下一条扫描线
				PointTemp.x = xleft;
				PointTemp.y = PointTemp.y - 2;
			  while (PointTemp.x < xright)
			  {
			  	bSpanFill = FALSE;
			  	while (pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y)) != BoundaryClr && pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y)) != SeedClr)
			  	{
			  		bSpanFill = TRUE;
			  		PointTemp.x++;
			  	}
			  	if (bSpanFill)
			  	{
			  		if (PointTemp.x == xright && pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y)) != BoundaryClr && pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y)) != SeedClr)
			  		{
			  			PopPoint = PointTemp;
			  		}
			  		else
			  		{
			  			PopPoint.x = PointTemp.x - 1;
			  			PopPoint.y = PointTemp.y;
			  		}
			  		PStakeU.Push(PopPoint);
			  		bSpanFill = FALSE;
			  	}
			  	while ((pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y)) == BoundaryClr && PointTemp.x < xright) || (pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y)) == SeedClr && PointTemp.x < xright))
			  		PointTemp.x++;
			  }
			}
			PStakeU.Clear();
			
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/304352.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号