MFC单文档应用程序问题
来源:互联网 发布:淘宝乐豆有什么用 编辑:程序博客网 时间:2024/05/14 15:04
1. 文档——视结构
每个类的主要函数有:
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
2. 创建单文档应用程序的一般步骤:
1) 利用AppWizard创建应用程序框架;
2) 在文档内中声明保存文档数据所需要数据对象;
3) 完成文档类的OnNewDocument函数,初始化新文档;
4) 完成文档类的Serialize函数,保持和加载文档数据;
5) 完成视类的OnInitialUpdate函数,初始化显示;
6) 完成视类的OnDraw函数,显示当前文档内容;
7) 在视类中加入可以使用户编辑文档数据所需的代码。
3. 简单文本和图形输出
建立一个简单的单文档应用程序SimpleTextPicture,通过修改OnDraw函数在视(View)中输出信息或画图。
找到函数OnDraw(CDC* /*pDC*/),改为OnDraw(CDC* pDC);
OnDraw函数在SimpleTextPicture.cpp文件中,专门用于输出信息或画图。负责视图显示功能(包括打印、显示、预览等)
3.1 显示正方形和文本void CSimpleTextPictureView::OnDraw(CDC* pDC) { CSimpleTextPictureDoc* pDoc =GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here <span style="color:#3366ff;">pDC->TextOut(10,120,_T("HelloWorld!")); pDC->Rectangle(20,20,100,100);</span> }
在AppWizard生成的OnDraw函数中加入以黑体字给出的两行代码,运行程序,显示如下:
3.2 显示彩色图形和文本
void CSimpleTextPictureView::OnDraw(CDC* pDC){CSimpleTextPictureDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data here<span style="color:#3366ff;">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("Hello World!")); //用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("%f"),a[0]);pDC->TextOut(20,40,str1);str1.Format(_T("%f"),a[1]);pDC->TextOut(20,60,str1);</span>}
运行结果如下:
4. 滚动字幕
创建一个简单的单文档应用程序Xxx2;
[1] 在Xxx2View.h中添加代码如下:
public: virtual ~CXxx2View(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc)const; #endifprotected:private: int n; //定义变量
[2] 在CXxx2View构造函数中初始化变量n
CXxx2View::CXxx2View(){ // TODO: add constructi on code here n=0;}
[3] 在Xxx2View.cpp文件中修改OnDraw函数:
void CXxx2View::OnDraw(CDC* pDC){CXxx2Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc);if (!pDoc)return;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类,在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)及其消息映射(右键->添加事件处理程序)。
下为“启动”对应的消息映射:
并修改代码:
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);}5. 使用计算数据画直方图
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 commandsdouble 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);<pre name="code" class="cpp"> for(int i = 1; i<6; i++, ch++) {pDC->Rectangle(200*i, 0, 200*i+width, pDoc->m_num[i-1]); str1.Format(_T("%c"),ch); //整型以字符格式赋给str1 pDC->TextOut(200*i+10,-10, str1); //输出ABCDE }<pre name="code" class="cpp"> 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. 运行程序,结果如下:
6. 单文档串行化编程之一
SerialRect应用程序串行化一个矩形数据,用对话框修改数据,用编辑/修改菜单打开对话框。
1. 用AppWizard建立一个普通单文档SerialRect工程,按下一步,直到出现下图,将CSerialRectView的基类设为CFormView。
2. 初始界面如下:
3. 在Form上添加控件
4. 添加变量Edit1~Edit4整型(m_x1, m_y1, m_x2, m_y2),取值范围0~300,Edit5为Control-CEdit型(m_Ctrl)
5. 用右键选择控件的Events修改Edit1的黙认EN_CHANGE消息处理OnChangeEdit1为自定义的OnChangeEdit。其他三个Edit也映射到这个函数。
6. 在Doc头文件SerialRectDoc.h中添加变量:
class CSerialRectDoc : public CDocument{ protected: // create from serialization only CSerialRectDoc(); DECLARE_DYNCREATE(CSerialRectDoc)// Attributes public: int x1, y1, x2, y2;// Operations}
7. 在SerialRectDoc.cpp的构造函数中初始化变量:
CSerialRectDoc::CSerialRectDoc(){ // TODO: add one-time construction code here x1=y1=x2=y2=0;}
8. 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);}
9. 在SerialRectDoc.cpp的串行化代码:
void CSerialRectDoc::Serialize(CArchive& ar){ if (ar.IsStoring()) {// TODO: add storing code herear<<x1<<y1<<x2<<y2; } else {// TODO: add loading code herear>>x1>>y1>>x2>>y2; }}
10. 为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);}7. 单文档串行化编程之二
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 "DateDialog.h"class CSerialDateDoc : public CDocument{protected: // create from serialization only CSerialDateDoc(); DECLARE_DYNCREATE(CSerialDateDoc)// Attributespublic: Date date;}
5. 编辑菜单中添加子菜单项,ID_EDIT_MODIFY,消息映射到SerialDateDoc.cpp文件中的OnEditModify()函数
6. 在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<<date.m_nYear <<date.m_nMonth <<date.m_nDay ; } else { 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);//关闭窗口时提示存盘}
7. 修改SerialDateView.cpp中的OnDraw代码
void CSerialDateView::OnDraw(CDC* pDC){ CSerialDateDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CString str; str.Format(_T("Year:%d"), pDoc->date.m_nYear); pDC->TextOut(20,20,str); str.Format(_T("Month:%d"), pDoc->date.m_nMonth); pDC->TextOut(20,40,str); str.Format(_T("Day:%d"), pDoc->date.m_nDay); pDC->TextOut(20,60,str);}整理自百度文库。
- MFC单文档应用程序问题
- MFC SDI单文档应用程序贴图
- MFC单文档应用程序显示图像
- 1.4 单文档MFC应用程序实例
- C++ MFC / VS2013 之一 单文档应用程序
- MFC应用程序类型:单文档、多文档与基于对话框
- 基于MFC的单文档,多文档,对话框应用程序
- 【MFC】应用程序类型:单文档、多文档与基于对话框
- 创建无边框的MFC单文档应用程序
- MFC单文档应用程序默认打开一个文件
- MFC 为单文档应用程序制作动态图标
- 利用MFC向导生成单文档应用程序框架
- 建立Office2007风格的MFC单文档应用程序
- 创建一个单文档MFC应用程序的那些事儿
- CSplitterWnd类分割MFC单文档应用程序窗口
- 利用MFC向导生成单文档应用程序框架
- 创建无边框的MFC单文档(SDI)应用程序
- MFC 单文档应用程序如何在状态栏显示时间
- java method TestJava4_9 方法的参数与返回值
- 结构体字节对齐和位域对齐——VC、gcc
- js 对象 与 json之间的相互转化
- How to Build and Run Android NDK Examples?
- UIScrollView的delaysContentTouches与canCencelContentTouches属性
- MFC单文档应用程序问题
- POI颜色类型
- 一道算法题
- Android5.0的ApiDemo
- CLASS class DEFINITION { DEFERRED [PUBLIC]} | LOAD
- nginx虚拟主机+php修改open_basedir
- 回文数
- 其他问题现在百度越来越看重域名年龄了是不是
- 启动图片