相关分类 VC实例 ->实例 ->VCShare

简单的图形软件

关键字 简单的图形软件

程序虽小,但包括如下知识点:
1,菜单。
2,工具栏。
3,状态栏。
4,对话框。
5,控件。
6,文件。
7,鼠标。
8,输出。
9,系列化。
10,文件的保存、新建、与关闭。

使用说明:
一,点击"图形->圆"菜单增加圆,在弹出的对话框中输入半径和圆心。
二,点击工具栏的最后一个按钮,按状态栏的提示增加矩形。
三,保存后新建再打开,是正确的。
四,保存后,关闭程序再打开是正确的。
五,保存后,马上打开是错的,暂没处理。

本软件分四个阶段完成。
一,新建一个单文档工程Grah。
新建一个类CGrahObj,并在此文件增加另外三个类。代码如下:
//GrahObj.h
#include "afxtempl.h"

class CGrahObj
{
public:
CGrahObj();
virtual ~CGrahObj();
virtual void OnDraw(CDC* pDC) = 0 ;
virtual void Serialize( CArchive& ar ) = 0 ;
enum GrahType{ARC_TYPE,RECTANGE_TYPE};
GrahType m_iType ;
};

class CArc : public CGrahObj
{
public:
CArc(CPoint pt,int r);
void OnDraw(CDC* pDC);
void Serialize( CArchive& ar );
protected:
CPoint m_pt ;//圆心
int m_iR ;//半径
};

class CRectange : public CGrahObj
{
public:
CRectange(CPoint pt,int h,int w);
void OnDraw(CDC* pDC);
void Serialize( CArchive& ar );
protected:
CPoint m_pt ;//左上角
int m_iH ;//高度
int m_iW ;//宽度
};

class CGrahObjManage
{
public:
void AddArc(CPoint pt,int r);
void AddRectange(CPoint pt,int h,int w);
void OnDraw(CDC* pDC);
void Release();
~CGrahObjManage();
void Serialize( CArchive& ar );
protected:
CArray<CGrahObj*,CGrahObj*> m_objs;
};

//GrahObj.cpp
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CGrahObj::CGrahObj()
{

}

CGrahObj::~CGrahObj()
{

}


//==========
CArc::CArc(CPoint pt,int r)
{
m_iType = ARC_TYPE ;
m_iR = r;
m_pt = pt ;
}

void CArc::OnDraw(CDC* pDC)
{
CRect r(m_pt.x-m_iR,m_pt.y-m_iR,m_pt.x+m_iR,m_pt.y+m_iR);
CPoint pt = m_pt;
pt.y += m_iR ;
pDC->Arc(&r,pt,pt);
}

void CArc::Serialize( CArchive& ar )
{
if( ar.IsStoring() )
{
ar << (int)m_iType;
ar << m_pt ;
ar << m_iR ;
}
else
{
int t;
ar >> t ; m_iType = (GrahType)t ;
ar >> m_pt ;
ar >> m_iR ;
}
}
//==========
CRectange::CRectange(CPoint pt,int h,int w)
{
m_pt = pt ;
m_iH = h ;
m_iW = w ;
m_iType = RECTANGE_TYPE ;
}

void CRectange::OnDraw(CDC* pDC)
{
CRect r(m_pt.x,m_pt.y,m_pt.x+m_iW,m_pt.y+m_iH);
pDC->Rectangle(&r);
}

void CRectange::Serialize( CArchive& ar )
{
if( ar.IsStoring() )
{
ar << (int)m_iType;
ar << m_pt ;
ar << m_iH ;
ar << m_iW ;
}
else
{
int t;
ar >> t ; m_iType = (GrahType)t ;
ar >> m_pt ;
ar >> m_iH ;
ar >> m_iW ;
}
}
//=========
void CGrahObjManage::OnDraw(CDC* pDC)
{
for(int i = m_objs.GetUpperBound() ; i >= 0 ; i-- )
{
CGrahObj* pObj = m_objs[i] ;
if( NULL == pObj )
continue ;
pObj->OnDraw(pDC);
}
}

void CGrahObjManage::AddArc(CPoint pt, int r)
{
CArc* pArc = new CArc(pt,r);
m_objs.Add(pArc);
}

void CGrahObjManage::AddRectange(CPoint pt,int h,int w)
{
CRectange* pRect = new CRectange(pt,h,w);
m_objs.Add(pRect);
}

void CGrahObjManage::Release()
{
for(int i = m_objs.GetUpperBound() ; i >= 0 ; i-- )
{
CGrahObj* pObj = m_objs[i] ;
if( NULL == pObj )
continue ;
delete pObj;
}
m_objs.RemoveAll();
}

CGrahObjManage::~CGrahObjManage()
{
Release();
}

void CGrahObjManage::Serialize( CArchive& ar )
{
if( ar.IsStoring() )
{
ar << m_objs.GetSize();
for(int i = m_objs.GetUpperBound() ; i >= 0 ; i-- )
{
CGrahObj* pObj = m_objs[i] ;
if( NULL == pObj )
continue ;
ar << pObj->m_iType ;
pObj->Serialize(ar);
}
}
else
{
int iSize;
ar >> iSize ;
for(int i = 0 ; i < iSize ; i++)
{
int iType ;
ar >> iType ;
CGrahObj* pObj = NULL ;
if(CGrahObj::ARC_TYPE == iType )
{
pObj = (CGrahObj*)new CArc(CPoint(0,0),0) ;
}
else if( CGrahObj::RECTANGE_TYPE == iType )
{
pObj = (CGrahObj*)new CRectange(CPoint(0,0),0,0) ;
}
if( NULL != pObj )
{
pObj->Serialize(ar);
m_objs.Add(pObj);
}
}
}

}
在文档类增加一个公有变量
#include "GrahObj.h"
CGrahObjManage m_objManage;
修改视图类的OnDraw函数
void CGrahView::OnDraw(CDC* pDC)
{
CGrahDoc* pDoc = GetDocument();
pDoc->m_objManage.OnDraw(pDC);
}




第二部分

================
增加一个对话框,并为其关联一个类CARCDlg,在上面增加3个编辑框,3个静态文本框,为三个编辑框分别关联三个int型变量m_x、m_y、m_r。
增加一个菜单项,ID为ID_ARC,标题为圆,在视图类为增加响应函数,代码如下:
#include "ARCDlg.h"
//...
void CGrahView::OnArc()
{
CARCDlg dlg ;
if( IDOK == dlg.DoModal())
{
CGrahDoc* pDoc = GetDocument();
pDoc->m_objManage.AddArc(CPoint(dlg.m_x,dlg.m_y),dlg.m_r);
Invalidate();
}
}



===================================

第三部分
在CMainFrame类增加公有函数
void CMainFrame::SetStateInfo(CString str)
{
m_wndStatusBar.SetPaneText(0,str);
}

视图类中增加两个变量CPoint m_ptStart; int m_iDefType ;

CGrahView::CGrahView()
{
m_iDefType = 0 ;
}

工具栏上增加一个按钮ID_RECTANGE。在视图类为它增加响应函数。
#include "MainFrm.h"
//...
void CGrahView::OnRectange()
{
CMainFrame* pFrm = (CMainFrame*)AfxGetMainWnd();
pFrm->SetStateInfo("移动鼠标到左下角,按下鼠标不松开,移动到右下角,松开鼠标");
m_iDefType = 1 ;
}

在视图类为增加WM_LBUTTONDOWN、WM_LBUTTONUP响应函数。
void CGrahView::OnLButtonDown(UINT nFlags, CPoint point)
{
m_ptStart = point ;
CView::OnLButtonDown(nFlags, point);
}


void CGrahView::OnLButtonUp(UINT nFlags, CPoint point)
{
if( 1 == m_iDefType)
{
CGrahDoc* pDoc = GetDocument();
pDoc->m_objManage.AddRectange(m_ptStart,point.y-m_ptStart.y,point.x-m_ptStart.x);
Invalidate();
m_iDefType = 0 ;
}

CView::OnLButtonUp(nFlags, point);
}
=================================

第四部分

重写文档类的系列化
void CGrahDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{

}
else
{
m_objManage.Release();
}
m_objManage.Serialize(ar);
}

重新文档类的新建
BOOL CGrahDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;

m_objManage.Release();

return TRUE;
}

操作视频:
115下载 新浪在线收看
代码下载:
第一步代码 第二步代码 第三步代码 第四步代码
相关文章
上一篇:VC实例迷宫问题寻路鼠标 下一篇:如何自动选择打印机