1 / 60

第 7 章屏幕绘图及文本显示

第 7 章屏幕绘图及文本显示. 7.1GDI 与设备描述表 7.1.1GDI 的基本概念 Windows 图形设备接口 GDI ( Graphical Device Interface )是为与设备无关的图形设计的。所谓 设备的无关性 ,就是操作系统屏蔽了硬件设备的差异,因而设备无关性能使用户编程时无需考虑特殊的硬件设置。

alika
Télécharger la présentation

第 7 章屏幕绘图及文本显示

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第7章屏幕绘图及文本显示

  2. 7.1GDI与设备描述表7.1.1GDI的基本概念 Windows图形设备接口GDI(Graphical Device Interface)是为与设备无关的图形设计的。所谓设备的无关性,就是操作系统屏蔽了硬件设备的差异,因而设备无关性能使用户编程时无需考虑特殊的硬件设置。 Windows把与绘图工作相关的操作都制作成了函数,GDI提供了用户可以调用的一套用于绘图的函数集。无论基础硬件如何,同一函数都能够生成相同结果。例如,调用GDI函数中的Ellipse函数可以绘制椭圆,调用TextOut函数可以绘制文本,调用Rectangle函数可以绘制矩形等。 除了这些绘图函数之外,GDI还有一套用于绘图的工具(对象),比如画刷、画笔等。 文本被看作是图形,这种处理方式虽然在创建文本输出时增加了复杂度,但也增强了灵活性。可以让原本在文本世界非常困难的工作变得非常轻松。

  3. 7.1.2设备描述环境 为了简化应用这些性质不同的设备的访问,实现与设备无关的绘图操作,Windows 提供了一种叫做设备描述表的机制,也称为设备环境DC(Device Context),它是Windows 应用程序与设备驱动程序和输出设备(如打印机、显示器等)之间的接口,用来作为应用程序与控制输出设备的低层之间的通道。 设备描述表是一种可以在其上绘图的“逻辑画布”,它接收应用程序的绘图命令,再将其翻译为控制设备驱动程序的低层指令。程序员可以在这个虚拟的图形显示对象上进行绘图,而把这个图形最终转换为实际物理设备上图形的工作则交给系统去完成。 设备环境DC(Device Context)是由GDI保存的一个数据结构,设备环境包含了输出设备的绘图特征,不同设备有不同的设备环境,在输出设备上输出的先决条件是获得该设备的设备环境。例如,为了在屏幕上显示绘图,Window程序必须有该显示器的一个DC。为了在打印机输出,还需要另一个专门为打印机创建的DC。

  4. 程序员使用GDI函数在设备描述环境中绘图 Windows 中的设备描述表(硬件多态)分为以下4 种类型。 (1)显示器型:支持显示器上的绘图操作。 (2)打印机型:支持打印机和绘图仪上的绘图操作。 (3)内存型:支持位图上的绘制操作。 (4)信息型:支持设备数据的访问。 打印机 设备描述环境 绘图仪 显示器

  5. 为了方便,Windows系统初始化了一套DC的属性和对象,表7-1为显示器DC的属性及默认值,获得了该设备的DC后,程序设计人员就可以在这个默认的环境下开始绘图工作了。当然,如果程序员对预置的属性和对象不满意的话,也可以按自己的要求对它们进行设置。例如,默认的DC中预置了一支黑色画笔,所以这时用GDI的绘图函数绘制的任何线条都是黑色的。如果想使用其它颜色绘制线条的话,程序员可以用其它颜色的画笔来替换这支黑色的画笔。DC在任何时候总是必须存在着一套完整的绘图工具。这意味着,不能从DC中删除一个工具,只能用一个工具替换另一个工具。绘图过程可描述为使用GDI 对象(逻辑画笔或画刷等)在设备描述表(逻辑画布)上绘制的过程

  6. 7.2CDC类 MFC的CDC类对设备描述表和GDI 函数进行了全面的封装,使这两者的使用更加方便。CDC 类是一个通用的类,可以从它派生出特定类型的DC子类。 1.CDC 类的成员函数 由于DC 与屏幕绘图及文本显示操作密切相关,CDC 类的成员函数主要包括以下几类: (1)初始化函数,比如为指定的设备创建设备描述符表等。 (2)设备描述符表函数,比如保存或恢复DC的状态等。 (3)绘图及其相关函数,比如设置绘图前景颜色、背景颜色、绘图工具选择、图形绘制等。 (4)文本与字体函数,比如文本输出、字体信息的取得等。 (5)坐标与映射函数,比如设置映射方式、各种坐标的转换等。

  7. 2.几种派生的CDC类

  8. CPaintDC是所有CDC类中最常用的一个类,它代表了应用程序窗口的客户区,它只能使用在CView类的OnDraw函数中。OnDraw函数的声明为:CPaintDC是所有CDC类中最常用的一个类,它代表了应用程序窗口的客户区,它只能使用在CView类的OnDraw函数中。OnDraw函数的声明为: Void OnDraw(CDC*pDC); 对应用程序窗口的客户区进行绘图的所有代码都必须写(被调用)在这个函数中。应用程序窗口在每次创建及需要刷新时就会产生WM_PAINT消息,如用户区移动或显示,用户窗口大小改变,程序通过滚动条滚动窗口,窗口被另一个窗口覆盖的恢复,还有下拉式菜单关闭等,这些情况下就会发送WM_PAINT消息。系统接收到这个消息就会自动调用OnDraw函数。这个函数的参数pDC就是指向CPaintDC对象的指针,在OnDraw的函数体中,就可以通过这个指针来使用DC类的成员函数进行绘图操作了。

  9. 【例7-1】在用户区显示字符串“Hello”。 (1)用MFCAppwizard创建一个名称为ex7_1的单文档应用程序框架。 (2)在视图类中的OnDraw函数中添加语句:pDC->TextOut(50,50, “HELLO ”),即视图类的代码为: void CEx7_1View::OnDraw(CDC *pDC) { CEx7_1Doc *pDoc=GetDocument(); ASSERT_VALID(pDoc); //TODO : add draw code for native data here pDC->TextOut(50,50,"HELLO");//输出字符串的语句 } 对于WM_PAINT 消息的响应,框架代码已经做了大量的工作,已经自动处理了DC的申请与释放的问题,用户所要做的只是在OnDraw()函数内完成绘图工作即可。下面的几节中,主要是在CPaintDC中绘图。

  10. 7.3映射模式 映射模式是设备描述符表DC 的一个重要属性,它影响到GDI 绘图及文本的显示效果。 7.3.1设备坐标 图形或文字要在物理设备(如显示器、打印机等)上输出,就必须使用该物理设备的坐标系统,称为设备坐标。设备坐标以设备的最小分辨单位——像素为基本单位,以左上角为坐标原点,X 轴向右延伸,Y 轴向下延伸 最常用的设备坐标就是屏幕的设备坐标,这里面又包含几种具体的设备坐标系。若以整个屏幕为范围,就是“屏幕坐标系统”,像WM_MOVE消息这样不依赖于窗口的消息,必须以整个屏幕为参照物,使用的是屏幕坐标。若以整个窗口为基准,将标题栏、菜单、滚动条、窗口边框等均计算在内,这种坐标称为“窗口坐标系统”,一般情况下窗口坐标较少使用。若以窗口的用户区为范围,点(0 , 0 )位于用户区的左上角,这种坐标称为用户区坐标,这是最常用的一种设备坐标。

  11. 7.3.2逻辑坐标 如果直接使用设备坐标绘图,由于屏幕和打印机的分辨率不同,同样是100个像素长的一条直线,在两种设备上的实际输出长度将不相同。假设程序员想画一条在两种设备上都是10cm长的直线,将不得不针对屏幕和打印机的分辨率分别计算它们各需要包含多少个设备像素。为了解决这个问题,在GDI 绘图中使用了逻辑坐标这一概念。逻辑坐标使用的是逻辑单位,逻辑单位与设备无关,比如逻辑单位是0.lmm ,则一条100 个逻辑单位长的直线,不论是显示在屏幕上,还是输出到打印机上,都是10cm 长。虽然最终显示或打印时仍然要使用像素点(设备坐标),但一个逻辑单位应该映射为物理设备上的多少个像素点,是由Windows 自动处理的。 本章后面几小节介绍的GDI 绘图函数使用的都是逻辑坐标。

  12. 坐标变换(曲面to平面) • 屏幕的高(y)和宽(h),地理坐标区域的范围(maxLon,minLon,maxLat,minLat) • 比例因子:算出每像素所代表的经度和纬度 • scaleX = ((maxLon-minLon)*3600)/h --X轴每像素代表的经度秒数; • scaleY = ((maxLat-minLat)*3600)/y ---Y轴每像素代表的纬度秒数; • 经纬度转屏幕坐标公式 • X = (lon - minLon)*3600/scaleX; • Y = (maxLat - lat)*3600/scaleY; • 屏幕坐标转经纬度坐标公式 • lon = X * scaleX/3600 + minLon; • lat = maxLat - y* scaleY/3600; • 为了保证精度,地理坐标的度*3600换算成秒,所有的取值用double来计算,最后的结果再转换成int。

  13. 7.3.3映射模式 映像模式定义了将逻辑单位转化为设备的度量单位的方法以及设备的X方向和Y方向,程序员可在一个统一的逻辑坐标系中操作而不必考虑输出设备的坐标系情况。映射模式对应用程序是很重要的。Windows 中定义了8 种映射模式

  14. MM _ TEXT 是最简单的一种映射模式,也是默认的映射模式,它使得逻辑坐标完全等价于设备坐标。其它几种映射模式下,逻辑坐标的原点也位于窗口的左上角,但对于Y 轴是向下增长的。 MM_ANISOTROPIC和MM_ISOTROPIC这两种映射模式通过将图形从程序员定义的逻辑坐标窗口映射到物理设备的视口以实现坐标转换。窗口是对应逻辑坐标系上程序员设定的区域,视口是对应实际输出设备上程序员设定的区域。这两种映射模式的区别是MM_ANISOTROPIC按照窗口和视口的坐标比例进行映射,而MM_ISOTROPIC将窗口中的对称图形映射到视口时仍为对称图形。在MM_ISOTROPIC映射模式下,圆总是圆的,但是在MM_ANISOTROPIC映射模式下,圆可以被拉扁成椭圆形状。 1.映射模式的设置 要改变DC的映射模式,可以使用CDC类的SetMapMode( )函数,函数原型形为:virtual int SetMapMode ( int nMapMode); 参数nMapMode 是新设置的映射模式,函数的返回值是DC先前的映射模式。 若要取得DC 当前的映射模式,可以使用CDC类的函数GetMapMode( ),函数原型形为:int GetMapMode ( ) const ; 此函数的返回值是当前的映射模式。

  15. 【例7-2】将“Hello World”显示在离客户区左边和上边各l 英寸的地方。 (1)用MFCAppwizard创建一个名称为ex7_2的单文档应用程序框架。 (2)在视图类中的OnDraw函数中添加语句,添加后的代码为: void CEx7_2View::OnDraw(CDC *pDC) { CEx7_2Doc *pDoc=GetDocument(); ASSERT_VALID(pDoc); //TODO : add draw code for native data here pDC->SetMapMode(MM_LOENGLISH) ; pDC->TextOut (100 ,-100 , “Hello World” ) ; //输出字符串的语句 }

  16. 2、设置窗口和视口的大小 窗口区域的定义由SetWindowExtEx函数完成,其函数原型为: BOOL SetWindowExtEx ( int nHeight //以逻辑单位表示的窗口区域高度 int nWidth, //以逻辑单位表示的窗口区域宽度 LPSIZE lpSize, //函数调用前窗口区域尺寸的SIZE结构地址 ); 视口区域的定义由SetViewportExtEx函数完成,函数原型为: BOOL SetViewportExtEx ( int nHeight //以逻辑单位表示的视口区域高度 int nWidth, //以逻辑单位表示的视口区域宽度 LPSIZE lpSize //函数调用前视口区域尺寸的SIZE结构地址 ); 设置窗口和视口的大小只有在映射模式为MM_ANISOTROPIC和MM_ISOTROPIC时才有意义。

  17. 7.4绘图工具的使用 Windows 提供了一些工具用于绘图,这些工具有:画笔(Pen)、画刷(Brush)、位图( Bitmap)、字体(Font)、调色板(Palette)、区域(Region)等,这些都称为GDI 对象。 7.4.1GDI绘图工具介绍 1.画笔 画笔是一种用来画线或有形边框的工具,可以指定它的颜色及宽度,也可以指定线型(实线、点线、虚线等)。 2.画刷 画刷(或称为刷子)定义了一种位图形式的像素模板,利用它可以对区域内部填以颜色。 3.位图 位图定义了每个显示像素的颜色,可以用来表示图像,以及图标、光标、刷子等的形状。

  18. 4.字体 字体是一种具有某种风格和尺寸的所有字符的完整集合,它常常被当作资源存在磁盘中。字体用来控制文字的显示。 5.调色板 调色板是一种颜色映射表,利用它可以使应用程序最大可能地使用输出设备的颜色输出能力,而无须严重于扰其它程序使用的颜色。 6.区域 区域由位于一个窗口内的椭圆或多边形组合而成,可以用来进行填充、剪裁以及鼠标选中测试等。 MFC 中用CPen类封装了Windows 的画笔、用CBrush 类封装了Windows 的画刷、用CBitmap即类封装了Windows 的位图、用CFont 类封装了Windows 的字体、用CPalette 类封装了Windows 的调色板、用CRgn 类封装了Windows 的区域。

  19. 7.4.2画笔 1.创建画笔 一步构造法: 利用CPen 类的带参构造函数来完成画笔对象的创建及初始化。CPen 类的带参构造函数有两个重载版本,下面介绍最常用的一个。 • CPen类的构造函数为: CPen ( int nPenstyle , int nWidth , COLORREF crColor ) 样式 宽度 颜色 CPen Pen1 ( PS_DASH , 5 , RGB ( 255 , 0 , 0 ) ) ;//栈中stack / /创建5 个单位粗红色虚线的画笔

  20. 参数nPenstyle 指定画笔的风格,表7-4中列出了最常用的取值。

  21. 参数nwidth 指定笔的宽度。 参数crColor用来以RGB值设置画笔的颜色。 Windows定义的一个用红、绿、蓝分色定义颜色的宏: RGB COLORREF RGB( BYTE bRed, //红色(0~255) BYTE bGreen,//绿色(0~255) BYTE bBlue //蓝色(0~255) ); RGB ( 0, 0 , 0 ) / /黑色 RGB ( 255 , 0 , 0 ) / /红色 RGB ( 255 , 255 , 255 ) / /白色 RGB ( 128 , 128 , 128 ) / / Windows 里的标准灰色 CPen Pen1(PS_DASH , 1 , RGB ( 255 , 0 , 0 )); / /创建1 个单位粗、红色、虚线的画笔

  22. 二步构造法:首先用CPen 类的无参构造函数构造CPen 类的对象,然后调用CPen 类的CreatePen( ) 函数初始化画笔对象。 BOOL CreatePen ( int nPenstyle , int nWidth , COLORREF crColor ) 样式 宽度 颜色 CPen Pen2; Pen2.CreatePen ( PS_DASH , 5 , RGB ( 255 , 0 , 0 ) ) ; //创建5 个单位粗红色虚线的画笔, //栈中stack

  23. 动态构造法:首先new出CPen 类的有参或无参构造函数构造CPen 类的对象及初始化画笔对象。然后,使用画笔对象,最后delete删除对象。 CPen *npen = new CPen(style[s],1,color);//3,堆中heap CPen *oldPen=pDC->SelectObject(npen);//3 pDC->MoveTo(20,row); pDC->LineTo(300,row); pDC->SelectObject(oldPen); red+=32; green+=16; blue+=8; row+=20; delete npen;//3,释放堆内存

  24. 2.将画笔载入DC 在创建了画笔之后,必须使用CDC的成员函数Selectobject把画笔载入DC,以替换DC中原来配置的默认画笔,然后才能使用该画笔绘制线条。Selectobject函数的原型为: CPen*Selectobject(CPen*pPen); 其参数为欲载入画笔的指针,返回值为原来画笔的指针。因为在DC内只能存在一个画笔对象,所以在程序中应定义一个保存原画笔的指针变量,来保留Selectobject函数的返回值,以便在新画笔使用后,恢复原画笔。即在程序中应有如下代码: CPen newPen(PS_SOLID,width,color); //创建新画笔 CPen*oldPen=pDC->Selectobject(&newPen); //载入新画笔并把旧画笔存入指针变量oldPen 一旦将画笔或画刷等选进设备描述表对象,它会保留在设备描述表对象内一直到再次选入新的画笔或画刷为止。为了不影响其它模块的绘图工作,一般在一个函数内改变了设备描述符表的画笔或画刷等属性时,应在该函数退出前再恢复设备描述符表原来的属性,方法是调用SelectObjeet ( )函数并以旧的画笔或画刷作为其参数。使用如下代码: pDC->Selectobject(oldPen); 以把保存在指针oldPen中的旧画笔重新载入DC。

  25. 【例7-3】一个绘制多种画笔样式及多种颜色线条的应用程序。【例7-3】一个绘制多种画笔样式及多种颜色线条的应用程序。 (1)用MFC AppWizard创建一个名称为ex7_3的单文档应用程序框架。 (2)在视图类中的OnDraw函数中添加语句,添加后的代码为: void CEx7_3View::OnDraw(CDC *pDC) { CEx7_3Doc *pDoc=GetDocument(); ASSERT_VALID(pDoc); //TODO : add draw code for native data here int style[]={PS_SOLID,PS_DASH,PS_DOT,PS_DASHDOT,PS_DASHDOTDOT }; int red=0,green=0,blue=0; int row=20;

  26. for(int s=0;s<5;s++) { int color=RGB(red,green,blue); CPen newPen(style[s],1,color); CPen *oldPen=pDC->SelectObject(&newPen); pDC->MoveTo(20,row); pDC->LineTo(300,row); pDC->SelectObject(oldPen); red+=32; green+=16; blue+=8; row+=20; } }

  27. 7.4.3画刷 画笔用来画图,而画刷用来对所画封闭图形进行填充,默认情况下用背景颜色进行填充。如果需要使用新颜色或者图案对一个封闭的图形内部进行填充,就要创建并载入画刷。可以创建并选择一个空画刷,使Windows 不对图形进行填充,这样画图时就不会覆盖原来屏幕上的内容。 1.创建画刷 创建画刷有两种方法:一步构造法和二步构造法。 一步构造法 在使用画刷之前,要使用CBrush类的构造函数来完成画刷对象的创建及初始化,构造函数的原型为: CBrush(COLORREF color); 和CBrush(int style,COLORREF color); 其中,参数style用来决定画刷的样式,color用来决定画刷的颜色.参数style可选值见表7-5。

  28. CBrush Brush1(RGB( 0 , 255 , 0) ) ; //创建绿色画刷 CBrush Brush2(HS_CROSS,RGB( 0 , 255 , 0) ) ; //创建绿色十字交叉线画刷

  29. 二步构造法 首先用CBrush 类的无参构造函数构造CBrush 类的对象,然后调用CBrush 类的CreateSolidBrush()或CreateHatchBrush ( )等函数初始化画刷对象。 (1)用CreateSolidBrush()函数可以创建实心的画刷(内部用单一颜色均匀填充),格式如下: bool CreateSolidBrush (COLORREF crColor ) ; 参数crColor 指定画刷的颜色。 返回值:如果函数运行成功,返回非0 值,否则返回0。 例如: CBrush Brush3 Brush3. CreateSolidBrush (RGB (0,255, 0)); //创建绿色画刷 (2)用CreateHatchBrush()函数可以创建影线的画刷(内部用斜线或网线填充),格式如下: bool CreateHatchBrush(int style, COLORREF color); 参数style用来决定画刷的样式,color用来决定画刷的颜色。 返回值:如果函数运行成功,返回非0 值,否则返回0。

  30. 例如: CBrush Brush4 Brush4. CreateHatchBrush(HS_CROSS,RGB(0 , 255 , 0)) ; //创建绿色十字交叉线画刷 2.将画刷载入DC 与使用画笔一样,在创建了画刷之后,如果要使用该画刷,则应该使用CDC类的成员函数SelectObject(),把画刷选入设备描述环境。函数原型如下: CBrush*SelectObject(CBrush*pBrush); 还要定义一个画刷指针,用来保存该函数返回的旧画刷指针。 3.动态构造法(?)

  31. 【例7-4】画刷的应用。 (1)用MFC AppWizard创建一个名称为ex7-4的单文档应用程序框架。 (2)在视图类的函数OnDraw中输人如下代码: void CEx7_4View::OnDraw(CDC *pDC) { CEx7_4Doc *pDoc=GetDocument(); ASSERT_VALID(pDoc); //TODO : add draw code for native data here int red=0,green=0,blue=0; int row=10; int style[]={HS_BDIAGONAL,HS_CROSS,HS_DIAGCROSS,HS_FDIAGONAL, HS_HORIZONTAL,HS_VERTICAL};

  32. for(int s=0;s<6;s++) { int clr=RGB(red,green,blue); CBrush newBrush(style[s], clr); CBrush *oldBrush=pDC->SelectObject(&newBrush); pDC->Rectangle(20,row,200,row+10); pDC->SelectObject(oldBrush); row+=20; } }

  33. 7.5绘图模式 在Windows中,绘图的最终效果可以通过设定不同的绘图模式来修饰。绘图模式决定新绘制的图形与屏幕上原有内容的逐位交互关系。例如以黑色画笔画线,当所画线经过屏幕上的一块黑色区域时,线将不可见,通过设置绘图模式可以让线在经过黑色区域时自动变为白色,从而达到可见的目的。 设置绘图模式的CDC成员函数为: SetROP2(int nDrawMode); 其中,参数nDrawMode为欲设置的绘图模式,返回值为原来的绘图模式。绘图模式的选项范围从完全忽略屏幕显示内容用画笔简单地画图到完全忽略画笔仅保留屏幕内容。Windows 有16 种不同的绘图模式

  34. 如果用R2_NOT绘图模式,它简单地以逐位方式改变屏幕上的显示。用此画笔绘图时,白色将变为黑色,黑色将变为白色。如果用它再一次绘制同一条直线,它将擦除直线,并恢复原来屏幕颜色。如果用R2_NOT绘图模式,它简单地以逐位方式改变屏幕上的显示。用此画笔绘图时,白色将变为黑色,黑色将变为白色。如果用它再一次绘制同一条直线,它将擦除直线,并恢复原来屏幕颜色。 获得绘图模式的CDC成员函数为: int GetROP2 ( ) const ; //不允许修改 此函数返回当前的绘图模式。

  35. 1.画点函数SetPixel SetPixel( )函数用于画点,它有两个重载版本,函数原形如下: COLORREF SetPixel ( int X , //参数X为点的横坐标 int Y, //参数Y为点的纵坐标 COLORREF crColor //参数crColor为点的颜色 ) COLORREF Setpixel ( POINT point , //参数point为点位置的POINT 类型变量 COLORREF crColor ) SetPixel( )函数的返回值是实际所画点的颜色,若操作失败(如指定的点位置在客户区之外),则返回l 。 7.6常用CDC类绘图函数 CDC类封装了大量的绘图函数,下面介绍常用的函数。

  36. 2.设置画笔当前位置的函数MoveTo的原型如下:2.设置画笔当前位置的函数MoveTo的原型如下: CPoint MoveTo ( int X, //参数X、Y 指定当前点的新位置 int Y ) CPoint MoveTo ( POINT point //参数point 指定当前点的新位置 ) 3.从当前位置向指定坐标点画直线的函数LineTo BOOL LineTo ( int X, //参数X、Y 指定直线的终点位置 int Y ) BOOL LineTo ( POINT point //参数point 指定直线的终点位置 )

  37. 4.从当前位置开始,依次用线段连接lpPoints中指定各点的函数Ployline4.从当前位置开始,依次用线段连接lpPoints中指定各点的函数Ployline BOOL Polyline ( LPPOINT lpPoints, //指向包含各点坐标的POINT结构数组的指针 int nCount // nCount为POINT数组中点的个数 ) 例如 POINT points[6]={{100,212},{70,227},{70,250},{130,250},{130,227},{100,212}}; Polyline(points,6); //画一个五边形

  38. 所画曲线 (x1,y1) (x4,y4) (x3,y3) (x2,y2) • 5. 绘制椭圆弧线的函数Arc, • BOOL Arc • ( • int X1,intY1, //边框矩形左上角的逻辑坐标 • int X2,int Y2, //边框矩形右下角的逻辑坐标 • int X3,int Y3, //椭圆弧起始点坐标 • int X4,int Y4 //椭圆弧终止点坐标 • )

  39. 所填区域 (x1,y1) (x4,y4) (x3,y3) (x2,y2) • 6. 绘制饼图,并用当前画刷进行填充 • BOOL Pie • ( • int X1,intY1, //边框矩形左上角的逻辑坐标 • int X2,int Y2, //边框矩形右下角的逻辑坐标 • int X3,int Y3, //椭圆弧起始经线的确定点坐标 • int X4,int Y4 //椭圆弧终止经线的确定点坐标 • )

  40. 7. 绘制矩形,并用当前画刷进行填充 BOOL Rectangle(int X1,int Y1,int X2,int Y2) (X1,Y1)和(X2,Y2)分别为矩形的左上角和右下角的逻辑坐标 圆角的高度和宽度 8. 绘制圆角矩形,并用当前画刷填充 BOOL RoundRect (int X1,int Y1,int X2,int Y2, int nHeight, int nWidth) 9. 绘制椭圆,并用当前画刷填充 BOOL Ellipse(intX1,intY1,intX2,intY2) 10.绘制多边形,并用当前画刷填充 BOOL Polygon(LPPOINT lpPoints,int nCount) 包含各点坐标的 POINT数组的地址 多边形点的个数

  41. 11.图形填充函数FloodFill 该函数的原型如下: FloodFill ( int x , //参数x 为点的横坐标, int y , //参数y 为点的纵坐标 COLORREF crColor //参数crColor为边界颜色 ) 用CDC 类的FloodFill ( )成员函数可完成对封闭图形的填充。点的坐标必须位于被填充的封闭图形内,边界颜色参数指定Windows 遇到该颜色时就停止填充工作。图形必须是封闭的,否则会由于在某一方向上遇不到指定边界颜色而填充整个窗口。 例如: CDC dc dc.SetROP2 (R2_BLACK ) ; //此句设定用黑色对图形进行填充 dc.FloodFill(point.x, point.y, RGB(0, 0, 0)) ; //对point 指定点所在的封闭图形填充,图形的边线为黑色

  42. 7.7绘图过程及应用实例 在MFC环境下绘图时,首先用MFC应用程序向导创建一个的单文档或多文档应用程序框架,然后在视图类中的OnDraw()函数中TODO语句后面添加语句,实现具体的绘图功能,具体步骤如下: (1)设置映像模式:逻辑单位转化为设备坐标的单位和xy轴向 (2)设置窗口、视口大小: MM_ANISOTROPIC和MM_ISOTROPIC (3)设置画笔:3 (4)设置画刷:3 (5)画笔选入设备环境:pDC-> SelectObject (6)画刷选入设备环境pDC-> SelectObject (7)设置绘图模式:新旧图形关系 (8)用绘图函数绘制各种图形 其中的1-7步可以省略,使用默认值绘图。

  43. 【例7-5】试用MFC屏幕绘图方法绘制图形,要求雪人的位置不随窗口大小的改变而改变,雪人形状如图7-7所示。【例7-5】试用MFC屏幕绘图方法绘制图形,要求雪人的位置不随窗口大小的改变而改变,雪人形状如图7-7所示。

  44. 新建一个单文档应用程序ex7_5。 在View类函数OnDraw(CDC* pDC)中添加下列代码: void CEx7_5View::OnDraw(CDC* pDC) { CEx7_5Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here RECT rect; GetClientRect(&rect); //RECT中的元素,left窗口左上角x 坐标;top窗口右上角y坐标一般为(0,0) //right窗口右下角x坐标;bottom窗口右下角y的坐标 pDC->SetWindowOrg(rect.left,rect.top); pDC->SetViewportOrg(rect.left,rect.top); pDC->SetViewportExt(rect.right,rect.bottom); pDC->SetWindowExt(rect.right/2,rect.bottom/2);

  45. CPen pen1(PS_SOLID,1,RGB(0,0,0)); CBrush brush1(RGB(255,251,240)); CBrush brush2(RGB(255,0,0)); CBrush brush3(RGB(160,160,164)); CPen*oldpen=pDC->SelectObject(&pen1); pDC->SelectObject(&brush3); pDC->Ellipse(115,250,336,285); //雪人影子 pDC->SelectObject(&brush1); pDC->Ellipse(27,99,233,280); //雪人身子 pDC->Ellipse(81,22,177,118); pDC->SelectObject(&brush2); pDC->Ellipse(113,54,129,70); //雪人眼睛 pDC->Ellipse(145,54,161,70);

  46. CPoint points[3]; //雪人鼻子 points[0].x = 139; points[0].y = 79; points[1].x = 171; points[1].y = 75; points[2].x = 139; points[2].y = 94; pDC->Polygon(points,3); }

  47. class CSnowMan类设计 • class CSnowMan{ • public: • CSnowMan(){} • CSnowMan(CShowManDoc* pDoc, CDC* pDC){ • m_pDoc=pDoc; • m_pDC=pDC; • } • void makeSnowman(int , RECT, int); • private: • //CString m_id; • vector<SnowMan> snowman; • CShowManDoc* m_pDoc; • CDC* m_pDC; • }; • struct SnowMan{ • CHead head; • CEye leye; • CEye reye; • CNose nose; • CBody body; • CArm larm; • CArm rarm; • CLeg lleg; • CLeg rleg; • };

More Related