计算机软件工程基础课件,高等教育出版社,第.ppt_第1页
计算机软件工程基础课件,高等教育出版社,第.ppt_第2页
计算机软件工程基础课件,高等教育出版社,第.ppt_第3页
计算机软件工程基础课件,高等教育出版社,第.ppt_第4页
计算机软件工程基础课件,高等教育出版社,第.ppt_第5页
已阅读5页,还剩56页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第8章 图形设备接口,第8章 图形设备接口,8.1 图形设备接口介绍 8.2文本和字体 8.3 简单图形绘制 8.4 基础实例字体应用程序 8.5 提高实例绘图应用程序 8.6 本章小结 8.7 思考练习题,8.1 图形设备接口介绍,图形设备接口(graphics device interface,GDI)是Windows提供的一个支持图形编程处理的抽象接口。GDI作为Windows的一个组成部分,提供了各种各样的绘图工具。应用程序通过GDI与设备打交道,GDI通过不同设备提供的驱动程序将绘图语句转换为对应的绘图指令,避免了用户直接对硬件进行操作,从而实现设备无关性。所谓设备无关性,是指操作系统屏蔽了硬件设备的差异,使用户编程时不用过多考虑设备的类型,如不同种类的显示器或打印机等。,8.1.1设备环境类,Windows设备环境是GDI的关键元素,GDI作为一个编程接口,提供了大量的与设备无关的图形处理函数,这些函数定义在Windows的三个核心动态链接库之一的Gdi32.dll中,编程时可以通过调用GDI函数绘制不同形状、颜色和类型的图形。MFC对GDI函数和绘图对象进行了封装,因此可以更方便地利用MFC中有关图形处理的类进行图形绘制。,8.1.1设备环境类,图8-1说明了Windows应用程序绘图的过程。,8.1.1设备环境类,MFC提供的DC类包括CDC类、CPaintDC类、CClientDC类、CWindowDC类和CMetaFileDC类等,其中CDC类是MFC设备环境类的基类,其他的MFC设备环境类都是CDC类的派生类。下面对这几个类进行简要介绍。 1)CDC类 CDC类既可作为其他MFC设备环境类的基类,又可作为一般的设备环境类使用,8.1.1设备环境类,为创建新的CDC设备描述表对象必须调用构造函数CDC:CDC(),接着是初始化。 初始化有如下三种方法: CreateDC()为指定设备,创建设备描述表。如果DC已经创建,则CreateDC()方法返回True值,否则返回False。 CreateIC()为指定设备创建信息描述表以获取使用设备信息,而无需创建设备描述表。 CreateCompatibleDC()创建新存储设备描述表,它与现有 设备描述表兼容。,8.1.1设备环境类,2)CPaintDC类 CPaintDC类是OnPaint函数使用的设备环境类,它代表一个窗口的绘图画面,只在相应WM_PAINT消息的函数中使用,大多数情况是在OnPaint()函数中使用。当应用程序窗口出于某种原因需要更新时,系统会想应用程序发送WM_PAINT消息,从而调用OnPaint()函数。在CView类的成员函数OnPaint中就这样定义了一个设备环境。,8.1.1设备环境类,void CView:OnPaint() /定义一个设备环境 CPaintDC dc(this); OnPrepareDC( 由于基类CView的OnPaint函数调用了OnDraw函数,因此编程时经常在OnDraw函数中输出图形。,8.1.1设备环境类,3)CClientDC类 CClientDC类可能是使用最多的CDC的派生类,它代表了客户区设备环境,因此所有使用CClientDC类对象完成的绘图操作都位于窗口的客户区内。客户区是指程序窗口中不包括边框、标题栏、菜单栏、工具栏和状态栏等界面元素的内部绘图区。当在客户区绘图时,需要利用CClientDC类定义一个客户区设备环境。,8.1.1设备环境类,4)CWindowDC类 CWindowDC类代表了整个程序窗口设备环境,包括窗口边框、标题栏和菜单栏等非客户区和客户区,因此使用窗口设备环境可以在整个程序窗口内绘图。 5)CMetaFileDC类 CMetaFileDC类是用于创建一个Windows图元文件的设备环境。Windows图元文件包含了一系列GDI绘图命令,使用这些信息可以重复创建所需的图形或文本。,8.1.2 GDI对象,Windows GDI提供了一些绘图对象,这些GDI对象是Windows图形设备接口的抽象绘图工具,程序通过GDI对象来设置绘图的工具和风格。GDI对象包含画笔、画刷、字体、位图和调色板。,8.1.2 GDI对象,GDI类在MFC中的层次结构如图8-2所示。,8.1.2 GDI对象,MFC的CDC类提供了成员函数SelectObject,用于选择用户自己创建的GDI对象,该函数有多种重载形式,可以选择用户已定制好的画笔、画刷、字体和位图等不同类型的GDI对象。 访函数常用的重载形式如下所示: CPen* SelectObject(CPen* pPen); CBrush* SelectObjec(CBrush* pBrush); Virtual CFont* SelectObject(CFont* pFont); CBitmap* SelectObject(CBitmap* pBitmap);,8.1.2 GDI对象,上述函数的参数是一个指向用户已定制好的GDI对象的指针,选择操作成功时函数将返回以前GDI对象的指针,否则返回NULL。 MFC的CDC类还提供了成员函数DeleteObject,用于释放创建的GDI对象。使用方式如下: GdiObjectName.DeleteObject(); 其中GdiObjectName是用户将要释放的GDI对象的名称。,8.1.2 GDI对象,Windows GDI提供了一些绘图对象,这些GDI对象是Windows图形设备接口的抽象绘图工具,程序通过GDI对象来设置绘图的工具和风格。GDI对象包含画笔、画刷、字体、位图和调色板等。GDI对象类在MFC中的层次结构如图8-2所示。,MFC的CDC类提供了成员函数SelectObject,用于选择用户自己创建的GDI对象,该函数有多种重载形式,可以选择用户已定制好的画笔、画刷、字体和位图等不同类型的GDI对象。该函数常用的重载形式如下所示: CPen*SelectObject(CPen*pPen); CBrush*SelectObject(CBrush*pBrush); Virtual CFont*SelectObject(CFont*pFont); CBitmap*SelectObject(CBitmap*pBitmap);,1.使用GDI对象绘图 绘图工具的使用包括创建GDI对象、选择GDI对象、使用GDI对象绘图和使用后释放GDI对象等步骤。 (1)定义一个GDI对象(如CPen对象、CBrush对象),然后用相应的函数(如CreatePen()、CreateSolidBrush())创建此GDI对象。但要注意,有些GDI派生类的构造函数允许用户提供足够的信息,从而一步即可完成对象的创建任务,如CPen类、CBrush类。 (2)将构造的GDI对象选入当前设备环境中,并将原来的GDI对象保存起来。 (3)绘图结束后,恢复当前设备环境中原来的GDI对象。,注意:对于显示设备环境来说,在每个消息控制函数的入口处,设备环境都是未被初始化的,当函数退出之后,在该函数内部所进行的任何GDI选择都不再有效,因此,每次都必须从头开始设置设备环境。,2.库存的GDI对象 除了自定义的GDI对象外,Windows还包含了一些预定义的库存GDI对象。由于它们是Windows系统的一部分,因此用户不用删除它们。CDC的成员函数SelectStockObject可以把一个库存对象选入当前设备环境中,并返回原先被选中的对象指针,同时使原先被选中的对象从设备环境中分离出来。,函数SelectStockObject可选用的库存GDI对象类型可以是下列值之一: BLACK_BRUSH:黑色画刷。 DKGRAY_BRUSH:深灰色画刷。 GRAY_BRUSH:灰色画刷。 HOLLOW_BRUSH:中空画刷。 LTGRAY_BRUSH:浅灰色画刷。 NULL_BRUSH:空画刷。 WHITE_BRUSH:白色画刷。 BLACK_PEN:黑色画笔。 NULL_PEN:空画笔。 WHITE_PEN:白色画笔。 DEVICE_DEFAULT_FONT:设备的默认字体。 SYSTEM_FONT:系统字体。,画笔和画刷是GDI对象中最常用的两个绘图对象,它们在绘图时可以同时使用。其中,画笔用于设置画线的方式,包括点、直线和曲线以及封闭几何图形周围的边线(如矩形和椭圆等),而画刷用于设置封闭图形内部区域的绘制方式。 当然,绘图的最终效果不完全取决于画笔和画刷的设置,还可以通过设置绘图模式进行修正。CDC类的成员函数SetROP2()用于设置绘图模式,该函数声明如下: int SetRop2(int nDrawMode);,8.1.3 映射模式,映射模式确定了在绘制图形时所依据的坐标系,它定义了逻辑单位的实际大小、坐标增长方向。所有映射模式的坐标原点均在设备输出区域(如客户区或打印区)的左上角。此外,对于某些映射模式,用户还可以自定义窗口的长度和宽度,设置视图区的物理范围。,8.1.3 映射模式,可以使用CDC:SetMapMode函数更改映射模式,并使用CDC:SetViewportOrg和CDC:SetWindowOrg函数移动逻辑坐标系的原点。Windows支持8种映射模式.,表8-2 映射模式,8.1.3 映射模式,如果希望坐标系的原点在显示区域中央而不是左上角,可以使用CDCLSetWindowOrg或CDC:SetViewportOrg初始化一个名为Rect的CRect对象以及窗口工作区的设备坐标,并且DC表示工作区设备上下文,则下例将坐标的原点移动到工作区:,CRect rect; GetClientRect(rect); pDC-SetViewportOrg(rect.Width()/2,rect.Height()/2);,8.1.4 自定坐标系统,Windows为应用程序提供了两类坐标:设备坐标和逻辑坐标。 Win32 API和MFC都提供了屏幕坐标向窗口坐标和客户区坐标、窗口坐标和客户区坐标向屏幕坐标的坐标转换函数,它们的原型如下:,8.1.4 自定坐标系统,BOOL ClientToScreen(HWND hWnd,LPPOINT lpPoint); BOOL ScreenToClient(HWND hWnd,LPPOINT lpPoint); BOOL CWindow:ClientToScreen(LPPOINT lpPoint); BOOL CWindow:ClientToScreen(LPRECT lpRect); BOOL CWindow:ScreenToClient(LPPOINT lpPoint); BOOL CWindow:ScreenToClient(LPRECT lpRect); BOOL CWnd:ClientToScreen(LPPOINT lpPoint); BOOL CWnd:ClientToScreent(LPRECT lpRect); BOOL CWnd:ScreenToClient(LPPOINT lpPoint); BOOL CWnd:ScreenToClient(LPRECT lpRect);,8.1.4 自定坐标系统,Win32 API 和MFC都提供了逻辑坐标和设备坐标相互转换的函数,它们的原型如下: BOOL DPtoLP(HDC hdc,LPPOINT lpPoints,int nCount); BOOL LPtoDP(HDC hdc,LPPOINT lpPoints,int nCount); void CDC:DPtoLP(LPPOINT lpPoints,int nCount=1); void CDC:DPtoLP(LPRECT lpRect); void CDC:DPtoLP(LPSIZE lpSize); void CDC:LPtoDP(LPPOINT lpPoints,int nCount=1); void CDC:LPtoDP(LPRECT lpRect); void CDC:LPtoDP(LPSIZE lpSize);,8.2文本和字体,很多Windows应用程序都需要显示文本,并且文本还是一些应用程序的主要处理对象,如微软的字体处理软件Word。文本与字体密切相关,字体决定了输出文本的外观特性,合适的字体可以增强文本的表现力。Windows为文本的显示提供了多种字体支持,而在程序中用户可以创建不同风格的逻辑字体来输出文本。,8.2.1 将对象选入设备(DC),无论何时将一个非常备对象选入DC,都最好记入前一个被选入DC的对象。当使用SelectObject函数时,会得到一个指向对象的指针。例如,如果使用SelectObject函数把最新创建的字体选入DC,则返回指向CFont对象的指针。在选择非常备字体之前,可以记录被选入DC的字体,如下所示: CFont *pOldFont; pOldFont=pDC-SelectObject(,8.2.1 将对象选入设备(DC),当使用完非常备字体(或其他GDI对象)之后,必须将旧字体选回到DC中。如果说新创建的GDI对象在开发人员试图删除它(或对象的析构函数试图删除它)的时候,仍然在DC中,则删除失败;该GDI对象占用的内存被锁定,直至应用程序退出。以下是当使用完非常备GDI对象后,应该添加的最后一行代码: pDC-SelectObject(pOldFont);,8.2.1 将对象选入设备(DC),以下例子显示了如何获得一个常备字体: CFont fontStock; fontStock.CreateStockObject(ANSI_FIXED_FONT); 与其绘图属性一样,在字体影响输出外观之前, 必须被连接到DC上。为了将字体连接到DC上,应调用CDC:SelectObject函数。例如,以下代码将刚创建的字体连接到DC上: pDC-SelectObject(,8.2.1 将对象选入设备(DC),另外,还可以选择非常备字体,但为了选择一种常备字体以外的字体,必须向GDI提交字体请求。表示字体请求的一种方式是使用LOGFONT(逻辑字体)数据结构。为了将字体请求提交给GDI,开发人员要填写此数据结构,并将它传递到CFont的初始化函数CFont:CreateFontIndirect中。此函数名称中的“Indirect”指明函数带有一个指针参数。另一个初始化函数CFont:CreateFont带有一系列参数,这些参数合在一起,与LOGFONT匹配。,8.2.2 字体的属性和创建,字体的属性有很多,但主要有字样、风格和尺寸 3个。 字样是字符书写和显示时表现出的特定模式,例如,对于汉字,通常有宋体、楷体、仿宋、黑体、隶 书以及幼圆等多种字样。 字体风格主要表现为字体的粗细和是否倾斜等特点。GDI+为用户提供了一些预定义的字体风格: FontStyleBold(加粗) FontStyleRegular(正常) FontStyleItalic(斜体) FontStyleBoldItalic (粗斜体) FontStyleUnderline(下划线) FontStyleStrikeout(删除线)。,8.2.2 字体的属性和创建,下面代码说明了如何利用CreatePointFont函数创建自己的字体。 CClientDC dc(this); /获取设备环境 CFont fntNew,*pfntOld; fntNew.CreatePointFont(200,”Arial”, /删除自定义字体,8.2.2 字体的属性和创建,使用CreateFontIndirect()函数和LOGFONT结构创建字体的代码如下所示。 CFont font; LOGFONT LogFnt; memset(,8.2.4 输出文本,文本的最终输出不仅依赖于文本的字体,而且还和文本的颜色、对齐方式等有很大关系。CDC类提供了4个输出文本的成员函数: 1. TextOut( ) 2. DrawText( ) 3. ExtTextOut( ) 4. TabbedTextOut( ),8.2.4 输出文本,输出文本的具体实现方法是首先。建立一个SDI应用程序,然后在OnDraw()函数中添加如下代码: void COutfontView:OnDraw(CDC* pDC) COutfontDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); / TODO: add draw code for native data here CRect rc(10,10,200,140); pDC-Rectangle(rc); pDC-DrawText(“单行文本居中“,rc,DT_CENTER|DT_VCENTER|DT_SINGLELINE); /将矩形向右偏移200 rc.OffsetRect(200,0); pDC-Rectangle(rc); /将一个Tab位的值指定为40个逻辑单位,8.2.4 输出文本,int nTab=40; /使用自定义的停止位(Tab) pDC-TabbedTextOut(rc.left,rc.top,“绘制tTabt文本t示例“,1, ,8.2.4 输出文本,上述代码的运行结果如图8-3所示。,8.3 简单图形绘制,进行绘图除了需要作为画布用的设备环境,还需要使用一些绘图工具,这些绘图工具又统称为GDI对象。画笔(pen)和画刷(brush)是GDI中两种最重要的绘图工具,画笔用于绘制各种直线和曲线(包括几何图形的边线),画刷用于填充封闭几何图形的内部区域。在默认状态下,当用户获取一个设备环境并在其中绘图时,系统使用设备环境默认的绘图工具及其属性。如果要使用不同风格和颜色的绘图工具进行绘图,必须重新为设备环境设置自定义的画笔、画刷等绘图工具。,8.3.1 创建画笔,画笔是一个GDI对象,一般用于绘制直线和曲线以及描画图形轮廓。定义画笔涉及3个关键特性:风格、宽度和颜色。 创建GDI画笔的最简单方式是构造一个CPen对象,并给它传递定义画笔的参数。 创建GDI画笔的第2种方式是使用无参数的构造函数,然后调用CPen:CreatePen,CPen:CreatePenIndirect或者CPen:CreateStockObject函数来定义画笔的风格、宽度和颜色属性。,8.3.1 创建画笔,为了使基本画笔风格中至少有一种符合要求,CPen类还提供了一个单独的构造函数,用于支持各种不同风格选项的修饰和几何画笔。 LOGBRUSH LogBrush; LogBrush.lbStyle=BS_SOLID; LogBrush.lbColor=RGB(0,255,0); CPen Pen(PS_GEOMETRIC|PS_SOLID |PS_ENDCAP_FLAT|PS_JOIN_ROUND,16, ,8.3.1 创建画笔,通过将绘图命令放置到CDC:BeginPath函数和CDC:EndPath函数调用之间,即可定义一个路径. pDC-BeginPath(); pDC-MoveTo(0,0); pDC-LineTo(200,0); pDC-LineTo(200,200); pDC-LineTo(0,200); pDC-CloseFigure(); pDC-EndPath(); pDC-StrokePath();,8.3.2 创建画刷,画刷是用于创建实心图形和渲染文本的GDI对象,并由CBrush类进行了封装。画刷有3种基本变形:原色画刷、阴影画刷以及图案画刷。CBrush类为各种画刷风格提供了构造函数。通过将COLORREF值传递到CBrush构造函数中,可以进一步生成原色画刷,如下所示: CBrush Brush(RGB(255,0,0);,8.3.2 创建画刷,通过创建一个未初始化的CBrush对象并调用CBrush:CreateSolidBrush函数能够生成原色画刷, 通过将阴影索引以及COLORREF值传递给CBrush的构造函数,或者通过调用CBrush:CreateHatchBrushIndirect,可以创建阴影画刷。,8.3.2 创建画刷,Windows可以使用以下7种常备画刷: BLACK_BRUSH DKGRAY_BRUSH GRAY_BRUSH LTGRAY_BRUSH HOLLOW_BRUSH NULL_BRUSH WHITE_BRUSH,8.3.3 简单图形绘制,图形的绘制通常需要先创建画笔和画刷,然后调用CDC类的绘图函数。MFC为用户提供了许多函数,其中包括画点、线、矩形、多边形、圆弧、椭圆、扇形等。,8.3.3 简单图形绘制,1画点 画点是最基本的绘图操作之一,可以通过SetPixel或SetPixelV函数来实现。这两个函数都是用于在指定的坐标上设置指定的颜色,只不过SetPixelV函数不需要返回实际像素点的RGB值。 COLORREF SetPixel(int x,int y,COLORREF crColor); COLORREF SetPixel(POINT point,COLORREF crColor); BOOL SetPixelV(int x,int y,COLORREF crColor); BOOL SetPixelV(POINT point,COLORREF crColor);,8.3.3 简单图形绘制,2画线 LineTo函数正是经当前位置所在点为直线起始点,另指定直线终点画出一段直线的。其原型如下: BOOL LineTo(int x,int y); BOOL LineTo(POINT point); 如果当前要画的直线并不与上一条直线的终点相接,那么应该调用MoveTo函数来调整当前位置。此函数不但可以用于更新当前位置,而且还可以用于返回更新前的当前位置。其函数原形如下: CPoint MoveTo(int x,int y); CPoint MoveTo(POINT point);,8.3.3 简单图形绘制,3折线 主要有Polyline、PolyPolyline和PolylineTo 3个函数 BOOL Polyline(LPPOINT lpPoints,int nCount); BOOL PolylineTo(const POINT*lpPoints,int nCount); 这两个函数用于画一系列连续的折线。 BOOL PolyPolyline(const POINT * lpPoint,const DWORD * lpPolyPoints,int nCount); 此函数可用于绘制多条折线。其中lpPoints同前定义,lpPolyPoints表示各条折线所需的顶点数,nCount表示折线的数目。,8.3.3 简单图形绘制,4矩形和圆角矩形 Rectangle和RoundRect函数分别用于矩形和圆角矩形的绘制,它们的原型如下: BOOL Rectangle(int x1,int y

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论