1 / 47

第八章 Visual C++ 图形程序设计

第八章 Visual C++ 图形程序设计. 一、基础知识 二、绘图工具 CGdiObject 类及子类 三、绘图操作 CDC 类及子类. 一、基础知识. 画家与程序员 图形设备接口( GDI) 和设备环境( DC) 图形刷新 映射模式( MM) 颜色. 1.1. 画家与程序员. 画家---程序员 画布---窗口客户区 画家使用的工具---画笔、画刷、调色板等. 图形示例:.

nau
Download Presentation

第八章 Visual C++ 图形程序设计

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. 第八章 Visual C++图形程序设计 一、基础知识 二、绘图工具 CGdiObject类及子类 三、绘图操作 CDC类及子类 中国地质大学(武汉) 计算机学院

  2. 一、基础知识 • 画家与程序员 • 图形设备接口(GDI)和设备环境(DC) • 图形刷新 • 映射模式(MM) • 颜色 中国地质大学计算机学院

  3. 1.1. 画家与程序员 • 画家---程序员 • 画布---窗口客户区 • 画家使用的工具---画笔、画刷、调色板等 中国地质大学计算机学院

  4. 图形示例: • Bring notebook, textbook, planner, and appropriate writing tools to class. • Know due dates, and submit all coursework on time. • All assignments are posted on the bulletin board and on the class Web site. 中国地质大学计算机学院

  5. 图形设备接口(GDI) GDI负责系统与用户或绘图程序之间的信息交换,并控制在输出设备上显示图形或文字, 是Windows系统的重要组成部分 开发人员只要建 立与输出设备的 关联,让系统加 载相应的设备驱 动程序即可 Windows 利用GDI和Windows设备驱动程序 支持与设备无关的图形 1.2. 图形设备接口与设备环境 Windows图形设备接口(GDI)是为与设备无关的图形设计的。所谓设备的无关性,就是操作系统屏蔽了硬件设备的差异,因而设备无关性能使用户编程时无需考虑特殊的硬件设置 中国地质大学计算机学院

  6. 为确保图形输出的设备无关性 不允许 用户 提供 • GDI的一些基本概念 • 设备描述表即为设备环境的属性的集合 应用程序与输出设备之间的桥梁 直接访问 外设 Win系统 统一的设备环境(DC) 使应用程序与设备相连

  7. 设备描述表及其属性 通过设备描述表的句柄来间接地存取 应用程序 应用程序每一次图形操作均参照设备描述表中的属性执行

  8. 图形刷新是绘图过程中必须考虑的重要问题 刷新请求 对刷新请求的响应 刷新方法 包括 关闭颜色选框后, 应用程序需要恢 复被覆盖部分的颜色和形状 应用程序在窗口中 绘制了一个椭圆, 颜色列表框覆盖了 椭圆的一部分 窗口大小的调整 窗口移动 被覆盖后的恢复 1.3.图形刷新 (1) 刷新请求

  9. (2) 系统对刷新请求的响应 当用户区的内容需要刷新时,系统向应用程序消息队列发送WM_PAINT消息,系统在应用程序的消息队列中加入该消息,以通知窗口函数执行刷新处理 用户区移动或显示 用户窗口大小改变 程序通过滚动条滚动窗口 窗口移动后的刷新 被覆盖区域的刷新 对象穿越后的刷新 (系统自动完成) 窗口被另一个窗口覆盖的 恢复如下拉式菜单关闭等 三种 刷新 光标穿过用户区 图标拖过用户区

  10. rcPaint 为标准的RECT数据结构,其作用是标识无效矩形,它包含了无效矩形的左上角和右下角的坐标 窗口被另一个窗口覆盖的区域称为无效区域。 Windows系统为每个窗口建立了一个PAINTSTRUCT结构,该结构中包含了包围无效区域的一个最小矩形的结构RECT,应用程序可以根据这个无效矩形执行刷新操作。 Typedef struct tagPAINTSTRUCT { HDC hdc; //设备环境句柄 BOOL fErase; //一般取真值,表示擦除无效矩形的背景 RECT rcPaint; //无效矩形标识 BOOL fRestore; //系统保留 BOOL fIncUpdate; //系统保留 BYTE rgbReserved[16];//系统保留 }PAINTSTRUCT;

  11. (3) 有效的刷新方法 记录事件。刷新时重新执行这个曾经发生的事件 常用的Windows应用程序刷新窗口的方法 保存副本。刷新时将副本拷贝到相应的窗口中 重新绘制。将图形绘制处理程序放在消息WM_PAINT响应模块中,刷新时重绘图形

  12. 1.4.映像模式 • 映像模式定义了将逻辑单位转化为设备的度量单位以及设备的x方向和y方向,程序员可在一个统一的逻辑坐标系中操作而不必考虑输出设备的坐标系情况 窗口:对应逻辑坐标系上程序员设定的区域 视口:对应实际输出设备上程序员设定的区域 窗口和视口 如何映射?

  13. 映射示意图---原始文档和显示的文档 中国地质大学计算机学院

  14. 原始文档和显示的文档 中国地质大学计算机学院

  15. 屏幕坐标系统 窗口坐标系统 用户区坐标系统 按照窗口和视口的坐标比例进行映射 将窗口中的对称图形映射到视口时仍为对称图形 缺省的映射模式 逻辑坐标系统 坐标系统 设备坐标系统

  16. CDC * pDC1; (1) 设置坐标的映射模式 pDC1->SetMapMode(MM_ISOTROPIC); (2) 设置逻辑坐标 pDC1->SetWindowExt(200,200); pDC1->SetWindowOrg(0,0); (3)设置物理坐标 pDC1->SetViewportExt(rc.right,-rc.bottom); pDC1->SetViewportOrg(0,rc.bottom);

  17. 1.5. 颜色 Windows使用宏RGB定义绘图的颜色,其形式为: RGB(nRed, nGreen,nBlue) RGB(0,0,255) 蓝色值 RGB(0,255,0) 绿色值 红色值 RGB(255,0,0)

  18. 二、Visual C++ 绘图工具CGdiObject类及子类 • 画家==程序员 • 绘图操作==CDC类及其子类 • 绘图工具==CGdiObject类及其子类 中国地质大学计算机学院

  19. 2.1. 画笔---计算机中一条线有哪些属性? 线的坐标 线型 线宽 线的颜色 中国地质大学计算机学院

  20. CPen类的操作步骤 (1)声明CPen对象。 (2)初始化画笔。 通过调用CreatePen成员函数可以初始化笔,该函数的原型为:BOOL CreatePen( int nPenStyle, int nWidth, COLORREF crColor ); (3)将新建的画笔对象选进设备场景中,同时保存原画笔对象的指针: pOldPen=pDC->SelectObject(&pen); (4)调用绘图函数生成图形。 (5)选择设备场景的原有画笔对象。 中国地质大学计算机学院

  21. 画笔的各种效果演示 中国地质大学计算机学院

  22. 2.2 画刷---有哪些属性? 中国地质大学计算机学院

  23. 画刷起什么作用? 画笔对象是用来绘制图形边界的。 画刷则是给图形内部着色的。 CBrush::CreateSolidBrush() 函数来初始化纯色画刷。 CBrush::CreateHatchBrush() 函数来初始化阴影画刷。 中国地质大学计算机学院

  24. 画刷起什么作用? 画笔对象是用来绘制图形边界的。 画刷则是给图形内部着色的。 CBrush::CreateSolidBrush() 函数来初始化纯色画刷。 CBrush br; br.CreateSolidBrush(RGB(255,0,0)); CBrush::CreateHatchBrush() 函数来初始化阴影画刷。 CBrush::CreateHatchBrush(int nIndex, DWORD crColor); 例如:创建一个十字线阴影的红色图案刷子 CBrush br; br.CreateHatchBrush(HS_CROSS,RGB(255,0,0)); 中国地质大学计算机学院

  25. 三、Visual C++ 绘图操作CDC类及其子类 • 画家==程序员 • 绘图操作==CDC类及其子类 • 绘图工具==CGdiObject类及其子类 中国地质大学计算机学院

  26. 3.1. CDC子类介绍--- CClientDC类 • CClientDC类只能在客户区绘图。 • 所谓客户区是指窗口区域中去掉边框、标题栏、菜单栏、工具栏、状态栏等以外的部分,它是用户可以操作的区域。 • 例如打开Word文档将是将某个.doc文件显示在其客户区域中。 • 在使用CClientDC进行绘图时,一般要调用GetClientRect函数来获取客户区域的大小。 • CClientDC类由CDC派生而来,它使调用和释放设备环境的过程 自动化。CClientDC对象在构造时调用Windows API函数GetDC, 在析构时调用响应的API函数ReleaseDC,这意味着与CClientDC对象相关的设备环境是窗口的客户区 • CClientDC对象的窗口句柄保存在成员变量m_hWnd, • 为构造CClientDC,需将CWnd作为参数传递给构造函数。

  27. CDC子类介绍--- CWindowDC类 派生类CWindowDC(管理框架窗口) CWindowDC类直接从CDC派生,它使调用和释放整个窗口(包括客户区和非客户区)的设备环境过程自动化。 CWindowDC对象在构造时调用Windows API函数GetWindowDC, 在析构时调用相应的API函数ReleaseDC,这意味着CWindowtDC对象可访问CWnd所指向的整个屏幕区域。 CWindowDC允许在显示器的任意位置绘图,坐标原点在整个窗口的左上角。由于使用CWindowDC可以在整个窗口类绘图,这给了程序员很大的自由度,但使用不当会带来麻烦。 在使用CWindowDC进行绘图时,一般要调用GetWindowRect函数来获取整个应用程序窗口区域的大小。 CWindowDC对象的窗口句柄保存在成员变量m_hWnd,为构造CWindowDC,需将CWnd作为参数传递给构造函数。

  28. 3.2. Visual C++的文本操作 文本输出函数 文本属性控制 文本的字体 中国地质大学计算机学院

  29. 3.2.1. 基本的文本输出函数 设置前景色: CDC::SetTextColor(int nColor); 设置背景色: CDC::SetBkColor(int nColor); 文本输出函数: CDC::TextOut(…); 示例: dc.SetTextColor(WHITE); dc.SetBkColor(DK_BLUE); dc.TextOut(10,10,“Here it is.”); 中国地质大学计算机学院

  30. 扩展的文本输出函数 文本输出除了前面讲的TextOut()外,常见的还有ExtTextOut(): 该函数的原型为: BOOL ExtTextOut { int x, int y; //输出的位置 UINT nOptions;//指定矩形的类型 LPCRECT lpRect;//输出的字符的矩形区域 const CString& str;//欲输出的字符 LPINT lpDxWidths ;//字符间距 }; 该函数用来在一个给定的矩形lpRect区域内输出字符串str,此矩形可以设置为透明的(nOptions=ETO_OPAQUE)或不透明的,当矩形区域为不透明时,用当前的背景色填充矩形。 中国地质大学计算机学院

  31. 扩展的文本输出函数 此矩形也可以设置为裁剪(nOptions=ETO_CLIPPED)性质或非裁剪性质,当设置为裁剪性质时,所有在矩形外面的字符串将被裁剪掉。 上述参数中,nOptions主要设置矩形的类型,可以为ETO_OPAQUE和ETO_CLIPPED两个值的一个或两个组合; lpDxWidths是一个指向整数数组的指针,此数组中存放以逻辑单位表示的字符间的距离,第n个数代表第n个和n+1个字符之间的距离。该参数为NULL时,则按缺省值处理。 中国地质大学计算机学院

  32. 3.2.2.文本属性控制---设置文本的背景色 缺省时,在绘制图形或者输出文本时,背景颜色是白色。可以使用CDC的成员函数SetBkColor函数来设置新的背景颜色,函数原型为: Virtual COLORREF SetBkColor(COLORREF crcolor); 其中参数crcolor用于指定新的背景颜色。 例如要将背景颜色设为红色,可以用以下语句: SetBkColor(RGB(255,0,0); 中国地质大学计算机学院

  33. 文本属性控制---控制文本的背景色 在设备描述表中有两项可以影响背景,一个是背景色,另一个是背景模式。背景模式可以为透明的(Transparent)或不透明的(Opaque),缺省为不透明的。当背景模式为不透明时,按背景颜色的值填充字符的空余部分,如果背景模式为透明的,将不用背景颜色填充,保留屏幕上原来的颜色。背景模式可用函数SetBkMode来设置,它设置当前的背景模式并返回原来的背景模式,该函数的原型为: int SetBkMode(int nBkMode); 参数nkbmode指定背景模式,其值可以是OPAQUE或者TRANSPARENT,如果值为OPAQUE,则显示时背景都改变为当前背景颜色。如果值为TRANSPARENT,则不改变背景颜色,此时,任何SetBkColor函数调用都无效,缺省的背景模式为OPAQUE。 中国地质大学计算机学院

  34. 文本属性控制---设置文本的排列方式 在文本显示时遇到的另一个问题是文本的排列方式,它控制文本和给定点的相对位置。在一个图形中加字符说明时,常常知道一个字符串的某一个边界,如左边界不应超过某个位置,或右边界不应超过某个位置,或显示的几行字符串的中心点对齐等。利用CDC的成员函数SetTextAlign函数就能方便地实现这种控制,其原型为: UINT SetTextAlign (UINT nFlags); 其中,nFlags为文本的对齐方式,其值如下: TA_LEFT 将点同边界矩形的水平中心对齐 TA_BASELINE S将点同所选字体的基线对齐 TA_BOTTOM 将点同边界矩形的底线对齐 中国地质大学计算机学院

  35. 3.2.3.文本的字体 字体反映了字符外观特性,如汉字有宋体、楷体、黑体等,西文也有字体如Arial、Roman等,同一个字符以不同的字体输出时外观会不太一样。VC提供了丰富的字体控制功能,不仅可以使用Windows提供的字体,还可以自己创建字体,这使得Windows下文本输出具有很大的灵活性,可以随心所欲,最大限度地满足用户对复杂文本的输出要求。可以这样说,Word字处理程序所能应用的有关字体的功能,在设备环境中都能给以支持。 中国地质大学计算机学院

  36. 文本的字体---使用库存字体 Windows系统本身提供了一些库存字体,对于大多数应用程序,使用库存字体即可完成基本的文本输出功能。 要想使用库存字体,需要使用CDC的成员函数SelectStockObject()来完成,例如: SelectStockObject(OEM_FIXED_FONT); 该语句把终端字体选入设备环境,这样,用TextOut或TextOutEx输出文本时,将使用DOS命令窗口的字体。其实,每个设备环境都有一个缺省字体,对于显示器而言,缺省字体就是SYSTEM_FONT系统字体,如果应用程序不需要执行很复杂的文本输出,使用缺省字体即可。 中国地质大学计算机学院

  37. 文本的字体---使用自定义逻辑字体 逻辑字体是用和设备无关的方式来描述一个字体,它使用通用的术语来描述一个字符的宏观特性(如高度、宽度、旋转角度、是否有下划线等),但它不能描述微观特性,没有足够的信息来显示字体,是从应用的角度描述一个字体,因为在应用时没有必要把字体的细微结构都描述出来,这会使使用变得很繁琐,这些细节由物体字体描述。我们使用时用逻辑字体来描述需要的文本,GDI根据逻辑字体的描述选配最接近的物理字体,由物理字体进行输出。 MFC提供的CFont类封装了逻辑字体。创建自定义字体并不是创建一种新的字体,而是创建一种逻辑字体。逻辑字体是一种字体属性的列表,如高度、宽度、字符集和字样等。字体映射器按逻辑字体给出的字体特性选择与之匹配的物理字体 中国地质大学计算机学院

  38. 文本的字体---创建字体 要创建字体,首先要声明一个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);//声明客户区设备环境变量dc CFont font; //声明逻辑字体变量font font.CreatePointFont(120, "Arial", &dc); CFont* def_font = dc.SelectObject(&font); dc.TextOut(5, 5, "Hello", 5); dc.SelectObject(def_font); //恢复旧字体 font.DeleteObject(); //删除所建立的字体 中国地质大学计算机学院

  39. 文本的字体---创建字体 (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 ); 中国地质大学计算机学院

  40. 3.3. 常用绘图函数 • (1).设置画笔当前位置的函数MoveTo, • BOOL MoveTo • ( • int X, int Y • ) (2). 从当前位置向指定坐标点画直线的函数LineTo, BOOL LineTo(int X,int Y) //X和Y为线段的终点坐标 (3). 从当前位置开始,依次用线段连接lpPoints中指定的各点 BOOL Polyline ( LPPOINT lpPoints, //指向包含各点坐标的POINT结构数组的指针 int nCount // nCount为POINT数组中点的个数 )

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

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

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

  44. (10). 绘制弓形图,并用当前画刷填充 • BOOL Chord( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 ); (11). 画点函数: COLORREF SetPixel( POINT point, COLORREF crColor );

  45. 3.4. 绘图模式 • 画笔和画刷对点线的绘制和图形的填充起着很重要作用,除此之外,还有设备描述表中的绘图模式(又称光栅操作模式)。例如当绘制一条线段时,该线段的颜色不仅取决于画笔的颜色,而且也取决于该线段所在显示区域的颜色。 • 当Windows使用画笔画线时,它实际上是在画笔像素和目标位置处原像素之间执行一种按位布尔运算,称为“光栅操作”(Raster Operation),简记为“ROP”。由于画线操作只涉及两种像素(画笔像素和目标像素),所以这种布尔运算又称为“二元光栅操作”(ROP2)。Windows定义了16种ROP2码,用来表示画笔像素和目标像素各种不同的组合方式。 • 可以调用CDC的成员函数SetROP2改变绘图模式,函数原型为: int SetROP2(int nDrawMode); 中国地质大学计算机学院

  46. 3.5. 总结: 绘图基本步骤 (1) 获取设备环境 (2) 设置逻辑坐标及逻辑原点 (3) 设置物理坐标及其设备原点 (4) 初始化绘图工具 (5) 调用绘图函数绘图 (3) 释放设备环境结束绘图 中国地质大学计算机学院

  47. 习题: 绘制多边形 1、当按鼠标左键时,开始绘制直线。 2、当按住鼠标左键在屏幕上移动鼠标时,在屏幕上 画一条直线;该直线开始于原先按下鼠标左键的位置,终止于当前鼠标移动到的位置。随着鼠标的移动,该直线也在移动,但直线的起始点不动,类似于一个橡皮筋固定在一端,而在拉动它的另一端。 3、当鼠标左键起来时,结束画直线操作。 4、当按鼠标右键时,封闭所画的多边形。 5、要求能选择直线的宽度、线的颜色、线型。 6、要求能选择填充的图案、填充的颜色。 中国地质大学计算机学院

More Related