
第2章文档/视图结构应用程序
1. 文档/视图结构的思想是将数据的管理与显示分离,其中文档用于管理应用程序的数据,而视图是用户界面,用于显示、打印文档中的数据,并管理与用户的交互。
2. SDI具有文档/视图结构的应用程序框架,该框架包括应用程序类、窗口框架类、文档类和视图类,编程的任务是在文档类和视图类中添加适当的代码。其中文档类中一个重要的成员函数是OnNewDocument(),用户在此添加代码完成对数据的初始化;而视图类中最重要的成员函数是OnDraw(),通过在该函数中添加代码实现窗口内容的输出。
3. 通过介绍几种SDI结构的典型应用程序来了解其结构及设计方法,典型应用包括:
?利用画笔、画刷等工具及位图处理的方法实现文字和图形的输出。
?利用定时器控件制作动画程序。
?对鼠标和键盘进行编程的基本方法。
?文件、字体、颜色等几种通用对话框的使用方法及自定义对话框的设计、调用方法。
?菜单的设计方法。
2.1 文档/视图结构
SDI 应用程序由AppWizard 创建好后,即使没有编写一行代码,仍然可以运行,并且具有一个标准Windows应用程序所需要的组成成份,程序员的工作就是往这个框架添加必要的代码。以下通过一个简单实例说明文档/视图结构应用程序的创建过程。
【例2.1】创建一个如图所示的应用程序,在窗口中显示一个矩形框,框中显示“同舟共济自强不息”。
假定本例的工程名为TEST ,程序创建过程如下:
(1)利用AppWizard 创建一个SDI 应用程序框架。
(2)文档类是存放数据的主要地方,本例在其中说明一个存放矩形框数据的CRect 类对象r 和一个存放字符串的CString 对象s ,方法为:
1
在工作区的“ClassView ”中,双击CTESTDoc 类,在该类代码中添加如下代码:public:
CRect r;
CString s;
说明:
CRect 是MFC 定义的一个类,有4 个数据成员:left 、top 、right 和bottom 。(left, top) 和(right, bottom )分别表示一个矩形左上角坐标和右下角坐标。
(3)在文档类的成员函数OnNewDocument() 中完成数据成员的初始化。方法为:在工作区的ClassView 中展开CTESTDoc 类,找到其成员函数OnNewDocument() ,在其中添加代码:
BOOL CTESTDoc::OnNewDocument()
{ if (!Cdocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
r=CRect(100,60,260,100);
s=”同舟共济自强不息”;
return TRUE;
} 说明:阴影部分为添加的代码。
(4)在工作区的“Class View ”中展开视图类CTESTView 类,找到其成员函数OnDraw() ,添加输出矩形框和文字的代码:
void CTESTView::OnDraw(CDC* pDC)
{ CTESTDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
pDC->Rectangle(pDoc->r);
pDC->TextOut(110,70,pDoc->s);
}
说明:
①GetDocument() 是视图类的一个重要成员函数,其返回值是指向当前文档的指针。视图类中的成员函数通过它访问文档类的公有数据成员。
②函数OnDraw() 是实现输出的关键函数,绝大多数的显示工作都是在这个函数中完成的。其参数pDC 指向窗口中央的客户区对象,程序使用了客户区对象的Rectangle 和TextOut 函数绘制矩形和输出文字。
( 5 ) 运行程序,结果如图所示。
(一)SDI 应用程序框架
1.应用程序类
每个应用程序类必须从CWinApp 派生出自己的应用程序类,该类封装了包括初始化、运行和结束的整个过程,其名称是AppWizard 根据工程名称自动命名的,规则如下:(1)如果工程名符合标识符的命名规则,则应用程序类名由字母C 、工程名和App 三部分组成。例如,工程名为TEST ,则应用程序类名为CTESTApp 。
(2)如果工程名以数字开始,则应用程序类名由字母Cmy 、工程名和App 三部分组成。例如,工程名为1TEST ,则应用程序类名为CMy1TESTApp 。
2
(3)忽略工程名的汉字。
文档类和视图类的命名规则与应用程序类类似,区别在于在后面分别添加了Doc 和View 。
2.窗口框架类
从CMainWnd 派生,提供了一个SDI 窗口的所有功能,如显示一个标题、一个菜单栏、一个工具栏等。所有SDI 应用程序窗口框架类都是CMainFrame ,但是性质是有区别的。
3.文档类
从CDocument 类派生出来,是应用程序进行数据定义和初始化的地方。文档类的数据成员只有被说明成公有成员才能被视图类中的成员函数访问,其重要成员函数是OnNewDocument() ,是进行数据成员初始化的地方。程序开始时会自动调用该函数。
4.视图类
从CView 中派生出来,是程序的用户界面,用于显示、打印存储在文档类对象中的数据,并管理与用户的交互。重要成员函数有:
(1)GetDocument() 函数
该函数的返回值是指向与当前视图相关联的文档对象的指针,因而通过它可以访问文档类对象中的公有私有成员。其一般使用形式为:
CTESTDoc* pDoc = GetDocument();
说明:
①在不同的应用程序中,pDoc 所指向的文档类对象的名称是不一样的。若工程名称为TEST ,则文档类的名称为CTESTDoc ,若工程名为ABC ,则文档类名为CABCDoc ,则应用CABCDoc* pDoc 定义。
②在OnDraw函数中,这个语句是自动生成的。在用户自定义的视图类成员函数中,如果需要访问文档类对象的公有数据成员,则应添加这样的语句。
(2)OnDraw() 函数
在视图类中,OnDraw() 是一个很重要的成员函数,用于实现输出。一般来说,窗口中的内容都是OnDraw() 输出的。
初始的OnDraw()函数如下:
void CTESTView::OnDraw(CDC* pDC)
{ CTESTDoc* pDoc = GetDocument(); // 获得指向文档类对象的指针
ASSERT_VALID(pDoc); // 检查pDoc 是否有效,若无效结束程序
// TODO: add draw code for native data here
}
说明:
OnDraw()函数有两种调方法:
①自动调用:当窗口发生变化视图需要重新绘制时,应用程序会自动调用该函数。
②手工调用:当程序中的数据改变了需要重新显示时,可以通过调用Invalidate() 和InvalidateRect() 函数,引发对Ondraw() 的调用。需要注意的是,不是直接调用Ondraw()函数。
Invalidate(TRUE) // 擦除窗口原有的内容,重新绘制。
Invalidate(FALSE) // 窗口原有的内容保留,再进行绘制。
InvalidateRect( 矩形, TRUE) // 擦除矩形区域内原有内容,重新绘制这个区域。
InvalidateRect( 矩形, FALSE) // 矩形区域内原有内容保留,再绘制这个区域。
3
2.2 图形和文字的输出
窗口中央的客户区是一个输出文字和图形的区域。
简单的文字和图形输出
文字输出
形式:
BOOL TextOut(int x, int y, LPCTSTR lpszString, int nCount);
说明:
从坐标(x,y) 开始显示lpszString 字符串,其中参数nCount 指定字符串中的字节数。
画点
形式:
COLORREF SetPixel(int x, int y, COLORREF crColor);
COLORREF SetPixel(POINT point, COLORREF crColor);
说明:
①POINT 是MFC 定义的结构类型,表示平面上的一个点。它的两个重要元素是x
和y ,分别表示一个点的x 坐标值和y 坐标值。与POINT 类似的是CPoint 类,两个
数据成员也是x 和y 。
②COLORREF 是一个32 位整数类型,用于表示颜色,其第0 、1 、2 字节分别
存放了一种颜色的红、绿、蓝的值。用三种颜色合成一种颜色的函数是RGB ,例如:
COLORREF C1=RGB(0, 0, 0) ;// 合成黑色
COLORREF C2=RGB(255, 255, 255); // 合成白色
COLORREF C3=RGB(255, 0, 0); // 合成红色
COLORREF C4=RGB(0, 255, 0); // 合成绿色
COLORREF C5=RGB(0, 0,255); // 合成蓝色
COLORREF C6=RGB(255, 255, 0); // 合成亮黄色
COLORREF C7=RGB(0,255, 255); // 合成青色
COLORREF C8=RGB(255, 0, 255); // 合成品红色
COLORREF C9=RGB(0, 0,128); // 合成深蓝色
COLORREF C10=RGB(0, 128, 0); // 合成深绿色
COLORREF C11=RGB(128, 128, 128); // 合成深灰色
COLORREF C12=RGB(128, 128, 128); // 合成浅灰色
③使用指定颜色crColor 在坐标(x,y) 或点point 处画一个点,返回用于画点的颜色。
画线
画线需要调用两个函数:首先调用MoveTo 函数确定线段的起点,然是调用LineTo 确
定线段的终点。
形式:
CPoint MoveTo(int x,int y);
CPoint MoveTo(POINT point);
BOOL LineTo(int x, int y);
BOOL LineTo(POINT point);
说明:(x,y)或point 是线段的起点或终点坐标。
画矩形
4
形式:
BOOL Rectangle(int x1, int y1, int x2, int y2);
BOOL Rectangle(LPCRECT lpRect);
说明:(x1,y1) 和(x2,y2) 是所画矩形的左上角和右下角坐标, lpRect 是指向矩形的指针。
画椭圆
形式:
BOOL Ellipse(int x1, int y1, int x2, int y2);
BOOL Ellipse(LPCRECT lpRect);
说明:
(x1,y1) 和(x2,y2) 是椭圆外接矩形的左上角和右下角坐标, lpRect 是指向外接矩形的指针。
获取客户区的大小
使用Wnd 类的成员函数GetClientRect 可以将客户区的坐标放入一个CRect 类的对
象中,然后调用成员函数计算到高度和宽度。
形式:
void GetClientRect( LPRECT lpRect ) const;
【例2.2】改变窗口时,矩形框和文字总是显示在窗口的中央
void CTESTView::OnDraw(CDC* pDC)
{
CTESTDoc* pDoc = GetDocument();
百度搜索“70edu”或“70教育网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,70教育网,提供经典行业范文MFC编程基础 2 文档_视图结构应用程序在线全文阅读。
相关推荐: