MFC单文档应用程序练2

更新时间:2024-03-26 05:45:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

MFC单文档应用程序

1. 一个简单的单文档应用程序

文件->新建项目->MFC应用程序 ,出现窗口按“下一步”,出现下面窗口 选择单文档

点 \调试—>运行\,最后运行界面为下图:

一个简单的单文档应用程序向导自动建立五个类:

向导自动建立的类 CAboutDlg CXxxApp CXxxView CXxxDoc 相应源文件 Xxx.cpp XxxView.cpp XxxDoc.cpp 其他源文件 StdAfx.cpp Xxx.rc 相应头文件 Xxx.h XxxView.h XxxDoc.h 其他头文件 StdAfx.h Resource.h CMainFrame MainFrame.cpp MainFrame.h 文档—视结构 MainFrame 框架窗口

视(View)

显示用户程序的数据及

处理用户与文档的交互 文档对象 永久存储

(磁盘文件)

每个类的主要函数:

void CAboutDlg::DoDataExchange(CDataExchange* pDX)

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)//创建窗体的工具栏,状态栏等 BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

BOOL CXxxApp::InitInstance() void CXxxApp::OnAppAbout()

BOOL CXxxDoc::OnNewDocument()//初始化文档字符数据、字体信息等 void CXxxDoc::Serialize(CArchive& ar)

BOOL CXxxView::PreCreateWindow(CREATESTRUCT& cs) void CXxxView::OnDraw(CDC* pDC)

BOOL CXxxView::OnPreparePrinting(CPrintInfo* pInfo)//弹出打印对话框 void CXxxView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo) void CXxxView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo) CXxxDoc* CXxxView::GetDocument() // non-debug version is inline

创建单文档应用程序的一般步骤:

? ? ? ? ? ? ?

利用AppWizard创建应用程序框架

在文档内中声明保存文档数据所需要数据对象

完成文档类的OnNewDocument函数,初始化新文档 完成文档类的Serialize函数,保持和加载文档数据 完成视类的OnInitialUpdate函数,初始化显示 完成视类的OnDraw函数,显示当前文档内容

在视类中加入可以使用户编辑文档数据所需的代码

2.简单文本和图形输出

建立一个简单的单文档应用程序SimpleTextPicture,通过修改OnDraw函数在视(View)中输出信息或画图。

找到函数OnDraw(CDC* /*pDC*/),改为OnDraw(CDC* pDC);

OnDraw函数在SimpleTextPicture.cpp文件中,专门用于输出信息或画图。负责视图显示功能(包括打印、显示、预览等)

例2.1 显示正方形和文本

void CSimpleTextPictureView::OnDraw(CDC* pDC) { CSimpleTextPictureDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here pDC->TextOut(10,120,_T(\ pDC->Rectangle(20,20,100,100); }

在AppWizard生成的OnDraw函数中加入以黑体字给出的两行代码,运行程序,显示如下:

例2.2显示彩色图形和文本

void CSimpleTextPictureView::OnDraw(CDC* pDC) {

}

CSimpleTextPictureDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);

// TODO: add draw code for native data here CPen pen; CBrush brush;

pen.CreatePen(PS_SOLID, 3, RGB(250,0,0)); brush.CreateSolidBrush(RGB(0,250,0)); pDC->SelectObject(pen); pDC->SelectObject(brush); pDC->Ellipse(100,200,300,300); DeleteObject(pen); DeleteObject(brush);

CString str(_T(\ //用UNICODE编码pDC->SetTextColor(RGB(0,0,250)); pDC->TextOut(120,150,str);

pDC->SetTextColor(RGB(125,125,125)); double a[]={31.4,888.54}; char ch[10]; CString str1;

str1.Format(_T(\pDC->TextOut(20,40,str1); str1.Format(_T(\pDC->TextOut(20,60,str1);

3.滚动字幕

创建一个简单的单文档应用程序Xxx2; [1] 在Xxx2View.h中添加代码如下: public: virtual ~CXxx2View(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif protected: private: int n;//定义变量

[2] 在CXxx2View构造函数中初始化变量n CXxx2View::CXxx2View() { // TODO: add construction code here n=0; }

[3] 在Xxx2View.cpp文件中修改OnDraw函数:

void CXxx2View::OnDraw(CDC* pDC) {

CXxx2Doc* pDoc = GetDocument(); if (!pDoc)

return;

ASSERT_VALID(pDoc);

pDC->SetTextColor(RGB(0,0,235)); pDC->SetBkMode(TRANSPARENT); CFont font; font.CreateFont(28,15,0,0,FW_NORMAL,false,false,false,DEFAULT_CHARSET,OUT_DEVICE_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,_T(\隶书\ pDC->SelectObject(&font); pDC->TextOut(n,100,_T(\世上无难事,只要肯登攀!\ n=n+20; RECT r; GetClientRect(&r); //获得窗口 if(n>r.right-r.left)//窗口如果n> 右坐标减去左坐标 n=0; }

[4]添加三条消息映射,并加入相应代码,在CXxx2View类上点击“右键->属性”,找到消息按扭,如下图:

点击

void CXxx2View::OnLButtonDblClk(UINT nFlags, CPoint point) { //鼠标左双击函数 // TODO: Add your message handler code here and/or call default SetTimer(1,500,NULL); CView::OnLButtonDblClk(nFlags, point); }

void CXxx2View::OnRButtonDblClk(UINT nFlags, CPoint point) { //鼠标右双击函数

// TODO: Add your message handler code here and/or call default KillTimer(1); CView::OnRButtonDblClk(nFlags, point); }

void CXxx2View::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default Invalidate();//刷新该函数的作用是使整个窗口客户区无效。需要重绘窗口 CView::OnTimer(nIDEvent); }

[5]添加菜单控制与代理

点击视图->资源视图,如下图,双击IDR_MAINFRAME,进入菜单编辑。

在资源Menu中添加运行子菜单:启动(IDC_MOVE)和停止(IDC_STOP)及其消息映射(右键->添加事件处理程序)。

下为“启动”对应的消息映射:

改为OnMove

并修改代码:

void CXxx2View::OnMove() //启动对应消息 { // TODO: Add your command handler code here SetTimer(1,300,NULL); }

void CXxx2View::OnStop() //停止对应的消息 { // TODO: Add your command handler code here KillTimer(1); }

4.使用计算数据画直方图

1. 使用AppWixard生成单文档工程Plot

2. 在PlotDoc.h中类 CPlotDoc的定义之前加入类Max的定义:

class Max {

double x1,x2,x3,x4;

double Max2(double,double); public:

Max(double,double,double,double); double Max4(); };

3. 在PlotDoc.cpp的文件尾部加入类Max的实现部分: // CPlotDoc commands

double Max::Max2(double a, double b) { if(a>=b) return a; else return b; }

Max::Max(double a, double b, double c, double d) { x1=a;x2=b;x3=c;x4=d; }

double Max::Max4() { return Max2(Max2(x1,x2),Max2(x3,x4)); }

4. 为CPlotDoc类增加一个公有的void类型的成员函数Find和一个公有int数据成员

数组m_num[5],使用类产生对象并计算它们的最大值,将它们转换成int,存入整数数组m_num。

void CPlotDoc::Find() {

Max a(110.5, 120.8, 110, 68); Max b(130, 256.5, 90, 200); Max c(125, 406.8, 350, 330); Max d(120, 356.8, 300, 280.5); Max e(102, 256.8, 120, 105); m_num[0] = (int) a. Max4(); m_num[1] = (int) b. Max4(); m_num[2] = (int) c. Max4(); m_num[3] = (int) d. Max4(); m_num[4] = (int) e. Max4(); }

5. 为CPlotDoc类的成员函数OnNewDocument增加调用语句准备数据。 BOOL CPlotDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; // TODO: add reinitialization code here

// (SDI documents will reuse this document) Find(); //增加的语句 return TRUE; }

6. 在视类中画图写字

void CPlotView::OnDraw(CDC* pDC) { CPlotDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here pDC->SetMapMode(MM_ISOTROPIC); pDC->SetViewportOrg(50,250); pDC->MoveTo(0,0); pDC->LineTo(1100,0); pDC->MoveTo(0,0); pDC->LineTo(0,600); int width = 40; int ch = 'A'; CString str1;

CBrush brush; brush.CreateSolidBrush(RGB(50, 250,0)); pDC->SelectObject(brush); for(int i = 1; i<6; i++, ch++) { pDC->Rectangle(200*i, 0, 200*i+width, pDoc->m_num[i-1]);

str1.Format(_T(\整型以字符格式赋给str1

pDC->TextOut(200*i+10,-10, str1); //输出ABCDE } CFont font; font.CreateFont(0,0,0,0,800,0,0,0,OEM_CHARSET,

OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,_T(\楷体\)); pDC->SelectObject(&font); pDC->TextOut(200,550, _T(\各公司销售点水果月销售量直方图\}

7. 运行程序,结果如下:

5. 单文档串行化编程之一

SerialRect应用程序串行化一个矩形数据,用对话框修改数据,用编辑/修改菜单打开对话框。

2. 用AppWizard建立一个普通单文档SerialRect工程,按下一步,直到出现下图,将

CSerialRectView的基类设为CFormView。

改为CFormView

3. 初始界面如下:

4. 在Form上添加控件

5. 添加变量Edit1~Edit4整型(m_x1, m_y1, m_x2, m_y2),取值范围0~300,Edit5为

Control-CEdit型(m_Ctrl)

6. 用右键选择控件的Events修改Edit1的黙认EN_CHANGE消息处理OnChangeEdit1为自

定义的OnChangeEdit。其他三个Edit也映射到这个函数。 7. 在Doc头文件SerialRectDoc.h中添加变量: class CSerialRectDoc : public CDocument {

protected: // create from serialization only CSerialRectDoc(); DECLARE_DYNCREATE(CSerialRectDoc) // Attributes public: int x1, y1, x2, y2; // Operations

6. 在SerialRectDoc.cpp的构造函数中初始化变量:

CSerialRectDoc::CSerialRectDoc() { // TODO: add one-time construction code here x1=y1=x2=y2=0; }

7. SerialRectView.cpp中添加下面内容: void CSerialRectView::OnChangeEdit() { // TODO: Add your control notification handler code here

UpdateData(); CSerialRectDoc* pDoc= GetDocument(); if(m_x1!=pDoc-> x1) pDoc-> x1 =m_x1; if(m_y1!=pDoc-> y1) pDoc-> y1 =m_y1; if(m_x2!=pDoc-> x2) pDoc-> x2 =m_x2; if(m_y2!=pDoc-> y2) pDoc-> y2 =m_y2; Invalidate(true); }

void CSerialRectView::OnInitialUpdate() { CFormView::OnInitialUpdate(); GetParentFrame()->RecalcLayout(); ResizeParentToFit(); m_x1=GetDocument()->x1; m_x2=GetDocument()->x2; m_y1=GetDocument()->y1; m_y2=GetDocument()->y2; UpdateData(false); }

8. 在SerialRectDoc.cpp的串行化代码:

void CSerialRectDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // TODO: add storing code here ar<>x1>>y1>>x2>>y2; } }

9. 为CSerialRectView类添加OnDraw函数

在工作区类视图中右键单击CSerialRectView类,选择Add Member Function弹出对话框:

void CSerialRectView::OnDraw(CDC *pDC) { m_Ctrl.UpdateWindow(); pDC=m_Ctrl.GetWindowDC(); pDC->Rectangle(m_x1,m_y1,m_x2,m_y2); UpdateData(false); }

6.单文档串行化编程之二

SerialData应用程序串行化日期结构数据,用对话框修改数据,用编辑/修改菜单打开对话框。

1. 用AppWizard建立一个普通单文档SerialDate工程 2. 添加一个对话框资源如下:

并为三个编辑框添加变量m_nYear, m_nMonth, m_nDay,

3. 用ClassWizard添加类CDateDialog(其基类为CDialog) 4. 在Doc头文件SerialDateDoc.h中添加下面内容: struct Date { int m_nYear; int m_nMonth; int m_nDay; };

#include \

class CSerialDateDoc : public CDocument {

protected: // create from serialization only CSerialDateDoc(); DECLARE_DYNCREATE(CSerialDateDoc) // Attributes public:

Date date;

4. 编辑菜单中添加子菜单项,ID_EDIT_MODIFY,消息映射到SerialDateDoc.cpp文件中的OnEditModify()函数

5. 在SerialDateDoc.cpp中添加代码 CSerialDateDoc::CSerialDateDoc() { date.m_nYear=2002; date.m_nMonth=6; date.m_nDay=1; }

void CSerialDateDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { ar<

{ ar>>date.m_nYear >>date.m_nMonth >>date.m_nDay ; } }

void CSerialDateDoc::OnEditModify() { CDateDialog dlg; dlg.m_nYear=date.m_nYear; dlg.m_nMonth=date.m_nMonth; dlg.m_nDay=date.m_nDay; if(dlg.DoModal()==IDOK) { date.m_nYear=dlg.m_nYear; date.m_nMonth=dlg.m_nMonth; date.m_nDay=dlg.m_nDay; } UpdateAllViews(NULL); SetModifiedFlag(true);//关闭窗口时提示存盘 }

6. 修改SerialDateView.cpp中的OnDraw代码 void CSerialDateView::OnDraw(CDC* pDC) { CSerialDateDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CString str; str.Format(_T(\ pDC->TextOut(20,20,str); str.Format(_T(\ pDC->TextOut(20,40,str); str.Format(_T(\ pDC->TextOut(20,60,str); }

本文来源:https://www.bwwdw.com/article/9vyr.html

Top