《visual c++实用教程 第8章:利用cdc实现绘图程序.ppt》由会员分享,可在线阅读,更多相关《visual c++实用教程 第8章:利用cdc实现绘图程序.ppt(69页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、Visual C+Visual C+第第8章章利用利用CDC实现绘图程序实现绘图程序 8.8.1 图形绘制的基本知识图形绘制的基本知识 8.2VC的文本操作8.3 CDC的绘图操作8.4Windows绘图工具习题Visual C+Visual C+教学要点教学要点 本章内容包括设备环境与绘图程序的关系,设备环境主要功能以在MFC对应的CDC类,利用设备环境类CDC操纵文本(文本的字体、颜色和属性控制),利用设备环境类CDC实现简单图形的绘制(点、线、椭圆、矩形和弧等),各种绘图工具(画笔、画刷)使用。要求了解CDC编写的绘图程序调用GDI,进而调用设备驱动程序的流程,CDC的几个派生类及其使用
2、,掌握CDC的文本操作和图形绘制、常见的绘图参数设置函数的用法、常见的绘图工具画笔和画刷的使用,熟练掌握调用API或CDC成员函数选择库存中的绘图工具。Visual C+Visual C+8.1 图形绘制绘制的基本知识8.1.1一个简单的图形程序8.1.2图形操作的接口GDI8.1.3图形操作有关的CDC类8.1.4CDC的内容Visual C+Visual C+8.1.1一个一个简单的图形程序 为了理解利用MFC编制图形程序的过程,也为了理解图形程序所用到的概念和原理,我们以一个简单的图形程序(仅仅用到了文本输出函数TextOut)为例,讲解程序的生成步骤及编写代码的步骤。该程序是利用MFC
3、AppWizard向导生成的第一个程序,我们对MFC编程的初步理解是:首先掌握AppWizard向导生成的步骤,然后理解AppWizard生成的应用程序架构包含哪些主要类,最后知道我们编写处理问题的代码放到MFC应用程序架构的什么地方。Visual C+Visual C+【例【例8-1】利用】利用MFC编写一个简单的绘图程序编写一个简单的绘图程序1.利用AppWizard生成应用程序架构(1)启动)启动VC6.0,选择选择“File”菜单的菜单的“New”命令,在命令,在弹出的弹出的“New”对话框中选择对话框中选择“Project”选项卡。在该选项卡。在该选项卡的列表中选择选项卡的列表中选择
4、“MFC AppWizard(exe)”项,在项,在“Project Name”编辑框中输入要创建的工程名称编辑框中输入要创建的工程名称SingleDraw,在在“Location”编辑框中设置工程的存编辑框中设置工程的存放位置,单击放位置,单击“OK”按钮。按钮。(2)在弹出的)在弹出的“MFC AppWizard-Step1”对话框中选择对话框中选择“single document”,即应用程序的类型为单文档模即应用程序的类型为单文档模式,然后单击式,然后单击“Finish”按钮。按钮。(3)在弹出的)在弹出的“New Project information”对话框中单对话框中单击击“OK
5、”按钮,完成应用程序框架的创建。按钮,完成应用程序框架的创建。Visual C+Visual C+【例【例8-18-1】续】续1 1 2应用程序架构包含的主要类 该程序主要包含的类有该程序主要包含的类有CAboutDlg关于对话框类、关于对话框类、CMainFrame主框架类、主框架类、CSingleDrawDoc文文档类、档类、CSingleDrawView视图类。视图类。有关绘制功能的实现,一般是在视图类中完成,有关绘制功能的实现,一般是在视图类中完成,因此,这一章的实例都是对视图类因此,这一章的实例都是对视图类CSingleDrawView的操作。的操作。Visual C+Visual
6、C+【例【例8-18-1】续】续2 2 3将代码放到MFC的某个类的虚函数或消息映射函数中绘图功能的实现,一般要超载视图类的OnDraw()虚函数,打开WorkSpace的ClassView选项卡,展开CSingleDrawView视图类,可以看到该类中有一个虚函数该类中有一个虚函数OnDraw(),双击该函数,就把光标定位到该函数的实现处,在其中编写代码如下:voidCSingleDrawView:OnDraw(CDC*pDC)CSingleDrawDoc*pDoc=GetDocument();ASSERT_VALID(pDoc);pDC-TextOut(100,100,“在视图类的在视图类
7、的 OnDraw虚函数中输出的最简单的一个图虚函数中输出的最简单的一个图 形程序形程序);Visual C+Visual C+【例【例8-18-1】续】续3 34运行程序编译并运行该程序(按Ctrl+F5热键),在屏幕上显示了一行文本。利用MFC的应用程序向导,我们仅写了一行代码,就完成了一个简单的图形程序输出文本图形。从代码量上是简单了,但要理解整个图形程序的显示过程,却有许多工作要作,下面就围绕与图形输出有关的内容来讲解图形程序的编写过程和原理。Visual C+Visual C+8.1.2图形操作的接口图形操作的接口GDI任何图形程序的输出,都离不开图形设备接口GDI(GraphicDe
8、viceInterface),它是管理Windows应用程序在窗口内的绘图操作和与此相关的许多其它信息。如图形设备(打印机、显示器)的信息、绘图的坐标系统和映射模式、绘图工具的当前状态(什么样的画笔、画刷、文本的前景色与背景色、文本所使用的字体)。Windows的GDI绘制的各种图形(点、线、圆、多边形、矩形等)是与设备无关的,即在屏幕的窗口内绘图与在打印机上绘图是相似的。GDI是一个可执行程序,它接收Windows应用程序的绘图请求(表现为GDI调用),并将它们传送给相应的设备驱动程序,再由设备驱动程序驱动相应的硬件设备,如打印机或显示器输出。Visual C+Visual C+8.1.2续
9、续应用程序使用GDI可以对三种类型的图形进行操作:文本操作、矢量图形操作和光栅图形操作(图像操作)。文本操作是以逻辑坐标为单位来计算文本的输出位置,用户可以通过各种GDI函数来作出具有各种效果的文本。矢量图形指的是利用画点、直线、曲线(折线、贝塞尔曲线等)、多边形、扇形、矩形等函数所绘制的图形。光栅图形操作是指以光栅图形函数对以位图形式存储的数据进行操作,它包括各种位图和图标的输出,其在屏幕上表现为对若干个行和列的像素操作。光栅图形操作是直接从内存到显存的拷贝操作,其缺点是需要额外的内存空间,优点是操作速度快。Visual C+Visual C+8.1.3图形操作有关的图形操作有关的CDC类类
10、 1再论设备描述表再论设备描述表设备描述表是一个用来确定任何设备(如显示器、打印机)的GDI输出位置和内容属性的集合,是Windows系统下的一个保存GDI内部数据的数据结构,它与特定的显示设备相关。对于显示器,设备描述表总是与显示器上的特定窗口相关。设备描述表中保存了显示图形所需要的各种参数值,如显示颜色、显示坐标、显示方式和背景颜色。在Windows下程序员对所有的绘图功能的调用,都是通过设备描述表来进行的。Visual C+Visual C+8.1.3续续 2.类类CDCCDC是后面所讲的其他DC类的基类。CDC基类定义了设备描述表对象,并且提供在显示器、打印机或Windows用户区上绘
11、图的方法,它封装了使用设备环境的GDI函数。所有的绘图操作都是直接或间接运用了CDC的成员函数,这些函数有的进行设备描述表操作,有的是用来画图的,还有的函数是用来获取或设置绘图属性,为映像和视点服务的。在由AppWizard创建的MFC应用程序中,视图类的OnDraw成员函数是一个处理图形的关键虚函数,它带有一个指向设备环境对象的指针pDC,MFC的绘图成大多都是通过pDC这个指针来加以访问的。下面为CDC类的函数的分类Visual C+Visual C+分类分类 用途用途 位图函数位图函数 操作位图和像素的函数操作位图和像素的函数 剪裁函数剪裁函数 定义和操作剪裁设备边界的函数定义和操作剪裁
12、设备边界的函数坐标函数坐标函数 在物理设备和逻辑设备之间转换的函数在物理设备和逻辑设备之间转换的函数 设备描述表函数设备描述表函数 获取有关获取有关DCDC及其属性信息的函数及其属性信息的函数绘图属性函数绘图属性函数 为为DCDC获取和设置颜色及模式的函数获取和设置颜色及模式的函数 绘图工具函数绘图工具函数 枚举在枚举在DCDC中可用的笔和刷子的函数中可用的笔和刷子的函数 椭圆和多边形函数椭圆和多边形函数绘制椭圆和多边形函数绘制椭圆和多边形函数字体函数字体函数 获取字体属性的函数获取字体属性的函数线输出函数线输出函数在在DCDC上绘制线的函数上绘制线的函数映像函数映像函数创创建建、获获取取和和
13、控控制制原原点点,扩扩展展窗窗口口和和视视及及为为DCDC获取和设置映像模式的函数获取和设置映像模式的函数区域函数区域函数 填充区域和控制区域颜色的函数填充区域和控制区域颜色的函数 简单绘图函数简单绘图函数提供简单矩形和图标的绘制特性函数提供简单矩形和图标的绘制特性函数 文本函数文本函数 输出文本并获取输出文本并获取DCDC当前选中的字体信息的函数当前选中的字体信息的函数 Visual C+Visual C+8.1.4CDC的内容的内容 1派生类派生类CPaintDCCPaintDC是从CDC派生出来的设备描述表类,它常常在窗口的OnPaint函数中使用。查看MFC的源代码(StudioVC9
14、8MFCSRCviewcore.cpp)中的OnPaint函数的实现可以知道,OnPaint函数首先构造一个CPaintDC对象,再调用OnPrepareDC()函数将其准备好,最后以这个准备好的CPaintDC对象指针为参数,来调用OnDraw函数进行各种图形处理。CPaintDC对象在构造时调用CWnd:BeginPaint函数,并返回DC用于绘图,在析构时自动调用CWnd:EndPaint函数释放DC。CPaintDC仅在WM_PAINT消息需要响应时才起作用,通常是在应用程序的OnPaint响应函数中使用。Visual C+Visual C+8.1.4续续12派生类CClientDC(
15、管理客户区)CClientDC类只能在客户区绘图。所谓客户区是指窗口区域中去掉边框、标题栏、菜单栏、工具栏、状态栏等以外的部分,它是用户可以操作的区域。例如打开Word文档将是将某个.doc文件显示在其客户区域中。在使用CClientDC进行绘图时,一般要调用GetClientRect函数来获取客户区域的大小。CClientDC类由CDC派生而来,它使调用和释放设备环境的过程自动化。CClientDC对象在构造时调用WindowsAPI函数GetDC,在析构时调用响应的API函数ReleaseDC,这意味着与CClientDC对象相关的设备环境是窗口的客户区。CClientDC对象的窗口句柄保
16、存在成员变量m_hWnd,为构造CClientDC,需将CWnd作为参数传递给构造函数。Visual C+Visual C+8.1.4续续23派生类CWindowDC(管理框架窗口)CWindowDC类直接从CDC派生,它使调用和释放整个窗口(包括客户区和非客户区)的设备环境过程自动化。CWindowDC对象在构造时调用WindowsAPI函数GetWindowDC,在析构时调用相应的API函数ReleaseDC,这意味着CWindowtDC对象可访问CWnd所指向的整个屏幕区域。CWindowDC允许在显示器的任意位置绘图,坐标原点在整个窗口的左上角。由于使用CWindowDC可以在整个窗口
17、类绘图,这给了程序员很大的自由度,但使用不当会带来麻烦。在使用CWindowDC进行绘图时,一般要调用GetWindowRect函数来获取整个应用程序窗口区域的大小。CWindowDC对象的窗口句柄保存在成员变量m_hWnd,为构造CWindowDC,需将CWnd作为参数传递给构造函数。Visual C+Visual C+8.2 VC的文本操作的文本操作8.2.1 文本输出函数8.2.2 文本属性控制8.2.3 文本的字体8.2.4 文本处理实例Visual C+Visual C+8.2.1文本输出函数文本输出函数 在前面的API编程5.5.2节中讲了一个最简单的文本输出函数TextOut()
18、,其实API编程模式和MFC编程模式的最大相似之处在于他们调用的API函数和MFC的成员函数的参数基本上一致,在MFC中出现了很多缺省参数,调用起来更简单,但他们的核心参数都是一样的,因此掌握了某一个API函数的用法,在利用MFC编程时,用法基本一致。API编程模式和MFC编程模式的最大不同在于其程序的框架不一样,可以说,API编程模式的程序框架操作系统已经定义好了,这个框架是最原始的操作系统框架,熟悉该框架比较容易,但框架内部需要自己做的工作还很多;而MFC是一个应用程序框架,是构建在操作系统之上的一个应用程序框架。Visual C+Visual C+8.2.1续续1文本输出除了前面讲的Te
19、xtOut()外,常见的还有ExtTextOut():该函数的原型为:BOOL ExtTextOutint x,int y;/输出的位置输出的位置UINT nOptions;/指定矩形的类型指定矩形的类型LPCRECT lpRect;/输出的字符的矩形区域输出的字符的矩形区域const CString&str;/欲输出的字符欲输出的字符 LPINT lpDxWidths;/字符间距字符间距;该函数用来在一个给定的矩形lpRect区域内输出字符串str,此矩形可以设置为透明的(nOptions=ETO_OPAQUE)或不透明的,当矩形区域为不透明时,用当前的背景色填充矩形。Visual C+Vi
20、sual C+8.2.1续续2此矩形也可以设置为裁剪(nOptions=ETO_CLIPPED)性质或非裁剪性质,当设置为裁剪性质时,所有在矩形外面的字符串将被裁剪掉。上述参数中,nOptions主要设置矩形的类型,可以为ETO_OPAQUE和ETO_CLIPPED两个值的一个或两个组合;lpDxWidths是一个指向整数数组的指针,此数组中存放以逻辑单位表示的字符间的距离,第n个数代表第n个和n+1个字符之间的距离。该参数为NULL时,则按缺省值处理。Visual C+Visual C+8.2.2文本属性控制文本属性控制1设置文本的背景色缺省时,在绘制图形或者输出文本时,背景颜色是白色。可以
21、使用CDC的成员函数SetBkColor函数来设置新的背景颜色,函数原型为:VirtualCOLORREFSetBkColor(COLORREFcrcolor);其中参数crcolor用于指定新的背景颜色。例如要将背景颜色设为红色,可以用以下语句:SetBkColor(RGB(255,0,0);Visual C+Visual C+8.2.2续续12控制文本的背景色在设备描述表中有两项可以影响背景,一个是背景色,另一个是背景模式。背景模式可以为透明的(Transparent)或不透明的(Opaque),缺省为不透明的。当背景模式为不透明时,按背景颜色的值填充字符的空余部分,如果背景模式为透明的,
22、将不用背景颜色填充,保留屏幕上原来的颜色。背景模式可用函数SetBkMode来设置,它设置当前的背景模式并返回原来的背景模式,该函数的原型为:intSetBkMode(intnBkMode);参数nkbmode指定背景模式,其值可以是OPAQUE或者TRANSPARENT,如果值为OPAQUE,则显示时背景都改变为当前背景颜色。如果值为TRANSPARENT,则不改变背景颜色,此时,任何SetBkColor函数调用都无效,缺省的背景模式为OPAQUE。Visual C+Visual C+8.2.2续续23设置文本的排列方式在文本显示时遇到的另一个问题是文本的排列在文本显示时遇到的另一个问题是文
23、本的排列方式,它控制文本和给定点的相对位置。在一个图形方式,它控制文本和给定点的相对位置。在一个图形中加字符说明时,常常知道一个字符串的某一个边界,中加字符说明时,常常知道一个字符串的某一个边界,如左边界不应超过某个位置,或右边界不应超过某个如左边界不应超过某个位置,或右边界不应超过某个位置,或显示的几行字符串的中心点对齐等。利用位置,或显示的几行字符串的中心点对齐等。利用CDC的成员函数的成员函数SetTextAlign函数就能方便地实现函数就能方便地实现这种控制,其原型为:这种控制,其原型为:UINTSetTextAlign(UINTnFlags);其中,nFlags为文本的对齐方式,其值
24、如下:TA_LEFT将点同边界矩形的水平中心对齐TA_BASELINES将点同所选字体的基线对齐TA_BOTTOM将点同边界矩形的底线对齐Visual C+Visual C+8.2.3文本的字体文本的字体字体反映了字符外观特性,如汉字有宋体、楷体、黑体等,西文也有字体如Arial、Roman等,同一个字符以不同的字体输出时外观会不太一样。VC提供了丰富的字体控制功能,不仅可以使用Windows提供的字体,还可以自己创建字体,这使得Windows下文本输出具有很大的灵活性,可以随心所欲,最大限度地满足用户对复杂文本的输出要求。可以这样说,Word字处理程序所能应用的有关字体的功能,在设备环境中都
25、能给以支持。Visual C+Visual C+8.2.3续续11使用库存字体Windows系统本身提供了一些库存字体,对于大多数应用程序,使用库存字体即可完成基本的文本输出功能。要想使用库存字体,需要使用CDC的成员函数SelectStockObject()来完成,例如:SelectStockObject(OEM_FIXED_FONT);该语句把终端字体选入设备环境,这样,用TextOut或TextOutEx输出文本时,将使用DOS命令窗口的字体。其实,每个设备环境都有一个缺省字体,对于显示器而言,缺省字体就是SYSTEM_FONT系统字体,如果应用程序不需要执行很复杂的文本输出,使用缺省字
26、体即可。Visual C+Visual C+字体名称字体名称 说明说明ANSI_FIXED_FONTANSI_FIXED_FONT 基于基于WindowsWindows字符集的固定字宽的字体,通常使用字符集的固定字宽的字体,通常使用CourierCourier字体字体 ANSI_VAR_FONTANSI_VAR_FONT基于基于WindowsWindows字符集的变宽字体,通常使用字符集的变宽字体,通常使用Ms Sans SerifMs Sans Serif字体字体 DEVICE_DEFAULT_DEVICE_DEFAULT_FONTFONT特定设备的缺省字体。该字体取决于特定设备的缺省字体。
27、该字体取决于GDIGDI字体的映射程序如何解字体的映射程序如何解释字体请求,因此对于不同的设备,其字体宽度可能不同释字体请求,因此对于不同的设备,其字体宽度可能不同 OEM_FIXED_FONTOEM_FIXED_FONTWindowsWindows在在DOSDOS命令提示窗口中使用的字体,又称终端字体,它命令提示窗口中使用的字体,又称终端字体,它是一种固定宽度的字体,随系统的不同而不同是一种固定宽度的字体,随系统的不同而不同 SYSTEM_FONTSYSTEM_FONT系统字体,是基于系统字体,是基于windowswindows字符集的变宽字体。系统使用该字体字符集的变宽字体。系统使用该字体
28、来显示窗口的标题、菜单和对话框中的文本。系统字符集总是来显示窗口的标题、菜单和对话框中的文本。系统字符集总是可用的,而其他字符集则需要安装后才可使用可用的,而其他字符集则需要安装后才可使用 WindowsWindows库存字体库存字体Visual C+Visual C+8.2.3续续22使用自定义逻辑字体逻辑字体是用和设备无关的方式来描述一个字体,它使用通用的术语来描述一个字符的宏观特性(如高度、宽度、旋转角度、是否有下划线等),但它不能描述微观特性,没有足够的信息来显示字体,是从应用的角度描述一个字体,因为在应用时没有必要把字体的细微结构都描述出来,这会使使用变得很繁琐,这些细节由物体字体描
29、述。我们使用时用逻辑字体来描述需要的文本,GDI根据逻辑字体的描述选配最接近的物理字体,由物理字体进行输出。MFC提供的CFont类封装了逻辑字体。创建自定义字体并不是创建一种新的字体,而是创建一种逻辑字体。逻辑字体是一种字体属性的列表,如高度、宽度、字符集和字样等。字体映射器按逻辑字体给出的字体特性选择与之匹配的物理字体Visual C+Visual C+8.2.3续续3 要创建字体,首先要声明一个要创建字体,首先要声明一个CFont对象来表示逻辑字体,然对象来表示逻辑字体,然后初始化后初始化CFont对象。常见的初始化方法有以下几种:对象。常见的初始化方法有以下几种:(1)用)用CFont
30、的成员函数的成员函数CreatePointFont直接创建逻辑字体,直接创建逻辑字体,函数原型为函数原型为:BOOL CreatePointFont(int nPointSize,LPCTSTR lpszFaceName,CDC*pDC=NULL);其中,字体的高度由其中,字体的高度由nPointSize 指定,它以指定,它以1/10点数为一个单位点数为一个单位。例如如该值为。例如如该值为100,则字体的高度为,则字体的高度为10点(点(1点点=0.013837英寸),英寸),字体的名称由字体的名称由lpszFaceName指定。下面为使用该函数的典型代码:指定。下面为使用该函数的典型代码:C
31、ClientDC dc(this);/声明客户区设备环境变量声明客户区设备环境变量dcCFont font;/声明逻辑字体变量声明逻辑字体变量fontfont.CreatePointFont(120,Arial,&dc);/初始化逻辑字体初始化逻辑字体font Visual C+Visual C+8.2.3续续4CFont*def_font=dc.SelectObject(&font);/将新建的字体font选入设备环境dc.TextOut(5,5,Hello,5);/以所建的字体显示hellodc.SelectObject(def_font);/恢复旧字体font.DeleteObject(
32、);/删除所建立的字体(2)用CFont的成员函数CreateFont直接创建逻辑字体,函数原型为:BOOL CreateFont(int nHeight,int nWidth,int nEscapement,int nOrientation,int nWeight,BYTE bItalic,BYTE bUnderline,BYTE cStrikeOut,BYTE nCharSet,BYTE nOutPrecision,BYTE nClipPrecision,BYTE nQuality,BYTE nPitchAndFamily,LPCTSTR lpszFacename);该函数的参数较多,功能
33、较强,自己查阅MSDN进行分析,我们只需要掌握第一种方法即可。Visual C+Visual C+8.2.4文本处理实例文本处理实例 【例8-2】利用MFC编写文本处理的应用程序。1程序功能描述使用库存字体和自定义字体,设置文本的前景色、背景色、对齐方式、背景模式,利用TextOut和ExtTextOut函数在屏幕上输出文本。2利用MFCAppWizard(exe)创建程序步骤(1)运行VC6.0,在File菜单中选择New命令,在打开的New对话框中选中Projects标签,在左边的列表框中选择MFCAppWizard(exe)选项,在右边的Projectname文本框中输入工程名TextT
34、est,并选择合适的路径。Visual C+Visual C+【例【例8-2】续】续1(2)单击OK按钮,启动AppWizard,在第一步中选择SingleDocument单选按钮。(3)从第2步到第6步使用缺省选项,最后生成工程TextTest。3编辑视图类CTextTestView中的OnDraw函数,实现文本的各种属性控制及输出。附CTextTestView.txtVisual C+Visual C+8.3 CDC的绘图操作的绘图操作8.3.1画点与画线函数操作8.3.2绘制封闭图形8.3.3设置绘图参数8.3.4绘图模式8.3.5绘图操作实例Visual C+Visual C+8.3.
35、1画点与画线函数操作画点与画线函数操作1画点CDC的成员函数SetPixel用来在指定位置上绘制一个特定的像素点,其原型为:COLORREFSetPixel(POINTpoint,COLORREFcrColor);其中参数point指定所绘制的点,crColor指定画点所用的颜色。倘若要在屏幕的(100,100)处画一个红色点,则代码为:pDC-SetPixel(CPoint(100,100),RGB(255,0,0);2画折线PolyLine()函数用于画一条折线,它的原型如下所示。BOOLPolyline(LPPOINTlpPoints,intnCount);其中lpPoints是指向折线
36、顶点数组的指针,而cCount则指定折线顶点数组中的顶点数目。Visual C+Visual C+8.3.1续续13画弧线使用CDC的成员函数Arc和ArcTo,可以用缺省的笔画一段不填充的椭圆弧。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);这两个函数画弧成功返回非0,否则返回0,函数中各参数的含义如下:参数x1与y1为包围弧的矩形的左上角x、y坐标;x2与y2为包围弧的矩形的右下角x
37、、y坐标;x3与y3为弧的起点x、y坐标;x与y为弧的终点x、y坐标。参数lpRect表示围绕弧的矩形,它可以是LPRECT或CRect对象,ptStart表示弧的起点的CPoint或POINT对象,该点不必精确地位于弧上;PtEnd表示弧的终点的CPoint或POINT对象,该点不必精确地位于弧上。Visual C+Visual C+8.3.2绘制封闭图形绘制封闭图形Windows提供了Rectangle、Ellipse、RoundRect、Chord、Pie等五个函数用来绘制并填充图形。1画矩形BOOL Rectangle(int x1,int y1,int x2,int y2);BOOL
38、 Rectangle(LPCRECT lpRect);此函数成功调用后返回非0值,否则返回0。其中参数(x1,y1)为指定矩形的左上角逻辑x与y坐标;(x2,y2)为指定矩形右下角的逻辑x与y坐标。参数LpRect为一个矩形结构的指针,用它来表示矩形的四个角。2画椭圆或圆使用CDC的成员函数Ellipse,可以使用当前笔绘制一个用当前画刷填充的椭圆或圆。其函数原型如下:Visual C+Visual C+8.3.2续续1BOOL Ellipse(int x1,int y1,int x2,int y2);BOOL Ellipse(LPCRECT lpRect);这两个函数画椭圆成功后返回非0值,
39、否则返回0。所画椭圆高度为y2-y1,宽度为x2-x1。在该函数中,椭圆是由其外接矩形来确定的。外接矩形的中心与椭圆中心重合,矩形的长和宽和椭圆的长短轴相等。函数中的参数与画矩形的相仿,分别表示椭圆外接矩形的左上角和右下角坐标。3画圆角矩形BOOL RoundRect(int x1,int y1,int x2,int y2,int x3,int y3);该函数用于绘制一个圆角矩形,并用当前的画刷来填充该圆角矩形的内部区域。其中参数(x1,y1)为指定矩形的左上角位置x与y坐标;(x2,y2)为指定矩形右下角位置x与y坐标,(x3,y3)用于定义矩形四个角上的边角内切椭圆的宽度和高度,值越大,圆
40、角矩形的角就越明显。如果x3=x2-x1,并且y3=y2-y1,则所绘制的圆角矩形变为一个椭圆。Visual C+Visual C+8.3.2续续24画饼图扇形饼图是一条弧和从弧的两个端点到中心的连线组成的图形。CDC的成员函数Pie可用于画饼图,函数原型如下: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);该函数的参数与Arc函数的参数的含义相仿,只不过Pie函数画的是封闭图形,Arc画的是非封闭图形。各参数
41、参见8.3.1节介绍。5画弓形弓形图是一条椭圆弧和连接该弧线两个端点的弦,并用当前的画刷来填充其内部区域的封闭图形。Chord原型如下:BOOLChord(intx1,inty1,intx2,inty2,intx3,inty3,intx4,inty4);该函数参数与Pie函数参数的含义相仿。Visual C+Visual C+8.3.3设置绘图参数设置绘图参数绘图参数主要包括文本的前景色、文本的背景色、背景模式、绘图模式、位图伸展模式等,恰当地设置绘图参数,可以达到各种绘图效果。绘图参数中的文本前景色靠CDC:SetTextColor()来控制,文本的背景色靠CDC:SetBkColor()来
42、控制,背景模式又称填充模式,指的是在使用画笔绘制虚线、点划线或者使用画刷来填充封闭区域时,点和画刷及画刷阴影线之间空隙的着色方式。该功能的实现靠CDC:SetBkModer()来完成,位图伸展模式被CDC的成员函数StretchBlt()使用,它决定进行位图伸展时(目标位图的大小与显示区域的大小不同时就要伸展)如何处理位图数据与目标中原有数据的关系。下面讲绘图参数设置中的绘图模式的设置及其功能。Visual C+Visual C+8.3.4绘图模式绘图模式画笔和画刷对点线的绘制和图形的填充起着很重要作用,除此之外,还有设备描述表中的绘图模式(又称光栅操作模式)。例如当绘制一条线段时,该线段的颜
43、色不仅取决于画笔的颜色,而且也取决于该线段所在显示区域的颜色。当Windows使用画笔画线时,它实际上是在画笔像素和目标位置处原像素之间执行一种按位布尔运算,称为“光栅操作”(RasterOperation),简记为“ROP”。由于画线操作只涉及两种像素(画笔像素和目标像素),所以这种布尔运算又称为“二元光栅操作”(ROP2)。Windows定义了16种ROP2码,用来表示画笔像素和目标像素各种不同的组合方式。可以调用CDC的成员函数SetROP2改变绘图模式,函数原型为:int SetROP2(int nDrawMode);附件参数nDrawMode指定所要求的绘图模式.doc Visual
44、 C+Visual C+8.3.4续续1注意:(1)在画线时,如果绘图模式为R2_NOT,则画出的线的颜色为原先屏幕颜色的反色。这样画的线均可见,而且第二次画同一条线时,将自动擦除该线并恢复为当前显示颜色。(2)R2_NOP绘图模式等效于同时选择NULL画笔和NULL画刷。(3)在R2_XORPEN的操作模式下,用相同的参数两次调用某一条绘图命令时(包括文字输出函数),其结果仍然保留原样,利用这种方式,我们可以实现图形动画效果。(4)在画虚线时,用于填充线间的空白颜色取决于当前背景模式和背景颜色。(5)在R2_NOTXORPEN的操作模式下,其功能有二,第一,将同一直线绘制两次,将删除该直线;
45、第二,无论背景是何颜色,第一次绘制的直线总是可见的。Visual C+Visual C+8.3.5绘图操作实例绘图操作实例【例8-3】一个演示绘图模式与画线的应用程序。1程序功能描述利用绘图模式实现“橡皮条”功能的直线绘制。一般的绘图软件(如AutoCAD),在画直线时的操作方法是:当按鼠标左键时,准备绘制直线,当在屏幕移动鼠标时,在屏幕上画一条直线,该直线开始于原先按下鼠标左键的位置,终止于当前鼠标移动到的位置。随着鼠标的移动,该直线也在移动,但直线的起始点不动,类似于一个橡皮筋固定在一端,而在拉动它的另一端。2利用MFCAppWizard(exe)创建程序步骤(1)生成应用程序框架利用应用
46、程序向导MFCAppWizard(exe)创建一个单文档的应用程序框架,该工程的名称为MyDraw,向导的每个步骤都使用缺省的。Visual C+Visual C+【例【例8-3】续】续1(2)在视图类CMyDraw添加数据成员在工程MyDraw的工作区中,选择“ClassView”选项卡,在类名列表窗口中选择视图类“CMyDrawView”,然后单击鼠标右键,在弹出的快捷菜单中选择“AddMemberVariable”命令,则弹出图8.2所示的对话框。在“VariableType”编辑框中输入bool,在“VariableName”编辑框中输入m_IsDraw,选择Access(访问控制属性
47、)为Private(私有)。最后按“OK”按钮,则在视图类CMyDrawView中添加了一个bool型的私有成员变量m_IsDraw,用于标记是否开始绘制直线,当该值为真时,代表开始画直线,为假时,代表停止画直线。另外,为了确定所画线的起始点和终止点,需要在视图类中添为了确定所画线的起始点和终止点,需要在视图类中添加两个加两个CPoint型的成员变量型的成员变量m_StartPoint和和m_EndPoint,前者存放直线的起始点,后者存放直线的终止点,添加的方法同上。Visual C+Visual C+图图8.2Visual C+Visual C+【例【例8-3】续】续2(3)对成员变量m_
48、IsDraw进行初始化在视图类CMyDrawView的构造函数中添加如下的代码可以实现对数据成员的初始化。CMyDrawView:CMyDrawView()m_IsDraw=false;/开始不绘制直线(4)添加鼠标左键按下消息的映射函数选择View|ClassWizard命令,弹出MFCClassWizard窗体,在Classname中选择CMyDrawView,在Messages中选择WM_LBUTTONDOWN,然后单击“AddFunction”按钮,这样就为视图类添加了WM_LBUTTONDOWN的消息处理函数OnLButtonDown,如图8.3所示。Visual C+Visual
49、C+图图8.3Visual C+Visual C+【例【例8-3】续】续3最后,单击“EditCode”按钮,光标自动定位到OnLButtonDown实现处,在该消息映射函数中添加后的代码如下:voidCMyDrawView:OnLButtonDown(UINTnFlags,CPointpoint)m_IsDraw=true;/开始绘制直线m_StartPoint=m_EndPoint=point;/开始画线时起始点与终止点重合CView:OnLButtonDown(nFlags,point);Visual C+Visual C+【例【例8-3】续】续4(5)添加鼠标移动的消息映射函数与上一步
50、类似,利用ClassWizard为视图类CMyDrawView添加击键消息WM_MOUSEMOVE的消息映射函数OnMouseMove(),并在该函数中添加代码,以用于移动屏幕上的图形(6)添加鼠标左键弹起的消息映射函数与上一步类似,利用ClassWizard为视图类CMyDrawView添加击键消息WM_LBUTTONUP的消息映射函数OnLButtonUp(),并在该函数中添加如下代码,以用于停止绘图:voidCMyDrawView:OnLButtonUp(UINTnFlags,CPointpoint)m_IsDraw=false;/停止绘制直线CView:OnLButtonUp(nFla