




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、从MFC示例开始6.1 图形绘制的基础知识6.2 VC的文本操作6.3 CDC的绘图操作6.3 Windows绘图工具本章内容 教学要点 本章内容包括设备环境与绘图程序的关系,设备环境主要功能以在MFC对应的CDC类,利用设备环境类CDC操纵文本(文本的字体、颜色和属性控制),利用设备环境类CDC实现简单图形的绘制(点、线、椭圆、矩形和弧等),各种绘图工具(画笔、画刷)使用。 要求了解CDC编写的绘图程序调用GDI ,进而调用设备驱动程序的流程,CDC的几个派生类及其使用,掌握CDC的文本操作和图形绘制、常见的绘图参数设置函数的用法、常见的绘图工具画笔和画刷的使用,熟练掌握调用API或CDC成
2、员函数选择库存中的绘图工具。从MFC示例开始利用类向导,生成一个名为MfcExam的标准MFC多文档工程类视图类视图资源视图资源视图文件视图文件视图视图区,也叫客户区,对应的类是CMfcExamView,所有有关视图区的显示,都是在CMfcExamView中的 OnDraw 函数中完成6.1图形绘制的基本知识 6.1.1 图形操作的接口GDI6.1.2 图形操作有关的CDC类6.1.3 CDC的内容6.1.1 图形操作的接口GDI 任何图形程序的输出,都离不开图形设备接口GDI(Graphic Device Interface),它是管理Windows应用程序在窗口内的绘图操作和与此相关的许多
3、其它信息。如图形设备(打印机、显示器)的信息、绘图的坐标系统和映射模式、绘图工具的当前状态(什么样的画笔、画刷、文本的前景色与背景色、文本所使用的字体)。 Windows的GDI绘制的各种图形(点、线、圆、多边形、矩形等)是与设备无关的,即在屏幕的窗口内绘图与在打印机上绘图是相似的。 GDI是一个可执行程序,它接收Windows应用程序的绘图请求(表现为GDI调用),并将它们传送给相应的设备驱动程序,再由设备驱动程序驱动相应的硬件设备,如打印机或显示器输出。6.1.1续 应用程序使用GDI可以对三种类型的图形进行操作:文本操作、矢量图形操作和光栅图形操作(图像操作)。(1)文本操作是以逻辑坐标
4、为单位来计算文本的输出位置,用户可以通过各种GDI函数来作出具有各种效果的文本。(2)矢量图形指的是利用画点、直线、曲线(折线、贝塞尔曲线等)、多边形、扇形、矩形等函数所绘制的图形。(3)光栅图形操作是指以光栅图形函数对以位图形式存储的数据进行操作,它包括各种位图和图标的输出,其在屏幕上表现为对若干个行和列的像素操作。光栅图形操作是直接从内存到显存的拷贝操作,其缺点是需要额外的内存空间,优点是操作速度快。6.1.2 图形操作有关的CDC类 1再论设备描述表 设备描述表是一个用来确定任何设备(如显示器、打印机)的GDI输出位置和内容属性的集合,是Windows系统下的一个保存GDI 内部数据的数
5、据结构,它与特定的显示设备相关。对于显示器,设备描述表总是与显示器上的特定窗口相关。设备描述表中保存了显示图形所需要的各种参数值,如显示颜色、显示坐标、显示方式和背景颜色。在Windows下程序员对所有的绘图功能的调用,都是通过设备描述表来进行的。6.1.2 续 2. 类CDC CDC是后面所讲的其他DC类的基类。CDC基类定义了设备描述表对象, 并且提供在显示器、打印机或Windows用户区上绘图的方法,它封装了使用设备环境的GDI函数。 所有的绘图操作都是直接或间接运用了CDC的成员函数,这些函数有的进行设备描述表操作,有的是用来画图的,还有的函数是用来获取或设置绘图属性,为映像和视点服务
6、的。 在由AppWizard创建的MFC应用程序中,视图类的OnDraw成员函数是一个处理图形的关键虚函数,它带有一个指向设备环境对象的指针pDC,MFC的绘图成大多都是通过pDC这个指针来加以访问的。 下面为CDC类的函数的分类分类分类 用途用途 位图函数位图函数 操作位图和像素的函数操作位图和像素的函数 剪裁函数剪裁函数 定义和操作剪裁设备边界的函数定义和操作剪裁设备边界的函数坐标函数坐标函数 在物理设备和逻辑设备之间转换的函数在物理设备和逻辑设备之间转换的函数 设备描述表函数设备描述表函数 获取有关获取有关DCDC及其属性信息的函数及其属性信息的函数绘图属性函数绘图属性函数 为为DCDC
7、获取和设置颜色及模式的函数获取和设置颜色及模式的函数 绘图工具函数绘图工具函数 枚举在枚举在DCDC中可用的笔和刷子的函数中可用的笔和刷子的函数 椭圆和多边形函数椭圆和多边形函数绘制椭圆和多边形函数绘制椭圆和多边形函数字体函数字体函数 获取字体属性的函数获取字体属性的函数线输出函数线输出函数在在DCDC上绘制线的函数上绘制线的函数映像函数映像函数创建、获取和控制原点,扩展窗口和视及为创建、获取和控制原点,扩展窗口和视及为DCDC获取和设置映像模式的函数获取和设置映像模式的函数区域函数区域函数 填充区域和控制区域颜色的函数填充区域和控制区域颜色的函数 简单绘图函数简单绘图函数提供简单矩形和图标的
8、绘制特性函数提供简单矩形和图标的绘制特性函数 文本函数文本函数 输出文本并获取输出文本并获取DCDC当前选中的字体信息的函当前选中的字体信息的函数数 6.1.3 CDC的内容 1派生类CPaintDC(1)CPaintDC是从CDC派生出来的设备描述表类,它常常在窗口的OnPaint函数中使用。查看MFC的源代码(StudioVC98MFCSRCviewcore.cpp)中的OnPaint函数的实现可以知道,OnPaint函数首先构造一个CPaintDC对象,再调用OnPrepareDC()函数将其准备好,最后以这个准备好的CPaintDC对象指针为参数,来调用OnDraw函数进行各种图形处理
9、。(2)CPaintDC对象在构造时调用CWnd:BeginPaint函数,并返回DC用于绘图,在析构时自动调用CWnd:EndPaint函数释放DC。CPaintDC仅在WM_PAINT消息需要响应时才起作用,通常是在应用程序的OnPaint响应函数中使用。6.1.3 续1 2派生类CClientDC(管理客户区) CClientDC类只能在客户区绘图。所谓客户区是指窗口区域中去掉边框、标题栏、菜单栏、工具栏、状态栏等以外的部分,它是用户可以操作的区域。例如打开Word文档将是将某个.doc文件显示在其客户区域中。在使用CClientDC进行绘图时,一般要调用GetClientRect函数来
10、获取客户区域的大小。 CClientDC类由CDC派生而来,它使调用和释放设备环境的过程自动化。CClientDC对象在构造时调用Windows API函数GetDC, 在析构时调用响应的API函数ReleaseDC,这意味着与CClientDC对象相关的设备环境是窗口的客户区。 CClientDC对象的窗口句柄保存在成员变量m_hWnd,为构造CClientDC,需将CWnd作为参数传递给构造函数。6.1.4续2 3派生类CWindowDC(管理框架窗口) CWindowDC类直接从CDC派生,它使调用和释放整个窗口(包括客户区和非客户区)的设备环境过程自动化。CWindowDC对象在构造时
11、调用Windows API函数GetWindowDC, 在析构时调用相应的API函数ReleaseDC,这意味着CWindowtDC对象可访问CWnd所指向的整个屏幕区域。 CWindowDC允许在显示器的任意位置绘图,坐标原点在整个窗口的左上角。由于使用CWindowDC可以在整个窗口类绘图,这给了程序员很大的自由度,但使用不当会带来麻烦。在使用CWindowDC进行绘图时,一般要调用GetWindowRect函数来获取整个应用程序窗口区域的大小。 CWindowDC对象的窗口句柄保存在成员变量m_hWnd,为构造CWindowDC,需将CWnd作为参数传递给构造函数。6.2VC的文本操作
12、6.2.1文本输出函数 6.2.2文本属性控制 6.2.3文本的字体 6.2.4文本处理实例6.2.1 文本输出函数 在前面的API编程5.5.2节中讲了一个最简单的文本输出函数TextOut(),其实API编程模式和MFC编程模式的最大相似之处在于他们调用的API函数和MFC的成员函数的参数基本上一致,在MFC中出现了很多缺省参数,调用起来更简单,但他们的核心参数都是一样的,因此掌握了某一个API函数的用法,在利用MFC编程时,用法基本一致。API编程模式和MFC编程模式的最大不同在于其程序的框架不一样,可以说,API编程模式的程序框架操作系统已经定义好了,这个框架是最原始的操作系统框架,熟
13、悉该框架比较容易,但框架内部需要自己做的工作还很多;而MFC是一个应用程序框架,是构建在操作系统之上的一个应用程序框架。6.2.1 续1 文本输出除了前面讲的TextOut()外,常见的还有ExtTextOut()。该函数的原型为:BOOL ExtTextOutint x, int y; /输出的位置UINT nOptions;/指定矩形的类型LPCRECT lpRect;/输出的字符的矩形区域const CString& str;/欲输出的字符 LPINT lpDxWidths ;/字符间距; 该函数用来在一个给定的矩形lpRect区域内输出字符串str,此矩形可以设置为透明的(nO
14、ptions=ETO_OPAQUE)或不透明的,当矩形区域为不透明时,用当前的背景色填充矩形。6.2.1 续2 此矩形也可以设置为裁剪(nOptions=ETO_CLIPPED)性质或非裁剪性质,当设置为裁剪性质时,所有在矩形外面的字符串将被裁剪掉。 上述参数中,nOptions主要设置矩形的类型,可以为ETO_OPAQUE和ETO_CLIPPED两个值的一个或两个组合;lpDxWidths是一个指向整数数组的指针,此数组中存放以逻辑单位表示的字符间的距离,第n个数代表第n个和n+1个字符之间的距离。该参数为NULL时,则按缺省值处理。6.2.2 文本属性控制 1 设置文本的背景色 缺省时,在
15、绘制图形或者输出文本时,背景颜色是白色。可以使用CDC的成员函数SetBkColor函数来设置新的背景颜色,函数原型为: Virtual COLORREF SetBkColor(COLORREF crcolor); 其中参数crcolor用于指定新的背景颜色。例如要将背景颜色设为红色,可以用以下语句: SetBkColor(RGB(255,0,0);6.2.2续1 2控制文本的背景色 在设备描述表中有两项可以影响背景,一个是背景色,另一个是背景模式。背景模式可以为透明的(Transparent)或不透明的(Opaque),缺省为不透明的。当背景模式为不透明时,按背景颜色的值填充字符的空余部分,
16、如果背景模式为透明的,将不用背景颜色填充,保留屏幕上原来的颜色。背景模式可用函数SetBkMode来设置,它设置当前的背景模式并返回原来的背景模式,该函数的原型为: int SetBkMode(int nBkMode); 参数nkbmode指定背景模式,其值可以是OPAQUE或者TRANSPARENT,如果值为OPAQUE,则显示时背景都改变为当前背景颜色。如果值为TRANSPARENT,则不改变背景颜色,此时,任何SetBkColor函数调用都无效,缺省的背景模式为OPAQUE。 6.2.2续2 3设置文本的排列方式 在文本显示时遇到的另一个问题是文本的排列方式,它控制文本和给定点的相对位置
17、。在一个图形中加字符说明时,常常知道一个字符串的某一个边界,如左边界不应超过某个位置,或右边界不应超过某个位置,或显示的几行字符串的中心点对齐等。利用CDC的成员函数SetTextAlign函数就能方便地实现这种控制,其原型为: UINT SetTextAlign (UINT nFlags); 其中,nFlags为文本的对齐方式,其值如下: TA_LEFT 将点同边界矩形的水平中心对齐 TA_BASELINES将点同所选字体的基线对齐 TA_BOTTOM将点同边界矩形的底线对齐 6.2.3 文本的字体 字体反映了字符外观特性,如汉字有宋体、楷体、黑体等,西文也有字体如Arial、Roman等,
18、同一个字符以不同的字体输出时外观会不太一样。VC提供了丰富的字体控制功能,不仅可以使用Windows提供的字体,还可以自己创建字体,这使得Windows下文本输出具有很大的灵活性,可以随心所欲,最大限度地满足用户对复杂文本的输出要求。可以这样说,Word字处理程序所能应用的有关字体的功能,在设备环境中都能给以支持。 6.2.3续1 1使用库存字体 Windows系统本身提供了一些库存字体,对于大多数应用程序,使用库存字体即可完成基本的文本输出功能。要想使用库存字体,需要使用CDC的成员函数SelectStockObject()来完成,例如: SelectStockObject(OEM_FIXE
19、D_FONT); 该语句把终端字体选入设备环境,这样,用TextOut或TextOutEx输出文本时,将使用DOS命令窗口的字体。其实,每个设备环境都有一个缺省字体,对于显示器而言,缺省字体就是SYSTEM_FONT系统字体,如果应用程序不需要执行很复杂的文本输出,使用缺省字体即可。字体名称字体名称 说明说明ANSI_FIXED_FONTANSI_FIXED_FONT 基于基于WindowsWindows字符集的固定字宽的字体,通常使用字符集的固定字宽的字体,通常使用CourierCourier字体字体 ANSI_VAR_FONTANSI_VAR_FONT 基于基于WindowsWindows
20、字符集的变宽字体,通常使用字符集的变宽字体,通常使用Ms Sans Ms Sans SerifSerif字体字体 DEVICE_DEFAULT_DEVICE_DEFAULT_FONTFONT特定设备的缺省字体。该字体取决于特定设备的缺省字体。该字体取决于GDIGDI字体的映射程序字体的映射程序如何解释字体请求,因此对于不同的设备,其字体宽度如何解释字体请求,因此对于不同的设备,其字体宽度可能不同可能不同 OEM_FIXED_FONTOEM_FIXED_FONTWindowsWindows在在DOSDOS命令提示窗口中使用的字体,又称终端字命令提示窗口中使用的字体,又称终端字体,它是一种固定宽度
21、的字体,随系统的不同而不同体,它是一种固定宽度的字体,随系统的不同而不同 SYSTEM_FONTSYSTEM_FONT系统字体,是基于系统字体,是基于windowswindows字符集的变宽字体。系统使用字符集的变宽字体。系统使用该字体来显示窗口的标题、菜单和对话框中的文本。系该字体来显示窗口的标题、菜单和对话框中的文本。系统字符集总是可用的,而其他字符集则需要安装后才可统字符集总是可用的,而其他字符集则需要安装后才可使用使用 Windows库存字体库存字体6.2.3续2 2使用自定义逻辑字体 逻辑字体是用和设备无关的方式来描述一个字体,它使用通用的术语来描述一个字符的宏观特性(如高度、宽度、
22、旋转角度、是否有下划线等),但它不能描述微观特性,没有足够的信息来显示字体,是从应用的角度描述一个字体,因为在应用时没有必要把字体的细微结构都描述出来,这会使使用变得很繁琐,这些细节由物体字体描述。我们使用时用逻辑字体来描述需要的文本,GDI根据逻辑字体的描述选配最接近的物理字体,由物理字体进行输出。 MFC提供的CFont类封装了逻辑字体。创建自定义字体并不是创建一种新的字体,而是创建一种逻辑字体。逻辑字体是一种字体属性的列表,如高度、宽度、字符集和字样等。字体映射器按逻辑字体给出的字体特性选择与之匹配的物理字体 6.2.3续3 要创建字体,首先要声明一个CFont对象来表示逻辑字体,然后初
23、始化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;
24、 /声明逻辑字体变量fontfont.CreatePointFont(120, Arial, &dc);/初始化逻辑字体font 6.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
25、( 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进行分析,我们只需要掌握第一种方法即可。6.2.4 文本处理实例 【例6-2
26、】利用MFC编写文本处理的应用程序。 1程序功能描述 使用库存字体和自定义字体,设置文本的前景色、背景色、对齐方式、背景模式,利用TextOut和ExtTextOut函数在屏幕上输出文本。2利用MFC AppWizard(exe)创建程序步骤(1)运行VC6.0,在File菜单中选择New命令,在打开的New对话框中选中Projects标签,在左边的列表框中选择MFC AppWizard(exe)选项,在右边的Project name文本框中输入工程名TextTest,并选择合适的路径。【例6-2】续1(2)单击OK按钮,启动AppWizard,在第一步中选择Single Document单选
27、按钮。(3)从第2步到第6步使用缺省选项,最后生成工程TextTest。 3编辑视图类CTextTestView 中的OnDraw函数,实现文本的各种属性控制及输出。void CTextTestView:OnDraw(CDC* pDC)CTextTestDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);CFont MyFont; /声明逻辑字体变量MyFontCFont* pOldFont;CRect rect; /定义矩形变量rect,保存客户区域CString caption=TextOut()函数输出的透明库存字体OEM_FIXED_FONT!;p
28、DC-SelectStockObject(OEM_FIXED_FONT); /选择库存字体GetClientRect(rect);/取得客户区的区域保存到rect中pDC-SetTextAlign(TA_BASELINE);/设置文本的对齐方式为将点与所选字体的基线对齐pDC-SetBkMode(TRANSPARENT);/设置背景模式不透明pDC-SetTextColor(RGB(255,0,0);/设置文本颜色为红色pDC-SetBkColor(RGB(0,0,255);/设置文本背景颜色为蓝色pDC-TextOut(rect.right/6,rect.bottom/6,caption);
29、/输出文本MyFont.CreatePointFont(140, Arial); /由CreatePointFont函数直接创建一种逻辑字体 pOldFont = pDC-SelectObject(&MyFont); /将新建的字体MyFont选入设备环境pDC-SetTextColor(:GetSysColor(COLOR_WINDOWTEXT);/将字体颜色设置为Windows系统的文本颜色int currentX=rect.right/6 ,currentY=rect.bottom*4/6;char *caption1=用CreatePointFont创建、ExtTextOut输
30、出的不透明的Arial字!;pDC-ExtTextOut(currentX,currentY,ETO_OPAQUE, CRect(currentX,currentY-30,currentX+300,currentY+30), caption1,strlen(caption1),NULL);/在指定的矩形内不透明显示文本 pDC-SelectObject(pOldFont);/恢复系统先前的字体6.3CDC的绘图操作 6.3.1 画点与画线函数操作 6.3.2 绘制封闭图形 6.3.3 设置绘图参数6.3.4 绘图模式 6.3.5 绘图操作实例6.3.1 画点与画线函数操作1画点 CDC的成员函
31、数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是指向折线顶点数组的指针,而cCo
32、unt则指定折线顶点数组中的顶点数目。 6.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为
33、弧的起点x、y坐标;x与y为弧的终点x、y坐标。 参数lpRect表示围绕弧的矩形,它可以是LPRECT 或CRect对象,ptStart表示弧的起点的CPoint 或POINT对象,该点不必精确地位于弧上;PtEnd表示弧的终点的CPoint 或POINT对象,该点不必精确地位于弧上。6.3.2 绘制封闭图形 Windows提供了Rectangle、Ellipse、RoundRect、Chord、Pie等五个函数用来绘制并填充图形。1画矩形BOOL Rectangle( int x1, int y1, int x2, int y2 );BOOL Rectangle( LPCRECT lpRe
34、ct ); 此函数成功调用后返回非0值,否则返回0。其中参数(x1,y1)为指定矩形的左上角逻辑x与y坐标;(x2,y2)为指定矩形右下角的逻辑x与y坐标。参数LpRect为一个矩形结构的指针,用它来表示矩形的四个角。6.3.2 续12画椭圆或圆 使用CDC的成员函数Ellipse,可以使用当前笔绘制一个用当前画刷填充的椭圆或圆。其函数原型如下:BOOL Ellipse(int x1, int y1, int x2, int y2 );BOOL Ellipse( LPCRECT lpRect ); 这两个函数画椭圆成功后返回非0值,否则返回0。所画椭圆高度为y2-y1,宽度为x2-x1。在该函
35、数中,椭圆是由其外接矩形来确定的。外接矩形的中心与椭圆中心重合,矩形的长和宽和椭圆的长短轴相等。函数中的参数与画矩形的相仿,分别表示椭圆外接矩形的左上角和右下角坐标。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,并且
36、y3=y2-y1,则所绘制的圆角矩形变为一个椭圆。6.3.2 续26.3.2 续34 画饼图扇形饼图是一条弧和从弧的两个端点到中心的连线组成的图形。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画的是非封闭图形。各参数参见6.3.1节介绍。5 画弓形弓形
37、图是一条椭圆弧和连接该弧线两个端点的弦,并用当前的画刷来填充其内部区域的封闭图形。Chord原型如下:BOOL Chord( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 ); 该函数参数与Pie函数参数的含义相仿。 6.3.2 续46.3.3 设置绘图参数 绘图参数主要包括文本的前景色、文本的背景色、背景模式、绘图模式、位图伸展模式等,恰当地设置绘图参数,可以达到各种绘图效果。 绘图参数中的文本前景色靠CDC:SetTextColor()来控制,文本的背景色靠CDC:SetBkColor()来控制,背景模式又称填
38、充模式,指的是在使用画笔绘制虚线、点划线或者使用画刷来填充封闭区域时,点和画刷及画刷阴影线之间空隙的着色方式。该功能的实现靠CDC:SetBkModer()来完成,位图伸展模式被CDC的成员函数StretchBlt()使用,它决定进行位图伸展时(目标位图的大小与显示区域的大小不同时就要伸展)如何处理位图数据与目标中原有数据的关系。下面讲绘图参数设置中的绘图模式的设置及其功能。6.3.4 绘图模式 画笔和画刷对点线的绘制和图形的填充起着很重要作用,除此之外,还有设备描述表中的绘图模式(又称光栅操作模式)。例如当绘制一条线段时,该线段的颜色不仅取决于画笔的颜色,而且也取决于该线段所在显示区域的颜色
39、。 当Windows使用画笔画线时,它实际上是在画笔像素和目标位置处原像素之间执行一种按位布尔运算,称为“光栅操作”(Raster Operation),简记为“ROP”。由于画线操作只涉及两种像素(画笔像素和目标像素),所以这种布尔运算又称为“二元光栅操作”(ROP2)。Windows定义了16种ROP2码,用来表示画笔像素和目标像素各种不同的组合方式。可以调用CDC的成员函数SetROP2改变绘图模式,函数原型为:int SetROP2(int nDrawMode); 绘图模式绘图模式说明说明布尔操作(布尔操作(P为画笔像为画笔像素素D为目标像素)为目标像素)R2_BLACK像素最终颜色为
40、黑色0R2_WHITE像素最终颜色为白色1R2_NOP像素颜色没有变化,还是原先目标像素颜色DR2_NOT像素最终颜色为原来颜色的反色DR2_COPYPEN(缺省缺省)像素最终颜色为当前画笔的颜色PR2_NOTCOPYPEN像素最终颜色为当前画笔颜色的反色PR2_MERGEPEN像素最终颜色为当前画笔颜色P和原来颜色D的逻辑或P|DR2_MERGEPENNOT像素最终颜色为当前画笔颜色P和原来颜色反色D的逻辑或P|DR2_MASKPEN像素最终颜色为当前画笔颜色P和原来颜色D的逻辑与P&DR2_MASKPENNOT像素最终颜色为当前画笔颜色P和原来颜色反色D的逻辑与P&DR2_
41、MERGENOTPEN像素最终颜色为当前画笔颜色P的反色和原来颜色的逻辑或P|DR2_MASKNOTPEN像素最终颜色为当前画笔颜色的反色和原来颜色的逻辑与P&DR2_NOTMERGEPEN像素最终颜色为R2_MERGEPEN结果的反色(P|D)R2_NOTMASKPEN像素最终颜色为R2_MASKPEN结果的反色(P&D)R2_XORPEN像素最终颜色为当前画笔颜色和原来颜色的异或结果PDR2_NOTXORPEN像素最终颜色为R2_XORPEN结果的反色(PD)6.3.4续1注意:(1) 在画线时,如果绘图模式为R2_NOT,则画出的线的颜色为原先屏幕颜色的反色。这样画的线均
42、可见,而且第二次画同一条线时,将自动擦除该线并恢复为当前显示颜色。(2) R2_NOP绘图模式等效于同时选择NULL画笔和NULL画刷。(3) 在R2_XORPEN的操作模式下,用相同的参数两次调用某一条绘图命令时(包括文字输出函数),其结果仍然保留原样,利用这种方式,我们可以实现图形动画效果。(4) 在画虚线时,用于填充线间的空白颜色取决于当前背景模式和背景颜色。(5) 在R2_NOTXORPEN的操作模式下,其功能有二,第一,将同一直线绘制两次,将删除该直线;第二,无论背景是何颜色,第一次绘制的直线总是可见的。6.3.5 绘图操作实例 【例6-3】一个演示绘图模式与画线的应用程序。1程序功
43、能描述 利用绘图模式实现“橡皮条”功能的直线绘制。一般的绘图软件(如AutoCAD),在画直线时的操作方法是:当按鼠标左键时,准备绘制直线,当在屏幕移动鼠标时,在屏幕上画一条直线,该直线开始于原先按下鼠标左键的位置,终止于当前鼠标移动到的位置。随着鼠标的移动,该直线也在移动,但直线的起始点不动,类似于一个橡皮筋固定在一端,而在拉动它的另一端。2利用MFC AppWizard(exe)创建程序步骤(1)生成应用程序框架 利用应用程序向导MFC AppWizard(exe)创建一个单文档的应用程序框架,该工程的名称为MyDraw,向导的每个步骤都使用缺省的。【例6-3】续1(2)在视图类CMyDr
44、aw添加数据成员在工程MyDraw的工作区中,选择“ClassView”选项卡,在类名列表窗口中选择视图类“CMyDrawView”,然后单击鼠标右键,在弹出的快捷菜单中选择“Add Member Variable”命令,则弹出图6.2所示的对话框。在“Variable Type”编辑框中输入bool,在“Variable Name”编辑框中输入m_IsDraw,选择Access(访问控制属性)为Private(私有)。最后按“OK”按钮,则在视图类CMyDrawView中添加了一个bool型的私有成员变量m_IsDraw,用于标记是否开始绘制直线,当该值为真时,代表开始画直线,为假时,代表停
45、止画直线。 另外,为了确定所画线的起始点和终止点,需要在视图类中添加两个CPoint型的成员变量m_StartPoint和m_EndPoint,前者存放直线的起始点,后者存放直线的终止点,添加的方法同上。图6.2【例6-3】续2(3)对成员变量m_IsDraw进行初始化 在视图类CMyDrawView的构造函数中添加如下的代码可以实现对数据成员的初始化。CMyDrawView:CMyDrawView() m_IsDraw=false; /开始不绘制直线(4)添加鼠标左键按下消息的映射函数选择View|ClassWizard命令,弹出MFC ClassWizard窗体,在Class name 中
46、选择CMyDrawView,在Messages中选择WM_LBUTTONDOWN,然后单击“Add Function”按钮,这样就为视图类添加了WM_LBUTTONDOWN的消息处理函数OnLButtonDown, 如图6.3所示。图6.3【例6-3】续3 最后,单击“Edit Code”按钮,光标自动定位到OnLButtonDown 实现处,在该消息映射函数中添加后的代码如下:void CMyDrawView:OnLButtonDown(UINT nFlags, CPoint point) m_IsDraw=true; /开始绘制直线m_StartPoint=m_EndPoint=point
47、; /开始画线时起始点与终止点重合CView:OnLButtonDown(nFlags, point); 【例6-3】续4(5)添加鼠标移动的消息映射函数 与上一步类似,利用ClassWizard为视图类CMyDrawView添加击键消息WM_MOUSEMOVE的消息映射函数OnMouseMove(),并在该函数中添加代码,以用于移动屏幕上的图形。void CMyDrawView:OnMouseMove(UINT nFlags, CPoint point) CClientDC dc(this); /构造一个客户设备环境dcif(m_IsDraw) dc.MoveTo(m_StartPoint)
48、; /移动到起始点 dc.SetROP2(R2_NOTXORPEN);/设置绘图模式为R2_NOTXORPEN dc.LineTo(m_EndPoint); /从点m_StartPoint画线到点m_EndPoint,即删除原旧线 dc.MoveTo(m_StartPoint); /移动到起始点 dc.LineTo(point);/从点 m_StartPoint画线到当前的鼠标位置point m_EndPoint=point; /改变终止点为当前的鼠标位置pointCView:OnMouseMove(nFlags, point);【例6-3】续4(6)添加鼠标左键弹起的消息映射函数 与上一步类
49、似,利用ClassWizard为视图类CMyDrawView添加击键消息WM_LBUTTONUP的消息映射函数OnLButtonUp(),并在该函数中添加如下代码,以用于停止绘图: void CMyDrawView:OnLButtonUp(UINT nFlags, CPoint point) m_IsDraw=false; /停止绘制直线CView:OnLButtonUp(nFlags, point); 6.4Windows绘图工具 6.4.1 绘图工具的划分6.4.2 使用画笔 6.4.3 使用画刷6.4.4 使用库存工具概要 VC绘图需要两个要素:设备描述表和基本绘图工具。设备描述表是由C
50、DC类及其派生类来描述,它是一个画图的画布,提供绘图的场地和环境。画布一般是窗口的客户区,每个窗口CWnd对象都提供一个设备环境,在该环境中有一套默认的基本绘图工具。上一节讲的文本操作中,可以更改文字的字体,字体就是一种绘图工具。当设备环境所提供的默认的绘图工具不能满足我们的需求时,就需要更改默认绘图工具,达到绘制丰富多彩图形的目的。 6.4.1 绘图工具的划分 绘图工具,又称绘图对象,使用他们可以在Windows设备环境中绘制具有各种效果的图形。如果把设备描述表比作画布,程序员比作画家的话,那么绘图工具就是画家手中的画笔、画刷、调色板等。任何一个画家,不论他的技艺有多么高超(类似于程序员要掌
51、握绘图原理),在没有任何绘图工具的情况下,都无法在画布上画图。 Windows的绘图工具包括画笔、画刷、字体、位图、调色板和区域。在MFC中这些绘图工具被封装到相应的类中。这些绘图工具中,字体在文本操作中已讲,该节中主要讲解其它的几类绘图工具,其中没有讲调色板和位图,自己查阅相关资料进行学习。 6.4.2 使用画笔 画笔是最简单的一种绘图工具,同时也是最重要的一种绘图对象。在现实世界中,可以用不同的笔产生不同的线。这正如绘图用的彩笔、不同颜色笔产生不同颜色的线。Windows也是利用这种面向对象的描述事物的方法,把笔作为一个对象,和现实世界一样,不同的笔产生不同的线。 1 画笔类CpenCPe
52、n对象封装了Windows GDI笔,并提供与CPen对象一起工作的几种方法。6.4.2续1 2画笔工具的操作步骤(1)声明CPen对象。(2)初始化画笔。通过调用CreatePen成员函数可以初始化笔,该函数的原型为:BOOL CreatePen( int nPenStyle, int nWidth, COLORREF crColor );(3)将新建的画笔对象选进设备场景中,同时保存原画笔对象的指针:pOldPen=pDC-SelectObject(&pen);(4)调用绘图函数生成图形。(5)选择设备场景的原有笔对象。6.4.2续2 3画笔工具的操作实例【例6-4】一个演示画笔的
53、例子。首先利用MFC AppWizard(exe)创建一个新工程,工程的名字为PenTest,除了应用程序的类型选为单文档模式外,向导的每个操作步骤都采用缺省的。(1) 编辑视图类CPenTestView的虚函数OnDraw,实现画笔工具的操作演示。(2)程序运行结果如图6.4所示void CPenTestView:OnDraw(CDC* pDC)CPenTestDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);_int8 i; CPen*pOldPen; for(i=0;iSelectObject( &NewPen );pDC-MoveTo(6
54、0,60+i*30);pDC-LineTo(200,60+i*30); /用新创建的笔画直线pDC-SelectObject( pOldPen ); /恢复设备描述表中原有笔elseAfxMessageBox(不能创建笔!); /给出错误提示return ;pDC-TextOut(60,60+i*30,不同风格的笔);/设置颜色表structtagColor int r,g,b; color6= 255,0,0,0,255,0,0,0,255,255,255,0,255,0,255,0,255,255 ;for(i=5;i=0;i-) /用不同颜色笔画圆 CPen NewPen; /声名一个笔
55、对象if( NewPen.CreatePen( PS_SOLID, 3, RGB(colori.r,colori.g,colori.b) ) ) pOldPen = pDC-SelectObject( &NewPen );/用新创建的笔画圆pDC-Ellipse( 400-(i+1)*15, 150-(i+1)*15, 400+(i+1)*15,150+(i+1)*15);pDC-SelectObject( pOldPen ); /恢复设备描述表中的原有的笔else AfxMessageBox(不能创建笔!);return ;pDC-TextOut(400-(i+4)*15,150+(
56、i+9)*15,不同颜色的笔); 画笔的各种效果演示6.4.3 使用画刷画笔对象是用来绘制图形边界的,而画刷则是给图形内部着色的。大多数CDC的绘图函数都要同时使用画笔和画刷使用画笔来来绘制各种图形的边界,使用画刷来填充图形的内部。1常用的两类画刷(1)纯色画刷 又称实画刷,事实上它是一个定义了8像素8像素的含有64个相同颜色的像素。在绘制时,Windows将多个这样的纯色位图平铺来填充封闭图形的内部。 创建纯色画刷首先创建一个非初始化的CBrush对象,然后调用CBrush:CreateSolidBrush()函数来初始化纯色画刷。6.4.3续1(2)阴影画刷 阴影画刷是用某种颜色的阴影线在
57、封闭图形内填充。它也是一个定义了8像素8像素的含有64个像素单位位图,该位图就是一个阴影。在绘制时,Windows将多个这样含有阴影的位图平铺来填充封闭图形内部。 创建阴影画刷首先创建一个非初始化的CBrush对象,然后调用CBrush: CreateHatchBrush()函数来初始化阴影画刷。 当使用阴影绘图时,Windows使用默认的背景颜色将阴影线段之间的空间填满。但是,若使用CDC:SetBkColor()函数改变了当前设备描述表的背景颜色,或者通过使用CDC:SetBkMode()函数从OPAQUE到TRANSPARENT改变背景模式,以便关闭背景填充时,这些默认值就被相应地改变了
58、。6.4.3续22画刷类CBrush CBrush对象封装了Windows GDI刷子,并提供与CBrush对象一起工作的一些函数,如表6.6所示。3画刷工具的使用步骤(1)生成CBrush的实例。刷子以多种样式和颜色出现在CBrush:CBrush(): CBrush( ); CBrush( COLORREF crColor ); CBrush( int nIndex, COLORREF crColor ); 表6.6画刷类CBrush的成员函数6.4.3续3上述函数的参数crColor指定刷子颜色;nIndex参数指定刷子图案,其值如表6.7所示。(2)调用相应的成员函数初始化刷子。(3)
59、将所创建的画刷选入设备环境,同时保存原画刷对象的指针。(4)调用绘图函数生成图形。(5)恢复原先设备环境中的画刷。 4画刷工具的操作实例【例6-5】一个演示各种画刷的例子。首先利用MFC AppWizard(exe)创建一个新工程,工程的名字为BrushTest,除了应用程序的类型选为单文档模式外,向导的每个操作步骤都采用缺省的。(1) 编辑视图类CBrushTestView的虚函数OnDraw,实现画刷工具的操作演示。(2)程序运行结果如图6.5所示。void CBrushTestView:OnDraw(CDC* pDC)CBrushTestDoc* pDoc = GetDocument()
60、;ASSERT_VALID(pDoc);_int8 i;CBrush* pNewBrush,*pOldBrush; /定义一个新画刷和旧画刷的指针变量定义一个新画刷和旧画刷的指针变量/设置纯色画刷的颜色表设置纯色画刷的颜色表structtagColor int r,g,b; color7=255,0,0,0,255,0,0,0,255,255,255,0,255,0,255,0,255,255;for(i=0;iCreateSolidBrush(RGB(colori.r, colori.g, colori.b)pOldBrush = pDC-SelectObject( pNewBrush ); /将新建的新画刷选入设备环境将新建的新画刷选入设备环境pDC-Rectangle(40
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 有机化学原料的环保合成方法优化研究进展分析预测考核试卷
- 机器人服务创新模式与实践案例考核试卷
- 景区旅游信息化平台运营与管理考核试卷
- 制作气球培训课件
- 家电公司转让合同范本
- 委托汽车融资合同范本
- 正规吊车租赁合同范本
- 围墙制作安装合同范本
- 项目建设策划合同范本
- 酒店餐饮服务流程优化与提升制度
- 人工智能大模型
- 高空作业车外墙施工方案
- 川教版信息技术五年级下册全册教学设计教案
- 重庆市江北区社区专职工作者招考聘用高频500题难、易错点模拟试题附带答案详解
- 掩体构筑与伪装教学法教案
- 让我们一起去追“星”!两弹一星之核弹老人魏世杰课件高二下学期爱国主义教育主题班会
- 2024年日历表电子版(带农历-含周数-周一开始-打印版)
- 2024年计算机组成原理期末考试试题及答案共五套
- DB32T-认知障碍老年人康复训练服务规范编制说明
- 三年级上册科学全册知识点2024年新青岛版六三制
- 网络营销(第三版) 课件 项目一 网络营销概述
评论
0/150
提交评论