实现重绘
来源:互联网 发布:淘宝的中药材 编辑:程序博客网 时间:2024/04/28 22:32
我们在上一章“简单绘制擦除”里面讲解了如何绘制和擦除图形,但是只要文档刷新前面所绘制的图形就会消失。绘图程序就是要保存所绘制的线条等,所以这次给大家讲解图形的重绘。
大家都知道MFC程序的Document-View结构,在Document类中保存数据,在View类中显示数据。所以只要在绘制图形时,只要把绘制的图形在Document类中保存起来,并且在View类中重绘出来就是了。
上章我们新建了一个myGraphic程序,这里接着修改此程序,要保存绘制的图形,需要用到数组来保存数据,以便访问。MFC提供了很多动态的数组,这里使用一个简单的支持类型检查的类CArray,在使用这个类时要包含头文件#include <afxtempl.h>。类的具体用法参看MSDN,这里直接用之。
此程序没有使用类,只是简单的绘制图形,要保存绘制的图形需要保存图形的起始点和终止点,还需要一个分辨图形类型的参数。一共需要三个变量,这里新建一个数据结构来包含这三个变量。定义如下:
struct SAVE_GRAPHIC
{
int nDrawType; // 图形的类型
CPoint ptOrigin; // 图形的起始点
CPoint ptEnd; // 图形的终止点
};
此时需要定义一个数组来保存定义的结构,数组的定义如下:CArray<SAVE_GRAPHIC*, SAVE_GRAPHIC*> m_arrGraphic;。这条语句主要意思是在变量m_arrGraphic中保存的是SAVE_GRAPHIC结构的指针(第二个参数),从m_arrGraphic中得到的是SAVE_GRAPHIC结构的指针(第一个参数)。
至此需做的准备都已做完,只剩下在绘制完图形后保存图形,在窗口重绘时绘制图形。要保存图形就在OnLButtonUp函数中实现,重绘图形就在OnDraw函数中实现(因为窗口重绘时会激活WM_PAINT消息,调用OnDraw函数)。
OnLButtonUp函数修改如下:
void CMyGraphicView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
ASSERT(m_nDrawType >= DRAW_NONE);
if (m_nDrawType < DRAW_NONE)
{
CView::OnLButtonUp(nFlags, point);
return;
}
if (0 == m_nStep)
{
m_ptOrigin = point;
m_ptPreMoving = point;
m_nStep = 1;
}
else if (1 == m_nStep)
{
CClientDC dc(this);
int nOldMode = dc.SetROP2(R2_NOTXORPEN);
switch (m_nDrawType)
{
case DRAW_NONE:
break;
case DRAW_LINE:
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptPreMoving);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
break;
case DRAW_RECT:
dc.SelectStockObject(NULL_BRUSH);
dc.Rectangle(CRect(m_ptOrigin, m_ptPreMoving));
dc.Rectangle(CRect(m_ptOrigin, point));
break;
default:
break;
}
if (m_nDrawType > DRAW_NONE && m_nDrawType <= DRAW_RECT)
{// 新增加的,保存绘制的图形
SAVE_GRAPHIC *pSaveGraphic = new SAVE_GRAPHIC;
pSaveGraphic->nDrawType = m_nDrawType;
pSaveGraphic->ptOrigin = m_ptOrigin;
pSaveGraphic->ptEnd = point;
CMyGraphicDoc *pDoc = GetDocument();
pDoc->m_arrGraphic.Add(pSaveGraphic);
}
m_nStep = 0;
dc.SetROP2(nOldMode);
}
CView::OnLButtonUp(nFlags, point);
}
在OnDraw函数中重绘图形也很简单,只需要从Document类中读取数据,在分类绘制图形即可。
void CMyGraphicView::OnDraw(CDC* pDC)
{
CMyGraphicDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
pDC->SelectStockObject(NULL_BRUSH);
for (int i = 0; i < pDoc->m_arrGraphic.GetSize(); ++i)
{
SAVE_GRAPHIC *pSaveGraphic = pDoc->m_arrGraphic.GetAt(i);
ASSERT(pSaveGraphic);
if (!pSaveGraphic)
continue;
switch (pSaveGraphic->nDrawType)
{
case DRAW_NONE:
break;
case DRAW_LINE:
pDC->MoveTo(pSaveGraphic->ptOrigin);
pDC->LineTo(pSaveGraphic->ptEnd);
break;
case DRAW_RECT:
pDC->Rectangle(CRect(pSaveGraphic->ptOrigin, pSaveGraphic->ptEnd));
break;
default:
break;
}
}
}
至此图形的重绘已经完成。
O(∩_∩)O~,别忘了,上面保存图形用的是new出来的指针,在堆上,所以在程序退出时一定要delete掉。在Document类释放资源可以重载虚函数virtual void DeleteContents();具体实现如下:
void CMyGraphicDoc::DeleteContents()
{
// TODO: Add your specialized code here and/or call the base class
for (int i = 0; i < m_arrGraphic.GetSize(); ++i)
delete m_arrGraphic.GetAt(i);
m_arrGraphic.RemoveAll();
CDocument::DeleteContents();
}
是不是很简单……
又听到一首好听的歌刘若英的《当爱在靠近》,这首歌的每一句歌词都是如此的温柔!
- VC实现重绘
- 实现重绘
- 重绘的实现
- awt 实现窗口重绘
- 在对话框中 实现重绘
- 在对话框中 实现重绘
- IOS_NSObject-CGRect类别 实现界面重绘
- swing 界面实现表格刷新重绘
- 画图板重绘——队列实现
- JBuilder2005实现重构
- 实现重定向
- Struts1实现重定向
- 实现重定向
- 实现重定向页面
- android实现重启
- GDAL重采样实现
- springMVC实现重定向
- 实现请求重定向
- 转:PERL 语言中的q,qw,qr,qx,qq......符号用法总结
- BSA:中国IT行业竞争力排名上升至全球39位
- perl 对文件排序经典实例
- C语言中的malloc和free造成内存泄露?
- js检测文件类型及大小
- 实现重绘
- 可空类型简单学习
- Linux进程和线程(草稿)
- Flex应用-一个简单的拼图游戏
- 硬编码
- JS预览上传图片
- Perl 的排序问题
- 黑客绑架破解版iPhone 勒索要赎金换安全防护方法
- perl 提取介于某个区间的几行文字(转)