04 绘图程序.docx

上传人:b****8 文档编号:9369163 上传时间:2023-02-04 格式:DOCX 页数:29 大小:28.70KB
下载 相关 举报
04 绘图程序.docx_第1页
第1页 / 共29页
04 绘图程序.docx_第2页
第2页 / 共29页
04 绘图程序.docx_第3页
第3页 / 共29页
04 绘图程序.docx_第4页
第4页 / 共29页
04 绘图程序.docx_第5页
第5页 / 共29页
点击查看更多>>
下载资源
资源描述

04 绘图程序.docx

《04 绘图程序.docx》由会员分享,可在线阅读,更多相关《04 绘图程序.docx(29页珍藏版)》请在冰豆网上搜索。

04 绘图程序.docx

04绘图程序

第四章 WINDOWS绘图程序设计

  图形设备接口(GDI:

GraphicsDeviceInterface)是Windows的子系统,它负责在视频显示器和打印机上显示图形。

正如您所认为的那样,GDI是Windows非常重要的部分。

不但您为Windows编写的应用系统在显示视觉信息时只使用GDI,就连Windows本身也只使用GDI来显示用户界面对象,诸如菜单、滚动条、图标和鼠标光标。

  不幸的是,如果要对GDI进行全面的讲述,将需要一整本书。

在本章中,我只是想向您提供画线和填充区域的基本知识,这对于理解GDI已经足够了。

GDI的结构

从程序员的观点来看,GDI由几百个函数调用和一些相关的数据类型、宏和结构组成。

但是在开始讲述这些函数的细节之前,让我们先从宏观上了解一下GDI的整体结构。

一、GDI原理

  Windows98/NT/2000中的图形主要由GDI32.DLL动态链接库输出的函数来处理。

在Windows98中,这个GDI32.DLL实际是利用16位GDI.EXE动态链接库来执行许多函数。

  这些动态链接库为您安装的视频显示器和任何打印机调用设备驱动程序中的例程。

视频驱动程序访问视频显示器的硬件,打印机驱动程序将GDI命令转换为各种打印机能够理解的代码或命令。

显然,不同的视频显示适配器和打印机要求不同的设备驱动程序。

  因为PC兼容机上可以连接许多种不同的视频设备,所以,GDI的主要目的之一是支持与设备无关的图形。

Windows程序应该能够毫无困难地在Windows支持的任意一种图形输出设备上运行,GDI通过将您的程序和不同输出设备的特性隔离开来的方法来达到这一目的。

  图形输出设备分为两大类:

光栅设备和矢量设备。

大多数PC的输出设备是光栅设备,这意味着它们以点模式来表示图像,这类设备包括视频显示适配器、点阵打印机和激光打印机。

矢量设备使用线来绘制图像,通常局限于绘图仪。

  许多传统的计算机图形编程都是完全基于矢量的,这意味着使用矢量图形系统的程序是在硬件之上一定层次的抽象。

输出设备用像素表示图形,但是程序与编程接口之间并不是用像素进行对话的。

您当然可以使用WindowsGDI作为一个高层次的矢量绘制系统,同时也可以将它用于比较低层次的像素操作。

  从这方面来看,WindowsGDI和传统的图形接口语言之间的关系,就如同C和其他编程语言之间的关系一样。

C以它在不同操作系统和环境之间的高度可移植性而闻名,然而C也以它允许程序员进行低层次系统调用而闻名,这些调用在其他高级语言中通常是不可能的。

正如C有时被认为是一种“高级汇编语言”一样,您可以认为GDI是图形设备硬件之间的一种高层接口。

  已经看到,默认时Windows使用基于像素的坐标系。

大多数传统的图形语言使用“虚拟”坐标系,其水平和垂直轴的范围从0~32767。

虽然有些图形语言不让您使用像素坐标,但是WindowsGDI允许您使用两者之一(甚至基于物理度量的坐标系)。

