第4章Windows的图形设备接口及Windows绘图•Windows图形设备接口(GDI)是为与设备无关的图形设计的。所谓设备的无关性,就是操作系统屏蔽了硬件设备的差异,因而设备无关性能使用户编程时无需考虑特殊的硬件设置。Windows支持与设备无关的图形利用GDI和Windows设备驱动程序开发人员只要建立与输出设备的关联,让系统加载相应的设备驱动程序即可一、图形设备接口(GDI)GDI负责系统与用户或绘图程序之间的信息交换,并控制在输出设备上显示图形或文字,是Windows系统的重要组成部分。设备描述表即为设备环境的属性的集合。应用程序与输出设备之间的桥梁Win系统外设直接访问不允许统一的设备环境(DC)提供使应用程序与设备相连用户为确保图形输出的设备无关性1.GDI的一些基本概念应用程序设备描述表及其属性应用程序每一次图形操作均参照设备描述表中的属性执行图形刷新是绘图过程中必须考虑的重要问题刷新请求对刷新请求的响应刷新方法包括(1)刷新请求应用程序在窗口中绘制了一个椭圆,颜色列表框覆盖了椭圆的一部分关闭颜色选框后,应用程序需要恢复被覆盖部分的颜色和形状窗口大小的调整窗口移动被覆盖后的恢复2.图形刷新(2)系统对刷新请求的响应当用户区的内容需要刷新时,系统向应用程序消息队列发送WM_PAINT消息,系统在应用程序的消息队列中加入该消息,以通知窗口函数执行刷新处理三种刷新窗口移动后的刷新被覆盖区域的刷新对象穿越后的刷新(系统自动完成)用户区移动或显示用户窗口大小改变程序通过滚动条滚动窗口窗口被另一个窗口覆盖的恢复如下拉式菜单关闭等光标穿过用户区图标拖过用户区窗口被另一个窗口覆盖的区域称为无效区域。Windows系统为每个窗口建立了一个PAINTSTRUCT结构,该结构中包含了包围无效区域的一个最小矩形的结构RECT,应用程序可以根据这个无效矩形执行刷新操作。TypedefstructtagPAINTSTRUCT{HDChdc;//设备环境句柄BOOLfErase;//一般取真值,表示擦除无效矩形的背景RECTrcPaint;//无效矩形标识BOOLfRestore;//系统保留BOOLfIncUpdate;//系统保留BYTErgbReserved[16];//系统保留}PAINTSTRUCT;rcPaint为标准的RECT数据结构,其作用是标识无效矩形,它包含了无效矩形的左上角和右下角的坐标常用的Windows应用程序刷新窗口的方法保存副本。刷新时将副本拷贝到相应的窗口中记录事件。刷新时重新执行这个曾经发生的事件重新绘制。将图形绘制处理程序放在消息WM_PAINT响应模块中,刷新时重绘图形(3)有效的刷新方法获取设备环境是应用程序输出图形的先决条件,常用的两种方法是调用函数BeginPaint或GetDC(1)调用BeginPaint函数应用程序响应WM_PAINT消息进行图形刷新时,主要通过调用BeginPaint函数获取设备环境hdc=BeginPaint(hwnd,&ps);//ps为PAINTSTRUCT类型结构定义方式为:PAINTSTRUCTps;系统获取设备环境的同时填写ps结构,以标识无效矩形区由BeginPaint函数获取的设备环境要用EndPaint函数释放voidEndPaint(HWNDhwnd,PAINTSTRUCT&ps)3.获取设备环境的方法(2)调用GetDC函数如果绘图工作并非由WM_PAINT消息驱动,则调用GetDC函数获取设备环境。hdc=GetDC(hwnd);由GetDC函数获取的设备环境必须用ReleaseDC函数释放voidReleaseDC(HWNDhwnd);BeginPaint与GetDC的区别项目函数BeginPaint函数GetDc函数使用环境只用于图形刷新时获取设备环境使用较为广泛操作区域使用BeginPaint函数获取设备环境后,操作区域为无效区域使用GetDC函数获取设备环境后,操作区域为整个用户区释放设备环境所用函数由EndPaint函数释放由ReleaseDC函数释放映像模式定义了将逻辑单位转化为设备的度量单位以及设备的x方向和y方向,程序员可在一个统一的逻辑坐标系中操作而不必考虑输出设备的坐标系情况。窗口:对应逻辑坐标系上程序员设定的区域视口:对应实际输出设备上程序员设定的区域窗口和视口如何映射?4.映像模式映像模式将一个逻辑单位映射为坐标系设定MM_ANISOTROPIC系统确定OptionalMM_HIENGLISH0.001英寸Y上,X右MM_HIMETRIC0.01毫米Y上,X右MM_ISOTROPIC系统确定Optional,但x轴和y轴的单位此例为1:1MM_LOENGLISH0.01英寸Y上,X右MM_LOMETRIC0.1毫米Y上,X右MM_TEXT一个像素Y下,X右MM_TWIPS1/1440英寸Y上,X右默认的映射模式将窗口中的对称图形映射到视口时仍为对称图形按照窗口和视口的坐标比例进行映射坐标系统逻辑坐标系统设备坐标系统屏幕坐标系统窗口坐标系统用户区坐标系统应用程序可获取设备环境的当前映像模式,并根据需要设置映像模式。相关函数设置设备环境的映像模式SetMapMode(hdc,nMapMode);nMapMode为映像模式的整型标识符获取当前设备环境的映像模式nMapMode=GetMapMode(hdc);窗口区域的定义由SetWindowExtEx函数完成,其函数原型为:BOOLSetWindowExtEx(HDChdc,intnHeight,nWidth,//以逻辑单位表示的窗口区域高宽度LPSIZElpSize,//函数调用前窗口区域尺寸的SIZE结构地址);视口区域的定义由SetViewportExtEx函数完成,函数原型为:BOOLSetViewportExtEx(HDChdc,intnHeight,nWidth,//以物理设备单位表示的新视口区域高宽度LPSIZElpSize);只有在映射模式为MM_ANISOTROPIC和MM_ISOTROPIC时才有意义视口的默认原点和窗口的默认原点均为(0,0)。可通过调用函数SetViewportOrgEx和SetWindowOrgEx设定窗口与视口的原点。SetWindowOrgEx函数的原型为:BOOLSetWindowOrgEx(HDChdc,intX,Y,//以逻辑单位表示的窗口原点坐标LPPOINTlpPoint//函数调用前原点坐标的POINT结构的地址);只有在映射模式为MM_ANISOTROPIC和MM_ISOTROPIC时才有意义(1)画笔的创建使用画笔之前必须事先定义一个画笔句柄。形式如下:HPENhP;然后调用函数GetStockObject获取Windows系统定义的四种画笔。例如获取画笔BLACK_PEN的形式如下:hP=GetStockObject(BLACK_PEN);WHITE_PENBLACK_PENDC_PENNULL_PEN画笔的操作创建画笔将画笔选入设备环境删除画笔二、绘图工具与颜色1.画笔(2)创建新画笔,形式如下:hP=CreatePen(intnPenStyle,//确定画笔样式intnWidth,//画笔宽度COLORREFrgbColor//画笔颜色);创建画笔后,必须调用SelectObject函数将其选入设备环境。SelectObject(hdc,hP);//hP为所创建或获取的画笔句柄不再使用当前画笔时,需删除画笔,以免占内存DeleteObject(hP);PS_DASH:虚线PS_DASHDOT:点划线PS_DASHDOTDOT:双点划线PS_DOT:点线PS_INSIDEFRAME:实线PS_NULL:无PS_SOLID:实线画刷的创建与应用与画笔很相似,操作画刷也包括创建、选入设备环境和删除。(1)画刷的创建使用画刷需事先定义一个画刷句柄。形式如下:HBRUSHhBr;//hBr为画刷句柄然后调用函数GetStockObject获取Windows系统提供的7种画刷hBr=(HBRUSH)GetStockObject(nBrushStyle)画刷样式BLACK_BRUSH黑色画刷DKGRAY_BRUSH深灰色画刷GRAY_BRUSH灰色画刷HOLLOW_BRUSH虚画刷LTGRAY_BRUSH亮灰色画刷NULL_BRUSH空画刷WHITE_BRUSH白色画刷指定颜色画刷如何获得?2.画刷可调用函数CreateSolidBrush和CreateHatchBrush创建画刷,hBr=CreateSolidBrush(rgbColor);创建具有指定颜色的单色画刷创建指定阴影图案和颜色的画刷(2)选入设备环境创建画刷后,通过SelectObject(hdc,hBr);将其选入设备环境(3)删除画刷不使用画刷时,可用DeleteObject(hBr);删除画刷,释放内存hBr=CreateHatchBrush(intnHctchStyle,COLORREFrgbColor);HS_BDIAGONAL45度从左上到右下HS_DIAGCROSS45度叉线HS_FDIAGONAL45度从左下到右上HS_CROSS垂直相交的阴影线HS_HORIZONTAL水平阴影线HS_VERTICAL垂直阴影线Windows使用宏RGB定义绘图的颜色,其形式为:RGB(nRed,nGreen,nBlue)红色值蓝色值绿色值RGB(255,0,0)RGB(0,255,0)RGB(0,0,255)3.颜色(1)设置画笔当前位置的函数MoveToEx,BOOLMoveToEx(HDChdc,intX,Y,//X、Y分别为新位置的逻辑坐标LPPOINTlpPoint//存放原画笔位置的POINT结构地址)(2)从当前位置向指定坐标点画直线的函数LineToEx,BOOLLineToEx(HDChdc,intX,intY)//X和Y为线段的终点坐标(3)从当前位置开始,依次用线段连接lpPoints中指定的各点BOOLPolyline(HDChdc,LPPOINTlpPoints,//指向包含各点坐标的POINT结构数组的指针intnCount//nCount为POINT数组中点的个数)三、常用绘图函数(4)绘制椭圆弧线的函数ArcBOOLArc(HDChdc,intX1,intY1,//边框矩形左上角的逻辑坐标intX2,intY2,//边框矩形右下角的逻辑坐标intX3,intY3,//椭圆弧起始点坐标intX4,intY4//椭圆弧终止点坐标)(x1,y1)(x2,y2)(x3,y3)(x4,y4)所画曲线(5)绘制饼图,并用当前画刷进行填充BOOLPie(HDChdc,intX1,intY1,//边框矩形左上角的逻辑坐标intX2,intY2,//边框矩形右下角的逻辑坐标intX3,intY3,//椭圆弧起始经线的确定点坐标intX4,intY4//椭圆弧终止经线的确定点坐标)(x1,y1)(x2,y2)(x3,y3)(x4,y4)所填区域(6)绘制矩形,并用当前画刷进行填充BOOLRectangle(HDChdc,intX1,intY1,intX2,intY2)(X1,Y1)和(X2,Y2)分别为矩形的左上角和右下角的逻辑坐标(7)绘制圆角矩形,并用当前画刷填充BOOLRoundRect(HDChdc,intX1,intY1,intX2,intY2,intnHeight,intnWidth)圆角的高度和宽度(8)绘制椭圆,并用当前画刷填充BOOLEllipse(HDChdc,intX1,intY1,intX2,intY2)(9)绘制多边形,并用当前画刷填充BOOLPolygon(HDChdc,LPPOINTlpPoints,intnCount)包含各点坐标的POINT数组的地址多边形点的个数【例4-1】利用绘图函数创建填充区。共有三个填充图形,第一个是用深灰色画刷填充带圆角的矩形,第二个是采用亮灰色画刷填充一个椭圆形图,第三个