1.创建4个菜单,为其添加消息响应,用成员变量保存绘画类型。添加LButtonDown和Up消息。
2.当窗口重绘时,如果想再显示原先画的数据,则需要保存数据。为此创建一个新类来记录绘画类型和两个点。
class CGraph
{
public:
CPoint m_ptOrigin;//起点
CPoint m_ptEnd;//终点
UINT m_nDrawType;//绘画类型
CGraph();
CGraph(UINT m_nDrawType,CPoint m_ptOrigin,CPoint m_ptEnd);//此为构造函数。
virtual ~CGraph();
};
//CGraph graph(m_nDrawType,m_ptOrigin,point);//不能用局部变量
//m_ptrArray.Add(&graph);//加入这种指针数组中
//加入到指针数组中
在GraphicView.h中有如下代码
CPtrArray m_ptrArray;
for(int i=0;i<m_ptrArray.GetSize();i++)
3.在CView::OnPaint()调用了OnDraw(),但在void CGraphicView::OnPaint()中MFC的Wizard没有调用OnDraw(),要注意这个区别。如果你此时想调用,必须手动添加代码。 OnDraw(&dc);
4.让窗口具有滚动条的功能。
void CGraphicView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
// TOD Add your specialized code here and/or call the base class
SetScrollSizes(MM_TEXT,CSize(800,600));//设置映射模式,设定窗口大小。OK!
}
5.坐标系的转换,此处不再详细介绍,需要时请查阅相关资料。
6.解决重绘时线跑到上面的问题。为什么会错位?因为逻辑坐标和设备坐标没有对应起来。
解决方法:
7.另外两种方法来保存数据。
将兼容DC的图拷贝到屏幕DC上去。
此处不再详细介绍这两种方法,因为介绍多了容易搞晕。呵呵
如何让CDC上输出的文字、图形具有保持功能,集合类CPtrArray的使用,CPaintDC与CClientDC的区别与应用,OnPaint与OnDraw在CView中的关系及实现内幕,滚动窗口的实现,坐标空间,映射方式,设备坐标与逻辑坐标的转换。元文件设备描述表的使用,如何利用兼容DC实现图形的保存和再现。
#先实现一下上节课的绘图功能
#保存所绘制的图像以及图像的重绘00:09
3个要素 绘制的类型,起点,终点
保存这3个要素就可以在OnDraw中对其进行重绘
×新建一个类来保存CGraph
class CGraph
{
public:
};
×动态存储这些对象
用MFC的集合类CPtrArray,支持void指针数组。CPtrArray与CObArray相似
MSDN:
The CPtrArray class supports arrays of void pointers.
The member functions of CPtrArray are similar to the member functions of class CObArray. Because of this similarity, you can use the CObArray reference documentation for member function specifics. Wherever you see a CObject pointer as a function parameter or return value, substitute a pointer to void.
CObject* CObArray::GetAt( int <nIndex> ) const;
for example, translates to
void* CPtrArray::GetAt( int <nIndex> ) const;
#增加Add,获取元素GetAt,获取元素数目GetSize
#代码:
//void CGraphicView::OnLButtonUp(UINT nFlags, CPoint point)
//使用new在堆中分配空间,在栈中分配的话CGraph的对象析构以后内存被回收
//void CGraphicView::OnDraw(CDC* pDC)
#OnDraw函数00:32
OnDraw是个虚函数。
Vc安装目录vc98-》MFC-》SRC-》viewcore.cpp
void CView::OnPaint() //可以在此设置断点看是否能够进入这里
{
在view类中重写OnPaint消息,则系统会调用自定义的OnPaint函数。
void CGraphicView::OnPaint()
{
}
#让窗口具有滚动的能力00:44
#在头文件和源文件中手动把view的基类改为CScrollView
#对CScrollView的尺寸进行设置
SetScrollSizes
//什么时候调用呢?窗口创建之后调用
//使用OnInitialUpdate(该函数是当第一个视图和文档关联之后被调用)(虚函数)
//而且它在第一次调用OnDraw的调用之前
void CGraphicView::OnInitialUpdate()
{
}
//?当移动到窗口下端划线,窗口重绘时所画的线条位置发生了改变
//坐标点并没有发生改变
//但我们作图的时候使用的是逻辑坐标,windows需要将逻辑坐标改变为设备坐标来输出图形
//而OnPrepareDC(&dc)用来调整显示上下文的属性
//可能就是它改变了上下文属性
//在MFC中查找OnPrepareDC函数(viewscrl.cpp)(先搜索CSrollView)
其中
#视口和窗口原点的改变01:25?????????????????????
CDC中提供了两个成员函数函数SetViewportOrg和SetWindowOrg,用来改变视口和窗口的原点。(获取则为Get……)
1#CMetaFileDC m_dcMetaFile;
2#m_dcMetaFile.Create();//参数为NULL则一个内存源文件被创建
3#把绘图时的dc都换成m_dcMetaFile
4#ONDRAW中使用close来返回一个源文件的句柄
//再次创建一个源文件
//在源文件dc中播放先前的源文件,从而保存了上次的操作
//删除源文件资源
#把源文件保存到文件中
添加菜单上打开和保存的命令响应
×CopyMetaFile
void CGraphicView::OnFileSave()
{
}
#打开文件
GetMetaFile××××××××××
//GetEnhMetaFile
void CGraphicView::OnFileOpen()
{
}
(2)使用兼容DC
#CDC m_dcCompatible;
#先判断兼容dc是否已经创建
//如果要在兼容dc上绘图必须要选入一幅位图,导入的也行
//m_dcCompatible.BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);CreateCompatibleBitmap返回的位图对象只包含相应设备描述表中的位图的位图信息头,不包含颜色表和象素数据块。因此,选入该位图对象的设备描述表不能像选入普通位图对象的设备描述表一样应用,必须在SelectObject函数之后,调用BitBlt将原始设备描述表的颜色表及象素数据块拷贝到兼容设备描述表。
同样把dc换成m_dcCompatible,由于是内存中dc,同样操作时是看不见的
OnDraw中贴图: