大二下学期项目--MFC多文档程序

一、实验目的

1)有四个以上文档

2)第一个视图类的基类是CEditView

3)在第二个文档中,画出一个图,要求有5种以上图形,图自己设计,可以是房子动物等

4)在第个文档中,实现动画画图,图案是一个自己设计的图形,比如是一个五角星或花,之后按下鼠标就拖出一个图形,不能是简单的圆、矩形和直线,要求设置不同颜色的画笔和画刷。

5)在第个文档中,单击菜单中的某一项可以打开对话框,包括菜单、对话框等资源

6)在第个文档中,对话框中至少5种控件分别存放学生的姓名(学号、年龄)、班级、党员,专业、爱好、住址等信息,每种控件的信息读取后在编辑框中显示出来。

7)在第个文档中,实现串行化,可以输入、保存并显示学生或员工信息。

二、多个类的继承关系画出结构图。 

三、每个类的定义,包括.h文件和.cpp文件。

1)第一视图类的基类是CEditView,在创建多文档时已完成(具体操作请    看实验步骤及方法中(1))。

2)第二个文档:

MyMdiView2.h里的public添加代码

public:

int m_picture;

POINT startpoint;

POINT endpoint;  

bool lbutton;

int keyFlag;

CPen *cpen;

CPen *erasePen;                           //定义画笔类对象

CBrush *cbrush9;                           //定义画刷类对象

CBrush* cbrush1;

CBrush* cbrush2;   //红色

CBrush* cbrush3;                         

CBrush* cbrush4;  

bool lMouseFlag;                         //表示鼠标左键是否按下

bool rMouseFlag;                        //表示鼠标右键是否按下

在MyMidView2.cpp添加代码

#include "stdafx.h"

#include "MyMdi.h"

#include "MyMdiView2.h"

#include "MyMdiDoc2.h"

// CMyMdiView2

IMPLEMENT_DYNCREATE(CMyMdiView2, CScrollView)

CMyMdiView2::CMyMdiView2()

{

keyFlag=0;

rMouseFlag=false;

lbutton=false;

cpen=new CPen(PS_SOLID,0,RGB(255,0,0));

erasePen=new CPen(PS_SOLID,20,RGB(255,255,255));

cbrush9=new CBrush(RGB(0,255,0));

cbrush1 = new CBrush(RGB(255, 192, 203));//粉刷

cbrush2 = new CBrush(RGB(255, 0, 0));//红刷

cbrush3 = new CBrush(RGB(139, 69, 19));//棕刷

cbrush4 = new CBrush(RGB(255, 165, 0));//橘刷

}

CMyMdiView2::~CMyMdiView2()

{

delete cpen;

delete erasePen;

delete cbrush9;

delete cbrush2;

delete cbrush1;

delete cbrush3;

delete cbrush4;

}

BEGIN_MESSAGE_MAP(CMyMdiView2, CScrollView)

//{{AFX_MSG_MAP(CMyMdiView2)

ON_WM_LBUTTONDOWN()

ON_WM_MOUSEMOVE()

ON_WM_LBUTTONUP()

ON_WM_RBUTTONDOWN()

ON_WM_RBUTTONUP()

//}}AFX_MSG_MAP

 ON_WM_LBUTTONDOWN()

    ON_WM_LBUTTONUP()

    ON_WM_MOUSEMOVE()

    ON_WM_RBUTTONDOWN()

    ON_WM_RBUTTONUP()

//ON_COMMAND_RANGE(ID_FLOWER,ID_RECT,OnOperPictureChange)

END_MESSAGE_MAP()

void CMyMdiView2::OnInitialUpdate()

{

CScrollView::OnInitialUpdate();

CSize sizeTotal;

// TODO: calculate the total size of this view

sizeTotal.cx = sizeTotal.cy = 100;

SetScrollSizes(MM_TEXT, sizeTotal);

}

void CMyMdiView2::OnDraw(CDC* pDC)

{

CMyMdiDoc2 * pDoc = (CMyMdiDoc2 *)GetDocument();

if(keyFlag!=0)

{

pDC->SelectObject(cpen);

pDC->SelectObject(cbrush9);

if(keyFlag==1) {

              pDC->SelectObject(cpen);//黑色

pDC->SelectObject(cbrush2);

pDC->Ellipse(startpoint.x , startpoint.y , endpoint.x , endpoint.y );//圆

pDC->SelectObject(cbrush3);

pDC->Ellipse(startpoint.x+20, startpoint.y+20, endpoint.x-20, endpoint.y-20);//圆

pDC->SelectObject(cbrush4);

pDC->Ellipse(startpoint.x + 40, startpoint.y + 40, endpoint.x - 40, endpoint.y - 40);//圆

}}

CRect rect;

    GetClientRect(&rect);

  // 创建画笔和画刷

    CPen pen1(PS_SOLID, 2, RGB(0, 0, 0)); // 黑色画笔

    CBrush brush1(RGB(255, 200, 150)); // 主体颜色

    CBrush brush2(RGB(0, 255, 0)); // 绿色,用于房顶

    CBrush brush3(RGB(200, 200, 200)); // 灰色,用于烟筒

    CPen* oldpen1 = pDC->SelectObject(&pen1);

    // 绘制房子主体

    pDC->SelectObject(&brush1);

    pDC->Rectangle(100, 200, 300, 400); // 矩形主体

    // 绘制房顶

    pDC->SelectObject(&brush2);

    POINT roofPoints[] = { {100, 200}, {200, 100}, {300, 200} };

    pDC->Polygon(roofPoints, 3);

    // 绘制门

    CBrush brush4(RGB(100, 50, 0)); // 棕色,用于门

    pDC->SelectObject(&brush4);

    pDC->Rectangle(170, 300, 230, 400);

    // 绘制窗户

    CBrush brush5(RGB(200, 255, 255)); // 浅蓝色,用于窗户

    pDC->SelectObject(&brush5);

    pDC->Rectangle(120, 250, 180, 300);

    pDC->MoveTo(150, 250);

    pDC->LineTo(150, 300);

    pDC->MoveTo(120, 275);

    pDC->LineTo(180, 275);

    // 绘制烟筒

    pDC->SelectObject(&brush3);

    pDC->Rectangle(220, 100, 240, 150);

    pDC->SelectObject(oldpen1);

    // 创建画笔

    CPen pen2(PS_SOLID, 2, RGB(255, 0, 0)); // 红色画笔

    CPen* oldpen2 = pDC->SelectObject(&pen1);

    // 绘制玫瑰花瓣

    pDC->Ellipse(100, 100, 150, 150);

    pDC->Ellipse(100, 150, 150, 200);

    pDC->Ellipse(150, 100, 200, 150);

    pDC->Ellipse(150, 150, 200, 200);

    pDC->Ellipse(125, 125, 175, 175);

    // 创建黄色画刷

    CBrush yellowBrush(RGB(255, 255, 0));

    // 选中黄色画刷并绘制玫瑰花芯

    CBrush* oldBrush = pDC->SelectObject(&yellowBrush);

    pDC->Ellipse(135, 135, 165, 165);

    pDC->SelectObject(oldBrush); // 恢复之前的画刷

    pDC->SelectObject(oldpen2);

pDC->SetWindowOrg(rect.left,rect.top);

pDC->SetViewportOrg(rect.left,rect.top);

pDC->SetViewportExt(rect.right,rect.bottom);

pDC->SetWindowExt(rect.right/2,rect.bottom/2);

CPen pen3(PS_SOLID, 1, RGB(0, 0, 0));

CBrush brush6(RGB(128, 128, 128));

CBrush brush7(RGB(255, 255, 255));

CBrush brush8(RGB(255, 0, 0));

CPen* oldpen = pDC->SelectObject(&pen1);

int offsetX = 300;

int offsetY = 200;

pDC->SelectObject(&brush6);

pDC->Ellipse(115 + offsetX, 250 + offsetY, 336 + offsetX, 285 + offsetY);      // 雪人影子

pDC->SelectObject(&brush7);

pDC->Ellipse(27 + offsetX, 99 + offsetY, 233 + offsetX, 280 + offsetY);      // 雪人身子

pDC->Ellipse(81 + offsetX, 22 + offsetY, 177 + offsetX, 118 + offsetY);

pDC->SelectObject(&brush8);

pDC->Ellipse(113 + offsetX, 54 + offsetY, 129 + offsetX, 70 + offsetY);   // 雪人眼睛

pDC->Ellipse(145 + offsetX, 54 + offsetY, 161 + offsetX, 70 + offsetY);

CPoint points[3];                

points[0].x = 139 + offsetX;

points[0].y = 79 + offsetY;

points[1].x = 171 + offsetX;

points[1].y = 75 + offsetY;

points[2].x = 139 + offsetX;

points[2].y = 94 + offsetY;

pDC->Polygon(points, 3);

CBrush brush9(RGB(255, 0, 0));

pDC->SelectObject(&brush4);

CPoint hatPoints[3];           

hatPoints[0].x = 72 + offsetX;

hatPoints[0].y = 22 + offsetY;

hatPoints[1].x = 127 + offsetX;

hatPoints[1].y = -30 + offsetY;

hatPoints[2].x = 197 + offsetX;

hatPoints[2].y = 22 + offsetY;

pDC->Polygon(hatPoints, 3);

}