您可以使用虚拟坐标系以便程序远离硬件,或者也可以使用设备坐标系而完全接近硬件。

  早期,许多用户在一种单色显示器上运行Windows。

即使近几年,笔记本计算机还只有灰度级别。

为此,GDI的设计保证了您可以在编写一个程序时不必过多地担心色彩问题——也就是说,Windows可以将色彩转换为灰度级别。

甚至在今天,Windows98使用的视频显示已经具有了不同的色彩能力(16色、256色、“高彩色”,以及“真彩色”)。

虽然,彩色喷墨打印机的成本已经很低了,但是大多数用户仍然坚持使用黑白打印机。

不加区别地使用这些设备是可以的,但是您的程序也应该能决定在某种显示设备上有多少色彩可以使用,从而最好地利用硬件。

  当然,就如同您编写C程序时,为了使它在其他计算机上运行而遇到一些微妙的移植性问题一样,您也可能不小心让设备依赖性溜进您的Windows程序,这就是不与硬件完全隔离的代价。

您还应该知道WindowsGDI的局限。

虽然可以在显示器上到处移动图形对象,但GDI通常是一个静态的显示系统,只有有限的动画支持。

如果需要为游戏编写复杂的动画,就应该研究一下MicrosoftDirectX,它提供了您需要的支持。

二、GDI函数调用

组成GDI的几百个函数调用可以分为几大类:

  获取《或创建》和释放(或清除)设备描述表的函数在绘图时需要设备描述表句柄。

GetDC和RealseDC函数让您在非WM_PAINT的消息期间来做到这一点,而BeginPaint和EndPaint函数(虽然在技术上它们是USER模块而不是GDI模块的一部分)在进行绘图的WM_PAINT消息期间使用。

获取有关设备描述表信息的函数GetTextMetrics函数来获取有关设备描述表中当前所选字体的尺寸信息。

绘图函数显然,在所有前提条件都得以满足之后,这些函数是真正重要的部分。

我们使用TextOut函数在窗口的客户区显示一些文本。

我们将看到,其他GDI函数还可以让您画线、填充区域。

  设置和获取设备描述表参数的函数设备描述表的“属性”决定有关绘图函数如何工作的细节。

例如,用SetTextColor来指定TextOut(或者其他文本输出函数)所绘制的文本色彩。

我们使用SetTextAlign来告诉GDI:

TextOut函数中的文本串的开始位置应该在串的右边而不是默认的左边。

设备描述表的所有属性都有默认值,当获取设备描述表时设置这些默认值。

对于所有的Set函数,都有相应的Set函数,以允许您获取当前设备描述表属性。

  使用GDI对象的函数GDI在这里变得有点混乱。

首先举一个例子:

默认时使用GDI绘制的所有直线都是实线,并具有一个标准的宽度。

您可能希望绘制更细的直线,或者是由一系列的点或短划线组成的直线。

这种线的宽度和这种线的线型不是设备描述表的属性,而是一个“逻辑画笔”的特征。

  您可以通过在CreatePen、CreatePenIndirect或ExtCreatePen函数中指定这些特征来创建一个逻辑画笔,这些函数返回一个逻辑画笔的句柄(虽然这些函数被认为是GDI的一部分,但是和大多数GDI函数调用不一样,它们不要求设备描述表的句柄)。

要使用这个画笔,就要将画笔句柄选进设备描述表。

我们认为,设备描述表中当前选中的画笔就是设备描述表的一个属性。

这样,您画任何线都使用这个画笔,然后,您可以取消设备描述表中的画笔选择,并清除画笔对象。

清除画笔对象是必要的,因为画笔定义占用了分配的内存空间。

除了画笔以外,GDI对象还用于创建填充封闭区域的刷子、字体、位图,以及GDI的其他一些方面。

三、GDI图元

  在屏幕或打印机上显示的图形类型本身可以被分为几类,通常被称为“图元”,它们是:

  直线和曲线:

线条是所有矢量图形绘制系统的基础。

