




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Visual C+Visual C+第第8章章利用利用CDC实现绘图程序实现绘图程序 8.8.1图形绘制的基本知识图形绘制的基本知识8.2VC的文本操作8.3CDC的绘图操作8.4 Windows绘图工具 习题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.4 CDC的内容Visual C+Visual C+8.1.1一个一个简单的图形程序为了理解利用MFC编制图形程序的过程,也为了理解图形程序所用到的概念和原理,我们以一个简单的图形程序(仅仅用到了文本输出函数TextOut)为例,讲解程序的生成步骤及 编 写 代 码 的 步
3、 骤 。 该 程 序 是 利 用MFCAppWizard向导生成的第一个程序,我们对 M F C 编 程 的 初 步 理 解 是 : 首 先 掌 握编 程 的 初 步 理 解 是 : 首 先 掌 握AppWizard向导生成的步骤,然后理解向导生成的步骤,然后理解AppWizard生成的应用程序架构包含哪些主生成的应用程序架构包含哪些主要类,最后知道我们编写处理问题的代码放到要类,最后知道我们编写处理问题的代码放到MFC应用程序架构的什么地方。应用程序架构的什么地方。Visual C+Visual C+【例【例8-1】利用】利用MFC编写一个简单的绘图程序编写一个简单的绘图程序1.利用AppW
4、izard生成应用程序架构(1)启动)启动VC6.0,选择选择“File”菜单的菜单的“New”命令,在弹出的命令,在弹出的“New”对话框中选择对话框中选择“Project”选项卡。在该选项卡的列表中选选项卡。在该选项卡的列表中选择择“MFC AppWizard(exe)”项,在项,在“Project Name”编辑框中输入要创建的工编辑框中输入要创建的工程名称程名称SingleDraw,在在“Location”编辑框编辑框中设置工程的存放位置,单击中设置工程的存放位置,单击“OK”按钮。按钮。(2)在弹出的)在弹出的“MFC AppWizard-Step1” 对对话框中选择话框中选择“si
5、ngle document”,即应用程即应用程序的类型为单文档模式,然后单击序的类型为单文档模式,然后单击“Finish”按钮。按钮。(3)在弹出的)在弹出的“New Project information” 对话框中单击对话框中单击“OK”按钮,完成应用程序框架按钮,完成应用程序框架的创建。的创建。 Visual C+Visual C+【例【例8-18-1】续】续1 1 2应用程序架构包含的主要类 该程序主要包含的类有该程序主要包含的类有CAboutDlg关于对关于对话框类、话框类、CMainFrame主框架类、主框架类、CSingleDrawDoc文档类、文档类、CSingleDrawVi
6、ew视图类。视图类。 有关绘制功能的实现,一般是在视图类中有关绘制功能的实现,一般是在视图类中完成,因此,这一章的实例都是对视图类完成,因此,这一章的实例都是对视图类CSingleDrawView的操作。的操作。 Visual C+Visual C+【例【例8-18-1】续】续2 23将代码放到MFC的某个类的虚函数或消息映射函数中 绘图功能的实现,一般要超载视图类的OnDraw()虚函数,打开WorkSpace的ClassView选项卡,展开CSingleDrawView视图类,可以看到该类中有一个虚函数该类中有一个虚函数OnDraw(),双击该函数,就把光标定位到该函数的实现处,在其中编写
7、代码如下:void CSingleDrawView:OnDraw(CDC* pDC)CSingleDrawDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);pDC-TextOut(100,100,“在视图类的 OnDraw虚函数中输出的最简单的一个图 形程序“); Visual C+Visual C+【例【例8-18-1】续】续3 34运行程序 编译并运行该程序(按Ctrl+F5热键),在屏幕上显示了一行文本。利用MFC的应用程序向导,我们仅写了一行代码,就完成了一个简单的图形程序输出文本图形。 从代码量上是简单了,但要理解整个图形程序的显示过程,却有许
8、多工作要作,下面就围绕与图形输出有关的内容来讲解图形程序的编写过程和原理。 Visual C+Visual C+8.1.2 图形操作的接口图形操作的接口GDI 任何图形程序的输出,都离不开图形设备接口GDI(Graphic Device Interface),它是管理Windows应用程序在窗口内的绘图操作和与此相关的许多其它信息。如图形设备(打印机、显示器)的信息、绘图的坐标系统和映射模式、绘图工具的当前状态(什么样的画笔、画刷、文本的前景色与背景色、文本所使用的字体)。 Windows的GDI绘制的各种图形(点、线、圆、多边形、矩形等)是与设备无关的,即在屏幕的窗口内绘图与在打印机上绘图是
9、相似的。GDI是一个可执行程序,它接收Windows应用程序的绘图请求(表现为GDI调用),并将它们传送给相应的设备驱动程序,再由设备驱动程序驱动相应的硬件设备,如打印机或显示器输出。Visual C+Visual C+8.1.2续续应用程序使用GDI可以对三种类型的图形进行操作:文本操作、矢量图形操作和光栅图形操作(图像操作)。文本操作是以逻辑坐标为单位来计算文本的输出位置,用户可以通过各种GDI函数来作出具有各种效果的文本。矢量图形指的是利用画点、直线、曲线(折线、贝塞尔曲线等)、多边形、扇形、矩形等函数所绘制的图形。光栅图形操作是指以光栅图形函数对以位图形式存储的数据进行操作,它包括各种
10、位图和图标的输出,其在屏幕上表现为对若干个行和列的像素操作。光栅图形操作是直接从内存到显存的拷贝操作,其缺点是需要额外的内存空间,优点是操作速度快。Visual C+Visual C+8.1.3 图形操作有关的图形操作有关的CDC类类 1再论设备描述表再论设备描述表 设备描述表是一个用来确定任何设备(如显示器、打印机)的GDI输出位置和内容属性的集合,是Windows系统下的一个保存GDI 内部数据的数据结构,它与特定的显示设备相关。对于显示器,设备描述表总是与显示器上的特定窗口相关。设备描述表中保存了显示图形所需要的各种参数值,如显示颜色、显示坐标、显示方式和背景颜色。在Windows下程序
11、员对所有的绘图功能的调用,都是通过设备描述表来进行的。Visual C+Visual C+8.1.3 续续 2. 类类CDC CDC是后面所讲的其他DC类的基类。CDC基类定义了设备描述表对象, 并且提供在显示器、打印机或Windows用户区上绘图的方法,它封装了使用设备环境的GDI函数。 所有的绘图操作都是直接或间接运用了CDC的成员函数,这些函数有的进行设备描述表操作,有的是用来画图的,还有的函数是用来获取或设置绘图属性,为映像和视点服务的。 在由AppWizard创建的MFC应用程序中,视图类的OnDraw成员函数是一个处理图形的关键虚函数,它带有一个指向设备环境对象的指针pDC,MFC
12、的绘图成大多都是通过pDC这个指针来加以访问的。 下面为CDC类的函数的分类Visual C+Visual C+分类分类 用途用途 位图函数位图函数 操作位图和像素的函数操作位图和像素的函数 剪裁函数剪裁函数 定义和操作剪裁设备边界的函数定义和操作剪裁设备边界的函数坐标函数坐标函数 在物理设备和逻辑设备之间转换的函数在物理设备和逻辑设备之间转换的函数设备描述表函数设备描述表函数获取有关获取有关DCDC及其属性信息的函数及其属性信息的函数绘图属性函数绘图属性函数为为DCDC获取和设置颜色及模式的函数获取和设置颜色及模式的函数绘图工具函数绘图工具函数枚举在枚举在DCDC中可用的笔和刷子的函数中可用
13、的笔和刷子的函数椭圆和多边形函数椭圆和多边形函数 绘制椭圆和多边形函数绘制椭圆和多边形函数字体函数字体函数获取字体属性的函数获取字体属性的函数线输出函数线输出函数在在DCDC上绘制线的函数上绘制线的函数映像函数映像函数创建、获取和控制原点,扩展窗口和视及为创建、获取和控制原点,扩展窗口和视及为DCDC获取和获取和设置映像模式的函数设置映像模式的函数区域函数区域函数填充区域和控制区域颜色的函数填充区域和控制区域颜色的函数简单绘图函数简单绘图函数提供简单矩形和图标的绘制特性函数提供简单矩形和图标的绘制特性函数文本函数文本函数输出文本并获取输出文本并获取DCDC当前选中的字体信息的函数当前选中的字体
14、信息的函数Visual C+Visual C+8.1.4 CDC的内容的内容 1派生类派生类CPaintDCCPaintDC是从CDC派生出来的设备描述表类,它常常在窗口的OnPaint函数中使用。查看MFC的源代码(StudioVC98MFCSRCviewcore.cpp)中的OnPaint函数的实现可以知道,OnPaint函数首先构造一个CPaintDC对象,再调用OnPrepareDC()函数将其准备好,最后以这个准备好的CPaintDC对象指针为参数,来调用OnDraw函数进行各种图形处理。CPaintDC对象在构造时调用CWnd:BeginPaint函数,并返回DC用于绘图,在析构时
15、自动调用CWnd:EndPaint函数释放DC。CPaintDC仅在WM_PAINT消息需要响应时才起作用,通常是在应用程序的OnPaint响应函数中使用。Visual C+Visual C+8.1.4 续续1 2派生类CClientDC(管理客户区) CClientDC类只能在客户区绘图。所谓客户区是指窗口区域中去掉边框、标题栏、菜单栏、工具栏、状态栏等以外的部分,它是用户可以操作的区域。例如打开Word文档将是将某个.doc文件显示在其客户区域中。在使用CClientDC进行绘图时,一般要调用GetClientRect函数来获取客户区域的大小。 CClientDC类由CDC派生而来,它使调
16、用和释放设备环境的过程自动化。CClientDC对象在构造时调用Windows API函数GetDC, 在析构时调用响应的API函数ReleaseDC,这意味着与CClientDC对象相关的设备环境是窗口的客户区。 CClientDC对象的窗口句柄保存在成员变量m_hWnd,为构造CClientDC,需将CWnd作为参数传递给构造函数。Visual C+Visual C+8.1.4续续2 3派生类CWindowDC(管理框架窗口) CWindowDC类直接从CDC派生,它使调用和释放整个窗口(包括客户区和非客户区)的设备环境过程自动化。CWindowDC对象在构造时调用Windows API函
17、数GetWindowDC, 在析构时调用相应的API函数ReleaseDC,这意味着CWindowtDC对象可访问CWnd所指向的整个屏幕区域。 CWindowDC允许在显示器的任意位置绘图,坐标原点在整个窗口的左上角。由于使用CWindowDC可以在整个窗口类绘图,这给了程序员很大的自由度,但使用不当会带来麻烦。在使用CWindowDC进行绘图时,一般要调用GetWindowRect函数来获取整个应用程序窗口区域的大小。 CWindowDC对象的窗口句柄保存在成员变量m_hWnd,为构造CWindowDC,需将CWnd作为参数传递给构造函数。Visual C+Visual C+8.2 VC的
18、文本操作的文本操作 8.2.1 文本输出函数 8.2.2 文本属性控制 8.2.3 文本的字体 8.2.4 文本处理实例Visual C+Visual C+8.2.1 文本输出函数文本输出函数在前面的API编程5.5.2节中讲了一个最简单的文本输出函数TextOut(),其实API编程模式和MFC编程模式的最大相似之处在于他们调用的API函数和MFC的成员函数的参数基本上一致,在MFC中出现了很多缺省参数,调用起来更简单,但他们的核心参数都是一样的,因此掌握了某一个API函数的用法,在利用MFC编程时,用法基本一致。API编程模式和MFC编程模式的最大不同在于其程序的框架不一样,可以说,API
19、编程模式的程序框架操作系统已经定义好了,这个框架是最原始的操作系统框架,熟悉该框架比较容易,但框架内部需要自己做的工作还很多;而MFC是一个应用程序框架,是构建在操作系统之上的一个应用程序框架。Visual C+Visual C+8.2.1 续续1文本输出除了前面讲的TextOut()外,常见的还有ExtTextOut():该函数的原型为:BOOL ExtTextOutint x, int y; /输出的位置输出的位置UINT nOptions; /指定矩形的类型指定矩形的类型LPCRECT lpRect;/输出的字符的矩形区域输出的字符的矩形区域const CString& str; /欲输
20、出的字符欲输出的字符 LPINT lpDxWidths ;/字符间距字符间距; 该函数用来在一个给定的矩形lpRect区域内输出字 符 串 s t r , 此 矩 形 可 以 设 置 为 不 透 明 的 (nOptions=ETO_OPAQUE)或透明的,当矩形区域为不透明时,用当前的背景色填充矩形。Visual C+Visual C+8.2.1 续续2 此矩形也可以设置为裁剪(nOptions=ETO_CLIPPED)性质或非裁剪性质,当设置为裁剪性质时,所有在矩形外面的字符串将被裁剪掉。 上述参数中,nOptions主要设置矩形的类型,可以为ETO_OPAQUE和ETO_CLIPPED两个
21、值的一个或两个组合;lpDxWidths是一个指向整数数组的指针,此数组中存放以逻辑单位表示的字符间的距离,第n个数代表第n个和n+1个字符之间的距离。该参数为NULL时,则按缺省值处理。Visual C+Visual C+8.2.2 文本属性控制文本属性控制 1 设置文本的背景色 缺省时,在绘制图形或者输出文本时,背景颜色是白色。可以使用CDC的成员函数SetBkColor函数来设置新的背景颜色,函数原型为: Virtual COLORREF SetBkColor(COLORREF crcolor); 其中参数crcolor用于指定新的背景颜色。例如要将背景颜色设为红色,可以用以下语句: S
22、etBkColor(RGB(255,0,0);Visual C+Visual C+8.2.2续续1 2控制文本的背景色 在设备描述表中有两项可以影响背景,一个是背景色,另一个是背景模式。背景模式可以为透明的(Transparent)或不透明的(Opaque),缺省为不透明的。当背景模式为不透明时,按背景颜色的值填充字符的空余部分,如果背景模式为透明的,将不用背景颜色填充,保留屏幕上原来的颜色。背景模式可用函数SetBkMode来设置,它设置当前的背景模式并返回原来的背景模式,该函数的原型为: int SetBkMode(int nBkMode); 参数nkbmode指定背景模式,其值可以是OP
23、AQUE或者TRANSPARENT,如果值为OPAQUE,则显示时背景都改变为当前背景颜色。如果值为TRANSPARENT,则不改变背景颜色,此时任何SetBkColor函数调用都无效,缺省的背景模式为OPAQUE。Visual C+Visual C+8.2.2续续2 3设置文本的排列方式在文本显示时遇到的另一个问题是文本的排在文本显示时遇到的另一个问题是文本的排列方式,它控制文本和给定点的相对位置。在列方式,它控制文本和给定点的相对位置。在一个图形中加字符说明时,常常知道一个字符一个图形中加字符说明时,常常知道一个字符串的某一个边界,如左边界不应超过某个位置,串的某一个边界,如左边界不应超过
24、某个位置,或右边界不应超过某个位置,或显示的几行字或右边界不应超过某个位置,或显示的几行字符串的中心点对齐等。利用符串的中心点对齐等。利用CDC的成员函数的成员函数SetTextAlign函数就能方便地实现这种控制,函数就能方便地实现这种控制,其原型为:其原型为: UINT SetTextAlign (UINT nFlags); 其中,nFlags为文本的对齐方式,其值如下:TA_LEFT 将点同边界矩形的水平中心对齐TA_BASELINE将点同所选字体的基线对齐TA_BOTTOM将点同边界矩形的底线对齐 Visual C+Visual C+8.2.3文本的字体文本的字体 字体反映了字符外观特
25、性,如汉字有宋体、楷体、黑体等,西文也有字体如Arial、Roman等,同一个字符以不同的字体输出时外观会不太一样。VC提供了丰富的字体控制功能,不仅可以使用Windows提供的字体,还可以自己创建字体,这使得Windows下文本输出具有很大的灵活性,可以随心所欲,最大限度地满足用户对复杂文本的输出要求。可以这样说,Word字处理程序所能应用的有关字体的功能,在设备环境中都能给以支持。 Visual C+Visual C+8.2.3续续1 1使用库存字体 Windows系统本身提供了一些库存字体,对于大多数应用程序,使用库存字体即可完成基本的文本输出功能。 要想使用库存字体,需要使用CDC的成
26、员函数SelectStockObject()来完成,例如: SelectStockObject(OEM_FIXED_FONT); 该语句把终端字体选入设备环境,这样用TextOut或TextOutEx输出文本时,将使用DOS命令窗口的字体。其实,每个设备环境都有一个缺省字体,对于显示器而言,缺省字体就是SYSTEM_FONT系统字体,如果应用程序不需要执行很复杂的文本输出,使用缺省字体即可。Visual C+Visual C+字体名称字体名称 说明说明ANSI_FIXED_FONANSI_FIXED_FONTT 基于基于WindowsWindows字符集的固定字宽的字体,通常使用字符集的固定字
27、宽的字体,通常使用CourierCourier字体字体 ANSI_VAR_FONTANSI_VAR_FONT基于基于WindowsWindows字符集的变宽字体,通常使用字符集的变宽字体,通常使用Ms Sans SerifMs Sans Serif字体字体 DEVICE_DEFAULT_DEVICE_DEFAULT_FONTFONT特定设备的缺省字体。该字体取决于特定设备的缺省字体。该字体取决于GDIGDI字体的映射程序如何字体的映射程序如何解释字体请求,因此对于不同的设备,其字体宽度可能不同解释字体请求,因此对于不同的设备,其字体宽度可能不同 OEM_FIXED_FONTOEM_FIXED_
28、FONTWindowsWindows在在DOSDOS命令提示窗口中使用的字体,又称终端字体,它命令提示窗口中使用的字体,又称终端字体,它是一种固定宽度的字体,随系统的不同而不同是一种固定宽度的字体,随系统的不同而不同 SYSTEM_FONTSYSTEM_FONT系统字体,是基于系统字体,是基于windowswindows字符集的变宽字体。系统使用该字字符集的变宽字体。系统使用该字体来显示窗口的标题、菜单和对话框中的文本。系统字符集总体来显示窗口的标题、菜单和对话框中的文本。系统字符集总是可用的,而其他字符集则需要安装后才可使用是可用的,而其他字符集则需要安装后才可使用 WindowsWindo
29、ws库存字体库存字体Visual C+Visual C+8.2.3续续2 2使用自定义逻辑字体 逻辑字体是用和设备无关的方式来描述一个字体,它使用通用的术语来描述一个字符的宏观特性(如高度、宽度、旋转角度、是否有下划线等),但它不能描述微观特性,没有足够的信息来显示字体,是从应用的角度描述一个字体,因为在应用时没有必要把字体的细微结构都描述出来,这会使使用变得很繁琐,这些细节由物体字体描述。我们使用时用逻辑字体来描述需要的文本,GDI根据逻辑字体的描述选配最接近的物理字体,由物理字体进行输出。 MFC提供的CFont类封装了逻辑字体。创建自定义字体并不是创建一种新的字体,而是创建一种逻辑字体。
30、逻辑字体是一种字体属性的列表,如高度、宽度、字符集和字样等。字体映射器按逻辑字体给出的字体特性选择与之匹配的物理字体。Visual C+Visual C+8.2.3续续3 要创建字体,首先要声明一个要创建字体,首先要声明一个CFont对象来表示逻辑字对象来表示逻辑字体,然后初始化体,然后初始化CFont对象。常见的初始化方法有以下几对象。常见的初始化方法有以下几种:种:(1)用)用CFont的成员函数的成员函数CreatePointFont直接创建逻直接创建逻辑字体,函数原型为辑字体,函数原型为: BOOL CreatePointFont( int nPointSize, LPCTSTR lp
31、szFaceName, CDC* pDC = NULL ); 其中,字体的高度由其中,字体的高度由nPointSize 指定,它以指定,它以1/10点数为一个点数为一个单位。例如如该值为单位。例如如该值为100,则字体的高度为,则字体的高度为10点(点(1点点=0.013837英寸),字体的名称由英寸),字体的名称由lpszFaceName指定。下面为使用该函数的指定。下面为使用该函数的典型代码:典型代码:CClientDC dc(this);/声明客户区设备环境变量声明客户区设备环境变量dcCFont font; /声明逻辑字体变量声明逻辑字体变量fontfont.CreatePointFo
32、nt(120, Arial, &dc);/初始化逻辑字体初始化逻辑字体fontVisual 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(); /删除所建立的字体(2) 用CFont的成员函数CreateFont直接创建逻辑字体,函数原型为: BOOL CreateFont( int nHeight,
33、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 ); 该函数的参数较多,功能较强,自己查阅MSDN进行分析,我们只需要掌握第一种方法即可。Visual C+Visual C+8.2.4 文本处理实例文本处
34、理实例【例8-2】利用MFC编写文本处理的应用程序。 1程序功能描述 使用库存字体和自定义字体,设置文本的前景色、背景色、对齐方式、背景模式,利用TextOut和ExtTextOut函数在屏幕上输出文本。2利用MFC AppWizard(exe)创建程序步骤(1)运行VC6.0,在File菜单中选择New命令,在打开的New对话框中选中Projects标签,在左边的列表框中选择MFC AppWizard(exe)选项,在右边的Project name文本框中输入工程名TextTest,并选择合适的路径。Visual C+Visual C+【例【例8-2】续】续1(2)单击OK按钮,启动AppW
35、izard,在第一步中选择Single Document单选按钮。(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.1 画点与画线函数操作画点与画线函数操作1画点 CDC的成员函数SetPixel用来在指定位置
36、上绘制一个特定的像素点,其原型为:COLORREF SetPixel( POINT point, COLORREF crColor ); 其中参数point指定所绘制的点,crColor指定画点所用的颜色。倘若要在屏幕的(100,100)处画一个红色点,则代码为:pDC- SetPixel(CPoint(100,100),RGB(255,0,0);2画折线 PolyLine()函数用于画一条折线,它的原型如下所示。BOOL Polyline( LPPOINT lpPoints, int nCount ); 其中lpPoints是指向折线顶点数组的指针,而cCount则指定折线顶点数组中的顶点数
37、目。Visual C+Visual C+8.3.1 续续1 3画弧线 使用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、y坐标;x3与y3
38、为弧的起点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 );BOO
39、L 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 ); 这两个函
40、数画椭圆成功后返回非0值,否则返回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)用于定义矩形四个
41、角上的边角内切椭圆的宽度和高度,值越大,圆角矩形的角就越明显。如果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函数的参数的含义相仿,
42、只不过Pie函数画的是封闭图形,Arc画的是非封闭图形。各参数参见8.3.1节介绍。5 画弓形弓形图是一条椭圆弧和连接该弧线两个端点的弦,并用当前的画刷来填充其内部区域的封闭图形。Chord原型如下:BOOL Chord( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 ); 该函数参数与Pie函数参数的含义相仿。 Visual C+Visual C+8.3.3 设置绘图参数设置绘图参数 绘图参数主要包括文本的前景色、文本的背景色、背景模式、绘图模式、位图伸展模式等,恰当地设置绘图参数,可以达到各种绘图效果。 绘图参
43、数中的文本前景色靠CDC:SetTextColor()来控制,文本的背景色靠CDC:SetBkColor()来控制,背景模式又称填充模式,指的是在使用画笔绘制虚线、点划线或者使用画刷来填充封闭区域时,点和画刷及画刷阴影线之间空隙的着色方式。该功能的实现靠CDC:SetBkModer()来完成,位图伸展模式被CDC的成员函数StretchBlt()使用,它决定进行位图伸展时(目标位图的大小与显示区域的大小不同时就要伸展)如何处理位图数据与目标中原有数据的关系。下面讲绘图参数设置中的绘图模式的设置及其功能。Visual C+Visual C+8.3.4 绘图模式绘图模式 画笔和画刷对点线的绘制和图
44、形的填充起着很重要作用,除此之外,还有设备描述表中的绘图模式(又称光栅操作模式)。例如当绘制一条线段时,该线段的颜色不仅取决于画笔的颜色,而且也取决于该线段所在显示区域的颜色。 当Windows使用画笔画线时,它实际上是在画笔像素和目标位置处原像素之间执行一种按位布尔运算,称为“光栅操作”(Raster Operation),简记为“ROP”。由于画线操作只涉及两种像素(画笔像素和目标像素),所以这种布尔运算又称为“二元光栅操作”(ROP2)。Windows定义了16种ROP2码,用来表示画笔像素和目标像素各种不同的组合方式。可以调用CDC的成员函数SetROP2改变绘图模式,函数原型为:in
45、t SetROP2(int nDrawMode); 附件参数nDrawMode指定所要求的绘图模式.doc Visual C+Visual C+8.3.4续续1注意:(1) 在画线时,如果绘图模式为R2_NOT,则画出的线的颜色为原先屏幕颜色的反色。这样画的线均可见,而且第二次画同一条线时,将自动擦除该线并恢复为当前显示颜色。(2) R2_NOP绘图模式等效于同时选择NULL画笔和NULL画刷。(3) 在R2_XORPEN的操作模式下,用相同的参数两次调用某一条绘图命令时(包括文字输出函数),其结果仍然保留原样,利用这种方式,我们可以实现图形动画效果。(4) 在画虚线时,用于填充线间的空白颜色
46、取决于当前背景模式和背景颜色。(5) 在R2_NOTXORPEN的操作模式下,其功能有二,第一,将同一直线绘制两次,将删除该直线;第二,无论背景是何颜色,第一次绘制的直线总是可见的。Visual C+Visual C+8.3.5 绘图操作实例绘图操作实例 【例8-3】一个演示绘图模式与画线的应用程序。1程序功能描述 利用绘图模式实现“橡皮条”功能的直线绘制。一般的绘图软件(如AutoCAD),在画直线时的操作方法是:当按鼠标左键时,准备绘制直线,当在屏幕移动鼠标时,在屏幕上画一条直线,该直线开始于原先按下鼠标左键的位置,终止于当前鼠标移动到的位置。随着鼠标的移动,该直线也在移动,但直线的起始点
47、不动,类似于一个橡皮筋固定在一端,而在拉动它的另一端。2利用MFC AppWizard(exe)创建程序步骤(1)生成应用程序框架 利用应用程序向导MFC AppWizard(exe)创建一个单文档的应用程序框架,该工程的名称为MyDraw,向导的每个步骤都使用缺省的。Visual C+Visual C+【例【例8-3】续】续1(2)在视图类CMyDraw添加数据成员在工程MyDraw的工作区中,选择“ClassView”选项卡,在类名列表窗口中选择视图类“CMyDrawView”,然后单击鼠标右键,在弹出的快捷菜单中选择“Add Member Variable”命令,则弹出图8.2所示的对话
48、框。在“Variable Type”编辑框中输入bool,在“Variable Name”编辑框中输入m_IsDraw,选择Access(访问控制属性)为Private(私有)。最后按“OK”按钮,则在视图类CMyDrawView中添加了一个bool型的私有成员变量m_IsDraw,用于标记是否开始绘制直线,当该值为真时,代表开始画直线,为假时,代表停止画直线。 另外,为了确定所画线的起始点和终止点,需要在视图类中添为了确定所画线的起始点和终止点,需要在视图类中添加两个加两个CPoint型的成员变量型的成员变量m_StartPoint和和m_EndPoint,前者存放直线的起始点,后者存放直线
49、的终止点,添加的方法同上。Visual C+Visual C+图图8.2Visual C+Visual C+【例【例8-3】续】续2(3)对成员变量m_IsDraw进行初始化 在视图类CMyDrawView的构造函数中添加如下的代码可以实现对数据成员的初始化。CMyDrawView:CMyDrawView() m_IsDraw=false; /开始不绘制直线(4)添加鼠标左键按下消息的映射函数选择View|ClassWizard命令,弹出MFC ClassWizard窗体,在Class name 中选择CMyDrawView,在Messages中选择WM_LBUTTONDOWN,然后单击“Ad
50、d Function”按钮,这样就为视图类添加了WM_LBUTTONDOWN的消息处理函数OnLButtonDown, 如图8.3所示。Visual C+Visual C+图图8.3Visual C+Visual C+【例【例8-3】续】续3 最后,单击“Edit Code”按钮,光标自动定位到OnLButtonDown 实现处,在该消息映射函数中添加后的代码如下:void CMyDrawView:OnLButtonDown(UINT nFlags, CPoint point) m_IsDraw=true; /开始绘制直线m_StartPoint=m_EndPoint=point; /开始画线
51、时起始点与终止点重合CView:OnLButtonDown(nFlags, point); Visual C+Visual C+【例【例8-3】续】续4(5)添加鼠标移动的消息映射函数 与上一步类似,利用ClassWizard为视图类CMyDrawView添加击键消息WM_MOUSEMOVE的消息映射函数OnMouseMove(),并在该函数中添加代码,以用于移动屏幕上的图形(6)添加鼠标左键弹起的消息映射函数 与上一步类似,利用ClassWizard为视图类CMyDrawView添加击键消息WM_LBUTTONUP的消息映射函数OnLButtonUp(),并在该函数中添加如下代码,以用于停止
52、绘图:void CMyDrawView:OnLButtonUp(UINT nFlags, CPoint point) m_IsDraw=false; /停止绘制直线CView:OnLButtonUp(nFlags, point); Visual C+Visual C+8.4 Windows绘图工具绘图工具 8.4.1 绘图工具的划分8.4.2 使用画笔 8.4.3 使用画刷8.4.4 使用库存工具Visual C+Visual C+概要概要 VC绘图需要两个要素:绘图需要两个要素:设备描述表设备描述表和和基基本绘图工具本绘图工具。设备描述表是由。设备描述表是由CDC类及其派类及其派生类来描述,
53、它是一个生类来描述,它是一个画图的画布,提供绘画图的画布,提供绘图的场地和环境图的场地和环境。画布一般是窗口的客户区,。画布一般是窗口的客户区,每个窗口每个窗口CWnd对象都提供一个设备环境,对象都提供一个设备环境,在该环境中有一套默认的基本绘图工具。上在该环境中有一套默认的基本绘图工具。上一节讲的文本操作中,可以更改文字的字体,一节讲的文本操作中,可以更改文字的字体,字体就是一种绘图工具。当设备环境所提供字体就是一种绘图工具。当设备环境所提供的默认的绘图工具不能满足我们的需求时,的默认的绘图工具不能满足我们的需求时,就需要更改默认绘图工具,达到绘制丰富多就需要更改默认绘图工具,达到绘制丰富多
54、彩图形的目的。彩图形的目的。Visual C+Visual C+8.4.1绘图工具的划分绘图工具的划分 绘图工具,又称绘图对象,使用他们可以在Windows设备环境中绘制具有各种效果的图形。如果把设备描述表比作画布,程序员比作画家的话,那么绘图工具就是画家手中的画笔、画刷、调色板等。任何一个画家,不论他的技艺有多么高超(类似于程序员要掌握绘图原理),在没有任何绘图工具的情况下,都无法在画布上画图。 Windows的绘图工具包括画笔、画刷、字体、位图、调色板和区域。在MFC中这些绘图工具被封装到相应的类中。这些绘图工具中,字体在文本操作中已讲,该节中主要讲解其它的几类绘图工具,其中没有讲调色板和
55、位图,自己查阅相关资料进行学习。 Visual C+Visual C+8.4.2 使用画笔使用画笔 画笔是最简单的一种绘图工具,同时也是最重要的一种绘图对象。在现实世界中,可以用不同的笔产生不同的线。这正如绘图用的彩笔、不同颜色笔产生不同颜色的线。Windows也是利用这种面向对象的描述事物的方法,把笔作为一个对象,和现实世界一样,不同的笔产生不同的线。 1 画笔类画笔类CpenCPen对象封装了Windows GDI笔,并提供与CPen对象一起工作的几种方法。Visual C+Visual C+8.4.2续续1 2画笔工具的操作步骤(1)声明CPen对象。(2)初始化画笔。通过调用Creat
56、ePen成员函数可以初始化笔,该函数的原型为:BOOL CreatePen( int nPenStyle, int nWidth, COLORREF crColor );(3)将新建的画笔对象选进设备场景中,同时保存原画笔对象的指针:pOldPen=pDC-SelectObject(&pen);(4)调用绘图函数生成图形。(5)选择设备场景的原有笔对象。Visual C+Visual C+8.4.2续续2 3画笔工具的操作实例【例8-4】一个演示画笔的例子。首先利用MFC AppWizard(exe)创建一个新工程,工程的名字为PenTest,除了应用程序的类型选为单文档模式外,向导的每个操作
57、步骤都采用缺省的。(1) 编辑视图类CPenTestView的虚函数OnDraw,实现画笔工具的操作演示。附件CPenTestView.txt(2)程序运行结果如图8.4所示Visual C+Visual C+画笔的各种效果演示画笔的各种效果演示Visual C+Visual C+8.4.3 使用画刷使用画刷画笔对象是用来绘制图形边界的,而画刷则是给图形内部着色的。大多数CDC的绘图函数都要同时使用画笔和画刷使用画笔来来绘制各种图形的边界,使用画刷来填充图形的内部。1常用的两类画刷常用的两类画刷(1)纯色画刷 又称实画刷,事实上它是一个定义了8像素8像素的含有64个相同颜色的像素。在绘制时,W
58、indows将多个这样的纯色位图平铺来填充封闭图形的内部。 创建纯色画刷首先创建一个非初始化的CBrush对象,然后调用CBrush:CreateSolidBrush()函数来初始化纯色画刷函数来初始化纯色画刷。Visual C+Visual C+8.4.3续续1(2)阴影画刷 阴影画刷是用某种颜色的阴影线在封闭图形内填充。它也是一个定义了8像素8像素的含有64个像素单位位图,该位图就是一个阴影。在绘制时,Windows将多个这样含有阴影的位图平铺来填充封闭图形内部。 创建阴影画刷首先创建一个非初始化的CBrush对象,然后调用CBrush: CreateHatchBrush()函数来初始化阴
59、影画刷函数来初始化阴影画刷。 当使用阴影绘图时,Windows使用默认的背景颜色将阴影线段之间的空间填满。但是,若使用CDC:SetBkColor()函数改变了当前设备描述表的背景颜色,或者通过使用CDC:SetBkMode()函数从OPAQUE到TRANSPARENT改变背景模式,以便关闭背景填充时,这些默认值就被相应地改变了。Visual C+Visual C+8.4.3续续22画刷类CBrush CBrush对象封装了Windows GDI刷子,并提供与CBrush对象一起工作的一些函数,如表8.6所示。3画刷工具的使用步骤(1)生成CBrush的实例。刷子以多种样式和颜色出现在CBru
60、sh:CBrush(): CBrush( ); CBrush( COLORREF crColor ); CBrush( int nIndex, COLORREF crColor ); Visual C+Visual C+表表8.6画刷类画刷类CBrush的成员函数的成员函数成员函数成员函数说明说明CreateBrushIndirectCreateBrushIndirect创建具有在创建具有在LOGBRUSHLOGBRUSH结构内指定的样式、颜色和图案的刷子,并结构内指定的样式、颜色和图案的刷子,并将它连接至将它连接至CBrushCBrush对象对象CreateHatchBrushCreateH
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 安全隐患排查总结模版
- 医疗信息化中的数据加密技术与应用
- 医疗行业的数据治理与合规性管理
- 供水泥合同范例
- 区块链技术助力音乐人维护原创权益
- DeFi与NFT科技赋能重塑支付生态
- 低成本装修卖房合同范例
- 医疗信息化建设的未来趋势与挑战分析
- 医保业务与数字技术的深度融合实践案例分享
- 从用户需求出发-医学生类应用的优化与迭代趋势探讨
- SAP固定资产各种折旧方法配置及操作手册
- 产业发展理论-第七章-产业政策课件
- 奥数举一反三简单推理
- 高中英语教师研修-罗马建筑文化课件
- 幼儿园教学课件小班社会《孤独的小熊》课件
- 客诉客退经济处罚准则及要求
- 医疗纠纷和解协议书(6篇)
- 293219民事诉讼法(第六版)教学PPT完整版课件全套ppt教学教程最全电子教案
- 人教版小学五年级数学竞赛试题及答案
- 农村不动产权籍调查工作指南
- 氧气安全标签
评论
0/150
提交评论