VC++6.0入门【第五章 图形和文本输出】.doc_第1页
VC++6.0入门【第五章 图形和文本输出】.doc_第2页
VC++6.0入门【第五章 图形和文本输出】.doc_第3页
VC++6.0入门【第五章 图形和文本输出】.doc_第4页
VC++6.0入门【第五章 图形和文本输出】.doc_第5页
免费预览已结束,剩余28页可下载查看

下载本文档

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

文档简介

第5章 图形与文本输出第5章 图形和文本输出精讲Windows使用图形设备接口(GDI)进行图形输出和文本输出,MFC封装了GDI对象,提供了CGdiObject类和CDC类支持图形输出和文本输出,本章你将学习使用CGdiObject类和CDC类在视图中输出各种图形和文本的方法和技巧。5.1图形设备接口和CDC5.1.1图形设备接口(GDI)Windows操作系统通过图形设备接口,简称GDI (Graphics Device Interface),管理Windows程序的所有图形输出,包括显示在屏幕上的窗口,屏幕保护程序的运行,文档的打印。GDI处理与不同输出设备的连接,从而应用程序开发者不需要去考虑基础硬件设备之间的不同。应用程序可以使用GDI创建3种类型的图形输出:矢量图形、光栅图形和文本。1 矢量图形矢量图形输出是指创建线和填充图形,包括点、直线、曲线、多边形、扇形和矩形。2 光栅图形光栅图形输出是指光栅图形函数对以位图形式存储的数据进行操作,它包括各种位图和图标的输出。在屏幕上表现为对若干行和列的像素操作,在打印机上则是若干行和列的点阵输出。光栅图形是直接从内存到显存的拷贝操作,所以速度快,但是对内存要求高。3 文本文本输出是GDI的另一项任务。输出文本时文本的输出位置的计算不是以行为单位,而是以逻辑坐标为单位计算。用户可以设置文本的各种效果,如加粗、斜体、设置颜色等。MFC处理图形输出是通过设备上下文CDC类和图形对象CGdiObject类来完成的。5.1.2 绘图工具GDI对象CGdiObjectCGdiObject是MFC提供绘图工具的类,它的派生类包括画笔(CPen)、画刷(CBrush)、字体(CFont)、位图(CBitmap)、调色板(CPalette)、区域(CRgn)等,它们的继承关系如图5-1所示。图5-1 CGdiObject类的构成各个派生类的任务是:1 画笔(CPen)封装GDI画笔,用于绘制对象的边框以及直线和曲线。默认画笔用于绘制与一个像素等宽的黑色实线。2 画刷(CBrush)封装GDI画刷。画刷是用来填充一个封闭的图形对象(如矩形,圆形)的内部区域。默认的画刷颜色是白色。3 字体(CFont)封装GDI字体对象,用户可以建立一种GDI字体,并使用CFont的成员函数来访问它。主要影响文本输出的效果,包括文字的大小、是否加粗、是否斜体、是否加下划线等。4 位图(CBitmap)封装GDI位图,提供成员函数装载和位图操作,位图可以用于填充区域。5 调色板(CPalette)封装GDI调色板,保存系统可用的色彩信息,是应用程序和彩色输出设备上下文的接口。6 区域(CRgn)封装GDI区域。区域是窗口内的一块多边形或椭圆形区域。CRgn用于设备上下文(通常是窗口)内的区域操作。CRgn通常与CDC类中与裁剪(clipping)有关的成员函数配合使用。5.1.3设备描述表(DC)设备上下文(Device Context),简称DC,是由GDI创建用来代表设备连接的数据结构。DC的主要功能有:(1) 允许应用程序使用一个输出设备。(2) 提供窗口应用程序,设备驱动,和输出设备之间的连接。(3) 保存当前信息,例如在一个窗口内绘图使用的颜色,画笔的宽度、画刷的类型等等。(4) 保存窗口剪取区域(clipping region),限制程序输出到输出设备中窗口覆盖的区域。5.1.4设备上下文类(CDC)MFC封装了DC,提供CDC类及它的子类访问GDI,如图5-2所示,各类作用介绍如下。CObjectCDCCClientDCCMetaFileDCCPanitDCCWindowDC图5-2 CDC及子类1 CDC类封装了所有图形输出函数,包含了一个DC的创建和初始化,及通用GDI对象的操作,包括画简单图形(如线、矩形、椭圆)和复杂的功能(如区域、位图、剪切区域)的操作。CDC类的适应范围最广,不仅能支持窗口,还能支持打印机。2 ClientDC类CClientDC又名客户区设备上下文,用于客户区的输出,一般在响应非窗口消息并对客户区绘图时要用到该类,例如在鼠标双击时要输出文本等。3 CPaintDCCPaintDC用于响应窗口重绘消息(WM_PAINT)的绘图输出,不仅可对客户区进行操作,还可以对非客户区进行操作。4 CWindowDCCWindowDC用于窗口客户区和非客户区(包括窗口边框、标题栏、控制按钮等)的绘制,除非要自己绘制窗口的边框和按钮,否则一般不用它。5 CMetaFileDCCMetaFileDC专门用于图元文件的绘制。图元文件记录一组GDI操作命令,可以通过这一组GDI命令重建图形输出。使用CMetaFileDC时,所有的图形输出命令会自动记录到一个与CMetaFileDC相关的图元文件中。5.1.5 OnDraw函数当用AppWizard创建单文档或多文档应用程序时,视图类包含成员函数OnDraw()函数,CDC指针被传递给OnDraw()函数,下面的程序清单5-1显示了在视图窗口中输出一行文本的一个简单的OnDraw()函数。程序清单5-1:用于输出的OnDraw()函数void CExam5View:OnDraw(CDC* pDC)CExam5Doc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data here pDC-TextOut(1,1,”hello world!”);当视图窗口或窗口的一部分需要重绘时,系统会发给窗口一个WM_PAINT消息,MFC的窗口框架会将该消息映射到CWnd:OnPaint()函数,OnPaint()函数创建一个DC,并调用视图的OnDraw() 函数。5.1.6 WM_PAINTWM_PAINT消息是最重要的绘图消息,它要求窗口重新绘制内容。产生WM_PAINT消息的场合通常有:(1) 窗口移动后及最大化,最小化后的刷新。(2) 被覆盖区域的刷新,如下拉菜单覆盖的区域。(3) 无效区域产生后的刷新,如执行滚动条操作,将一区域移动至不可见。有时数据发生变化时,需要人为生成一个绘制消息,重绘窗口,可以调用几个CWnd的函数。表5-1 产生绘制消息的函数函数举例说 明Invalidate(TRUE);此函数声明整个客户区无效CRect Rect(1,1,300,300)InvalidateRect(&Rect, TRUE)此函数声明选定的区域无效,这样可以减少因重绘而产生的屏幕闪烁5.1.7 获取设备上下文(DC)绘图前必须准备好设备上下文(DC),在一个MFC应用程序获得DC的常用方法有两种:一种是接受一个参数为指向CDC对象的指针,另一种是构造CClientDC对象。一些消息处理函数可以通过参数接受指向CDC对象的指针,如OnDraw()函数。程序清单5-2:用于输出一个黑点的OnDraw()函数void CExam5View:OnDraw(CDC* pDC)CExam5Doc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data here /在坐标为10,10的位置上画一点,颜色为黑色 pDC-SetPixel(CPoint(10,10),RGB(0,0,0); 也可以使用CClientDC类创建一个局部DC对象,例如,在键盘响应消息处理函数和鼠标响应消息处理函数中要进行文本输出或图形绘制时,通常要创建一个这样的对象,并使用this指针为该对象赋值。程序清单5-3:在鼠标点击画一红点的鼠标左键单击消息处理函数void CExam5View:OnLButtonDown(UNIT nFlags,CPoint point)/ TODO: add draw code for native data hereCClientDC dc(this); /this 指针将CExam5View赋值给创建的dc对象 dc.SetPixel(point,RGB(255,0,0);CView: OnLButtonDown( nFlags,point);5.1.8 编程实例【例5-1】编写一个单文档MFC(EXE)程序Exam5_1,在视图类增加成员变量,追踪鼠标左键双击的最新坐标,并输出坐标信息,运行效果如图5-3所示。图5-3 实例Exam5_1运行效果1 使用AppWizard创建一个单文档MFC(EXE程序)2 为视图类增加成员变量记录坐标并初始化(1) 选择WorkSpace的ClassView标签,右键单击CExam5_1View类。在弹出的快捷菜单中选择Add Member Variable菜单项,增加CPoint类的公有成员变量m_LPoint。 (2) 在CExam5_1View类的构造函数CExam5_1View()中,初始化变量m_LPoint为0,0。如程序清单5-4所示。程序清单5-4:CPoint类型对象引用CExam5_1View:CExam5_1View()/ TODO: add construction code here m_LPoint.x=0;m_LPoint.y=0;3 在OnDraw()函数中添加代码,在第一行输出成员变量的值。如程序清单5-5粗体部分所示。程序清单5-5:在视图中输出整型数据的OnDraw()函数void CExam5_1View:OnDraw(CDC* pDC)CExam5_1Doc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data hereCString str;str.Format(“鼠标左键双击的位置是%d,%d”,m_LPoint.x,m_LPoint.y); pDC-TextOut(0,0,str);4 在视图类增加鼠标左键双击的消息映射,修改成员变量,更新视图(1) 打开ClassWizard,选择Message Map标签,Class Name列表中选择CExam5_1View,Object IDS列表中选择CExam5_1View,Messages列表中选择WM_LBUTTONDBLCLK,单击“Add Function”按钮,添加鼠标左键双击消息映射。(2) 单击“Edit Code”按钮,添加处理代码,用当前鼠标位置Point值替换m_LPoint的值,并设置无效区域,刷新视图。程序清单5-6:产生重绘消息的鼠标消息处理函数void CExam5_1View: OnLButtonDblClk(UINT nFlags, CPoint point)/ TODO: Add your message handler code here and/or call defaultm_LPoint=point;Invalidate(TRUE);CView:OnLButtonDblClk(nFlags, point);5 编译、链接、执行,可得到如图5-3所示的结果5.2 处理文本在窗口应用程序中经常使用GDI处理文本输出,文本的输出过程包括文本的属性设置、字体设置、文本格式化、调用文本输出函数输出文本等具体的过程,下面将分别讲述。5.2.1设置文本颜色在窗口操作系统中采用32位来表示颜色,MFC和SDK采用COLORREF数据结构表示颜色,COLORREF的结构如图5-4所示,采用8位(值域范围为0-255)分别表示红、蓝、绿三色。定义颜色的最简单的方法是使用RGB()宏,它采用三个参数,用0-255的值来表示红色、蓝色、绿色。同样使用宏GetRValue(),GetGValue(),GetBValue()可以从一个COLORREF类型的变量中分离三元色。.图5-4 颜色的表示常用设备颜色清单/基本三元色COLORREF crRed=RGB(255,0,0);COLORREF crGreen=RGB(0,255,0);COLORREF crBlue=RGB(0,0,255)/ 16-color设备支持颜色const COLORREF g_crBlack = RGB(0,0,0);const COLORREF g_crYellow = RGB(255,255,0);const COLORREF g_crDkYellow = RGB128,128,0);const COLORREF g_crRed = RGB(255,0,0);const COLORREF g_ crDkRed = RGB(128,0,0);const COLORREF g_crMagenta = RGB(255,0,255);const COLORREF g_ crDkMagenta = RGB128,0,128);const COLORREF g_crBlue= RGB(0,0,255);const COLORREF g_ crDkBlue = RGB(0,0,128);const COLORREF g_crCyan = RGB(0,255,255);const COLORREF g_ crDkCyan = RGB(0,128,128);const COLORREF g_crGreen = RGB(0,255,0);const COLORREF g_ crDkGreen = RGB(0,128,0);const COLORREF g_crGray = RGB(192,192, 192);const COLORREF g_ crDkGray = RGB(128, 128, 128);const COLORREF g_crWhite = RGB(255,255,255);/ 256色设备支持的颜色举例const COLORREF g_crLtYellow = RGB(255,251,240);const COLORREF g_crLtGreen = RGB(192,220,192);const COLORREF g_crLtBlue = RGB(166,202,240);const COLORREF g_crMedGreen = RGB(160,160,164);设置颜色的场合有设置文本颜色、设置画笔和画刷的颜色。设置画笔和画刷的颜色的方法我们将在介绍GDI对象时讲述,设置文本颜色包括设置前景色和背景色。(1) 为了设置在绘制文本的前景像素时使用的颜色,调用CDC:SetTextColor(),函数定义如下:COLORREF SetTextColor(COLORREF crColor);(2) 为了设置在绘制文本的背景像素时使用的颜色,调用CDC:SetBkColor(),函数定义如下:COLORREF SetBkColor(COLORREF crColor);对Exam5_1程序增加实现产生黑色背景,红色文本的视图。程序清单见下面粗体部分:程序清单5-7:在视图中设置颜色的OnDraw()函数void CExam5_1View:OnDraw(CDC* pDC)CExam5_1Doc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data herepDC-SetTextColor (RGB(255,0,0);pDC-SetBkColor (RGB(0,0,0);CString str; str.Format(鼠标左键双击的位置是%d,%d,m_LPoint.x, m_LPoint.y); pDC-TextOut(0,0,str);5.2.2设置文本显示属性 CDC还提供了设置文本显示属性的函数,下表5-2列出了三组控制文本的显示属性常用函数:表5-2 文本属性设置函数函 数说 明SetBkMode和GetBkMode设置和获得背景模式SetTextAlign和GetTextAlign设置和获得对齐方式SetTextJusttification SetTextCharaterExtra调整文本文本背景模式的默认设置是OPAQUE,它要求GDI用户要使用背景颜色,可替换设置为TRANSPARENT,要求GDI用户在绘制文本时,不要使用背景色,函数的格式:int CDC:SetBkMode ( int nBkMode );SetBkMode()函数返回先前的背景模式,nBkMode表示背景模式,只有两种:OPAQUE和TRANSPARENT。int CDC:GetBkMode ( ) const;GetBkMode()函数返回当前使用的背景模式。文本对齐描述了(x,y)文本坐标和文本框之间的关系。默认设置将文本与文本坐标右下方对齐。可使用SetTextAlign函数设置文本对齐,函数格式:UINT SetTextAlign ( UINT nFlags );nFlag 为表5-3中列出的标志的组合,各栏中的标志之间相互排斥,只能从一栏中取一种标志,第一行为系统的默认设置值,例如:pDC-SetTextAlign(TA_RIGHT|TA_TOP);表5-3文本对齐风格X轴对齐Y轴对齐更新当前位置TA_LEFTTA_TOPTA_NOUPSATECPTA_CENTERTA_BASELINETA_UPDATECPTA_RIGHTTA_BOTTOM如果准备将不同字体,不同字号的文本混合在一行,使用y轴默认设置TA_TOP将产生奇怪的现象,这时应该更改y轴默认设置为 TA_BOTTOM。SetTextJusttification()和SetTextCharaterExtra()函数用于设置文本属性:文本调整和文本额外间隔。这两种属性能够帮助填补文本行。填补文本行是为了生成WYSIWYG(所见即所得)输出。在大多数情况下,它意味着显示屏幕输出变形,以模仿打印输出的效果。 SetTextJusttification()函数能够指定添加到各个间隔字符的像素数,如果需要更多地填充,则应调用SetTextCharaterExtra()函数,将额外的像素添加到各个字符(而不是间隔字符)。5.2.3 设置字体字体是一组复杂的图形图像,大小和设计都是统一的,用于表示字符数据。字体通常由磅值、名称和风格标识的,如8磅粗体Arial这样的风格。处理字体的最简单的方法是使用GDI的常备字体,如要自己设置显示字体的风格需要创建一个CFont的对象,具体步骤如下:1 定义CFont对象2 调用CreateFont()函数创建字体3 将创建的字体对象选入DC,并保存前一个被选入DC的字体对象CreateFont()函数包括大量参数,具体解释如下:(1) 格式:BOOL CreateFont( int nHeight, /字体所需高度,为0使用默认值int nWidth, /字符的宽度值,为0表示设备的纵横比匹配可用字体的纵横比int nEscapement, /字体转义,指定转义矢量和x轴的夹角int nOrientation, /字体方向,指定字符基线和x轴的夹角(以0.1度为单位)int nWeight, /字体厚度BYTE bItalic,/是否斜体,布尔值BYTE bUnderline, /是否带有下划线,布尔值BYTE cStrikeOut, /是否带有删除线,布尔值BYTE nCharSet, /使用的字符集BYTE nOutPrecision, /输出精度BYTE nClipPrecision, /剪取精度BYTE nQuality, /输出质量BYTE nPitchAndFamily, /字符间距和字族LPCTSTR lpszFacename /字体的字样名称);(2) 返回值:如果成功,返回非0值;失败,返回0值。(3) 参数:nWeight 字体厚度常用参数有:FW_NORMAL、FW_REGULAR和FW_BOLDnCharSet 字符集常用参数有:ANSI_SHARSET、DEFAULT_CHARSET、SYBOL_CHARSET、SHIFTJIS_CHARSET、OEM_CHARSET等nOutPrecision 输出精确度定义。输出与请求使用的字体的高度、宽度、字符走向、转义和字间距的匹配程度,常用参数有:OUT_CHARACTER_PRECIS、 OUT_STRING_PRECIS、OUT_DEFAULT_PRECIS、OUT_DEVICE_PRECIS等等。nClipPrecision 剪取精度定义。如何剪取部分位于剪取区域之外的字符,常用参数有:CLIP_CHARACTER_PRECIS、 CLIP_DEFAULT_PRECIS、CLIP_MASK。nQuality 字体的输出质量定义。GDI怎样才能将逻辑字体属性与实际物理字体匹配起来,常用参数值:DEFAULT_QUALITY、DRAFT_QUALITY和PROOF_QUALITY。 nPitchAndFamily 通常是字符间距与字族的组合值,如:DEFAULT_PITCH|FF_DONTCARE 下面通过实例显示字体对象的创建和使用。运行效果如图5-5所示:图5-5 设置字体效果程序清单5-8:在视图中创建并使用字体对象的OnDraw()函数void CExam5View:OnDraw(CDC* pDC)CExam5Doc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data here CFont NewFont;NewFont.CreateFont (65,65,0,0,FW_DONTCARE,true,false,false,DEFAULT_CHARSET,OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,黑体);CFont *pOldFont;pOldFont=pDC-SelectObject (&NewFont);pDC-TextOut(10,10, 倾斜的黑体字); 5.2.4 格式化文本Windows系统不参与窗口客户区的管理,这就意味着在客户区内输出文本,应用程序必须管理换行,后继字符的位置等输出格式。由于文本字符串的间隔不仅取决于由用户指定的字体,而且取决于目标设备的分辨率,因此在绘制任何文本之前,需要计算文本坐标。CDC类提供了如下表所示的文本测量函数。表5-4 文本测量函数函 数说 明GetTextExtent当选用当前嵌入DC中的字体绘图时,获得给定字符串将占据的空间宽度和高度GetTextMetrics为当前选入DC的字体获取类型为TEXTMETRIC的数据,此数据结构中包含基本的字体测量信息字体测量函数的使用的场合通常有:1 确定后继文本坐标在很多场合单行文本需要分离成多次输出,即多次调用TextOut()。例如在蓝色文本的后边显示红色文本,或者是在同一行文本上使用字体。这时需要计算下一个字符串的位置,使用GetTextExtent()函数可以获得所选字体中的字符串的宽度和高度,函数的格式如下:CSize GetTextExtent(LPCTSTR lpszString, int nCount) 其中:lpszString是字符串的指针,nCount是所包括的字符数。返回值CSize是包含两个成员的结构:cx是字符串的宽度,cy是字符串的高度。下面给出了一个使用GetTextExtent()函数的实例。运行效果如图5-6所示,实现代码如程序清单5-9所示。其中GetLength()函数是CString类的成员函数,返回字符串的长度。图5-6 设置字体效果程序清单5-9:在视图中输出一行使用两种颜色的文本void CExam5View:OnDraw(CDC* pDC)CExam5Doc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data hereint x,y;x=150;y=100;CString strHello=Hello ; CString strVc= VC+ !; /输出第一个蓝色字符串pDC-SetTextColor (RGB(0,0,255);pDC-TextOut (x,y,strHello); /取得第一个字符串的像素长度CSize strSize=pDC-GetTextExtent (strHello,strHello.GetLength (); /设定第二个字符串的输出位置X坐标x+=strSize.cx;/ 输出第二个绿色字符串pDC-SetTextColor (RGB(0,255,0);pDC-TextOut (x,y,strVc);2 确定换行时文本坐标GetTextMetric()函数用来计算涉及确定两行文本之间的间隔。当然你可以使用GetTextExtent()函数的返回值中的字符串的高度来决定两行文本之间的间隔,但这种方式并不精确。文本中行之间的间隔包括两部分:字符单元高度和外部行距大小。这两部分内容都包含在TEXTMETRIC数据结构中。调用GetTextMetric()函数可以获得当前字体的TEXTMETRIC结构的内容,并计算文本行间隔方式如下:TEXTMETRIC tm;pDC-GetTextMetrics(&tm);int LineHeight=tm.tmHeight+tm.tmExternalLeading ;数据类型TEXTMETRIC的定义和图示如下: typedef struct tagTEXTMETRIC /* tm */ int tmHeight; int tmAscent; int tmDescent; int tmInternalLeading; int tmExternalLeading; int tmAveCharWidth; int tmMaxCharWidth; int tmWeight; BYTE tmItalic; BYTE tmUnderlined; BYTE tmStruckOut; 图5-7 字体结构图 BYTE tmFirstChar; BYTE tmLastChar; BYTE tmDefaultChar; BYTE tmBreakChar; BYTE tmPitchAndFamily; BYTE tmCharSet; int tmOverhang; int tmDigitizedAspectX; int tmDigitizedAspectY; TEXTMETRIC; 5.2.5 文本输出函数CDC提供了以下几个函数用于文本输出:表5-5文本输出函数函 数说 明TextOut在屏幕的固定位置用当前设定的颜色、字体、对齐方式输出文本TabbedTextOut与TextOut的功能相似,唯一差别是可以为支持制表符而定义一组制表站位置DrawText在一个区域中显示并格式化文本ExtTextOut与TextOut的功能相似,但可以使用该函数删去超出矩形的正文,用正文背景填充矩形,调整字符间隔 TextOut()是最常用的文本输出函数,它的格式:BOOL CDC:TextOut( int x, int y, const CString& str );其中:x,y 是输出位置的坐标,str 是要输出的文本串。在输出文本之前,应先设置输出文本串的颜色、字体及对齐方式。使用DrawText()函数可以在一个指定的区域中输出文本,并且可以在这个区域内进行水平和垂直方向的对齐方式的设置,还可以在一个词中间断开以适应矩形边界。它的格式如下:int CDC:DrawText ( const CString& str, LPRECT lpRect, UINT nFormat );函数正确执行后返回文本行的高度,str是输出的文本,lpRect是指定矩形输出区域,nFormat是格式常量。下面给出了一个使用 DrawText()的实例。程序清单5-10:在视图中使用DrawText在一个矩形区域中水平垂直居中,输出蓝色文本的OnDraw()函数void CExam5View:OnDraw(CDC* pDC)CExam5Doc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data herepDC-SetTextColor (RGB(0,0,255);CRect Rect;Rect.SetRect(100,100,300,300);pDC-Rectangle(Rect); pDC-DrawText (this is a sample of DrawText !, Rect, DT_CENTER| DT_VCENTER|DT_SINGLELINE); 执行效果如图5-8所示:图5-8 使用DrawText函数5.2.6 文本输出编程实例【例5-2】阅读单文档MFC(EXE)程序Exam5_2中处理文本显示的OnDraw()函数。程序执行效果如图5-9所示,请分析,输出的每一行文本串作了哪些文本属性设置、格式设置和字体设置。图5-9 文本处理实例程序清单5-11:在视图中处理文本的OnDraw()函数void CExam5_2View:OnDraw(CDC* pDC)CExam5_2Doc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data hereint y;int x;CString outstr4;outstr0=第一个紫红色的使用系统字体的文本串;outstr1=第二个黄色黑体文本串;outstr2=第三个蓝色文本串;outstr3=最后一个大号字,加下划线的斜体文本串;x=0;y=0;/输出第一行 pDC-SetTextColor (RGB(255,0,255); pDC-TextOut (x,y,outstr0);/输出第二行 TEXTMETRIC tm; pDC-GetTextMetrics (&tm); y=y+tm.tmHeight+100*tm.tmExternalLeading ; CFont NewFont1;NewFont1.CreateFont (30,10,0,0,FW_HEAVY, false,false,false,ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, 黑体);CFont *pOldFont;pOldFont=pDC-SelectObject (&NewFont1);pDC-SetTextColor(RGB(255,255,0);pDC-TextOut(x,y,outstr1); /输出第三个文本串 pDC-GetTextMetrics (&tm); pDC-SetTextColor (RGB(0,0,255); CSize strSize=pDC-GetTextExtent (outstr1,outstr1.GetLength (); x+=strSize.cx; pDC-TextOut (x,y,outstr2); / 输出第四个文本串 pDC-GetTextMetrics (&tm); x=0; y=y+tm.tmHeight+20*tm.tmExternalLeading ; CFont NewFont2;NewFont2.CreateFont (30,0,0,0,FW_NORMAL, true,true,false,ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, 大号字);pDC-SelectObject (&NewFont2);pDC-SetTextColor(RGB(155,155,155);pDC-TextOut(x,y,outstr3); pDC-SelectObject (pOldFont);pDC-SelectObject (&NewFont2); pDC-SetTextColor(RGB(155,155,155); pDC-TextOut(x,y,outstr3); pDC-SelectObject (pOldFont);分析如表5-6所示:表5-6文本属性格式化字体文本串1红色默认字体文本串2绿色求下一行位置高度20,宽度10,粗体,黑体字文本串3蓝色求同行字符串尾部位置文本串4灰色求下一行位置高度30,斜体,下划线,大号字请注意pOldFont的使用,在第一次调用SelectObject()函数,函数返回老的字体设置,由CFont对象指针pOldFont接受,在OnDraw()函数的最后再使用SelectObject()是恢复原来的字体设置。5.3 处理绘图5.3.1 简单的图形输出CDC提供了基本的绘图操作函数,如画点,画线,画圆,画矩形,画多边形等等,简单介绍如下:1 点pDC-SetPixel(CPoint(200,200),RGB(255,0,0); /在200,200的位置画一个红点2 线pDC-MoveTo(0,0); /直线起点的坐标为(0,0)pDC-LineTo (100,100); /从起点(0,0)到终点(100,100)画一条直线pDC-MoveTo (0,100);pDC-LineTo (100,0);3 矩形CRect rect(0,0,100,100); /画一个长100,宽100的矩形pDC-Rectangle(&rect);4 圆和椭圆CRect rect(0,0,100,100); /在矩形内画圆pDC-Ellipse(&rect);CRect rect(0,0,50,100); /在矩形内画椭圆pDC-Ellipse(&rect);5 多边形CPoint poly4; /画一个平行四边形poly0=CPoint(0,0);poly1=CPoint(50,50);poly2=CPoint(50,100);poly3=CPoint(0,50);pDC-Polygon(poly,4);6 其它图形CDC:Pie / 画饼图CDC:Chord /画弦CDC:FillRect /用指定颜色填充矩形且不画边线CDC:Draw3DRect /用于绘制名种3D边框CDC:RoundRect /画圆角矩形绘图函数的具体的使用方法可以查阅MSDN。5.3.2 库存对象不管以CDC类指针形式还是以CDC子类对象形式获得设备上下对象,系统都默认指定了一组绘图属性,如表5-7所示。表5-7 系统默认绘图属性绘图属性默认值改变默认值的函数画笔一个像素宽的黑色实线SelectObject,SelectStockObject画刷白色的实心刷SelectObject,SelectStockObject背景颜色白色SetBKColor背景模式OPAQUESetBKMode刷子原点设备坐标(0,0)SetBrushOrg当前绘图位置逻辑坐标(0,0)MoveTo混合模式R2_COPYPENSetRop2映射模式MM_TEXTSetMapMode库存对象是由操作系统维护的用于绘制屏幕的常用对象,包括库存画笔、画刷、字体等。使用SelectStockObject()函数可以直接选择库存对象修改系统默认值。可直接选用的库存对象如表5-8所示。表5-8 系统默认绘图属性GDI分类库存对象值FontsANSI_FIXED_FONTANSI_VAR_FONTDEVICE_DEFAULT_FONTOEM_FIXED_FONTSYSTEM_FONTPensBLACK_PENWHITE_PENNULL_PENBrushsBLACK_BRUSHDKGRAY_BRUSHGRAY_BRUSHHOLLOW_BRUSHLTGRAY_BRUSHNULL_BRUSHWHITE_BRUSH下面的实例演示了如何使用库存对象:程序清单5-12:在视图中选用画笔和画刷库存对象画图的OnDraw()函数void CExam5View:OnDraw(CDC* pDC)CExam5Doc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data here CRect rect;rect.SetRect (CPoint(0,0),CPoint(200,200);pDC-SelectStockObject (WHITE_PEN); /选用白色画笔pDC-SelectStockObject (GRAY_BRUSH);/选用灰色画刷pDC-Rectangle (rect); pDC-MoveTo(0,0);pDC-LineTo (200,200);pDC-MoveTo (0,200);pDC-LineTo (200,0);演示效果如图5-10所示。图5-10 选用库存对象设置绘图属性5.3.3设置绘图坐标系首先要介绍逻辑坐标和设备坐标的概念,一般地说,如果要把一幅大小为400mm800mm的图画显示在500像素200像素的windows窗口中,前者称为逻辑坐标,后者称为设备坐标。它们的关系如图5-11所示:逻辑坐标设备坐标400mm800mm500像素200像素 图5-11 逻辑坐标与设备坐标设备坐标系的原点总是在窗口的左上角,它的单位是像素。而逻辑坐标系的单位有多种,可以

温馨提示

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

评论

0/150

提交评论