收藏 分享(赏)

第7章图形、文本和位图.ppt

上传人:j35w19 文档编号:8220808 上传时间:2019-06-15 格式:PPT 页数:74 大小:662.50KB
下载 相关 举报
第7章图形、文本和位图.ppt_第1页
第1页 / 共74页
第7章图形、文本和位图.ppt_第2页
第2页 / 共74页
第7章图形、文本和位图.ppt_第3页
第3页 / 共74页
第7章图形、文本和位图.ppt_第4页
第4页 / 共74页
第7章图形、文本和位图.ppt_第5页
第5页 / 共74页
点击查看更多>>
资源描述

1、第7章图形、文本和位图,7.1概述,7.2图形设备接口,7.3图形绘制,7.4字体与文字处理,7.5在对话框及控件中绘图,7.6综合应用,7.1概述,7.1.1 设备环境类设备环境类CDC提供了绘制和打印的全部函数。为了能让用户使用一些特殊的设备环境,CDC还派生了CPaintDC、CClientDC、CWindowDC和CMetaFileDC类。(1)CPaintDC比较特殊,它的构造函数和析构函数都是针对OnPaint进行的,但用户一旦获得相关的CDC指针,就可以将它当成任何设备环境(包括屏幕、打印机)指针来使用。CPaintDC类的构造函数会自动调用BeginPaint,而它的析构函数则

2、会自动调用EndPaint。(2)CClientDC只能在窗口的客户区(不包括边框、标题栏、菜单栏以及状态栏)中进行绘图,点(0,0)通常指的是客户区的左上角。而CWindowDC允许在窗口的任意位置中进行绘图,点(0,0)指整个窗口的左上角。CWindowDC和CClientDC构造函数分别调用GetWindowDC和GetDC,但它们的析构函数都是调用ReleaseDC函数。(3)CMetaFileDC封装了在一个Windows图元文件中绘图的方法。图元文件是一系列与设备无关的图片的集合,由于它对图象的保存比像素更精确,因而往往在要求较高的场合下使用,例如AutoCAD的图像保存等。目前的

