版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第第7章章 图形、文本和位图图形、文本和位图7.1 概述概述Visual C+的的CDC(Device Context,设备环境,设备环境)类是类是MFC中中最重要的类之一,它封装了绘图所需求的一切函数,是用户最重要的类之一,它封装了绘图所需求的一切函数,是用户编写图形和文字处置程序必不可少的。编写图形和文字处置程序必不可少的。当然,绘制图形和文字时还必需指定相应的设备环境。设备当然,绘制图形和文字时还必需指定相应的设备环境。设备环境是由环境是由Windows保管的一个数据构造,该构造包含运用保管的一个数据构造,该构造包含运用程程序向设备输出时所需求的信息。序向设备输出时所需求的信息。7.1.
2、1 设备环境类设备环境类(1) CPaintDC比较特殊,它的构造函数和析构函数都是针对OnPaint进展的,但用户一旦获得相关的CDC指针,就可以将它当成任何设备环境(包括屏幕、打印机)指针来运用。CPaintDC类的构造函数会自动调用BeginPaint,而它的析构函数那么会自动调用EndPaint。(2) CClientDC只能在窗口的客户区(不包括边框、标题栏、菜单栏以及形状栏)中进展绘图,点(0,0)通常指的是客户区的左上角。而CWindowDC允许在窗口的任意位置中进展绘图,点(0,0)指整个窗口的左上角。CWindowDC和CClientDC构造函数分别调用GetWindowDC
3、和GetDC,但它们的析构函数都是调用ReleaseDC函数。(3) CMetaFileDC封装了在一个Windows图元文件中绘图的方法。图元文件是一系列与设备无关的图片的集合,由于它对图象的保管比像素更准确,因此往往在要求较高的场所下运用,例如AutoCAD的图像保管等。目前的Windows已运用加强格式(enhanced-format)的32位图元文件来进展操作。7.1.2 坐标映射坐标映射在讨论坐标映射之前,先来看看以下语句:pDC-Rectangle(CRect(0,0,200,200);它是在某设备环境中绘制出一个高为200个像素,宽也为200个像素的方块。由于默许的映射方式是MM
4、_TEXT,其逻辑坐标(在各种映射方式下的坐标)和设备坐标(显示设备或打印设备坐标系下的坐标)相等。因此这个方块在1024 x 768的显示器上看起来要比在640 x 480的显示器上显得小一些,而且假设将它打印在600dpi精度的激光打印机上,这个方块就会显得更小了。如表7.1所示。表表7.1 映射方式映射方式7.1.2 坐标映射坐标映射例例Ex_Draw 经过设置窗口和视口大小来改动显示的比例经过设置窗口和视口大小来改动显示的比例(1) 用用MFC AppWizard创建一个默许的单文档运用程序创建一个默许的单文档运用程序Ex_Draw。(2) 在在CEx_DrawView:OnDraw函
5、数中添加以下代码:函数中添加以下代码:void CEx_DrawView:OnDraw(CDC* pDC)CEx_DrawDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);CRect rectClient;GetClientRect(rectClient); / 获得当前窗口的客户区大小获得当前窗口的客户区大小pDC-SetMapMode(MM_ANISOTROPIC); / 设置设置MM_ANISOTROPIC映射方映射方式式pDC-SetWindowExt(1000,1000); / 设置窗口范围设置窗口范围pDC-SetViewportExt(re
6、ctClient.right,-rectClient.bottom); / 设置视口范围设置视口范围pDC-SetViewportOrg(rectClient.right/2,rectClient.bottom/2);/ 设置视设置视口原点口原点pDC-Ellipse(CRect(-500,-500,500,500);例例Ex_Draw(3) 编译运转,结果如图7.1所示。图7.1 改动显示比例7.1.3 CPoint、CSize和和CRect在图形绘制操作中,经常需求运用MFC中的CPoint、CSize和CRect等简单数据类由于CPoint(点)、CSize(大小)和CRect(矩形)是
7、对Windows的POINT、SIZE和RECT结构的封装,因此它们可以直接运用各自构造的数据成员,如下所示:typedef struct tagPOINT typedef struct tagSIZE LONG x; / 点的x坐标 int cx; / 程度大小 LONG y; / 点的y坐标 int cy; / 垂直大小 POINT; SIZE;typedef struct tagRECT LONG left;/ 矩形左上角点的x坐标 LONG top; / 矩形左上角点的y坐标 LONG right; / 矩形右下角点的x坐标 LONG bottom; / 矩形右下角点的y坐标 RECT
8、;7.1.3 CPoint、CSize和和CRect1. CPoint、CSize和和CRect类的构造函数类的构造函数CPoint类带参数的常用构造函数原型如下:类带参数的常用构造函数原型如下: CPoint( int initX, int initY ); CPoint( POINT initPt );其中,其中,initX和和initY分别用来指定分别用来指定CPoint的成员的成员x和和y的值。的值。initPt用来指定一个用来指定一个POINT构造或构造或CPoint对象来初始化对象来初始化CPoint的成员。的成员。CSize类带参数的常用构造函数原型如下:类带参数的常用构造函数原
9、型如下: CSize( int initCX, int initCY ); CSize( SIZE initSize ); 其中,其中,initCX和和initCY用来分别设置用来分别设置CSize的的cx和和cy成员。成员。initSize用来指定一用来指定一个个SIZE构造或构造或CSize对象来初始化对象来初始化CSize的成员。的成员。CRect类带参数的常用构造函数原型如下:类带参数的常用构造函数原型如下: CRect( int l, int t, int r, int b ); CRect( const RECT& srcRect ); CRect( LPCRECT lpS
10、rcRect ); CRect( POINT point, SIZE size ); CRect( POINT topLeft, POINT bottomRight );7.1.3 CPoint、CSize和和CRect2. CRect类的常用操作类的常用操作由于一个由于一个CRect类对象包含用于定义矩形的左上角和右下角点的成员变量,因此类对象包含用于定义矩形的左上角和右下角点的成员变量,因此在传送在传送LPRECT、LPCRECT或或RECT构造作为参数的任何地方,都可以运用构造作为参数的任何地方,都可以运用CRect对象来替代。对象来替代。 CRect类的操作函数有很多,这里只引见矩形的
11、扩展、减少以及两个矩形的类的操作函数有很多,这里只引见矩形的扩展、减少以及两个矩形的“并并和和“交操作,更多的常用操作如表交操作,更多的常用操作如表7.2所示。所示。表表7.2 CRect类常用的成员函数类常用的成员函数7.1.3 CPoint、CSize和和CRect2. CRect类的常用操作类的常用操作成员函数成员函数InflateRect和和DeflateRect用来扩展和减少一个矩形。由于它们的操作用来扩展和减少一个矩形。由于它们的操作是是相互的,也就是说,假设指定相互的,也就是说,假设指定InflateRect函数的参数为负值,那么操作的结果函数的参数为负值,那么操作的结果是缩是缩
12、小矩形,因此下面只给出小矩形,因此下面只给出InflateRect函数的原型:函数的原型:void InflateRect( int x, int y );void InflateRect( SIZE size );void InflateRect( LPCRECT lpRect );void InflateRect( int l, int t, int r, int b );其中,其中,x用来指定扩展用来指定扩展CRect左、右边的数值。左、右边的数值。y用来指定扩展用来指定扩展CRect上、下边的上、下边的数值。数值。size中的中的cx成员指定扩展左、右边的数值,成员指定扩展左、右边的数
13、值,cy指定扩展上、下边的数值。指定扩展上、下边的数值。lpRect的各个成员用来指定扩展每一边的数值。的各个成员用来指定扩展每一边的数值。l、t、r和和b分别用来指定扩展分别用来指定扩展CRect左、上、右和下边的数值。左、上、右和下边的数值。 7.1.3 CPoint、CSize和和CRect2. CRect类的常用操作类的常用操作成员函数成员函数IntersectRect和和UnionRect分别用来将两个矩形进展相交和合并,当分别用来将两个矩形进展相交和合并,当结结果为空时前往果为空时前往FALSE,否那么前往,否那么前往TRUE。它们的原型如下:。它们的原型如下:BOOL Inter
14、sectRect( LPCRECT lpRect1, LPCRECT lpRect2 );BOOL UnionRect( LPCRECT lpRect1, LPCRECT lpRect2 );其中,其中,lpRect1和和lpRect2用来指定操作的两个矩形。例如:用来指定操作的两个矩形。例如:CRect rectOne(125, 0, 150, 200);CRect rectTwo( 0, 75, 350, 95);CRect rectInter;rectInter.IntersectRect(rectOne, rectTwo); / 结果为结果为(125, 75, 150, 95)ASSE
15、RT(rectInter = CRect(125, 75, 150, 95);rectInter.UnionRect (rectOne, rectTwo);/ 结果为结果为(0, 0, 350, 200)ASSERT(rectInter = CRect(0, 0, 350, 200);7.1.4 颜色和颜色对话框颜色和颜色对话框在MFC中,CDC运用的是RGB颜色空间,即选用红(R)、绿(G)、蓝(B)三种基色分量,经过对这三种基色不同比例的混合,可以得到不同的彩色效果。并且,MFC运用COLORREF数据类型来表示一个32位的RGB颜色,它也可以用以下的十六进制表示: 0 x00bbggrr
16、 此方式的rr、gg、bb分别表示红、绿、蓝三个颜色分量的16进制值,最大为0 xff。在详细操作RGB颜色时,还可运用以下的宏操作: GetBValue 获得32位RGB颜色值中的蓝色分量 GetGValue 获得32位RGB颜色值中的绿色分量 GetRValue 获得32位RGB颜色值中的红色分量 RGB 将指定的R、G、B分量值转换成一个32位的RGB颜色值。MFC的CColorDialog类为运用程序提供了颜色选择通用对话框,如图7.2所示。图7.2 颜色对话框7.1.4 颜色和颜色对话框颜色和颜色对话框CColorDialog类具有以下的构造函数:CColorDialog( COLO
17、RREF clrInit = 0, DWORD dwFlags = 0, CWnd* pParentWnd = NULL );其中,clrInit用来指定选择的默许颜色值,假设此值没指定,那么为RGB(0,0,0) (黑色)。pParentWnd用来指定对话框的父窗口指针。dwFlags用来表示定制对话框外观和功能的系列标志参数。它可以是以下值之一或|组合:CC_ANYCOLOR 在根本颜色单元中列出一切可得到的颜色 CC_FULLOPEN 显示一切的颜色对话框界面。假设此标志没有被设定,那么用户单击“规定自定义颜色按钮才干显示出定制颜色的界面 CC_PREVENTFULLOPEN 禁用“规定
18、自定义颜色按钮 CC_SHOWHELP 在对话框中显示“协助按钮 CC_SOLIDCOLOR 在根本颜色单元中只列出所得到的纯色当对话框“OK退出(即DoModal前往 IDOK)时,可调用以下成员获得相应的颜色。 COLORREF GetColor( ) const;/ 前往用户选择的颜色。 void SetCurrentColor( COLORREF clr );/ 强迫运用clr作为当前选择的颜色 static COLORREF * GetSavedCustomColors( );/ 前往用户本人定义颜色7.1.5 图形设备接口图形设备接口Windows为设备环境提供了各种各样的绘图工具
19、,例如用于画线的“画笔、填充区域的“画刷以及用于绘制文本的“字体。MFC封装了这些工具,并提供相应的类来作为运用程序的图形设备接口GDI,这些类有一个共同的笼统基类CGdiObject,详细如表7.3所示。表表7.3 MFC的的GDI类类7.1.5 图形设备接口图形设备接口1. 运用运用GDI对象对象在选择在选择GDI对象进展绘图时,往往遵照着以下的步骤:对象进展绘图时,往往遵照着以下的步骤:(1) 在堆栈中定义一个在堆栈中定义一个GDI对象对象(如如CPen、CBrush对象对象),然后用相应的函数,然后用相应的函数(如如CreatePen、CreateSolidBrush)创建此创建此GD
20、I对象。但要留意:有些对象。但要留意:有些GDI派生类的构造函数允许用户提供派生类的构造函数允许用户提供足够的信息,从而一步即可完成对象的创建义务,这些类有足够的信息,从而一步即可完成对象的创建义务,这些类有CPen、CBrush。(2) 将构造的将构造的GDI对象选入当前设备环境中,但不要忘记将原来的对象选入当前设备环境中,但不要忘记将原来的GDI对象保管起来。对象保管起来。(3)绘图终了后,恢复当前设备环境中原来的绘图终了后,恢复当前设备环境中原来的GDI对象。对象。(4)由于由于GDI对象是在堆栈中创建中,当程序终了后,会自动删除程序创建的对象是在堆栈中创建中,当程序终了后,会自动删除程
21、序创建的GDI对象。对象。详细操作可像下面的代码过程:详细操作可像下面的代码过程:void CMyView:OnDraw( CDC* pDC )CPen penBlack; / 定义一个画笔变量定义一个画笔变量penBlack.CreatePen( PS_SOLID, 2, RGB(0,0,0); / 创建画笔创建画笔 / 将此画笔选入当前设备环境并保管原来的画笔将此画笔选入当前设备环境并保管原来的画笔CPen* pOldPen = pDC-SelectObject( &penBlack );/ 用此画笔绘图用此画笔绘图pDC-MoveTo(.);pDC-LineTo(.);/ 其他绘
22、图函数其他绘图函数pDC-SelectObject( pOldPen ); / 恢复设备环境中原来的画笔恢复设备环境中原来的画笔7.1.5 图形设备接口图形设备接口2. 库存的库存的GDI对象对象除了自定义的除了自定义的GDI对象外,对象外,Windows还包含了一些预定义的库存还包含了一些预定义的库存GDI对象。由于对象。由于它们是它们是Windows系统的一部分,因此用户用不着删除它们。系统的一部分,因此用户用不着删除它们。CDC的成员函数的成员函数SelectStockObject可以把一个库存对象选入当前设备环境中,并前往原先被选可以把一个库存对象选入当前设备环境中,并前往原先被选中中
23、的对象指针,同时使原先被选中的对象从设备环境中分别出来。如下面的代码:的对象指针,同时使原先被选中的对象从设备环境中分别出来。如下面的代码:void CEx_SDIView:OnDraw( CDC* pDC )CPen newPen( PS_SOLID, 2, RGB(0,0,0) ) )pDC-SelectObject( &newPen ); pDC-MoveTo(.); pDC-LineTo(.);/ 其他绘图函数其他绘图函数 pDC-SelectStockObject( BLACK_PEN );/ newPen被分被分别出来别出来2. 库存的库存的GDI对象对象函数SelectS
24、tockObject可选用的库存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 系统字体7.2 简单图形绘制简单图形绘制图形的绘制通常需求先创建画笔和画刷,然后调用相应的绘图函数。7.2.1 画笔画笔是Windows运用程序中用来绘
25、制各种直线和曲线的一种图形工具,它可分为修饰画笔和几何画笔两种类型。在这两种类型中,几何画笔的定义最复杂,它不但有修饰画笔的属性,而且还跟画刷的款式、阴影线类型有关,通常用在对绘图有较高要求的场所。而修饰画笔只需简单的几种属性,通常用在简单的直线和曲线等场所。7.2.1 画笔画笔表表7.4 修饰画笔的风格修饰画笔的风格7.2.1 画笔画笔创建一个修饰画笔,可以运用CPen类的CreatePen函数,其原型如下:BOOL CreatePen( int nPenStyle, int nWidth, COLORREF crColor );其中,参数nPenStyle、nWidth、crColor分别
26、用来指定画笔的风格、宽度和颜色。此外,还有一个CreatePenIndirect函数也是用来创建画笔对象,它的作用与CreatePen函数是完全一样的,只是画笔的三个属性不是直接出如今函数参数中,而是经过一个LOGPEN构造间接地给出。BOOL CreatePenIndirect( LPLOGPEN lpLogPen );此函数用由LOGPEN构造指针指定的相关参数创建画笔,LOGPEN构造如下:typedef struct tagLOGPEN /* lgpn */ UINT lopnStyle;/ 画笔风格,同上 POINT lopnWidth; / POINT构造的y不起作用,而用x表示画
27、笔宽度 COLORREF lopnColor;/ 画笔颜色 LOGPEN;7.2.2 画刷画刷画刷的属性通常包括填充色、填充图案和填充款式三种。画刷的填充色和画笔颜色一样,都是运用COLORREF颜色类型,画刷的填充图案通常是用户定义的8 8位图,而填充款式往往是CDC内部定义的一些特性,它们都是以HS_为前缀的标识,如图7.3所示:HS_BDIAGONALHS_CROSSHS_DIAGCROSSHS_FDIAGONAL HS_HORIZONTAL HS_VERTICAL图7.3 画刷的填充款式7.2.2 画刷画刷CBrush类根据画刷属性提供了相应的创建函数,例如创建填充色画刷和填充样式画刷
28、的函数为CreateSolidBrush和CreateHatchBrush,它们的原型如下:BOOL CreateSolidBrush( COLORREF crColor ); / 创建填充色画刷BOOL CreateHatchBrush( int nIndex, COLORREF crColor ); / 创建填充款式画刷其中,nIndex用来指定画刷的内部填充款式,而crColor表示画刷的填充色。与画笔相类似,也有一个LOGBRUSH 逻辑构造用于画刷属性的定义,并经过 CBrush的成员函数CreateBrushIndirect来创建,其原型如下:BOOL CreateBrushInd
29、irect( const LOGBRUSH* lpLogBrush );其中,LOGBRUSH 逻辑构造如下定义:typedef struct tagLOGBRUSH / lb UINT lbStyle; / 风格 COLORREF lbColor; / 填充色 LONG lbHatch; / 填充款式 LOGBRUSH; 7.2.3 图形绘制图形绘制1. 画点、线画点、线(1) 画点是最根本的绘图操作之一,它是经过调用画点是最根本的绘图操作之一,它是经过调用CDC:SetPixel或或CDC:SetPixelV函数来实现的。这两个函数都是用来在指定的坐标上设置指定的颜色,函数来实现的。这两个
30、函数都是用来在指定的坐标上设置指定的颜色,只不过只不过SetPixelV函数不需求前往实践像素点的函数不需求前往实践像素点的RGB值;正是由于这一点,函值;正是由于这一点,函数数SetPixelV要比要比SetPixel快得多。快得多。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, COL
31、ORREF crColor );实践显示像素的颜色未必等同于实践显示像素的颜色未必等同于crColor所指定的颜色值,由于有时受设备限所指定的颜色值,由于有时受设备限制,不能显示制,不能显示crColor所指定的颜色值,而只能取其近似值。所指定的颜色值,而只能取其近似值。与上述函数相对应的与上述函数相对应的GetPixel函数是用来获取指定点的颜色。函数是用来获取指定点的颜色。COLORREF GetPixel( int x, int y ) const;COLORREF GetPixel( POINT point ) const;1. 画点、线画点、线(2) 画线也是特别常用的绘图操作之一。
32、CDC的LineTo和MoveTo函数就是用来实现画线功能的两个函数,经过这两个函数的配合运用,可完成任何直线和折线的绘制操作。这个当前位置还可用函数CDC:GetCurrentPosition来获得,其原型如下:CPoint GetCurrentPosition( ) const;LineTo函数正是经当前位置所在点为直线起始点,另指定直线终点,画出一段直线的。其原型如下:BOOL LineTo( int x, int y );BOOL LineTo( POINT point );7.2.3 图形绘制图形绘制2. 折线折线除了除了LineTo函数可用来画线之外,函数可用来画线之外,CDC中还
33、提供了一系列用于画各种折线的函中还提供了一系列用于画各种折线的函数。它们主要是数。它们主要是Polyline、PolyPolyline和和PolylineTo。这三个函数中,。这三个函数中,Polyline和和PolyPolyline既不运用当前位置,也不更新当前位置;而既不运用当前位置,也不更新当前位置;而PolylineTo总是把当前总是把当前位位置作为起始点,并且在折线画完之后,还把折线终点所在位置设为新的当前位置作为起始点,并且在折线画完之后,还把折线终点所在位置设为新的当前位置。置。BOOL Polyline( LPPOINT lpPoints, int nCount );BOOL
34、PolylineTo( const POINT* lpPoints, int nCount );这两个函数用来画一系列延续的折线。参数这两个函数用来画一系列延续的折线。参数lpPoints是是POINT或或CPoint的顶点的顶点数数组;组;nCount表示数组中顶点的个数,它至少为表示数组中顶点的个数,它至少为2。BOOL PolyPolyline( const POINT* lpPoints, const DWORD* lpPolyPoints, int nCount );此函数可用来绘制多条折线。其中此函数可用来绘制多条折线。其中lpPoints同前定义,同前定义,lpPolyPoint
35、s表示各条折表示各条折线线所需的顶点数,所需的顶点数,nCount表示折线的数目。表示折线的数目。7.2.3 图形绘制图形绘制3. 矩形和圆角矩形矩形和圆角矩形CDC提供的提供的Rectangle和和RoundRect函数分别用于矩形和圆角矩形的绘制,它函数分别用于矩形和圆角矩形的绘制,它们们的原型如下:的原型如下:BOOL Rectangle( int x1, int y1, int x2, int y2 );BOOL Rectangle( LPCRECT lpRect );BOOL RoundRect( int x1, int y1, int x2, int y2, int x3, int
36、 y3 );BOOL RoundRect( LPCRECT lpRect, POINT point );参数参数lpRect的成员的成员left,top,right,bottom分别表示分别表示x1,y1,x2,y2,point的成员的成员x,y分别分别表示表示x3,y3;而;而x1,y1表示矩形的左上角坐标,表示矩形的左上角坐标,x2,y2表示矩形的右上角坐标,表示矩形的右上角坐标,x3,y3表示绘制圆角的椭圆大小,如图表示绘制圆角的椭圆大小,如图7.4所示。所示。图7.4 圆角矩形图7.5 多边形填充方式7.2.3 图形绘制图形绘制4. 设置多边形填充方式设置多边形填充方式多边形填充方式决
37、议了图形填充时寻觅填充区域的方法,有两种选择:多边形填充方式决议了图形填充时寻觅填充区域的方法,有两种选择:ALTERNATE和和WINDING。ALTERNATE方式是寻觅相邻的奇偶边作为填充区域,而方式是寻觅相邻的奇偶边作为填充区域,而WINDING是按顺时是按顺时针或逆时针进展寻觅;普通情况,这两种方式的填充效果是一样的,但对于像五角星这样针或逆时针进展寻觅;普通情况,这两种方式的填充效果是一样的,但对于像五角星这样的图形,填充的结果大不一样,例如下面的代码,其结果如图的图形,填充的结果大不一样,例如下面的代码,其结果如图7.5所示。所示。.POINTpt5=247,10,230,90,
38、290,35,210,30,275,85;CBrushbrush(HS_FDIAGONAL,RGB(255,0,0);CBrush* oldbrush=pDC-SelectObject(&brush);pDC-SetPolyFillMode(ALTERNATE);pDC-Polygon(pt,5);for(int i=0;iSetPolyFillMode(WINDING);pDC-Polygon(pt,5);pDC-SelectObject(oldbrush);brush.DeleteObject();代码中,代码中,SetPolyFillMode是是CDC类的一个成员函数,用来设置填
39、充方式,它的参数可以类的一个成员函数,用来设置填充方式,它的参数可以是是ALTERNATE和和WINDING。7.2.3 图形绘制图形绘制5. 多边形多边形前面曾经引见过折线的画法,而多边形可以说就是由首尾相接的封锁折线所围成前面曾经引见过折线的画法,而多边形可以说就是由首尾相接的封锁折线所围成的图形。画多边形的函数的图形。画多边形的函数Polygon原型如下:原型如下:BOOL Polygon( LPPOINT lpPoints, int nCount );可以看出,可以看出,Polygon函数的参数方式与函数的参数方式与Polyline函数是一样的。但也稍有一点小函数是一样的。但也稍有一点
40、小差差异。例如,要画一个三角形,运用异。例如,要画一个三角形,运用Polyline函数,顶点数组中就得给出四个顶点函数,顶点数组中就得给出四个顶点(虽然始点和终点反复出现虽然始点和终点反复出现),而用,而用Polygon函数那么只需给出三个顶点。函数那么只需给出三个顶点。与与PolyPolyline可画多条折线一样,运用可画多条折线一样,运用PolyPolygon函数,一次可画出多个多函数,一次可画出多个多边边形,这两个函数的参数方式和含义也一样。形,这两个函数的参数方式和含义也一样。BOOL PolyPolygon( LPPOINT lpPoints, LPINT lpPolyCounts,
41、 int nCount );7.2.3 图形绘制图形绘制6. 圆弧和椭圆圆弧和椭圆经过调用经过调用CDC的的Arc函数可以画一条椭圆弧线或者整个椭圆。这个椭圆的大小是函数可以画一条椭圆弧线或者整个椭圆。这个椭圆的大小是由其外接矩形由其外接矩形(本身并不可见本身并不可见)所决议的。所决议的。Arc函数的原型如下:函数的原型如下:BOOL Arc( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 );BOOL Arc( LPCRECT lpRect, POINT ptStart, POINT ptEnd );这里,这里,
42、x1,y1,x2,y2或或lpRect用来指定外接矩形的位置和大小,而椭圆中心与点用来指定外接矩形的位置和大小,而椭圆中心与点(x3,y3)或或ptStart所构成的射线与椭圆的交点就成为椭圆弧线的起始点,椭圆中所构成的射线与椭圆的交点就成为椭圆弧线的起始点,椭圆中心心与点与点(x4,y4)或或ptEnd所构成的射线与椭圆的交点就成为椭圆弧线的终点。椭圆上所构成的射线与椭圆的交点就成为椭圆弧线的终点。椭圆上弧线始点到终点的部分是要绘制的椭圆弧,如图弧线始点到终点的部分是要绘制的椭圆弧,如图7.6所示。所示。图7.6 弧线中心外接矩形弧线(x1,y1)(x2,y2)起点坐标终点坐标7.2.3 图
43、形绘制图形绘制7. 弦形和扇形弦形和扇形CDC类成员函数类成员函数Chord和和Pie是用来绘制弦形是用来绘制弦形(图图7.7)和扇形和扇形(图图7.8),它们具有和,它们具有和Arc一样的参数。一样的参数。BOOL Chord( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 );BOOL Chord( LPCRECT lpRect, POINT ptStart, POINT ptEnd );BOOL Pie( int x1, int y1, int x2, int y2, int x3, int y3, int
44、x4, int y4 );BOOL Pie( LPCRECT lpRect, POINT ptStart, POINT ptEnd );图7.7 弦形中心外接矩形弦形(x1,y1)(x2,y2)起点坐标终点坐标图7.8 扇形中心外接矩形扇形(x1,y1)(x2,y2)起点坐标终点坐标7.2.3 图形绘制图形绘制8. Bzier曲线曲线Bzier曲线是最常见的非规那么曲线之一,它的外形不仅便于控制,而且更主要曲线是最常见的非规那么曲线之一,它的外形不仅便于控制,而且更主要的的是它具有几何不变性是它具有几何不变性(即它的外形不随坐标的变换而改动即它的外形不随坐标的变换而改动),因此在许多场所往往,
45、因此在许多场所往往采用这种曲线。采用这种曲线。Bzier曲线属于三次曲线,只需给定四个点曲线属于三次曲线,只需给定四个点(第一和第四个点是第一和第四个点是端端点,另两个是控制点点,另两个是控制点),就可独一确定其外形,如图,就可独一确定其外形,如图7.9所示。所示。P1P2P3P4图7.9 Bzier曲线8. Bzier曲线曲线函数PolyBezier是用来画出一条或多条Bzier曲线的,其函数原型如下:BOOL PolyBezier( const POINT* lpPoints, int nCount );其中lpPoints是曲线端点和控制点所组成的数组,nCount表示lpPoints数
46、组中的点数。假设lpPoints用于画多条Bzier曲线,那么除了第一条曲线要用到四个点之外,后面的曲线只需用三个点,由于后面的曲线总是把前一条曲线的终点作为本人的起始端点。函数PolyBezier不运用也不更新当前位置。假设需求运用当前位置,那么就应该运用PolyBezierTo函数。 BOOL PolyBezierTo( const POINT* lpPoints, int nCount );7.2.3 图形绘制图形绘制9. 绘图例如绘图例如下面来看一个简单的例如。它是用来表示一个班级某门课程的成果分布,用一个下面来看一个简单的例如。它是用来表示一个班级某门课程的成果分布,用一个直方图来反
47、映直方图来反映90五个分数段的人数,它需求五个分数段的人数,它需求绘制五个矩形,相邻矩形的填充款式还要有所区别,并且还需求显示各分数段的绘制五个矩形,相邻矩形的填充款式还要有所区别,并且还需求显示各分数段的人数。其结果如图人数。其结果如图7.10所示。所示。图7.10 Ex_Draw运转结果7.2.3 图形绘制图形绘制例例Ex_Draw 课程的成果分布直方图课程的成果分布直方图用用MFC AppWizard创建一个默许的单文档运用程序创建一个默许的单文档运用程序Ex_Draw。为为CEx_DrawView类添加一个成员函数类添加一个成员函数DrawScore,用来根据成果来绘制直方,用来根据成
48、果来绘制直方图,该函数的代码如下:图,该函数的代码如下:void CEx_DrawView:DrawScore(CDC *pDC, float *fScore, int nNum)/ fScore是成果数组指针,是成果数组指针,nNum是学生人数是学生人数int nScoreNum = 0, 0, 0, 0, 0;/ 各成果段的人数的初始值各成果段的人数的初始值/ 下面是用来统计各分数段的人数下面是用来统计各分数段的人数for (int i=0; inNum; i+) int nSeg = (int)(fScorei) / 10;/ 取数的取数的十十位上的值位上的值if (nSeg 6)nSe
49、g = 5;/ 90分数段分数段nScoreNumnSeg - 5 +;/ 各分数段计数各分数段计数int nSegNum = sizeof(nScoreNum)/sizeof(int); / 计算有多少个分数段计算有多少个分数段 / 求分数段上最大的人数int nNumMax = nScoreNum0;for (i=1; inSegNum; i+) if (nNumMax SelectObject( &brush1 );/ 将brush1选入设备环境CPen* oldPen = pDC-SelectObject( &pen );/ 将pen选入设备环境CRect rcSeg(
50、rc);rcSeg.right = rcSeg.left + nSegWidth;/ 使每段的矩形宽度等于nSegWidthCString strSeg=90;CRect rcStr;for (i=0; iSelectObject( &brush2 );elsepDC-SelectObject( &brush1 );rcSeg = rcSeg.bottom - nScoreNumi*nSegHeight - 2;/ 计算每段矩形的高度pDC-Rectangle(rcSeg);if (nScoreNumi 0) CString str;str.Format(%d人, nScore
51、Numi);pDC-DrawText( str, rcSeg, DT_CENTER | DT_VCENTER | DT_SINGLELINE );rcStr = rcSeg;rcStr = rcStr.bottom + 2;rcStr.bottom += 20;pDC-DrawText( strSegi, rcStr, DT_CENTER | DT_VCENTER | DT_SINGLELINE ); / 后面还会讲到rcSeg.OffsetRect( nSegWidth, 0 );/ 右移矩形pDC-SelectObject( oldBrush );/ 恢复原来的画刷属性pDC-Select
52、Object( oldPen );/ 恢复原来的画笔属性例Ex_Draw(3) 在CEx_DrawView:OnDraw函数中添加以下代码:void CEx_DrawView:OnDraw(CDC* pDC)CEx_DrawDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);float fScore = 66,82,79,74,86,82,67,60,45,44,77,98,65,90,66,76,66, 62,83,84,97,43,67,57,60,60,71,74,60,72,81,69,79,91,69,71,81;DrawScore(pDC, f
53、Score, sizeof(fScore)/sizeof(float);(4) 编译并运转,如前图7.10所示。7.3 字体与文字处置字体与文字处置字体是文字显示和打印的外观方式,它包括了文字的字样、风格和尺寸等多方面的属性。适当地选用不同的字体,可以大大地丰富文字的外在表现力。例如,把文字中某些重要的字句用较粗的字体显示,可以表达出突出、强调的意图。7.3.1 字体和字体对话框字体和字体对话框1. 字体的属性和创建字体的属性有很多,但其主要属性有字样、风格和尺寸三个。字样是字符书写和显示时表现出的特定方式,例如,对于汉字,通常有宋体、楷体、仿宋、黑体、隶书以及幼圆等多种字样。字体风格主要表现
54、为字体的粗细和能否倾斜等特点。字体尺寸是用来指定字符所占区域的大小,通常用字符高度来描画。字体尺寸可以取毫米或英寸作为单位,但为了直观起见,也经常采用一种称为“点的单位,一点约折合为1/72英寸。1. 字体的属性和创建字体的属性和创建逻辑字体的详细属性可由LOGFONT构造来描画,这里仅列最常用到的构呵斥员。typedef struct tagLOGFONT LONG lfHeight; / 字体的逻辑高度 LONG lfWidth; / 字符的平均逻辑宽度 LONG lfEscapement; / 倾角 LONG lfOrientation; / 书写方向 LONG lfWeight; /
55、字体的粗细程度 BYTE lfItalic; / 斜体标志 BYTE lfUnderline; / 下划线标志 BYTE lfStrikeOut; / 删除线标志 BYTE lfCharSet; / 字符集,汉字必需为GB2312_CHARSET TCHAR lfFaceNameLF_FACESIZE;/ 字样称号/ LOGFONT; 1. 字体的属性和创建字体的属性和创建根据定义的逻辑字体,用户就可以调用CFont类的CreateFontIndirect函数创建文本输出所需求的字体,如下面的代码:LOGFONT lf;/ 定义逻辑字体的构造变量memset(&lf, 0, sizeo
56、f(LOGFONT);/ 将lf中的一切成员置0lf.lfHeight = -13;lf.lfCharSet = GB2312_CHARSET;strcpy(LPSTR)&(lf.lfFaceName), 黑体);/ 用逻辑字体构造创建字体CFontcf;cf.CreateFontIndirect(&lf); / 在设备环境中运用字体CFont* oldfont = pDC-SelectObject(&cf);pDC-TextOut(100,100,Hello);pDC-SelectObject(oldfont);/ 恢复设备环境原来的属性cf.DeleteObject
57、();/ 删除字体对象7.3.1 字体和字体对话框字体和字体对话框2. 运用字体对话框运用字体对话框CFontDialog类提供了字体及其文本颜色选择的通用对话框,如图类提供了字体及其文本颜色选择的通用对话框,如图7.11所示。它的构所示。它的构造函数如下:造函数如下:CFontDialog( LPLOGFONT lplfInitial = NULL, DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS, CDC* pdcPrinter = NULL, CWnd* pParentWnd = NULL );其中,参数其中,参数lplfInitial是一个是一个
58、LOGFONT构造指针,用来设置对话框最初的字体特性。构造指针,用来设置对话框最初的字体特性。dwFlags指定选择字体的标志。指定选择字体的标志。pdcPrinter用来表示打印设备环境指针。用来表示打印设备环境指针。pParentWnd表示对话框的父窗口指针。表示对话框的父窗口指针。图7.11 字体对话框2. 运用字体对话框运用字体对话框当字体对话框DoModal前往IDOK后,可运用以下的成员函数:void GetCurrentFont( LPLOGFONT lplf );/ 前往用户选择的LOGFONT字体CString GetFaceName( ) const;/ 前往用户选择的字体
59、称号CString GetStyleName( ) const;/ 前往用户选择的字体款式称号int GetSize( ) const;/ 前往用户选择的字体大小COLORREF GetColor( ) const; / 前往用户选择的文本颜色int GetWeight( ) const;/ 前往用户选择的字体粗细程度BOOL IsStrikeOut( ) const;/ 判别能否有删除线BOOL IsUnderline( ) const;/ 判别能否有下划线BOOL IsBold( ) const;/ 判别能否是粗体BOOL IsItalic( ) const;/ 判别能否是斜体。2. 运用
60、字体对话框运用字体对话框经过字体对话框可以创建一个字体,如下面的代码:LOGFONT lf;CFontcf;memset(&lf, 0, sizeof(LOGFONT);/ 将lf中的一切成员置0CFontDialog dlg(&lf);if (dlg.DoModal()=IDOK)dlg.GetCurrentFont(&lf);pDC-SetTextColor(dlg.GetColor();cf.CreateFontIndirect(&lf); .7.3.2 常用文本输出函数常用文本输出函数文本的最终输出不仅依赖于文本的字体,而且还跟文本的颜色、对齐方式等有很大关系。CDC类提供了四个输出文本的成员函数:TextOut、ExtTextOut、TabbedTextOut和DrawText。对于这四个函数,用户应根据详细
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年农药喷洒作业服务合同版B版
- 2024年基因编辑技术研究与应用合同
- 房地产开发公司2024年度股权转让合同解析3篇
- 经典(2024版)大型连锁超市商品供应合同2篇
- 2024年健身器材维护与保养服务合同
- 2024专用版采购代理业务合作合同版
- 2024事业单位人员聘用合同范文
- 2024专项会展场地租赁及管理合同
- 2024年互联网餐饮服务经营合同
- 2024年度健身房建设与运营管理合同2篇
- 《建设工程投标实务》课件
- 2024年生产部年度工作计划(3篇)
- 消防安全工作台账
- 《品牌策划与推广》课件
- 学校节水合同范例
- 《安全知识教育》课件
- 肺癌中医护理方案图文课件
- 安全部经理述职
- 对项目施工管理的总体安排和总体施工组织布置及规划
- (2021更新)国家开放大学电大专科《网络营销与策划》判断题案例分析题题库及答案
- 科幻小说阅读(原卷版)-2023年浙江中考语文复习专练
评论
0/150
提交评论