void CMyMdiView2::OnLButtonDown(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CMyMdiDoc2 * pDoc = (CMyMdiDoc2 *)GetDocument();

lMouseFlag=true;

SetCapture();       //捕获鼠标动作

if(nFlags)

keyFlag=1;

else keyFlag=0;

startpoint=point;

endpoint=point;  

CScrollView::OnLButtonDown(nFlags, point);

}

void CMyMdiView2::OnMouseMove(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CMyMdiDoc2 * pDoc = (CMyMdiDoc2 *)GetDocument();

if(lMouseFlag)

{ endpoint=point;

           Invalidate(true);  

}

CView::OnLButtonUp(nFlags, point);

if(rMouseFlag==true)

{

//SetCursor(LoadCursor(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDC_CURSOR1))); // 设置鼠标形状

CDC* pDC = GetDC(); // 获取设备上下文

pDC->SelectObject(erasePen);

pDC->SelectObject(cbrush9);

pDC->SetROP2(R2_COPYPEN);// 设置为覆盖绘图方式

pDC->Rectangle(point.x+10,point.y+10,point.x,point.y);

ReleaseDC(pDC); // 释放设备上下文

}

CScrollView::OnMouseMove(nFlags, point);

}

void CMyMdiView2::OnLButtonUp(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CMyMdiDoc2 * pDoc = (CMyMdiDoc2 *)GetDocument();

ReleaseCapture();

endpoint=point;

Invalidate(true);   //参数为true则用白刷子刷新用户区后再画,为false则在原来基础上面画图。

lMouseFlag=false;

CScrollView::OnLButtonUp(nFlags, point);

}

void CMyMdiView2::OnRButtonDown(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

rMouseFlag=true;

SetCapture(); //捕获鼠标动作

startpoint=point;

endpoint=startpoint;

CScrollView::OnRButtonDown(nFlags, point);

}

void CMyMdiView2::OnRButtonUp(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

ReleaseCapture(); // 释放鼠标捕获

rMouseFlag=false;

CScrollView::OnRButtonUp(nFlags, point);

}

3)在个文档

1.在MyMidDoc3.h中的public下进行定义

CString m_di;

CString m_str;//字符串化

2.在MyMidDoc3.cpp中以下代码

#include"CDIgInput.h"//添加对应的头文件

BOOL CMyMidDoc3::OnNewDocument()

{

if (!CDocument::OnNewDocument())

return FALSE;

m_str = "可以点击'编辑'下拉菜单下的'信息录入',显示信息录入表格

return TRUE;

}

BEGIN_MESSAGE_MAP(CMyMidDoc3, CDocument)

ON_COMMAND(ID_Sh, &CMyMidDoc3::OnSh)

END_MESSAGE_MAP()

#ifdef _DEBUG

// CMyMidDoc3 序列化

//字符串化

void CMyMidDoc3::Serialize(CArchive& ar)

{

if (ar.IsStoring())

{

// TODO:  在此添加存储代码

ar << m_di;

}

else

{

// TODO:  在此添加加载代码

ar >> m_di;

}

}

#endif

void CMyMidDoc3::OnSh()

{

// TODO: 在此添加命令处理程序代码

CDIgInput inputDlg; //创建一个 CInputDlg类的对象

if (inputDlg.DoModal() == IDOK)//显示对话框

{

m_str = "";//获取输入的字符串

m_di = inputDlg.m_Edit5;

UpdateAllViews(NULL);//更新视图

}

3、在MyMidView3.cpp文件中添加从文档读取的数据

void MyMidView3::OnDraw(CDC* pDC)

{

//CDocument* pDoc = GetDocument();

CMyMidDoc3* pDoc = (CMyMidDoc3*)GetDocument();

ASSERT_VALID(pDoc);

// TODO:  在此添加绘制代码

CString str = pDoc->m_str; // 从文档类中读取数据

pDC->TextOut(5,10,str);

CString str1 = pDoc->m_di;// 从档类中读取数据

pDC->TextOut(100,50,str1);

}

4. DlgInput.cpp : implementation file

#include "stdafx.h"

#include "MyMdi.h"

#include "DlgInput.h"

void CDlgInput::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CDlgInput)

DDX_Control(pDX, IDC_BUTTON2, m_Button2);

DDX_Control(pDX, IDC_COMBO4, m_Combo4);

DDX_Control(pDX, IDOK, m_ok);

DDX_Control(pDX, IDC_COMBO3, m_Combo3);

DDX_Control(pDX, IDC_COMBO2, m_Combo2);

DDX_Control(pDX, IDC_COMBO1, m_Combo1);

// DDX_Radio(pDX, IDC_RADIO1, m_Radio1);

DDX_Text(pDX, IDC_EDIT1, m_Edit1);

DDX_Text(pDX, IDC_EDIT5, m_Edit5);

DDX_Text(pDX, IDC_EDIT2, m_Edit2);

DDX_Text(pDX, IDC_EDIT3, m_Edit3);

DDX_Check(pDX, IDC_CHECK1, m_bcheck);

//}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(CDlgInput, CDialog)

//{{AFX_MSG_MAP(CDlgInput)

ON_BN_CLICKED(IDC_BUTTON2, OnButton2)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

BOOL CDlgInput::OnInitDialog()

{

CDialog::OnInitDialog();

// m_Button2.SetCheck(1);

// TODO: Add extra initialization here

m_bcheck=TRUE;

UpdateData(FALSE);

m_Combo1.AddString("数据科学与大数据技术");

m_Combo1.AddString("计算机科学与技术");

m_Combo1.AddString("医学信息工程");

m_Combo1.AddString("通信工程");

m_Combo2.AddString("1班");

m_Combo2.AddString("2班");

m_Combo2.AddString("3班");

m_Combo3.AddString("河北省保定市");

m_Combo3.AddString("河北省石家庄市");

m_Combo3.AddString("河北省张家口市");

m_Combo4.AddString("游泳");

m_Combo4.AddString("羽毛球");

m_Combo4.AddString("篮球");

m_Combo4.AddString("唱歌");

 // 将成员变量的值更新到对话框的控件上

    UpdateData(FALSE);

return TRUE;  //return TRUE unless you set the focus to a contr

}

void CDlgInput::OnButton2()

{

// TODO: Add your control notification handler code here

CString cs4,cs5,cs6,cs7;

CString allCs1;

CString allCs2;

CString allCs;

m_Combo4.GetWindowText(cs4);//爱好

UpdateData(TRUE);

m_Combo1.GetWindowText(cs5);//专业

m_Combo2.GetWindowText(cs6);//班级

m_Combo3.GetWindowText(cs7);//地址

allCs1 = allCs1+"姓名:"+m_Edit1 +"  " + "学号:" + m_Edit2 +"  " + "年龄:" + m_Edit3 + "  "+"\n爱好:" + cs4 +" "+ "专业:" + cs5+" "+ "班级:" + cs6+ " "+"地址:" + cs7;//名字 学号 专业

CString cs;

if (m_bcheck == 1) { cs = "是党员"; }

else { cs= "不是党员"; }

allCs2 = allCs2 + " "+cs;

allCs = allCs +  " " + allCs2;

m_Edit5=m_Edit5+allCs1;

m_Edit5=m_Edit5+allCs;

UpdateData(FALSE);

}

void CDlgInput::OnOK()

{

UpdateData(TRUE);

CString cs;

if (m_bcheck == 1) { cs = "是党员"; }

else { cs= "不是党员"; }

CDialog::OnOK();

}

4)在为了使CMyMdiDoc2类和CMyMdiView2在CMyMdiApp类中成为可识别的对象类,必须在CMyMdiApp.cpp文件中包含CMyMdiDoc2类和CMyMdiView2的说明头文件CMyMdiDoc2.h和CMyMdiView2.h,加入代码。第三个文档也是如此。

#include "MyMdiView.h"

#include "MyMdiDoc2.h"

#include "MyMdiView2.h"

#include "MyMdiDoc3.h"

#include "MyMdiView3.h"

四、实验步骤及方法

  1. 在Visual C++ 6.0中,创建一个多文档应用程序MyMdi,在“MFC应用程序向导—步骤四”中,单击“高级”按钮,弹出“高级选项”对话框,在文件扩展名中输入mmd,在主框标题框中输入Xx,在过滤器名框中输入“MyMdi文件(*.mmd)”,在“MFC应用程序向导—步骤6”对话框中,为CMyMdiView类设置基类为CEditView,其他的都保留默认设置,最后点击完成即可,第一种文档已经创建成功,运行无错即可向下进行。在MFC类向导窗口中,点击Add Class按钮,选择New子菜单,弹出New Class对话框,在Name 框中输入新的文档类名称CMyMdiDoc2,在Base class框中输入选择CDocument,点击“确定”按钮,用同种方法在应用程序中添加CScrollView的派生类MyMdiView2,用上述方法也创建CMyMdiDoc3和MyMdiView3

  2. 在Resource.h文件中,手动添加下列代码:

#define IDR_XXTYPE                      129

#define IDR_XXTYPE2                     130

#define IDR_XXTYPE3                     131

手工加入第二个资源模板字符串。具体方法:从工作空间的资源视图选择String,打开字串表资源,找到IDR_MYMIDTYPE的代码,进行复制粘贴在此基础上修改。

因为本应用程序支持多种文档,所以在应用程序的Initlnstance()函数中,需要定义的文档模板对象,打开MyMdi.cpp文件,添加代码如下:

CMultiDocTemplate* pDocTemplate;

pDocTemplate = new CMultiDocTemplate(

IDR_MYMDITYPE,

RUNTIME_CLASS(CMyMdiDoc),

RUNTIME_CLASS(CChildFrame), // custom MDI child frame

RUNTIME_CLASS(CMyMdiView));

AddDocTemplate(pDocTemplate);

CMultiDocTemplate* pDocTemplate2;

pDocTemplate2 = new CMultiDocTemplate(

IDR_MYMDITYPE2,

RUNTIME_CLASS(CMyMdiDoc2),

RUNTIME_CLASS(CChildFrame), // custom MDI child frame

RUNTIME_CLASS(CMyMdiView2));

AddDocTemplate(pDocTemplate2);

CMultiDocTemplate* pDocTemplate3;

pDocTemplate3= new CMultiDocTemplate(

IDR_MYMDITYPE3,

RUNTIME_CLASS(MyMdiDoc3),

RUNTIME_CLASS(CChildFrame), // custom MDI child frame

RUNTIME_CLASS(MyMdiView3));

AddDocTemplate(pDocTemplate3);

  1. 为了使MyMdiDoc2类和XxView2在MyMdiApp类中成为可识别的对象类,必须在MyMdi.cpp文件中包含MyMdiDoc2类和MyMdiView2的说明头文件XxDoc2.h和XxView2.h,加入代码。第三个也是如此。

#include "MyMdiDoc.h"

#include "MyMdiView.h"

#include "MyMdiDoc2.h"

#include "MyMdiView2.h"

#include "MyMdiDoc3.h"

#include "MyMdiView3.h"

7)对与第三个文档,点击编辑菜单中的信息录入,测就出现了对话框,同时实现了显示信息可输入、串行化,保存等功能。

  • 为程序添加对话框,在资源视图中找到Dialog新插入一个为IDD_CDlgInput并且在对话框中学生录入信息所需要的控件,进行整理(图8-3),为其分别连接建立类向导同时为其中的控件添加相关联的成员变量(图8-4)。

在资源视图中找到Menu,将菜单IDR_MYMIDTYPE复制命名一份,ID为IDR_MYMIDTYPE。在新创建的编辑在当中加入“信息录入”,并将起ID设置为ID_Sh。

  • 为程序添加对话框,在资源视图中找到Dialog新插入一个为IDD_CDlgInput并且在对话框中学生录入信息所需要的控件,进行整理(图8-3),为其分别连接建立类向导同时为其中的控件添加相关联的成员变量(图8-4)。

为程序添加对话框,在资源视图中找到Dialog新插入一个为IDD_CDlgInput并且在对话框中学生录入信息所需要的控件,进行整理,为其分别连接建立类向导同时为其中的控件添加相关联的成员变量。

  • 然后利用类向导为对话框生成CDialog类的派生类CDlgInput。
  • 最后在相对应的文件添加代码(具体内容请查看类的定义)。
  1. 运行程序(具体结果请查看测试结果里的内容)。
  2. 对个文档进行操作,无误后,该程序测运行操作成功。

五、调试分析与测试结果

1)调试分析

在写代码中编译运行会出现错误,可以根据编译器提示语句找到相关部分进行修改。多次且随时编译运行来增加程序的可靠性和正确性。

2)结果:就不展示了​​​​​​

六.程序调试心得体会(困难及经验)

    (1)困难:

①.程序的断言总是出错,存在报警

(2)经验:

 ①. 打代码是要仔细,注意大小写问题,和字母拼写问题。

②.注意逻辑问题,避免出现不必要的错误。

③.要注意引用对应的头文件。

七.参考文献:

     李忠华 《面向对象程序设计》    

郑光勇《C++面向对象程序设计》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值