3、Windows已使用增强格式(enhanced-format)的32位图元文件来进行操作。,7.1概述,7.1.2坐标映射 在讨论坐标映射之前,先来看看下列语句:pDC-Rectangle(CRect(0,0,200,200);它是在某设备环境中绘制出一个高为200个像素,宽也为200个像素的方块。由于默认的映射模式是MM_TEXT,其逻辑坐标(在映射模式下的坐标)和设备坐标(显示设备或打印设备坐标系下的坐标)相等。因此这个方块在1024 x 768的显示器上看起来要比在640 x 480的显示器上显得小一些,而且若将它打印在600dpi精度的激光打印机上,这个方块就会显得更小了。为了能保证打

4、印的结果不受设备的影响,Windows定义了一些映射模式,这些映射模式决定了设备坐标和逻辑坐标之间的关系,如表7.1所示。,表7.1 映射模式,7.1概述,在映射模式MM_ANISOTROPIC和MM_ISOTROPIC中,常常可以调用CDC: SetWindowExt(设置窗口大小)和CDC:SetViewportExt(设置视口大小)函数来设置所需要的比例因子。这里的“窗口”和“视口”的概念往往不易理解。所谓“窗口”,可以理解成是一种逻辑坐标下的窗口,而“视口”是实际看到的那个窗口,也就是设备坐标下的窗口。根据“窗口”和“视口”的大小就可以确定x和y的比例因子,它们的关系如下:x比例因子

5、= 视口x大小 / 窗口x大小y比例因子 = 视口y大小 / 窗口y大小例Ex_Draw 通过设置窗口和视口大小来改变显示的比例(1)创建一个默认的单文档应用程序Ex_Draw。,7.1概述,(2)在CEx_DrawView:OnDraw函数中添加下列代码:void CEx_DrawView:OnDraw(CDC* pDC)CEx_DrawDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);CRect rectClient;GetClientRect(rectClient); / 获得当前窗口的客户区大小pDC-SetMapMode(MM_ANISOTRO

6、PIC); / 设置MM_ANISOTROPIC映射模式pDC-SetWindowExt(1000,1000); / 设置窗口范围pDC-SetViewportExt(rectClient.right,-rectClient.bottom); / 设置视口范围pDC-SetViewportOrg(rectClient.right/2,rectClient.bottom/2);/ 设置视口原点pDC-Ellipse(CRect(-500,-500,500,500);,7.1概述,(3)编译运行,结果如图7.1所示。,图7.1 改变显示比例,7.1概述,7.1.3 CPoint、CSize和CRe

7、ct在图形绘制操作中,常常需要使用MFC中的CPoint、CSize和CRect等简单数据类。由于CPoint(点)、CSize(大小)和CRect(矩形)是对Windows的POINT、SIZE和RECT结构的封装,因此它们可以直接使用各自结构的数据成员,如下所示:typedef struct tagPOINT LONG x; / 点的x坐标LONG y; / 点的y坐标 POINT;typedef struct tagSIZE int cx; / 水平大小int cy; / 垂直大小 SIZE;typedef struct tagRECT LONG left; / 矩形左上角点的x坐标LO

8、NG top; / 矩形左上角点的y坐标LONG right; / 矩形右下角点的x坐标LONG bottom; / 矩形右下角点的y坐标 RECT;,7.1概述,1. CPoint、CSize和CRect类的构造函数CPoint类带参数的常用构造函数原型如下:CPoint( int initX, int initY );CPoint( POINT initPt );其中,initX和initY分别用来指定CPoint的成员x和y的值。initPt用来指定一个POINT结构或CPoint对象来初始化CPoint的成员。CSize类带参数的常用构造函数原型如下:CSize( int initCX

9、, 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,7.1概述,其中,l、t、r、b分别用来指定CRect的left、top、right和bottom成员的值。srcRect 和lpSrcRect 分别用一个RECT结构或指针来初始化CRect的成员。point用来指

10、定矩形的左上角位置。size用来指定矩形的长度和宽度。topLeft和bottomRight分别用来指定CRect的左上角和右下角的位置。2. CRect类的常用操作由于一个CRect类对象包含用于定义矩形的左上角和右下角点的成员变量,因此在传递LPRECT、LPCRECT或RECT结构作为参数的任何地方,都可以使用CRect对象来代替。需要说明的是,当构造一个CRect时,要使它符合规范。也就是说,使其left小于right,top小于bottom。例如,但若左上角为(20, 20),而右下角为(10, 10),那么定义的这个矩形就不符合规范。一个不符合规范的矩形,CRect的许多成员函数都

11、会不会有正确的结果。基于此种原因,常常使用CRect:NormalizeRect函数使一个不符合规范的矩形合乎规范。CRect类的操作函数有很多,这里只介绍矩形的扩大、缩小以及两个矩形的“并”和“交”操作,更多的常用操作如表7.2所示。,7.1概述,表7.2 CRect类常用的成员函数,7.1概述,成员函数InflateRect和DeflateRect用来扩大和缩小一个矩形。由于它们的操作是相互的,也就是说,若指定InflateRect函数的参数为负值,那么操作的结果是缩小矩形,因此下面只给出InflateRect函数的原型:void InflateRect( int x, int y );v

12、oid InflateRect( SIZE size );void InflateRect( LPCRECT lpRect );void InflateRect( int l, int t, int r, int b );其中,x用来指定扩大CRect左、右边的数值。y用来指定扩大CRect上、下边的数值。size中的cx成员指定扩大左、右边的数值,cy指定扩大上、下边的数值。lpRect的各个成员用来指定扩大每一边的数值。l、t、r和b分别用来指定扩大CRect左、上、右和下边的数值。需要注意的是,由于InflateRect是通过将CRect的边向远离其中心的方向移动来扩大的,因此对于前两个

13、重载函数来说,CRect的总宽度被增加了两倍的x或cx,总高度被增加了两倍的y或cy。,7.1概述,成员函数IntersectRect和UnionRect分别用来将两个矩形进行相交和合并,当结果为空时返回FALSE,否则返回TRUE。它们的原型如下:BOOL IntersectRect( LPCRECT lpRect1, LPCRECT lpRect2 );BOOL UnionRect( LPCRECT lpRect1, LPCRECT lpRect2 );其中,lpRect1和lpRect2用来指定操作的两个矩形。例如:CRect rectOne(125, 0, 150, 200);CRec

14、t rectTwo( 0, 75, 350, 95);CRect rectInter;rectInter.IntersectRect(rectOne, rectTwo); / 结果为(125, 75, 150, 95)ASSERT(rectInter = CRect(125, 75, 150, 95);rectInter.UnionRect (rectOne, rectTwo); / 结果为(0, 0, 350, 200)ASSERT(rectInter = CRect(0, 0, 350, 200);,7.1概述,7.1.4 颜色和颜色对话框在MFC中,CDC使用的是RGB颜色空间,即选用红

15、(R)、绿(G)、蓝(B)三种基色分量,通过对这三种基色不同比例的混合,可以得到不同的彩色效果。并且,MFC使用COLORREF数据类型来表示一个32位的RGB颜色,它也可以用下列的十六进制表示: 0x00bbggrr 此形式的rr、gg、bb分别表示红、绿、蓝三个颜色分量的16进制值,最大为0xff。在具体操作RGB颜色时,还可使用下列的宏操作:GetBValue 获得32位RGB颜色值中的蓝色分量GetGValue 获得32位RGB颜色值中的绿色分量GetRValue 获得32位RGB颜色值中的红色分量 RGB 将指定的R、G、B分量值转换成一个32位的 RGB颜色值。MFC的CColor

16、Dialog类为应用程序提供了颜色选择通用对话框,如图7.2所示。,7.1概述,图7.2 颜色对话框,7.1概述,CColorDialog类具有下列的构造函数:CColorDialog( COLORREF clrInit = 0, DWORD dwFlags = 0, CWnd* pParentWnd = NULL );其中,clrInit用来指定选择的默认颜色值,若此值没指定,则为RGB(0,0,0) (黑色)。pParentWnd用来指定对话框的父窗口指针。dwFlags用来表示定制对话框外观和功能的系列标志参数。它可以是下列值之一或”|”组合:CC_ANYCOLOR 在基本颜色单元中列出

17、所有可得到的颜色CC_FULLOPEN 显示所有的颜色对话框界面。若此标志没有被设定,则用户单击“规定自定义颜色”按钮才能显示出定制颜色的界面CC_PREVENTFULLOPEN 禁用“规定自定义颜色”按钮CC_SHOWHELP 在对话框中显示“帮助”按钮CC_SOLIDCOLOR 在基本颜色单元中只列出所得到的纯色当对话框“OK”退出(即DoModal返回 IDOK)时,可调用下列成员获得相应的颜色。COLORREF GetColor( ) const; / 返回用户选择的颜色。void SetCurrentColor( COLORREF clr );/ 强制使用clr作为当前选择的颜色st

18、atic COLORREF * GetSavedCustomColors( ); / 返回用户自己定义颜色,7.2图形设备接口,Windows为设备环境提供了各种各样的绘图工具,例如用于画线的“画笔”、填充区域的“画刷”以及用于绘制文本的“字体”。MFC封装了这些工具,并提供相应的类来作为应用程序的图形设备接口GDI,这些类有一个共同的抽象基类CGdiObject,具体如表7.3所示。,表7.3 MFC的GDI类,7.2图形设备接口,7.2.1 使用GDI对象在选择GDI对象进行绘图时,往往遵循着下列的步骤:(1)在堆栈中定义一个GDI对象(如CPen、CBrush对象),然后用相应的函数(如

19、CreatePen、CreateSolidBrush)创建此GDI对象。但要注意:有些GDI派生类的构造函数允许用户提供足够的信息,从而一步即可完成对象的创建任务,这些类有CPen、CBrush。(2)将构造的GDI对象选入当前设备环境中,但不要忘记将原来的GDI对象保存起来。(3)绘图结束后,恢复当前设备环境中原来的GDI对象。(4)由于GDI对象是在堆栈中创建中,当程序结束后,会自动删除程序创建的GDI对象。 具体操作可像下面的代码过程:void CMyView:OnDraw( CDC* pDC )CPen penBlack; / 定义一个画笔变量penBlack.CreatePen( P

20、S_SOLID, 2, RGB(0,0,0); / 创建画笔 / 将此画笔选入当前设备环境并保存原来的画笔CPen* pOldPen = pDC-SelectObject( / 恢复设备环境中原来的画笔,7.2图形设备接口,除了自定义的GDI对象外,Windows还包含了一些预定义的库存GDI对象。由于它们是Windows系统的一部分,因此用户用不着删除它们。CDC的成员函数SelectStockObject可以把一个库存对象选入当前设备环境中,并返回原先被选中的对 象指针,同时使原先被选中的对象从设备环境中分离出来。如下面的代码:void CEx_SDIView:OnDraw( CDC* p

21、DC )CPen newPen( PS_SOLID, 2, RGB(0,0,0) ) )pDC-SelectObject( / newPen被分离出来,7.2图形设备接口,函数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

22、 设备默认字体SYSTEM_FONT 系统字体,7.2图形设备接口,7.2.2 画笔画笔是Windows应用程序中用来绘制各种直线和曲线的一种图形工具,它可分为修饰画笔和几何画笔两种类型。在这两种类型中,几何画笔的定义最复杂,它不但有修饰画笔的属性,而且还跟画刷的样式、阴影线类型有关,通常用在对绘图有较高要求的场合。而修饰画笔只有简单的几种属性,通常用在简单的直线和曲线等场合。一个修饰画笔通常具有宽度、风格和颜色三种属性。画笔的宽度用来确定所画的线条宽度,它是用设备单位表示的。默认的画笔宽度是一个像素单位。画笔的颜色确定了所画的线条颜色。画笔的风格确定了所绘图形的线型,它通常有实线、虚线、点线

23、、点划线、双点划线、不可见线和内框线等七种风格。这些风格在Windows中都是以PS_为前缀的预定义的标识,如表7.4所示。,表7.4 修饰画笔的风格,7.2图形设备接口,创建一个修饰画笔,可以使用CPen类的CreatePen函数,其原型如下: BOOL CreatePen( int nPenStyle, int nWidth, COLORREF crColor );其中,参数nPenStyle、nWidth、crColor分别用来指定画笔的风格、宽度和颜色。此外,还有一个CreatePenIndirect函数也是用来创建画笔对象,它的作用与CreatePen函数是完全一样的,只是画笔的三个

24、属性不是直接出现在函数参数中,而是通过一个LOGPEN结构间接地给出。BOOL CreatePenIndirect( LPLOGPEN lpLogPen );此函数用由LOGPEN结构指针指定的相关参数创建画笔,LOGPEN结构如下:typedef struct tagLOGPEN /* lgpn */UINT lopnStyle; / 画笔风格,同上POINT lopnWidth; / POINT结构的y不起作用,而用x表示画笔宽度COLORREF lopnColor; / 画笔颜色 LOGPEN;值得注意的是: 当修饰画笔的宽度大于1个像素时,画笔的风格只能取PS_NULL、PS_SOLI

25、D或 PS_INSIDEFRAME,定义为其他风格不会起作用。 画笔的创建工作也可在画笔的构造函数中进行,它具有下列原型:CPen( int nPenStyle, int nWidth, COLORREF crColor );,7.2图形设备接口,7.2.3 画刷 画刷用于指定填充的特性,许多窗口、控件以及其他区域都需要用画刷进行填充绘制,它比画笔的内容更加丰富。 画刷的属性通常包括填充色、填充图案和填充样式三种。画刷的填充色和画笔颜色一样,都是使用COLORREF颜色类型,画刷的填充图案通常是用户定义的8 x 8位图,而填充样式往往是CDC内部定义的一些特性,它们都是以HS_为前缀的标识,如

26、图7.3所示:,7.2图形设备接口,CBrush类根据画刷属性提供了相应的创建函数,例如创建填充色画刷和填充样式画刷的函数为CreateSolidBrush和CreateHatchBrush,它们的原型如下:BOOL CreateSolidBrush( COLORREF crColor ); / 创建填充色画刷BOOL CreateHatchBrush( int nIndex, COLORREF crColor );/ 创建填充样式画刷其中,nIndex用来指定画刷的内部填充样式,而crColor表示画刷的填充色。 与画笔相类似,也有一个LOGBRUSH 逻辑结构用于画刷属性的定义,并通过CB

27、rush的成员函数CreateBrushIndirect来创建,其原型如下:BOOL CreateBrushIndirect( const LOGBRUSH* lpLogBrush ); 其中,LOGBRUSH 逻辑结构如下定义:typedef struct tagLOGBRUSH / lb UINT lbStyle; / 风格COLORREF lbColor; / 填充色LONG lbHatch; / 填充样式 LOGBRUSH; 另外,还需注意: 画刷的创建工作也可在其构造函数中进行,它具有下列原型:CBrush( COLORREF crColor );CBrush( int nIndex

28、, COLORREF crColor );CBrush( CBitmap* pBitmap );,7.2图形设备接口, 画刷也可用位图来指定其填充图案,但该位图应该是8 x 8像素,若位图太大,Windows则只使用其左上角的8 x 8的像素。 画刷仅对绘图函数Chord、Ellipse、FillRect、FrameRect、InvertRect、Pie、 Polygon、PolyPolygon、Rectangle、RoundRect有效。7.2.4 位图Windows的位图有两种类型:一种称之为GDI位图,另一种是DIB位图。GDI位图是由MFC中的CBitmap类来表示的,在CBitmap

29、类的对象中,包含了一种和Windows的GDI模块有关的Windows数据结构,该数据结构是与设备有关的,故此位图又称为DDB位图(device-dependent bitmap,设备相关位图)。当用户的程序取得位图数据信息时,其位图显示方式视显卡而定。由于GDI位图的这种设备依赖性,当位图通过网络传送到另一台PC时,可能就会出现问题。DIB(device-independent bitmap,设备无关位图)是设备无关位图,它比GDI位图有很多编程优势,例如它自带颜色信息,从而使调色板管理更加容易。且任何运行Windows的机器都可以处理DIB,并通常以后缀为BMP的文件形式被保存在磁盘中或作

30、为资源存在于程序的EXE或DLL文件中。,7.2图形设备接口,1. CBitmap类CBitmap类封装了Windows的GDI位图操作所需的大部分函数。其中,LoadBitmap是位图的初始化函数,其函数原型如下:BOOL LoadBitmap( LPCTSTR lpszResourceName );BOOL LoadBitmap( UINT nIDResource );该函数从应用程序中调入一个位图资源(由nIDResource或lpszResourceName指定)。若用户直接创建一个位图对象,可使用CBitmap类中的CreateBitmap、 CreateBitmapIndirect

31、以及CreateCompatibleBitmap函数,其原型如下。BOOL CreateBitmap( int nWidth, int nHeight, UINT nPlanes, UINT nBitcount, const void* lpBits );该函数用指定的宽度(nWidth)、高度(nHeight)和位模式创建一个位图对象。其中,参数nPlanes表示位图的颜色位面的数目,nBitcount表示每个像素的颜色位个数,lpBits表示包含位值的短整型数组;若此数组为NULL,则位图对象还未初始化。BOOL CreateBitmapIndirect( LPBITMAP lpBitma

32、p );该函数直接用BITMAP结构来创建一个位图对象。BOOL CreateCompatibleBitmap( CDC* pDC, int nWidth, int nHeight );该函数为某设备环境创建一个指定的宽度(nWidth)和高度(nHeight)的位图对象。,7.2图形设备接口,2. GDI位图的显示由于位图不能直接显示在实际设备中,因此对于GDI位图的显示则必须遵循下列步骤:(1)调用CBitmap类的CreateBitmap、CreateCompatibleBitmap以及 CreateBitmapIndirect函数创建一个适当的位图对象。(2)调用CDC:CreateC

33、ompatibleDC函数创建一个内存设备环境,以便位图在内存中保存下来,并与指定设备(窗口设备)环境相兼容;(3)调用CDC:SelectObject函数将位图对象选入内存设备环境中;(4)调用CDC:BitBlt或CDC:StretchBlt函数将位图复制到实际设备环境中。(5)使用之后,恢复原来的内存设备环境。例如,下面的示例过程就是调用一个位图并在视图中显示。例Ex_BMP 在视图中显示位图(1)创建一个默认的单文档应用程序Ex_BMP。(2)按快捷键Ctrl+R,弹出“插入资源”对话框,选择Bitmap资源类型。(3)单击导入按钮,出现“导入资源”对话框,将文件类型选择为“所有文件(

34、*.*)”,从外部文件中选定一个位图文件,然后单击引入按钮,该位图就被调入应用程序中。保留默认的位图资源标识IDB_BITMAP1。,7.2图形设备接口,(4)在CEx_BMPView:OnDraw函数中添加下列代码:void CEx_BMPView:OnDraw(CDC* pDC)CEx_BMPDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);CBitmap m_bmp;m_bmp.LoadBitmap(IDB_BITMAP1); / 调入位图资源BITMAP bm; / 定义一个BITMAP结构变量m_bmp.GetObject(sizeof(BIT

35、MAP), / 恢复原来的内存设备环境,7.2图形设备接口,(5)编译运行,结果如图7.4所示。,图7.4 Ex_BMP运行结果,7.2图形设备接口,通过上述代码过程可以看出:位图的最终显示是通过调用CDC:BitBlt函数来完成的。除此之外,也可以使用CDC:StretchBlt函数。这两个函数的区别在于:StretchBlt函数可以对位图进行缩小或放大,而BitBlt则不能,但BitBlt的显示更新速度较快。它们的原型如下:BOOL BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC,int xSrc, int ySrc,

36、DWORD dwRop );BOOL StretchBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop );其中,参数x、y表示位图目标矩形左上角的x、y逻辑坐标值,nWidth、nHeight表示位图目标矩形的逻辑宽度和高度,pSrcDC表示源设备CDC指针,xSrc、ySrc表示位图源矩形的左上角的x、y逻辑坐标值,dwRop表示显示位图的光栅操作方式。光栅操作方式有很多种,但经常使用的是SRCCOPY,

37、用来直接将位图复制到目标环境中。StretchBlt函数还比BitBlt参数多两个:nSrcWidth、nSrcHeight,它们是用来表示源矩形的逻辑宽度和高度。事实上,位图显示的最令人注意的地方是先将位图装入内存设备中,然后再显示。根据这一现象,可以将要显示的图形先在内存设备中绘制,然后再显示,可以起到快速显示的作用。若有多个内存设备进行交替使用,则还可实现图形的动态显示,后面会讨论。,事实上,位图显示的最令人注意的地方是先将位图装入内存设备中,然后再显示。根据这一现象,可以将要显示的图形先在内存设备中绘制,然后再显示,可以起到快速显示的作用。若有多个内存设备进行交替使用,则还可实现图形的

38、动态显示,后面会讨论。,7.3图形绘制,1. 点画点是最基本的绘图操作之一,它是通过调用CDC:SetPixel或CDC:SetPixelV函数来实现的。这两个函数都是用来在指定的坐标上设置指定的颜色,只不过SetPixelV函数不需要返回实际像素点的RGB值;正是因为这一点,函数SetPixelV要比SetPixel快得多。COLORREF SetPixel( int x, int y, COLORREF crColor );COLORREF SetPixel( POINT point, COLORREF crColor );BOOL SetPixelV(int x, int y, COLO

39、RREF crColor);BOOL SetPixelV( POINT point, COLORREF crColor );实际显示像素的颜色未必等同于crColor所指定的颜色值,因为有时受设备限制,不能显示crColor所指定的颜色值,而只能取其近似值。与上述函数相对应的GetPixel函数是用来获取指定点的颜色。COLORREF GetPixel( int x, int y ) const;COLORREF GetPixel( POINT point ) const;,7.3图形绘制,2. 画线画线也是特别常用的绘图操作之一。CDC的LineTo和MoveTo函数就是用来实现画线功能的两

40、个函数,通过这两个函数的配合使用,可完成任何直线和折线的绘制操作。这里,首先值得一提的是在画直线时,总存在一个称为“当前位置”的特殊位置。每次画直线都是以此当前位置为起始点,画线操作结束之后,直线的结束点位置又成为了当前位置。有了当前位置的自动更新,就可避免了每次画线时都要给出两点的坐标。当然,这个当前位置还可用函数CDC:GetCurrentPosition来获得,其原型如下:CPoint GetCurrentPosition( ) const;LineTo函数正是经当前位置所在点为直线起始点,另指定直线终点,画出一段直线的。其原型如下:BOOL LineTo( int x, int y )

41、;BOOL LineTo( POINT point );如果当前要画的直线并不与上一条直线的终点相接,那么应该调用MoveTo函数来调整当前位置。此函数不但可以用来更新当前位置,而且还可用来返回更新前的当前位置。其函数原型如下:CPoint MoveTo( int x, int y );CPoint MoveTo( POINT point );,7.3图形绘制,3. 折线除了LineTo函数可用来画线之外,CDC中还提供了一系列用于画各种折线的函数。它们主要是Polyline、PolyPolyline和PolylineTo。这三个函数中,Polyline和PolyPolyline既不使用当前位

42、置,也不更新当前位置;而PolylineTo总是把当前位置作为起始点,并且在折线画完之后,还把折线终点所在位置设为新的当前位置。BOOL Polyline( LPPOINT lpPoints, int nCount );BOOL PolylineTo( const POINT* lpPoints, int nCount );这两个函数用来画一系列连续的折线。参数lpPoints是POINT或CPoint的顶点数组;nCount表示数组中顶点的个数,它至少为2。BOOL PolyPolyline( const POINT* lpPoints, const DWORD* lpPolyPoints,

43、 int nCount );此函数可用来绘制多条折线。其中lpPoints同前定义,lpPolyPoints表示各条折线所需的顶点数,nCount表示折线的数目。7.3.2 矩形和多边形虽然利用前面的直线、折线也可画出矩形和多边形来,但CDC中提供的相关函数使其更胜一筹。,7.3图形绘制,1. 矩形和圆角矩形CDC提供的Rectangle和RoundRect函数分别用于矩形和圆角矩形的绘制,它们的原型如下:BOOL Rectangle( int x1, int y1, int x2, int y2 );BOOL Rectangle( LPCRECT lpRect );BOOL RoundRec

44、t( int x1, int y1, int x2, int y2, int x3, int 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.5所示。2. 设置多边形填充模式多边形填充模式决定了图形填充时寻找填充区域的方法,有两种选择:ALTERNATE和WINDING。ALTERNATE模式是寻找

45、相邻的奇偶边作为填充区域,而WINDING是按顺时针或逆时针进行寻找;一般情况,这两种模式的填充效果是相同的,但对于像五角星这样的图形,填充的结果大不一样,例如下面的代码,其结果如图7.6所示。,7.3图形绘制,7.3图形绘制,.POINT pt5=247,10,230,90,290,35,210,30,275,85;CBrush brush(HS_FDIAGONAL,RGB(255,0,0);CBrush* oldbrush=pDC-SelectObject(,7.3图形绘制,7.3.3 曲线同点、直线一样,圆弧也是图形的基本元素。CDC提供的圆弧及曲线成员函数可以方便地生成各种非规则形状的

46、图形。1. 圆弧和椭圆通过调用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 );,这里,x1,y1,x2,y2或lpRect用来指定外接矩形的位置和大小,而椭圆中心与点(x3,y3)或ptStart所构成的射线与椭圆的交点就成为椭圆弧线的起始点,椭圆中心与点(x4

47、,y4)或ptEnd所构成的射线与椭圆的交点就成为椭圆弧线的终点。椭圆上弧线始点到终点的部分是要绘制的椭圆弧(如图7.7所示)。,7.3图形绘制,需要说明,要唯一地确定一条椭圆弧线,除了上述参数外,还有一个重要参数,那就是弧线绘制的方向。默认时,这个方向为逆时针,但可以通过调用SetArcDirection函数将绘制方向改设为顺时针方向。int SetArcDirection( int nArcDirection );该函数成功调用时返回以前的绘制方向,nArcDirection可以是AD_CLOCKWISE(顺时针) 或AD_COUNTERCLOCKWISE(逆时针)。此方向对函数Arc、P

48、ie 、ArcTo、Rectangle、Chord、RoundRect、Ellipse有效。另外,ArcTo也是一个画圆弧的CDC成员函数,它与Arc函数的唯一的区别是:ArcTo函数将圆弧的终点作为新的当前位置,而Arc不会。BOOL ArcTo( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 );BOOL ArcTo( LPCRECT lpRect, POINT ptStart, POINT ptEnd );与上述函数相类似, 调用CDC成员函数Ellipse可以用当前画刷绘制一个椭圆区域。BOOL Ellip

49、se( int x1, int y1, int x2, int y2 );BOOL Ellipse( LPCRECT lpRect );参数x1,y1,x2,y2或lpRect表示椭圆外接矩形的大小的位置。,7.3图形绘制,2. 弦形和扇形 CDC函数Chord和Pie是用来绘制弦形(图7.8)和扇形(图7.9),它们具有和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 x4, int y4 );BOOL Pie( LPCRECT lpRect, POINT ptStart, POINT ptEnd );3. Bzier曲线Bzier曲线是最常见的非规则曲线之一,它的形状不仅便于控制,而且更主要的是它具有几何不变性(即它的形状不随坐标的变换而改变),因此在许多场合往往采用这种曲线。Bzier曲线属于三次曲线,只需给定四个点(第一和第四个点是端点,另两个是控制点),就可唯一确定其形状,如图7.10所示。,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报