VC++深入详解(9):图形的保存和重绘

本文探讨了在VC++中遇到的图形重绘问题。当窗口被最小化后再次显示,原有的图形会消失。为了解决这个问题,文章提出需要保存图形的类型、起点和终点,并在重绘函数中利用这些信息恢复图形。通过创建一个类来封装这些数据,实现了图形的持久化和正确重绘。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先,我们重新实现一下上次课实现的功能:通过菜单,选择画哪种图形,然后进行绘图。但是这个功能有一个严重的问题,就是窗口发生重绘(比如我们把程序最小化以后再重新显示)以后,原来的图就不见了!怎么解决这个问题呢?我们必须保存每次画的图。然后在重绘函数中把它们重新画出来。准确的说,其实我们只需要保存3样东西就行了:类型(画点、画线、画矩形、画椭圆)、起点、终点。我们可以用一个类封装它们。

class CGraph  
{
public:
	CGraph();
	CGraph(UINT m_nDrawType, CPoint m_ptOrigin, CPoint m_ptEnd);
	virtual ~CGraph();
	UINT m_nDrawType;
	CPoint m_ptOrigin;
	CPoint m_ptEnd;


};
并且重载了构造函数:

CGraph::CGraph(UINT m_nDrawType, CPoint m_ptOrigin, CPoint m_ptEnd)
{
	this->m_nDrawType = m_nDrawType;
	this->m_ptOrigin = m_ptOrigin;
	this->m_ptEnd = m_ptEnd;
}
那么把它们存在什么地方呢?肯定不能使用数组,因为我们并不知道要存多少元素。MFC为我们封装了一个称为CPtrArray类,它支持void*类型的。通过GetAt来获得某个元素,通过Add 来增加一个元素,通过GetSize 来获得总的元素个数。我们为自己的view类增加一个CPtrArray类型的成员变量m_ptrArray,然后在每次OnLButtonUp消息的中,将前面提到的3个变量保存:

	CGraph graph(m_nDrawType,m_ptOrigin,point);
	m_ptrArray.Add(&graph);
然后,在OnDraw函数中把它们重新画出来:

void CCH_11_GRAPHView::OnDraw(CDC* pDC)
{
	CCH_11_GRAPHDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
	for(int i = 0 ; i < m_ptrArray.GetSize();++i)
	{
		switch (((CGraph*)m_ptrArray.GetAt(i))->m_nDrawType)
		{
		case 1:
			pDC->SetPixel(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd,RGB(0,0,0));
			break;
		case 2:
			pDC->MoveTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin);
			pDC->LineTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd);
			break;
		case 3:
			pDC->Rectangle(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin,
				((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd));
			break;
		case 4:
			pDC->Ellipse(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin,
				((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd));
			break;
		}
	}
}

但是我们发现,当窗口重绘以后,原来的图像依然没有显示出来,问题出在了哪里呢?其实在于OnLButtonUp中的构造的graph是一个局部变量,所以,当程序运行完以后,它就被析构了。即使我们保存了它的地址,但是在OnDraw函数中使用的,实际上是已经被虚构的无效的地址了,所以不能正常绘图。解决的办法也很简单,就是在OnLButtonUp中new一个graph出来,然后增加到m_ptrArray中就行了:

//	CGraph graph(m_nDrawType,m_ptOrigin,point);
//	m_ptrArray.Add(&graph);
	CGraph *pGraph = new CGraph(m_nDrawType,m_ptOrigin,point);
	m_ptrArray.Add(pGraph);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值