好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

第8章:利用CDC实现绘图程序.ppt

69页
  • 卖家[上传人]:公****
  • 文档编号:579658552
  • 上传时间:2024-08-27
  • 文档格式:PPT
  • 文档大小:443.54KB
  • / 69 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • Visual C++Visual C++第第8章章利用利用CDC实现绘图程序实现绘图程序• 8.8.1 图形绘制的基本知识图形绘制的基本知识 8.2  VC的文本操作   8.3   CDC的绘图操作   8.4   Windows绘图工具             习题 Visual C++Visual C++ 教学要点教学要点 本章内容包括设备环境与绘图程序的关系,设备环境主要功能以在MFC对应的CDC类,利用设备环境类CDC操纵文本(文本的字体、颜色和属性控制),利用设备环境类CDC实现简单图形的绘制(点、线、椭圆、矩形和弧等),各种绘图工具(画笔、画刷)使用     要求了解CDC编写的绘图程序调用GDI ,进而调用设备驱动程序的流程,CDC的几个派生类及其使用,掌握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)为例,讲解程序的生成步骤及编写代码的步骤。

      该程序是利用MFCAppWizard向导生成的第一个程序 , 我 们 对 MFC编 程 的 初 步 理 解 是 : 首 先 掌 握AppWizard向导生成的步骤,然后理解AppWizard生成的应用程序架构包含哪些主要类,最后知道我们编写处理问题的代码放到MFC应用程序架构的什么地方 Visual C++Visual C++【例【例8-1】利用】利用MFC编写一个简单的绘图程序编写一个简单的绘图程序   1.利用AppWizard生成应用程序架构((1)启动)启动VC6.0,,选择选择“File”菜单的菜单的“New”命令,在命令,在弹出的弹出的“New”对话框中选择对话框中选择“Project”选项卡在该选项卡在该选项卡的列表中选择选项卡的列表中选择“MFC AppWizard(exe)”项,在项,在“Project Name”编辑框中输入要创建的工程名称编辑框中输入要创建的工程名称SingleDraw,,在在“Location”编辑框中设置工程的存编辑框中设置工程的存放位置,单击放位置,单击“OK”按钮2)在弹出的)在弹出的“MFC AppWizard-Step1” 对话框中选择对话框中选择“single document”,,即应用程序的类型为单文档模即应用程序的类型为单文档模式,然后单击式,然后单击“Finish”按钮。

      按钮3)在弹出的)在弹出的“New Project information” 对话框中单对话框中单击击“OK”按钮,完成应用程序框架的创建按钮,完成应用程序框架的创建  Visual C++Visual C++【例【例8-18-1】续】续1 1 2.应用程序架构包含的主要类 该程序主要包含的类有该程序主要包含的类有CAboutDlg关于对话框类、关于对话框类、CMainFrame主框架类、主框架类、CSingleDrawDoc文文档类、档类、CSingleDrawView视图类 有关绘制功能的实现,一般是在视图类中完成,有关绘制功能的实现,一般是在视图类中完成,因此,这一章的实例都是对视图类因此,这一章的实例都是对视图类CSingleDrawView的操作                Visual C++Visual C++【例【例8-18-1】续】续2 2 3.将代码放到MFC的某个类的虚函数或消息映射函数中    绘图功能的实现,一般要超载视图类的OnDraw()虚函数,打开WorkSpace的ClassView选项卡,展开CSingleDrawView视图类,可以看到该类中有一个虚函数该类中有一个虚函数OnDraw(),双击该函数,就把光标定位到该函数的实现处,在其中编写代码如下:     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的应用程序向导,我们仅写了一行代码,就完成了一个简单的图形程序——输出文本图形       从代码量上是简单了,但要理解整个图形程序的显示过程,却有许多工作要作,下面就围绕与图形输出有关的内容来讲解图形程序的编写过程和原理  Visual C++Visual C++8.1.2    图形操作的接口图形操作的接口——GDI            任何图形程序的输出,都离不开图形设备接口GDI(Graphic Device Interface),它是管理Windows应用程序在窗口内的绘图操作和与此相关的许多其它信息如图形设备(打印机、显示器)的信息、绘图的坐标系统和映射模式、绘图工具的当前状态(什么样的画笔、画刷、文本的前景色与背景色、文本所使用的字体)                                Windows的GDI绘制的各种图形(点、线、圆、多边形、矩形等)是与设备无关的,即在屏幕的窗口内绘图与在打印机上绘图是相似的 GDI是一个可执行程序,它接收Windows应用程序的绘图请求(表现为GDI调用),并将它们传送给相应的设备驱动程序,再由设备驱动程序驱动相应的硬件设备,如打印机或显示器输出。

      Visual C++Visual C++8.1.2续续             应用程序使用GDI可以对三种类型的图形进行操作:文本操作、矢量图形操作和光栅图形操作(图像操作)ü文本操作是以逻辑坐标为单位来计算文本的输出位置,用户可以通过各种GDI函数来作出具有各种效果的文本ü矢量图形指的是利用画点、直线、曲线(折线、贝塞尔曲线等)、多边形、扇形、矩形等函数所绘制的图形ü光栅图形操作是指以光栅图形函数对以位图形式存储的数据进行操作,它包括各种位图和图标的输出,其在屏幕上表现为对若干个行和列的像素操作光栅图形操作是直接从内存到显存的拷贝操作,其缺点是需要额外的内存空间,优点是操作速度快 Visual C++Visual C++8.1.3  图形操作有关的图形操作有关的CDC类类 1.再论设备描述表.再论设备描述表        设备描述表是一个用来确定任何设备(如显示器、打印机)的GDI输出位置和内容属性的集合,是Windows系统下的一个保存GDI 内部数据的数据结构,它与特定的显示设备相关对于显示器,设备描述表总是与显示器上的特定窗口相关设备描述表中保存了显示图形所需要的各种参数值,如显示颜色、显示坐标、显示方式和背景颜色。

      在Windows下程序员对所有的绘图功能的调用,都是通过设备描述表来进行的 Visual C++Visual C++8.1.3 续续 2. 类类CDC           CDC是后面所讲的其他DC类的基类CDC基类定义了设备描述表对象, 并且提供在显示器、打印机或Windows用户区上绘图的方法,它封装了使用设备环境的GDI函数         所有的绘图操作都是直接或间接运用了CDC的成员函数,这些函数有的进行设备描述表操作,有的是用来画图的,还有的函数是用来获取或设置绘图属性,为映像和视点服务的             在由AppWizard创建的MFC应用程序中,视图类的OnDraw成员函数是一个处理图形的关键虚函数,它带有一个指向设备环境对象的指针pDC,MFC的绘图成大多都是通过pDC这个指针来加以访问的  下面为CDC类的函数的分类 Visual C++Visual C++分类分类 用途用途 位图函数位图函数 操作位图和像素的函数操作位图和像素的函数 剪裁函数剪裁函数 定义和操作剪裁设备边界的函数定义和操作剪裁设备边界的函数坐标函数坐标函数 在物理设备和逻辑设备之间转换的函数在物理设备和逻辑设备之间转换的函数 设备描述表函数设备描述表函数 获取有关获取有关DCDC及其属性信息的函数及其属性信息的函数绘图属性函数绘图属性函数 为为DCDC获取和设置颜色及模式的函数获取和设置颜色及模式的函数 绘图工具函数绘图工具函数 枚举在枚举在DCDC中可用的笔和刷子的函数中可用的笔和刷子的函数 椭圆和多边形函数椭圆和多边形函数绘制椭圆和多边形函数绘制椭圆和多边形函数字体函数字体函数 获取字体属性的函数获取字体属性的函数线输出函数线输出函数在在DCDC上绘制线的函数上绘制线的函数映像函数映像函数创创建建、、获获取取和和控控制制原原点点,,扩扩展展窗窗口口和和视视及及为为DCDC获取和设置映像模式的函数获取和设置映像模式的函数区域函数区域函数 填充区域和控制区域颜色的函数填充区域和控制区域颜色的函数 简单绘图函数简单绘图函数提供简单矩形和图标的绘制特性函数提供简单矩形和图标的绘制特性函数 文本函数文本函数 输出文本并获取输出文本并获取DCDC当前选中的字体信息的函数当前选中的字体信息的函数 Visual C++Visual C++8.1.4   CDC的内容的内容 1.派生类.派生类CPaintDCüCPaintDC是从CDC派生出来的设备描述表类,它常常在窗口的OnPaint函数中使用。

      查看MFC的源代码(Studio\VC98\MFC\SRC\viewcore.cpp)中的OnPaint函数的实现可以知道,OnPaint函数首先构造一个CPaintDC对象,再调用OnPrepareDC()函数将其准备好,最后以这个准备好的CPaintDC对象指针为参数,来调用OnDraw函数进行各种图形处理üCPaintDC对象在构造时调用CWnd::BeginPaint函数,并返回DC用于绘图,在析构时自动调用CWnd::EndPaint函数释放DCCPaintDC仅在WM_PAINT消息需要响应时才起作用,通常是在应用程序的OnPaint响应函数中使用 Visual C++Visual C++8.1.4  续续1    2.派生类CClientDC(管理客户区)      CClientDC类只能在客户区绘图所谓客户区是指窗口区域中去掉边框、标题栏、菜单栏、工具栏、状态栏等以外的部分,它是用户可以操作的区域例如打开Word文档将是将某个.doc文件显示在其客户区域中在使用CClientDC进行绘图时,一般要调用GetClientRect函数来获取客户区域的大小     CClientDC类由CDC派生而来,它使调用和释放设备环境的过程自动化。

      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函数GetWindowDC, 在析构时调用相应的API函数ReleaseDC,这意味着CWindowtDC对象可访问CWnd所指向的整个屏幕区域              CWindowDC允许在显示器的任意位置绘图,坐标原点在整个窗口的左上角由于使用CWindowDC可以在整个窗口类绘图,这给了程序员很大的自由度,但使用不当会带来麻烦在使用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(),其实API编程模式和MFC编程模式的最大相似之处在于他们调用的API函数和MFC的成员函数的参数基本上一致,在MFC中出现了很多缺省参数,调用起来更简单,但他们的核心参数都是一样的,因此掌握了某一个API函数的用法,在利用MFC编程时,用法基本一致API编程模式和MFC编程模式的最大不同在于其程序的框架不一样,可以说,API编程模式的程序框架操作系统已经定义好了,这个框架是最原始的操作系统框架,熟悉该框架比较容易,但框架内部需要自己做的工作还很多;而MFC是一个应用程序框架,是构建在操作系统之上的一个应用程序框架。

      Visual C++Visual C++8.2.1 续续1文本输出除了前面讲的TextOut()外,常见的还有ExtTextOut():该函数的原型为:BOOL ExtTextOut{int x, int y;; //输出的位置输出的位置UINT nOptions;;//指定矩形的类型指定矩形的类型LPCRECT lpRect;;//输出的字符的矩形区域输出的字符的矩形区域const CString& str;;//欲输出的字符欲输出的字符 LPINT lpDxWidths ;;//字符间距字符间距};              该函数用来在一个给定的矩形lpRect区域内输出字符串str,此矩形可以设置为透明的(nOptions=ETO_OPAQUE)或不透明的,当矩形区域为不透明时,用当前的背景色填充矩形 Visual C++Visual 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 .设置文本的背景色            缺省时,在绘制图形或者输出文本时,背景颜色是白色可以使用CDC的成员函数SetBkColor函数来设置新的背景颜色,函数原型为:              Virtual COLORREF SetBkColor(COLORREF crcolor);       其中参数crcolor用于指定新的背景颜色例如要将背景颜色设为红色,可以用以下语句:          SetBkColor(RGB(255,0,0); Visual C++Visual C++8.2.2续续1       2.控制文本的背景色            在设备描述表中有两项可以影响背景,一个是背景色,另一个是背景模式背景模式可以为透明的(Transparent)或不透明的(Opaque),缺省为不透明的当背景模式为不透明时,按背景颜色的值填充字符的空余部分,如果背景模式为透明的,将不用背景颜色填充,保留屏幕上原来的颜色背景模式可用函数SetBkMode来设置,它设置当前的背景模式并返回原来的背景模式,该函数的原型为:                                                   int SetBkMode(int nBkMode);          参数nkbmode指定背景模式,其值可以是OPAQUE或者TRANSPARENT,如果值为OPAQUE,则显示时背景都改变为当前背景颜色。

      如果值为TRANSPARENT,则不改变背景颜色,此时,任何SetBkColor函数调用都无效,缺省的背景模式为OPAQUE  Visual C++Visual C++8.2.2续续2      3.设置文本的排列方式           在文本显示时遇到的另一个问题是文本的排列在文本显示时遇到的另一个问题是文本的排列方式,它控制文本和给定点的相对位置在一个图形方式,它控制文本和给定点的相对位置在一个图形中加字符说明时,常常知道一个字符串的某一个边界,中加字符说明时,常常知道一个字符串的某一个边界,如左边界不应超过某个位置,或右边界不应超过某个如左边界不应超过某个位置,或右边界不应超过某个位置,或显示的几行字符串的中心点对齐等利用位置,或显示的几行字符串的中心点对齐等利用CDC的成员函数的成员函数SetTextAlign函数就能方便地实现函数就能方便地实现这种控制,其原型为:这种控制,其原型为:                   UINT SetTextAlign (UINT nFlags);        其中,nFlags为文本的对齐方式,其值如下:TA_LEFT     将点同边界矩形的水平中心对齐TA_BASELINES将点同所选字体的基线对齐TA_BOTTOM将点同边界矩形的底线对齐  Visual C++Visual C++8.2.3文本的字体文本的字体        字体反映了字符外观特性,如汉字有宋体、楷体、黑体等,西文也有字体如Arial、Roman等,同一个字符以不同的字体输出时外观会不太一样。

      VC提供了丰富的字体控制功能,不仅可以使用Windows提供的字体,还可以自己创建字体,这使得Windows下文本输出具有很大的灵活性,可以随心所欲,最大限度地满足用户对复杂文本的输出要求可以这样说,Word字处理程序所能应用的有关字体的功能,在设备环境中都能给以支持  Visual C++Visual C++ 8.2.3续续1   1.使用库存字体            Windows系统本身提供了一些库存字体,对于大多数应用程序,使用库存字体即可完成基本的文本输出功能           要想使用库存字体,需要使用CDC的成员函数SelectStockObject()来完成,例如: SelectStockObject(OEM_FIXED_FONT);             该语句把终端字体选入设备环境,这样,用TextOut或TextOutEx输出文本时,将使用DOS命令窗口的字体其实,每个设备环境都有一个缺省字体,对于显示器而言,缺省字体就是SYSTEM_FONT系统字体,如果应用程序不需要执行很复杂的文本输出,使用缺省字体即可 Visual C++Visual C++字体名称字体名称 说明说明ANSI_FIXED_FONTANSI_FIXED_FONT   基于基于WindowsWindows字符集的固定字宽的字体,通常使用字符集的固定字宽的字体,通常使用CourierCourier字体字体 ANSI_VAR_FONT ANSI_VAR_FONT 基于基于WindowsWindows字符集的变宽字体,通常使用字符集的变宽字体,通常使用Ms Sans SerifMs Sans Serif字体字体 DEVICE_DEFAULT_DEVICE_DEFAULT_FONTFONT特定设备的缺省字体。

      该字体取决于特定设备的缺省字体该字体取决于GDIGDI字体的映射程序如何解字体的映射程序如何解释字体请求,因此对于不同的设备,其字体宽度可能不同释字体请求,因此对于不同的设备,其字体宽度可能不同 OEM_FIXED_FONTOEM_FIXED_FONTWindowsWindows在在DOSDOS命令提示窗口中使用的字体,又称终端字体,它命令提示窗口中使用的字体,又称终端字体,它是一种固定宽度的字体,随系统的不同而不同是一种固定宽度的字体,随系统的不同而不同 SYSTEM_FONTSYSTEM_FONT系统字体,是基于系统字体,是基于windowswindows字符集的变宽字体系统使用该字体字符集的变宽字体系统使用该字体来显示窗口的标题、菜单和对话框中的文本系统字符集总是来显示窗口的标题、菜单和对话框中的文本系统字符集总是可用的,而其他字符集则需要安装后才可使用可用的,而其他字符集则需要安装后才可使用 WindowsWindows库存字体库存字体 Visual C++Visual C++8.2.3续续2       2.使用自定义逻辑字体            逻辑字体是用和设备无关的方式来描述一个字体,它使用通用的术语来描述一个字符的宏观特性(如高度、宽度、旋转角度、是否有下划线等),但它不能描述微观特性,没有足够的信息来显示字体,是从应用的角度描述一个字体,因为在应用时没有必要把字体的细微结构都描述出来,这会使使用变得很繁琐,这些细节由物体字体描述。

      我们使用时用逻辑字体来描述需要的文本,GDI根据逻辑字体的描述选配最接近的物理字体,由物理字体进行输出             MFC提供的CFont类封装了逻辑字体创建自定义字体并不是创建一种新的字体,而是创建一种逻辑字体逻辑字体是一种字体属性的列表,如高度、宽度、字符集和字样等字体映射器按逻辑字体给出的字体特性选择与之匹配的物理字体  Visual C++Visual C++8.2.3续续3 要创建字体,首先要声明一个要创建字体,首先要声明一个CFont对象来表示逻辑字体,然对象来表示逻辑字体,然后初始化后初始化CFont对象常见的初始化方法有以下几种:对象常见的初始化方法有以下几种:((1)用)用CFont的成员函数的成员函数CreatePointFont直接创建逻辑字体,直接创建逻辑字体,函数原型为函数原型为: BOOL CreatePointFont( int nPointSize, LPCTSTR lpszFaceName, CDC* pDC = NULL ); 其中,字体的高度由其中,字体的高度由nPointSize 指定,它以指定,它以1/10点数为一个单位点数为一个单位。

      例如如该值为例如如该值为100,则字体的高度为,则字体的高度为10点(点(1点点=0.013837英寸),英寸),字体的名称由字体的名称由lpszFaceName指定下面为使用该函数的典型代码:指定下面为使用该函数的典型代码:CClientDC 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(); //删除所建立的字体(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 ); 该函数的参数较多,功能较强,自己查阅MSDN进行分析,我们只需要掌握第一种方法即可。

      Visual C++Visual C++8.2.4   文本处理实例文本处理实例 【例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按钮,启动AppWizard,在第一步中选择Single Document单选按钮3)从第2步到第6步使用缺省选项,最后生成工程TextTest 3.编辑视图类CTextTestView 中的OnDraw函数,实现文本的各种属性控制及输出附\CTextTestView.txt Visual 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用来在指定位置上绘制一个特定的像素点,其原型为: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则指定折线顶点数组中的顶点数目  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为弧的起点x、y坐标;x4与y4为弧的终点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 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值,否则返回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)用于定义矩形四个角上的边角内切椭圆的宽度和高度,值越大,圆角矩形的角就越明显如果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画的是非封闭图形。

      各参数参见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  设置绘图参数设置绘图参数         绘图参数主要包括文本的前景色、文本的背景色、背景模式、绘图模式、位图伸展模式等,恰当地设置绘图参数,可以达到各种绘图效果        绘图参数中的文本前景色靠CDC::SetTextColor()来控制,文本的背景色靠CDC::SetBkColor()来控制,背景模式又称填充模式,指的是在使用画笔绘制虚线、点划线或者使用画刷来填充封闭区域时,点和画刷及画刷阴影线之间空隙的着色方式该功能的实现靠CDC::SetBkModer()来完成,位图伸展模式被CDC的成员函数StretchBlt()使用,它决定进行位图伸展时(目标位图的大小与显示区域的大小不同时就要伸展)如何处理位图数据与目标中原有数据的关系。

      下面讲绘图参数设置中的绘图模式的设置及其功能 Visual C++Visual C++8.3.4   绘图模式绘图模式 ü画笔和画刷对点线的绘制和图形的填充起着很重要作用,除此之外,还有设备描述表中的绘图模式(又称光栅操作模式)例如当绘制一条线段时,该线段的颜色不仅取决于画笔的颜色,而且也取决于该线段所在显示区域的颜色ü    当Windows使用画笔画线时,它实际上是在画笔像素和目标位置处原像素之间执行一种按位布尔运算,称为“光栅操作”(Raster Operation),简记为“ROP”由于画线操作只涉及两种像素(画笔像素和目标像素),所以这种布尔运算又称为“二元光栅操作”(ROP2)Windows定义了16种ROP2码,用来表示画笔像素和目标像素各种不同的组合方式ü可以调用CDC的成员函数SetROP2改变绘图模式,函数原型为:int 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) 在画虚线时,用于填充线间的空白颜色取决于当前背景模式和背景颜色5) 在R2_NOTXORPEN的操作模式下,其功能有二,第一,将同一直线绘制两次,将删除该直线;第二,无论背景是何颜色,第一次绘制的直线总是可见的 Visual C++Visual C++8.3.5   绘图操作实例绘图操作实例 【例8-3】一个演示绘图模式与画线的应用程序1.程序功能描述      利用绘图模式实现“橡皮条”功能的直线绘制一般的绘图软件(如AutoCAD),在画直线时的操作方法是:当按鼠标左键时,准备绘制直线,当在屏幕移动鼠标时,在屏幕上画一条直线,该直线开始于原先按下鼠标左键的位置,终止于当前鼠标移动到的位置随着鼠标的移动,该直线也在移动,但直线的起始点不动,类似于一个橡皮筋固定在一端,而在拉动它的另一端。

      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所示的对话框在“Variable Type”编辑框中输入bool,在“Variable Name”编辑框中输入m_IsDraw,选择Access(访问控制属性)为Private(私有)最后按“OK”按钮,则在视图类CMyDrawView中添加了一个bool型的私有成员变量m_IsDraw,用于标记是否开始绘制直线,当该值为真时,代表开始画直线,为假时,代表停止画直线     另外,为了确定所画线的起始点和终止点,需要在视图类中添为了确定所画线的起始点和终止点,需要在视图类中添加两个加两个CPoint型的成员变量型的成员变量m_StartPoint和和m_EndPoint,前者存放直线的起始点,后者存放直线的终止点,添加的方法同上。

      Visual C++Visual C++图图8.2 Visual 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,然后单击“Add Function”按钮,这样就为视图类添加了WM_LBUTTONDOWN的消息处理函数OnLButtonDown, 如图8.3所示 Visual C++Visual C++图图8.3 Visual C++Visual C++【例【例8-3】续】续3            最后,单击“Edit Code”按钮,光标自动定位到OnLButtonDown 实现处,在该消息映射函数中添加后的代码如下:void CMyDrawView::OnLButtonDown(UINT nFlags, CPoint point) {m_IsDraw=true; //开始绘制直线m_StartPoint=m_EndPoint=point; //开始画线时起始点与终止点重合CView::OnLButtonDown(nFlags, point);}  Visual C++Visual C++【例【例8-3】续】续4(5)添加鼠标移动的消息映射函数–与上一步类似,利用ClassWizard为视图类CMyDrawView添加击键消息WM_MOUSEMOVE的消息映射函数OnMouseMove(),并在该函数中添加代码,以用于移动屏幕上的图形(6)添加鼠标左键弹起的消息映射函数–与上一步类似,利用ClassWizard为视图类CMyDrawView添加击键消息WM_LBUTTONUP的消息映射函数OnLButtonUp(),并在该函数中添加如下代码,以用于停止绘图: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类及其派生类类及其派生类来描述,它是一个来描述,它是一个画图的画布,提供绘图的场画图的画布,提供绘图的场地和环境地和环境画布一般是窗口的客户区,每个窗画布一般是窗口的客户区,每个窗口口CWnd对象都提供一个设备环境,在该环境对象都提供一个设备环境,在该环境中有一套默认的基本绘图工具上一节讲的文中有一套默认的基本绘图工具上一节讲的文本操作中,可以更改文字的字体,字体就是一本操作中,可以更改文字的字体,字体就是一种绘图工具当设备环境所提供的默认的绘图种绘图工具当设备环境所提供的默认的绘图工具不能满足我们的需求时,就需要更改默认工具不能满足我们的需求时,就需要更改默认绘图工具,达到绘制丰富多彩图形的目的绘图工具,达到绘制丰富多彩图形的目的 Visual C++Visual C++8.4.1绘图工具的划分绘图工具的划分     绘图工具,又称绘图对象,使用他们可以在Windows设备环境中绘制具有各种效果的图形如果把设备描述表比作画布,程序员比作画家的话,那么绘图工具就是画家手中的画笔、画刷、调色板等任何一个画家,不论他的技艺有多么高超(类似于程序员要掌握绘图原理),在没有任何绘图工具的情况下,都无法在画布上画图。

             Windows的绘图工具包括画笔、画刷、字体、位图、调色板和区域在MFC中这些绘图工具被封装到相应的类中这些绘图工具中,字体在文本操作中已讲,该节中主要讲解其它的几类绘图工具,其中没有讲调色板和位图,自己查阅相关资料进行学习 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)初始化画笔通过调用CreatePen成员函数可以初始化笔,该函数的原型为: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,除了应用程序的类型选为单文档模式外,向导的每个操作步骤都采用缺省的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个相同颜色的像素在绘制时,Windows将多个这样的纯色位图平铺来填充封闭图形的内部   创建纯色画刷首先创建一个非初始化的CBrush对象,然后调用CBrush::CreateSolidBrush()函数来初始化纯色画刷函数来初始化纯色画刷。

      Visual C++Visual C++8.4.3续续1(2)阴影画刷         阴影画刷是用某种颜色的阴影线在封闭图形内填充它也是一个定义了8像素×8像素的含有64个像素单位位图,该位图就是一个阴影在绘制时,Windows将多个这样含有阴影的位图平铺来填充封闭图形内部          创建阴影画刷首先创建一个非初始化的CBrush对象,然后调用CBrush:: CreateHatchBrush()函数来初始化阴影画函数来初始化阴影画刷刷       当使用阴影绘图时,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的实例。

      刷子以多种样式和颜色出现在CBrush::CBrush():     CBrush( ); CBrush( COLORREF crColor ); CBrush( int nIndex, COLORREF crColor );       Visual C++Visual C++表表8.6画刷类画刷类CBrush的成员函数的成员函数成员函数成员函数说明说明CreateBrushIndirectCreateBrushIndirect创创建建具具有有在在LOGBRUSHLOGBRUSH结结构构内内指指定定的的样样式式、、颜颜色色和和图图案案的的刷刷子子,,并并将将它连接至它连接至CBrushCBrush对象对象CreateHatchBrushCreateHatchBrush创建具有阴影线图案和颜色的刷子,并将它连接至创建具有阴影线图案和颜色的刷子,并将它连接至CBrushCBrush对象对象CreateSolidBrushCreateSolidBrush创建具有指定实线颜色的刷子,并将它连接至创建具有指定实线颜色的刷子,并将它连接至CBrushCBrush对象对象CreateSysColorBrushCreateSysColorBrush创建默认系统颜色刷子,并将它连接至创建默认系统颜色刷子,并将它连接至CBrushCBrush对象对象FromHandleFromHandle从从Windows HBRUSHWindows HBRUSH对象返回指向对象返回指向CBrushCBrush对象的指针对象的指针Operator HBRUSHOperator HBRUSH返回连接到返回连接到CBrushCBrush对象的对象的WindowsWindows句柄句柄 Visual C++Visual C++8.4.3续续3上述函数的参数crColor指定刷子颜色;nIndex参数指定刷子图案,其值如表8.7所示。

      2)调用相应的成员函数初始化刷子3)将所创建的画刷选入设备环境,同时保存原画刷对象的指针4)调用绘图函数生成图形5)恢复原先设备环境中的画刷 4.画刷工具的操作实例【例8-5】一个演示各种画刷的例子首先利用MFC AppWizard(exe)创建一个新工程,工程的名字为BrushTest,除了应用程序的类型选为单文档模式外,向导的每个操作步骤都采用缺省的1) 编辑视图类CBrushTestView的虚函数OnDraw,实现画刷工具的操作演示附件\例8-5.txt(2)程序运行结果如图8 Visual C++Visual C++画刷风格画刷风格说明说明HS_BDIAGONALHS_BDIAGONAL由由4545度下降阴影线(自左向右)度下降阴影线(自左向右)HS_CROSSHS_CROSS水平和垂直交叉阴影线水平和垂直交叉阴影线HS_DIAGCROSSHS_DIAGCROSS4545度十字交叉阴影线度十字交叉阴影线HS_FDIAGONALHS_FDIAGONAL以以4545度上升阴影线(自左向右)度上升阴影线(自左向右)HS_HORIZONTALHS_HORIZONTAL水平阴影线水平阴影线HS_VERTIALHS_VERTIAL垂直阴影线垂直阴影线表8.7画刷的风格 Visual C++Visual C++图8.5 各种画刷演示 Visual C++Visual C++8.4.4   使用库存工具使用库存工具ü在Windows的GDI中,包含一些预定义的图形工具,无需用户创建就可以使用,这些对象称为库存工具对象。

      库存工具对象包括画笔、画刷和字体等使用库存工具对象要采用CDC的成员函数SelectStockObject来完成,其原型为:virtual CGdiObject* SelectStockObject( int nIndex );ü其中参数nIndex 指定要选入设备环境中的库存工具,常见的图形工具值如表8.8所示 Visual C++Visual C++表表8.8 库存工具库存工具图形对象图形对象说明说明图形对象图形对象说明说明BLACK_BRUSHBLACK_BRUSH黑色画刷黑色画刷DKGRAY_BRUSH   DKGRAY_BRUSH   暗灰画刷暗灰画刷GRAY_BRUSH   GRAY_BRUSH   灰色画刷灰色画刷HOLLOW_BRUSH   HOLLOW_BRUSH   中空画刷中空画刷LTGRAY_BRUSH  LTGRAY_BRUSH    淡灰色画刷淡灰色画刷WHITE_BRUSH    WHITE_BRUSH    白色画刷白色画刷BLACK_PEN   BLACK_PEN   黑色画笔黑色画笔WHITE_PEN   WHITE_PEN   白色画笔白色画笔ANSI_FIXED_FONTANSI_FIXED_FONT    WindowsWindows固定倾角(单间隔)的系统字体固定倾角(单间隔)的系统字体  ANSI_VAR_FONT ANSI_VAR_FONT   WindowsWindows可变倾角(比例间隔)的系统字体可变倾角(比例间隔)的系统字体  SYSTEM_FONT  SYSTEM_FONT    系统字体,系统字体,WindowsWindows使用它来画菜单、对话框中的控件和其它文本使用它来画菜单、对话框中的控件和其它文本DEFAULT_PALETTEDEFAULT_PALETTE      缺省的调色板,该调色板包含了系统调色板中的缺省的调色板,该调色板包含了系统调色板中的2020种静态颜色种静态颜色 表表8.8 库存工具库存工具 Visual C++Visual C++【例【例8-6】】【例8-6】一个演示各种库存绘图工具(包括画笔、画刷和字体的)的例子。

      首先利用MFC AppWizard(exe)创建一个新工程,工程的名字为StockTest,除了应用程序的类型选为单文档模式外,向导的每个操作步骤都采用缺省的1) 编辑视图类CStockTestView的虚函数OnDraw,实现库存工具的操作演示例8-6.txt(2)程序运行结果如图8.6所示 Visual C++Visual C++图图8.68.6库存工具的演示效果库存工具的演示效果 Visual C++Visual C++习题习题 一、名词解释       1.设备环境2.绘图模式3.画刷二、简答题       1.设备环境类CDC是一个封装了与绘图有关的类,从它派生了常用的几个类:CClientDC、CWindowsDC、CPaintDC请问这些类主要包含哪些功能,有什么区别?      2.要想绘图,必须使用绘图工具在利用CDC进行绘图程序的编写时,VC都有默认的绘图工具我们可以利用CDC的SelectObject()成员函数把自己所建立的绘图工具选入设备环境中,从而可以使用这些工具请以“画笔”工具为例,阐述如何创建并使用绘图工具?  Visual C++Visual C++习题习题3.视图CView有一个很重要的可超载虚函数OnDraw(CDC *pDC),一般真正的绘图代码都是在这里完成的。

      该函数的参数是一个指向设备环境的指针,那么该函数被调用时传递过来的实参是什么,它又是在什么地方被调用的查看MFC的源代码viewcore.cpp(在VC98\MFC\SRC目录下)可以找到该函数的调用处如下void CView::OnPaint(){// standard paint routineCPaintDC dc(this);OnPrepareDC(&dc);OnDraw(&dc);} Visual C++Visual C++习题习题       可见OnDraw()函数的调用是在OnPaint()中调用的,而该函数WM_PAINT消息的响应函数,因此该消息出现时,OnDraw()间接调用请分析OnPaint()的实现代码中的每个语句的含义     4.CDC提供了画矩形、圆角矩形、椭圆的成员函数,而没有提供画圆的    函数事实上,圆是椭圆的特例,改变画椭圆函数的参数的值,就可以绘制出圆,请写出利用画椭圆函数绘制圆的一般调用方式            三、实验题     1.8.3.4节中讲了一个利用“橡皮筋”技术画直线的实例,请参照该实例,利用该技术画出“矩形”即鼠标左键按下时,代表绘制矩形开始,并绘制出矩形的左上角处的点,当鼠标左键向右下角移动时,动态地画出一个矩形,鼠标移动,该矩形的右下角也在移动,直到鼠标左键弹起来。

      编写该程序,并上机调试 Visual C++Visual C++  2.在上道题目中,要利用类向导向应用程序中增加WM_LBUTTONDOWN、WM_MOUSEMOVE、WM_LBUTTONUP对这三个消息映射的函数,完后,在程序中产生了相应的代码与消息影射有关的代码有三处:.h.文件中有消息映射宏的说明,.cpp文件中有消息映射的实现和相应消息映射函数的实现请在上述程序的基础上,对与消息映射有关的三处作一些注释并模仿其形式,看是否能手工添加一个对WM_RBUTTONDOWN的消息映射的说明与实现。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.