GDI支持直线、矩形、椭(包括椭圆的子集,也就是我们所说的“圆”)、椭圆圆周上的部分曲线即所谓“弧”,以及贝塞尔曲线,我们将在本章中分别对它们进行介绍。

所有更复杂的曲线可由折线(polyline)代替,折线通过一组非常短的直线来定义一条曲线。

线条用设备描述表中选中的当前画笔绘制。

  填充区域:

当一系列直线或者曲线封闭了一个区域时,该区域可以使用当前GDI画剧对象进行填充。

这个画刷可以是实心色彩、图案(可以是一系列的水平、垂直或者对角标记),也可以是在区域内垂直或者水平重复的位图图像。

  位图:

位图是位的矩形数组,这些位对应于显示设备上的像素,它们是光栅图形的基础工具。

位图通常用于在视频显示器或者打印机上显示复杂(一般都是真实的图像。

位图还可以用于显示必须很快绘制的小图像,诸如图标、鼠标光标,以及在应用工具栏中出现的按钮等。

GDI支持两种类型的位图——老的(虽然还非常有用)“设备有关”位图,是GDI对象;新的(如Windows3.0的)“设备无关”位图(或者DIB),可以存储在磁盘文件中。

  文本:

文本的数学味道不像计算机图形的其他方面那样浓。

文本和几百年的传统印刷术有关,它被许多印刷工人作为一门艺术看待。

因此,文本通常不仅是所有的计算机图形系统中最复杂的部分,而且也是最重要的部分(如果识字还是社会基本要求的话)。

用于定义GDI字体对象和获取字体信息的数据结构是Windows中最庞大的部分之一。

从Windows3.1开始,GDI开始支持TrueType字体,该字体是在填充轮廓线基础上创建的,这样的填充轮廓线可由其他GDI函数处理。

基于兼容性和存储大小的考虑,Windows98继续支持旧式的基于位图的字体。

四、其他方面

GDI的其他方面无法这么容易地分类,它们是:

  映射模式和交换虽然默认时以像素为单位进行绘图,但是并非局限于此。

GDI映射模式允许您以英寸(或者甚至以几分之一英寸)、mm或者任何您想使用的单位来绘图(WindowsNT还支持传统的以3x3矩阵表示的“坐标变换”,这允许倾斜和旋转图形对象。

不幸的是,在Windows98中不支持坐标变换)元文件元文件是以二进制形式存储的GDI命令的集合。

元文件主要用于通过剪贴板传输矢量图形表示。

区域区域是形状任意的复杂区,通常定义为较简单区域的布尔组合。

在GDI内部,区域除了存储为最初用来定义区域的线条组合以外,还以一系列扫描线的形式存储。

您可以将区域用于绘制轮廓、填充和剪裁。

路径路径是GDI内部存储的直线和曲线的集合。

路径可以用于绘图、填充和剪裁,还可以转换为区域。

剪裁绘图可以限制在客户区的某一部分中,这就是所谓的剪裁。

剪裁区域可以是矩形或非短形,剪裁通常是通过区域或者路径来定义的。

调色板定制调色板通常限于显示256色的显示器。

Windows仅保留这些色彩之中的20种供系统使用,您可以改变其他236种色彩,以准确显示按位图形式存储的真实图像。

打印虽然本章限于视频显示,但是您在本章中所学到的全部知识都适用于打印。

设备描述表

在开始绘图之前,让我们更精确地讨论一下设备描述表当您想在一个图形输出设备(诸如屏幕或者打印机)上绘图时,您首先必须获得个设备描述表(或者DC)的句柄。

将句柄返回给程序时,Windows就给了您使用设备的权限。

然后您在GDI函数中将这个句柄作为一个参数,向Windows标识您想在其上进行绘图的设备。

设备描述表中包含许多确定GDI函数如何在设备上工作的当前“属性”,这些属性允许传递给GDI函数的参数只包含起始坐标或者尺寸信息,而不必包含Windows在设备上显示对象时需要的所有其他信息。

例如,调用TextOut时,您只需要在函数中给出设备描述表句柄、起始坐标、文本和文本的长度。

您不必指定字体、文本色、文本后面的背景色彩,以及字符间距,因为这些属性都是设备描述表的一部分。

当您想改变这些属性之一时,您调用一个可以改变设备描述表中属性的函数,以后针对该设备描述表的TextOut调用来使用改变后的属性。

一、获取设备描述表句柄

  Windows提供了几种获取设备描述表句柄的方法。

如果在处理一条消息时获取了设备描述表句柄,应该在退出窗口函数之前释放它(或者删除它)。

一旦释放了句柄,它就不再有效了。

最常用的获取并释放设备描述表句柄的方法是,在处理WM_PAINT消息时,使用BeginPaint和EndPaint调用:

hdc=BeginPaint(hwnd,&ps);

…….

EndPaint(hwnd,&ps);

变量ps是类型为PAINTSTRUCT的结构,该结构的hdc字段是BeginPaint返回的设备投述表句柄。

  PAINTSTRUCT结构又包含一个名为rcPaint的RECT(短形)结构,cPaint定义一个包围窗口客户区无效范围的矩形。

使用从BeginPaint获得的设备描述表句柄,只能在这个区域内绘图。

BeginPaint调用使该区域有效。

Windows程序还可以在处理非WM_PAINT消息时获取设备描述表句柄:

hdc=GetWindowDC(hwnd);

………

ReleaseDC(hwnd,hdc);

  这个设备描述表适用于窗口句柄为hwnd的客户区。

这些调用与BeginPaint和EdPaint的组合之间的基本区别是,利用从GetDC返回的句柄可以在整个客户区上绘图。

当然,GetDC和ReleaseDC不使客户区中任何可能的无效区域变成有效。

Windows程序还可以获取适用于整个窗口(而

不仅限于窗口的客户区)的设备描述表句柄:

hdc=GetWindowDC(hwnd);

………

ReleaseDC(hwnd,hdc);

这个设备描述表除了客户区之外,还包括窗口的标题栏、菜单、滚动条和框架(frame)。

GetWindowsDC函数很少使用,如果想尝试用一用它,则必须捕获WM_NCPAINT(“非客户绘制”)消息,Windows使用该消息在窗口的非客户区上绘图。

BeginPaint、GetDC和GetWindowDC获得的设备描述表都与视频显示器上的某个特定窗口相关。

获取设备描述表句柄的另一个更通用的函数是CreateDC:

hdc=CreateDC(pszDriver,pszDevice,pszOutput,pData);

………

DeleteDC(hdc);

例如,您可以通过下面的调用来获取整个屏幕的设备描述表句柄:

hdc=CreateDC(TEXT(“DISPLAY”),NULL,NULL,NULL);

  在窗口之外写东西一般是不合适的,但对于一些不同寻常的应用程序来说,这样做很方便(您还可以通过在调用GetDC时使用一个NULL参数,从而获取整个屏幕的设备描述表句柄,不过这一事实并没有载人文档)。

二、获取设备描述表信息

  一个设备描述表通常是指一个物理显示设备,如视频显示器和打印机。

通常,您需要获取有关该设备的信息,其中包括显示器的显示尺寸(单位为像素或者物理度量)和色彩范围。

您可以通过调用GetDeviceCaps(“获取设备能力”)函数来获取这些信息:

iValue=GetDeviceCaps(hdc,ilndex);

  其中,参数ilndex取值为WINGDI.H头文件中定义的29个标识符之一。

例如,当ilndex的值为HORZRES时,将导致GetDeviceCaps返回设备的宽度(单位为像素);当GetDeviceCaps的值为VERTRES时,将导致GetDeviceCaps返回设备的高度(单位为像素)。

如果hdc屏幕设备描述表的句柄,则GetDeviceCaps返回打印机显示区域的高度和宽度,它们也是以像素为单位的。

还可以使用GetDeviceCaps来确定设备处理各种不同类型的图形的能力,这通常对于处理视频显示并不十分重要,但是对于使用打印设备却是非常重要。

例如,大多数笔式绘图仪不能画位图图像,而GetDeviceCaps就可以将这一情况告诉您。

三、WINDOWSGDI函数

GetDC()函数

功能:

用于获取指定窗体客户区的显示器设备描述表句柄。

函数声明:

HDCGetDC(HWNDhWnd);

参数:

hWnd:

窗体句柄。

返回值:

如果成功,返回指定窗体客户区的设备描述表句柄,否则返回NULL。

窗体客户区绘图

一、步骤

1.获取设备环境句柄

2.获取绘图工具

3.选择绘图工具

4.利用选择的绘图工具绘图

5.恢复原来的绘图工具并删除选择的绘图工具

6.释放设备环境句柄

ReleaseDC()函数

功能:

用于释放设备描述表句柄。

函数声明:

intReleaseDC(HWNDhWnd,HDChDC);

参数:

hWnd:

窗体句柄;

hDC:

设备描述表句柄。

返回值:

如果成功,返回1,否则返回0。

注释:

GetDC()函数与ReleaseDC()函数必须匹配使用,而且不能在WM_PAINT中使用。

BeginPaint()函数

功能:

用于获取窗体客户区绘图的相关信息,并为绘图做好准备。

函数声明:

HDCBeginPaint(HWNDhwnd,LPPAINTSTRUCTlpPaint);

参数:

hWnd:

窗体句柄;

lpPaint:

指向绘图结构类型的指针变量。

返回值:

如果成功,返回指定窗体客户区的设备描述表句柄,否则返回NULL。

PAINTSTRUC结构类型

PAINTSTRUCT结构类型包含一些窗体绘图的基本信息,定义如下:

typedefstructtagPAINTSTRUCT

{

  HDChdc;//窗体句柄;

  BOOLfErase;//窗体客户区背景是否删除标记;

  RECTrcPaint;//需要绘制的窗体客户区区域标记;

  BOOLfRestore;//系统保留;

  BOOLfIncUpdate;//系统保留;

  BYTErgbReserved[32];//系统保留;

}PAINTSTRUCT;

RECT结构类型

RECT结构类型用于描述一个矩形,定义如下:

typedefstruct_RECT

{

  LONGleft;//矩形左边界坐标;

  LONGtop;//矩形上边界坐标;

  LONGright;//矩形右边界坐标;

  LONGbottom;//矩形下边界坐标;

}RECT;

EndPaint()函数

功能:

用于结束窗体客户区绘图。

函数声明:

BOOLEndPaint(HWNDhWnd,CONSTPAINTSTRUCT*lpPaint);

参数:

hWnd:

窗体句柄;

lpPaint:

指向绘图结构类型的指针变量。

返回值:

如果成功,返回TRUE,否则返回FALSE。

注释:

BeginPaint()函数与EndPaint()函数必须匹配使用,而且只能在WM_PAINT中使用。

SetPixel()函数

功能:

用于在窗体客户区绘制点(像素)。

函数声明:

COLORREFSetPixel(HDChdc,intX,intY,COLORREFcrColor);

参数:

hdc:

设备描述表句柄;

X:

点(像素)的x坐标;

Y:

点(像素)的y坐标;

crColor:

点(像素)的颜色;

返回值:

如果成功,返回点(像素)的颜色值,否则返回-1。

COLORREF类型

COLORREF类型用于描述32位

RGB颜色值,

其十六进制颜色值定义如下:

0x00bbggrr

RGB()宏

功能:

用于设置颜色。

宏定义:

COLORREFRGB(BYTEbRed,BYTEbGreen,BYTEbBlue);

参数:

bRed:

红色辉度级别;

bGreen:

绿色辉度级别;

bBlue:

兰色辉度级别;

返回值:

返回颜色值。

CreatePen()函数

功能:

用于建立逻辑笔。

函数声明:

HPENCreatePen(intfnPenStyle,intnWidth,COLORREFcrColor);

参数:

fnPenStyle:

逻辑笔类型;

nWidth:

逻辑笔宽度;

crColor:

逻辑笔颜色。

逻辑笔类型:

PS_SOLID

PS_DASH

PS_DOT

PS_DASHDOTDOT

PS_INSIDEFRAME

PS_NULL

返回值:

如果成功,返回逻辑笔句柄,否则返回NULL。

MoveToEx()函数

功能:

用于窗体客户区移动逻辑笔。

函数声明:

BOOLMoveToEx(HDChdc,intX,intY,LPPOINTlpPoint);

参数:

hdc:

设备描述表句柄;

X:

移动位置的x坐标;

Y:

移动位置的y坐标;

lpPoint:

原位置坐标;

返回值:

如果成功,返回TRUE,否则返回FALSE。

LineTo()函数

功能:

用于在窗体客户区当前位置画线。

函数声明:

BOOLLineTo(HDChdc,intnXEnd,intnYEnd);

参数:

hdc:

设备描述表句柄;

nXEnd:

目标点的x坐标;

nYEnd:

目标点的y坐标。

返回值:

如果成功,返回TRUE,否则返回FALSE。

Ellipse()函数

功能:

用于窗体客户区绘制椭圆。

函数声明:

BOOLEllipse(HDChdc,intnLeftRect,intnTopRect,intnRightRect,intnBottomRect);

参数:

hdc:

设备描述表句柄;

nLeftRect:

椭圆外边界左边界坐标;

nTopRect:

椭圆外边界上边界坐标;

nRightRect:

椭圆外边界右边界坐标;

nBottomRect:

椭圆外边界下边界坐标;

返回值:

如果成功,返回TRUE,否则返回FALSE。

SelectObject()函数

功能:

用于选择一种绘图工具柄将其装入设备描述表。

函数声明:

HGDIOBJSelectObject(HDChdc,HGDIOBJhgdiobj);

参数:

hdc:

设备描述表句柄;

hgdiobj:

绘图工具句柄。

返回值:

如果成功,返回原设备描述表中绘图工具句柄,否则返回NULL。

?

DeleteObject()函数

功能:

用于删除一个绘图工具。

函数声明:

BOOLDeleteObject(HGDIOBJhObject);

参数:

hObject:

绘图工具句柄。

返回值:

如果成功,返回TRUE,否则返回FALSE。

TextOut()函数

功能:

用于在窗体客户区输出文本。

函数声明:

BOOLTextOut(HDChdc,intnXStart,intnYStart,LPCTSTRlpString,intcbString);

参数:

hdc:

设备描述表句柄;

nXStart:

文本左上角坐标;

nYStart:

文本左上角坐标;

lpString:

指向文本字符串的指针变量;

cbString:

文本字符串长度;

返回值:

如果成功,返回TRUE,否则返回FALSE。

SetBkMode()函数

功能:

用于设置窗体客户区背景填充方式。

函数声明:

intSetBkMode(HDChdc,intiBkMode);

参数:

hdc:

设备描述表句柄;

iBkMode:

填充方式。

OPAQUE:

不透明方式;

TRANSPARENT:

透明方式;

返回值:

如果成功,返回填充方式,否则返回0。

SetTextColor()函数

功能:

用于文本颜色。

函数声明:

COLORREFSetTextColor(HDChdc,COLORREFcrColor);

参数:

hdc:

设备描述表句柄;

crColor:

文本笔颜色。

返回值:

如果成功,返回原文本笔颜色,否则返回CLR_INVALID。

CreateFont()函数

功能:

用于建立逻辑字模。

函数声明:

HFONTCreateFont(intnHeight,

        intnWidth,

        intnEscapement,

        intnOrientation,

        intfnWeight,

        DWORDfdwItalic,

   

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 教学研究 > 教学反思汇报

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1