第三章 Visual Basic 图形应用程序设计 3.1 坐标系 3.2 使用图形控件 3.3 使用图形方法 3.4 使用颜色 3.5 使用图片对象 3.6 使用API函数
第三章 Visual Basic 图形应用程序设计 Visual Basic 为应用程序的使用,提供了复杂的文本和图形功能。如果能将文本当作可视化的元素,则大小、形状和颜色都可以看到,这就能增强所提供的信息。正如报纸要使用标题、专栏和要点来把文字分成互相穿插的一些块一样,文本的一些属性也可以用于强调重要的概念和感兴趣的细节。Visual Basic 在设计时还提供一些有很大灵活性的图形功能,包括添加通过显示一连串图像所实现的动画。
3.1 坐标系 为描述点的位置,通常使用坐标系,在计算机图形学中,坐标系有用户坐标系(笛卡尔坐标系)和设备坐标系。用户坐标系又称为世界坐标系,设备坐标系又称为屏幕(对象)坐标系。
1、二维坐标系 二维坐标系以平面直角坐标系,由水平方向的x轴和垂直方向的y轴组成,坐标表示在x方向y方向的数目。其原点在(0,0)处,并可使用负的坐标值,如图形3-1所示。 图3-1 二维坐标系
2、三维坐标系 三维坐标系有两种表示方式,如图3-2所示。图3-2(a)的x-y-z轴的方向满足右手定则,称右手坐标系;图3-2(b)的x-y-z轴的方向满足左手定则,称为左手坐标系。在计算机图形学中,三维直角坐标常采用左手坐标系。将右手坐标系空间点转为左手坐标系空间点很简单,只需将z坐标取负即可。坐标系确定之后,空间任一点的位置即可用坐标表示。 图3-2 三维世界坐标系
3、极坐标系和球坐标系 二维直角坐标系的点的坐标(x,y)还可使用它的矢和幅角来 表示: 称为极坐标系。 表示: 称为极坐标系。 球坐标系是使用点的幅角和矢径表示三维直角坐标系的点的坐标(x,y,z): 图3-3 球坐标系
3.1.2 VB6.0设备坐标系 为描述对象在载体上的位置,VB6.0设置对象的坐标系。VB6.0在进行图形处理时的坐标系可分为窗体坐标系和窗体内控件对象坐标系。坐标系统是一个二维网格,可定义屏幕上、窗体中或其它容器中(如:图片框或 Printer 对象)的位置。
1、窗体坐标系 如图3-4所示,窗体上除标题栏和窗体边框以外的可供使用的区域为工作区。在工作区,系统默认窗体坐标系的原点在工作区的左上角。使用窗体中的坐标,可定义网格上的位置:(x, y)。x 值是沿 x 轴点的位置,最左端是缺省位置 0。y 值是沿 y 轴点的位置,最上端是缺省位置 0。该坐标系统的图示:
2、窗体内控件对象坐标系 在VB6.0图形处理中,可使用的对象除了窗体外,通常使用图片框(这时称图片框为容器)。使用图片框对象处理图形时,系统默认坐标系的原点在其工作区的左上角,水平向右方向为x轴,垂直向下方向为y轴。 以下规则用于 Visual Basic 坐标系统: (1)当移动控件或调整控件的大小时,使用控件容器的坐标系统。如果直接在窗体上绘制对象时,窗体就是容器。如果在框架或图片框里绘制控件时,框架或控件是容器。 (2)有的图形和 Print 方法,使用容器的坐标系统。例如,那些在图片框里绘制控件的语句,使用的是控件的坐标系统。 一些用来调整窗体大小或移动窗体的语句,用缇来表示窗体的位置和大小。 (3)当创建用来调整窗体大小或移动窗体的代码时,应先检查 Screen 对象的 Height 属性和 Width 属性,以确保窗体在屏幕上大小合适。屏幕的左上角总是(0,0)。任何容器的缺省坐标系统,都是由容器的左上角(0,0)坐标开始。 (4)沿这些坐标轴定义位置的测量单位,统称为刻度。在 Visual Basic 中,坐标系统的每个轴都有自己的刻度。坐标轴的方向、起点和坐标系统的刻度,都是可以改变的。
3、坐标的单位 系统默认对象坐标系坐标的单位是twip(缇),在实用中也可以由使用ScaleMode属性对坐标的单位进行重新设置,设置方法为: 对象名.ScaleMode=属性值 ScaleMode属性有8种选择,该值指示对象坐标的度量单位。 例如: Form1.ScaleMode = 1 '表示窗体坐标系的坐标单位是twip Form1.ScaleMode = 3 '表示窗体坐标系的坐标单位是像素 在缺省 设置下,Visual Basic 绘图对象的坐标是以 twip为单位,但习惯上在图形程序设计中,人们乐于使用像素为坐标单位,使用640×480,800×600等格式。
3、坐标的单位 常数 值 单位 意义 说明 VbUser User 用户自定义 User 用户自定义 自定义坐标系,即 ScaleHeight、ScaleWidth、ScaleLeft 和 ScaleTop 属性中的一个或多个被设置为自定义的值。 VbTwips 1 Twip 默认 (缺省值)缇(每逻辑英寸为 1440 缇;每逻辑厘米为 567 个缇)。 VbPoints 2 Point 点 磅(每逻辑英寸为 72 个磅)。 VbPixels 3 Pixel 像素 像素(监视器或打印机分辨率的最小单位)。 VbCharacters 4 Character 字符 字符(水平每个单位=120 缇;垂直每个单位=240 缇。) VbInches 5 Inch 英寸 VbMillimeters 6 Millimeter 毫米 VbCentimeters 7 Centimeter 厘米
4、用户自定义坐标系 Visual Basic 允许用户用自定义坐标系,有两种具体办法。 (1) Scale 方法 通过自定义左上角和右下角坐标来设置新的人权标系统,用户自定义坐标时一般先选定ScaleMode=0,然后设定ScaleMode=3,最后用Scale方法定义坐标系。例如: Form1.ScaleMode = 0 Form1.ScaleMode = 3 Form1.Scale (0,0)-(640,480) 这里设定窗体对象Form1的工作区为640×480,单位是像素。工作区左上角为坐标原点,y轴向下为正方向,为绘图方便,也可以将图形坐标的原点设在工作区的中央,向上为y正方向,向右为x正方向。例如: Scale (-320,240) -(320,-240) 。
4、用户自定义坐标系 (2)通过对象属性ScaleLeft和ScaleTop直接赋值自定义坐标系 Object.ScaleWidth = 640 '定义对象工作区宽为680 Object.ScaleHeight = 480 '定义对象工作区高为480 Object.ScaleLeft = -320 Object.ScaleTop = 240 这里定义对象的左上角坐标是(-320,240),执行上述代码之后,则在该对象内绘图的所有方法都将基于这个左上角新坐标什进行计算,一般而言,当设定ScaleWidth=640后,系统将自动设置属性ScaleMode=0。
5、纵横比 正确地设置对象的纵横比能够显示正确的图形。一般设置方法如下: asp = ScaleHeight / ScaleWidth '设置对象的纵横比 ScaleWidth = 640 '定义窗体坐标系宽为640 ScaleHeight = -Int(ScaleWidth * asp) 例:将坐标原点设在窗体工作区中央,y正方向向上并正确设置纵横比。使用对象 Form Name = Form1 程序代码如下: Private Sub Form_Load() ScaleMode = 0 '用户自定义坐标系 ScaleMode = 3 '坐标单位为像素 asp = ScaleHeight / ScaleWidth '纵横比 ScaleWidth = 640 '定义窗体坐标系宽为640 ScaleHeight = -Int(ScaleWidth * asp) '定义窗体坐标系高 ScaleLeft = -Int(ScaleWidth / 2) ScaleTop = -Int(ScaleHeight / 2) End Sub
3.1.3窗口—视见变换 在图形应用程序设计中,例如三维绘图、统计图等,给出的数据x,y值都是世界坐标系的坐标值。因此,在设备坐标系上绘图时,需进行变换,即将世界坐标系中的x变量的某段取值范围x1~x2与设备坐标系的点坐标X1~X2相对应,y变量的范围y1~y2与设备坐标系的点坐标Y1~Y2相对应,才能在屏幕上正确地绘出图形(如图3-5所示)。这种从世界坐标系中取出部分对象数据的操作称为开窗口,在设备坐标系上设定一个矩形显示区称为开视窗。这种将世界坐标系窗口内的对象数据,映射为设备坐标系上指定的视图窗内的点(像素)的操作称为窗口—视见变换。考虑到y轴方向与屏幕坐标系的Y轴方向相反,其换算关系式如下。
3.1.3窗口—视见变换 X轴方向:数值区间为x1~x2,视见区间X1~X2。则数值x对应的X为: Y轴方向:数值区间为y1~y2,视见区间Y1~Y2。则数值y对应的Y为:(如计算X,Y为非整数时,应取整数。 )
3.2 图形控件的限制条件 Visual Basic 提供三种控件,是为了在应用程序中创作图形效果而设计的:image 控件、Line 控件、shape 控件 1、图形控件的优点 在设计时,图像控件、直线控件和形状控件,对于创建图形十分有用。图形控件的一个优点是,需要的系统资源比其它 Visual Basic 控件少,这就提高了 Visual Basic 应用程序的性能。 图形控件的另一个优点是,创建图形所用的代码比图形方法用的要少。例如,在窗体上放置一个圆,既可用 Circle 方法,也可用形状控件。Circle 方法要求在运行时用代码创建圆;而用形状控件的话,只需在设计时简单地把它拖到窗体上,并设置特定的属性。
3.2 图形控件的限制条件 2、图形控件的限制条件 当图形控件的设计目的是为了使性能最大化,而对应用程序的要求又最小化时,要达到这一目标,就要限制 Visual Basic 控件共有的其它功能。图形控件: (1)不能出现在其它控件之上,除非它们是在一个容器里,而这个容器能出现在其它控件之上(如:图片框)。 (2)不能在运行时接收焦点。 (3)不能作为其它控件的容器。 (4)不具有 hWnd 属性。 图片控件(PictureBox)具有比上述控件更复杂,也占用更多的内存空间。
3.2.1 给应用程序添加图片 图片可显示在 Visual Basic 应用程序的三种位置处: 窗体上、图片框内、图象控件内。 图片可来自 Microsoft Windows 的各种绘图程序,例如,随同各种版本 Microsoft Windows 一起提供的那些绘图程序,其它图形应用程序,或剪切美术库等。Visual Basic 提供了一个大图标库,可在应用程序中作为图形使用。Visual Basic 也能象 .bmp、.dib、.ico、.cur、.wmf、.emf 等文件那样,把 .jpeg 和 .gif 文件添加到应用程序中。
3.2.1 给应用程序添加图片 1、 设计时添加图片 设计时添加图片有两种方法: (1) 从图片文件中将图片加载到窗体上、图片框中或图象控件里: 在“属性”窗口,从“属性”列表中选择“图片”,并单击“属性”按钮。Visual Basic 将显示一个对话框,从中可选择要加载的图片文件。 如果给窗体设置了 Picture 属性,选定的图片就会显示在窗体上,被放置在其上任何控件的后面。类似地,如果给图片框设置了 Picture 属性,则该图片就会显示在该框中,被放置在其上任何控件的后面。 (2)一个图片粘贴到窗体上,图片框中或图象控件里: 把图片从另一个应用程序(例如 Microsoft Paint)复制到剪贴板上。返回 Visual Basic 环境中,选择该窗体,图片框或图象控件,然后从“编辑”菜单上,选择“粘贴”。 一旦为窗体,图片框或图象控件设置了 Picture 属性—无论是加载或粘帖图片—设置值框所显示的字,将是 "(Bitmap)","(Icon)",或 "(Metafile)"。为了改变此设置值,可加载或粘帖另一幅图片。双击设置值框内所显示的字,并按 DEL 键,可将 Picture 属性重新设置为 "(None)"。
3.2.1 给应用程序添加图片 2、运行时添加图片 运行时添加图片有四种方法: (1)用 LoadPicture 函数,指定一文件名,并将该图片赋值给 Picture 属性。 下列语句将 Cars.bmp 文件加载到名为 picDisplay 的图片框内(通过设置其 Name 属性,可对一控件命名): picDisplay.Picture = LoadPicture(“C:\Picts\Cars.bmp”) 任何需要的时候,都可加载一新图片到窗体上,图片框中或图象控件里。尽管图片的源文件不会受到影响,但加载的新图片将会完全替代正显示的图片。 (2)用LoadResPicture 函数,可把工程中 .res 文件的一图片,赋值给 Picture 属性。 下列语句将资源文件里资源标识号 ID 为 10 的位图,加载到名为 picResource 的图片框内: Set picResource.Picture = LoadResPicture(10, vbResBitmap)
3.2.1 给应用程序添加图片 2、运行时添加图片 (3)对象间图片的相互复制。 如果图片一旦被加载或粘帖到窗体、图片框或图象控件以后,那么运行时就可把它赋值给另一窗体,图片框或图象控件。例如,下列语句将把名为 picDisplay 图片框中的图片,复制到名为 imgDisplay 的图象控件内: Set imgDisplay.Picture = picDisplay.Picture (4)从剪贴板对象复制图片。 语法:object.GetData (format) format可选的。一个常数或数值,如“设置值”中所描述的,它指定 Clipboard 图形的格式。必须用括号将该常数或数值括起来。如果 format 为 0 或省略,GetData 自动使用适当的格式。 FORM1.Picture = Clipboard.GetData 常数 值 描述 vbCFBitmap 2 位图(.bmp文件) vbCFMetafile 3 元文件(.wmf文件) vbCFDIB 8 设备无关位图 (DIB) vbCFPalette 9 调色板
3.2.1 给应用程序添加图片 注意 如果是在设计时从文件中加载或粘帖图片,则图片就和窗体一起被保存和加载,而应用程序可将图片从一个对象复制到其它对象。然后,在创建 .exe 文件时,就不必把此图片文件的备份提供给用户,因为 .exe 文件本身包含有它的图象。另外,可以考虑提供 .res 文件和使用 LoadResPicture。.res 文件将被编译到 .exe 文件中,而位图则以任何资源编辑器都可读的标准格式保存。如果要在运行时用 LoadPicture 函数加载图片,则必须把图片文件和应用程序一起提供给用户。
3.2.1 给应用程序添加图片 3、运行时删除图片 也可使用 LoadPicture 函数在运行时删除图片,而无须用其它图片替换它。下列语句是从名为 imgDisplay 的图象控件中删除图片: Set imgDisplay.Picture = LoadPicture("")
3.2.1 给应用程序添加图片 4、移动图片和改变图片尺寸 如果窗体、图片框或图象控件被移动(设计时或运行时),则其上的图片也将自动地随它一起移动。如果窗体、图片框或图象控件调整大小后太小,容纳不下图片,则该图片将从右边和底部被裁剪。如果图片被加载或复制到那些因为过小而不能完整显示它的窗体、图片框或图象控件时,该图片也会被裁剪。
3.2.1 给应用程序添加图片 5、AutoSize 属性: 如果想让图片框能自动扩展到可容纳新图片的大小,可将该图片框的 AutoSize 属性设置为 True。这样,在运行时当往图片框加载或复制图片时,Visual Basic 会自动扩展该控件到恰好能够显示整个图片。由于窗体不会改变大小,如果加载的图象大于窗体的边距,图象经过裁剪后被显示出来。
3.2.1 给应用程序添加图片 6、图象控件的 Stretch 属性: 如果要使图象控件中的图片能自动扩展以适应特定的尺寸,可使用 Stretch 属性。当 Stretch 属性为 False 时,图象控件自动调整其大小以适应加载图片的要求。为了调整图片大小以适应图象控件的要求,可将图象控件的 Stretch 属性设置为 True。
3.2.2 窗体和控件的图形属性概述 类别 属性 显示处理 AutoRedraw, ClipControls 当前绘图位置 窗体和各种控件都具有图形属性。下表列出这些属性。 类别 属性 显示处理 AutoRedraw, ClipControls 当前绘图位置 CurrentX, CurrentY 绘图技术 DrawMode, DrawStyle, DrawWidth, BorderStyle, BorderWidth 填充技术 FillColor, FillStyle 颜色 BackColor, ForeColor, BorderColor, FillColor 窗体和图片框具有的一些附加属性: Scale 属性和Font 属性
3.2.3 用 AutoRedraw 创建持久的图形 每个窗体和图片框都具有 AutoRedraw 属性。AutoRedraw 是 Boolean 属性,当它设置为 True 时,会把图形输出保存在内存里。可用 AutoRedraw 属性创建持久的图形。 1、持久的图形 Microsoft Windows 操纵屏幕图象,来造成重叠窗口的影像。当一个窗口移到其它窗口上时,可暂时隐藏其它窗口,移过后,被覆盖的窗口和它的内容需要重新显示。Windows 管理和控制窗口与控件的重新显示。而用户的 Visual Basic 应用程序必须控制窗体和图片框内图形的重新显示。 如果在窗体上用图形方法创建图形,通常希望它们重新显示在以前的位置 (persistent graphics),可用 AutoRedraw 属性创建持久的图形。
3.2.3 用 AutoRedraw 创建持久的图形 2、AutoRedraw 和窗体 AutoRedraw 的缺省值是 False。当 AutoRedraw 设置为 False,窗体上显示的任何由图形方法创建的图形如果被另一个窗口暂时挡住,将会丢失。另外,如果扩大窗体,窗体边界外的图形将会丢失。设置 AutoRedraw 为 False 的效果如图 1所示。 设置 AutoRedraw 为 False 的效果
3.2.3 用 AutoRedraw 创建持久的图形 当窗体的 AutoRedraw 属性设置为 True 时,Visual Basic 会将图形方法适用于内存中的一块“画布”上。应用程序复制此画布的内容,以便重新显示被其它窗口暂时隐藏起来的图形。在大多数情况下,该窗体画布的大小即屏幕的大小。如果窗体的 MaxButton 属性为 False 且窗体的边界不可调,那么该画布的大小即窗体的大小。 当窗体大小可调时,该画布也可使应用程序保存超出窗体边界之外的图形。设置 AutoRedraw 为 True 的结果显示如下图。 设置 AutoRedraw 为 True 的效果
3.2.3 用 AutoRedraw 创建持久的图形 3、AutoRedraw 和图片框 当图片框的 AutoRedraw 属性设置为 True 时,Visual Basic 仅在内存保存此图片框的可视内容。这是因为保存图片框内容的画布,与图片框大小是相同的。超出其外的图形被裁剪后,既使改变图片框的大小,也不能再显示。
3.2.3 用 AutoRedraw 创建持久的图形 4、使用非持久的图形 可将窗体及其所有图片框的 AutoRedraw 设置为 False 来节省内存。但那样的图形将不再自动成为持久性的。需要时必须用代码管理所有图形的重画。 可将所有想要重画的线、圆、点的代码,包括在窗体或图片框的 Paint 事件中。这种方式最适用于有限个易于重建的图形。 无论何时需要重画窗体或图片框的一部分时,都可调用 Paint 事件过程—例如,当覆盖住对象的窗口移去后,或重新调整窗体大小使得图形恢复可视时。如果 AutoRedraw 设置为 True,除非应用程序显式地调用它,否则,该对象的 Paint 过程不会被调用执行。因为对象的可视内容保存在画布中,所以不需要 Paint 事件。
3.2.3 用 AutoRedraw 创建持久的图形 5、运行时改变 AutoRedraw 的设置 在程序中设置 AutoRedraw,可以在画持久图形(如背景色或网格)和临时图形之间切换。如果设置 AutoRedraw 为 False,以前的输出成为背景屏幕的一部分。当 AutoRedraw 设置为 False,用 Cls 方法清除绘图区时不会删除背景图形。把 AutoRedraw 改回 True 后,再用 Cls 将清除背景图形。
3.2.4 用 ClipControls 裁剪区域 ClipControls是 Boolean 属性,返回或设置一个值,决定 Paint 事件中的图形方法是重绘整个对象,还是只绘刚刚露出的区域。在运行时为只读。 每个窗体、图片框和框架控件,都具有 ClipControls 属性。 当 ClipControls 属性为 True 时,Windows 在 Paint 事件之前,窗体或容器的背景定义一个裁剪区域。此裁剪区域将围绕所有非图形控件,但是不在 Image、Label、Line 或 Shape 控件的周围剪裁。
3.2.4 用 ClipControls 裁剪区域
3.2.4 用 ClipControls 裁剪区域 当 ClipControls 为 False 时,Windows 不在 Paint 事件之前给窗体或容器的背景定义裁剪区域。而且,Paint 事件中图形方法的输出,只显示在窗体或控件必须重画的部分。因为计算和管理裁剪区域需要花费时间,那么设置 ClipControls 为 False 就可以使含有许多非重叠控件的窗体(如复杂对话框)显示得更快。 注意:避免将 ClipControls 设置为 True 的固有控件,嵌套在 ClipControls 属性设置为 False 的控件内(例如:命令按钮在图片框内)。这种控件嵌套引起控件不能准确重绘。为解决这个问题,将容器控件和嵌套的控件的 ClipControls 属性设置为 True。
3.2.5 动态地移动控件 使用 Visual Basic,在运行时移动控件是最容易取得的效果之一。可以直接改变控件位置定义的属性,也可使用 Move 方法。 1、使用 Left 和 Top 属性 Left 属性是控件左上角到窗体左边的距离。Top 属性是控件左上角到窗体上边的距离。 通过改变 Left 和 Top 属性的设置值移动控件,可使用以下语句: txtField1.Left = txtField1.Left + 200 txtField1.Top = txtField1.Top – 300
3.2.5 动态地移动控件 2、移动 Line 控件 如前面提到的,直线控件没有 Left 和 Top 属性。但是,可使用特殊的属性,对窗体上直线控件的位置进行控制。下表列出这些属性,以及用它们怎样决定直线控件的位置 属性 描述 X1 直线起点的 x 坐标。 Y1 直线起点的 y 坐标。 X2 直线终点的 x 坐标。 Y2 直线终点的 y 坐标。
3.2.5 动态地移动控件 3、使用 Move 方法 改变 Left 和 Top 或 X 和 Y 属性,会使控件产生先水平移动然后再垂直移动的颠簸效果。Move 方法则能产生更平滑的对角线方向的移动。 Move 方法的语法如下: [object.]Move left [, top[, width[, height] ] ] object 是被移动的窗体或控件。如果省略了 object,则移动的是当前窗体。left 和 top 参数是 object 对象的 Left 和 Top 属性的新设置值,而 width 和 height 则是它的 Width 和 Height 属性的新设置值。其中,只有 left 是必须的,但是,若要指定其它参数时,就必须一并指定参数列表中出现在指定参数之前的所有参数。
3.2.5 动态地移动控件 4、绝对移动 当对象在其容器中移动到指定坐标处时,就是绝对移动。下述语句是用绝对移动,将名为 txtField1 的控件,移动到坐标(100,200)处: txtField1.Move 100, 200 5、相对移动 通过指定从当前位置应当移动的距离,使控件移动时,就是相对移动。下述语句是使用相对移动,将 txtField1 移动到它当前位置向右和向下 100 缇处: txtField1.Move txtField1.Left + 100, txtField1.Top + 100
3.2.6 动态地改变控件大小 在运行时可以改变图片框、图象控件、或窗体的大小和形状,以下属性影响大小 属性 应用于 描述 Align PictureBox 和 Data 控件 如果设置图片框和窗体的顶部 (1) 或底部 (2) 对齐,该图片框的宽度等于窗体内部的宽度。如果设置图片框和窗体的左边 (3) 或右边 (4) 对齐,该图片框的高度等于窗体内部的高度。 Height 除 Timer、菜单、和 Line 以外的所有窗体和控件 用窗体的刻度模式表示的对象高度(缺省是缇数)。 Width 用窗体的刻度模式表示的对象宽度(缺省是缇数)。 AutoSize Label 和 PictureBox 如果为 Ture,则总是要使 Visual Basic 根据内容大小调节图片框的尺寸。 Stretch Image 控件 如果为 True,位图或元文件拉伸到适合图像控件的大小。如果为 False,图像控件的大小要与它包含的位图或元文件的大小相匹配。
3.2.7 创建简单动画 在运行时改变图片可以创建简单动画。最简单的方法是在两幅图片之间切换。也可通过几个框架使用一系列图片来创建动画。还可使图片动态地移动,能够创建出更精致的动画。 1、在两幅图片之间切换 一些图标可成对使用。例如,在 \Icon 子目录中有两个匹配的信封图标,一个信封未打开,一个已撕开,如下图中所示。通过在这两个图标之间进行转换,或称切换,可创建一个动画,以便显示邮件的状态。 下列语句改变名为 imgMailStatus 的图标控件的 Picture 属性,以便将它的图片从一个未打开的信封切换到一个打开的信封。 imgMailStatus.Picture = imgMailOpen.Picture 2、在一些图片间轮转 通过在多个图片之间进行轮转,可以创建更长的动画。这项技术基本和在两幅图片之间切换一样,但是需要应用程序进行选择当前图像所用位图的操作。对动画中各个图片进行控制的一种方法,是使用控件数组。
3.3 使用图形方法 方法 描述 Cls 清除所有图形和 Print 输出。 PSet 设置各个像素的颜色。 Point 除了图形控件之外,Visual Basic 还提供有创建图形的一些方法。总结在下表中的这些图形方法,适用于窗体和图片框。 方法 描述 Cls 清除所有图形和 Print 输出。 PSet 设置各个像素的颜色。 Point 返回指定点的颜色值。 Line 画线、矩形、或填充框。 Circle 画圆、椭圆、或圆弧。 PaintPicture 在任意位置画出图形。 注意 Print 方法也可认为是一种图形方法,因为它的输出也写在对象上,并象PSet、Line 和 Circle 方法一样,也要以内存图像的方式进行保存(如果 AutoRedraw 是打开的)。
3.3 使用图形方法 1、图形方法的优点 在许多的工作需要使用图形控件的情况下,图形方法能工作得很好。例如,在图表中要创建网格线需要用到直线控件数组,而使用 Line 方法时却只需少量代码即可。当窗体改变大小时,跟踪数组中 Line 控件的位置,比起用 Line 方法简单地重新画线要麻烦得多。 当需要可视的效果直接显示在窗体上时,如,要显示出有关对话的色条,可以为这种临时性效果,编写几组代码行,而不是使用另一个控件。
3.3 使用图形方法 2、图形方法的限制条件 用图形方法创建图形是在代码中进行的,这就意味着,必须运行应用程序才能看到图形方法的结果。因而,对于创建界面的简单设计元素来说,图形方法就不能代替图形控件的作用。设计时改变图形控件的的外观,比修改并测试图形方法的代码容易。 每一种图形方法都是绘制输出到窗体上、图片框内或者是 Printer 对象。为了指示画出的位置,要给图形方法加上窗体或图片框控件的名字。如果省略了画出的对象,Visual Basic 就认为是要画在代码所连接的窗体上。例如,下列语句画一个点,在: 名为 MyForm 的窗体上 :MyForm.PSet (500, 500) 名为 picPicture1 的图片框内 :picPicture1.PSet (500, 500) 当前窗体上 :PSet (500, 500) 每一个绘图区都有自己的坐标系,决定坐标使用的单位。另外,每一个绘图区都有自己的完整的一组图形属性。 3、清除画图区 在任何时候若想清除绘图区进行重画,应使用 Cls 方法。指定的绘图区以背景色 (BackColor) 重画: [object.]Cls 使用没有指定 object 的 Cls 方法,将清除该代码所连接的窗体。
3.3.1 Pset方法 单个像素的控制,是简单的图形操作。PSet 方法用来设置指定点处点亮一个指定着色的点,用法如下 [object.]PSet (x, y)[, color] Object:对象名,窗体或图片框 x,y:是单精度参数,所以它们可以接受整数或分数的输入。输入可以是任何含有变量的数值表达式。 Color:显示点的颜色。如果没有包括 color 参数,PSet 将像素设置为前景色 (ForeColor)。例如,下述语句在当前窗体(代码所连接的窗体),MyForm,和 picPicture1 上设置各种点: PSet (10.75, 50.33) MyForm.PSet (230, 1000) PicPicture1.PSet (1.5, 3.2) 为了“擦除”一点,只要把其颜色设置为背景色即可: PSet (50, 75), BackColor
3.3.2 Point 方法 Point 方法和 PSet 方法功能相反,其功能是获取窗体或图片杠四返回指定位置处的颜色值。格式如下: Object.Point (x,y) Object:对象名,窗体或图片框。 (x,y):指定像素的坐标位置。
3.3.2 Point 方法 使用方法如下: Dim PointColor as Long '变量说明,颜色返回值为长整型 PointColor=Object.Point(x,y)‘获取图像指定位置的颜色值 像素颜色值PointColor是一个长整型的数值,使用4个字节,最上位字节的值为“0”,其他3个字节依次为R,G,B,值为0~255。 从PointColor值分解出R值,G值,B值使用AND运算符。算法为: PointColor=Object.Point(x,y) R = PoinColor And &HFF G = (PoinColor And &HFF00&) \ &HFF& B = (PoinColor And &HFF0000) \ &HFF00&
3.3.3 Line 方法 画一个指定颜色的直线或长方形 object.Line [Step] (x1, y1) [Step] (x2, y2), [color], [B][F] Object:可选择的,对象名,窗体或图片框。 Step :可选的关键字,指定起点坐标,它们相对于由 CurrentX 和 CurrentY 属性提供的当前图形位置。 (x1, y1):可选的。Single (单精度浮点数),直线或矩形的起点坐标。ScaleMode 属性决定了使用的度量单位。如果省略,线起始于由 CurrentX 和 CurrentY 指示的位置。 Step :可选的关键字,指定相对于线的起点的终点坐标。 (x2, y2):必需的。Single (单精度浮点数),直线或矩形的终点坐标。 Color:可选的。Long (长整型数),画线时用的 RGB 颜色。如果它被省略,则使用 ForeColor 属性值。可用 RGB 函数或 QBColor 函数指定颜色。 B:可选的。如果包括,则利用对角坐标画出矩形。 F:可选的。如果使用了 B 选项,则 F 选项规定矩形以矩形边框的颜色填充。 不能不用 B 而用 F。如果不用 F 光用 B,则矩形用当前的 FillColor 和 FillStyle 填充。FillStyle 的缺省值为 transparent。
3.3.3 Line 方法 例如,下列语句可在窗体上画一条斜线。 Line (500, 500)–(2000, 2000) Visual Basic 所画出的一条直线,要包括第一个端点,而不是最后一个端点。这种行为在从点到点画封闭曲线时是有用的。为了画最后一个端点,应使用这种语法: PSet [Step] (0, 0)[, color] Step 关键字 PSet、Line、和 Circle 方法使用以下语法可指定一个或多个点(x, y),可在每个点之前加上 Step 关键字,用来指定要画出的点,是相对最后画出点的位置。Visual Basic 要将 x 和 y 的值加到最后所画的点上。例如,下边这条语句: Line (100, 200)–(150, 250) 等价于: Line (100, 200)–Step(50, 50) 在许多情况下,Step 关键字可免除持续不断地记录最后所画点位置的负担。经常最为关心的可能是两点的相对位置,而不是它们的绝对位置。
3.3.3 Line 方法 绘制方框 可使用 Line 方法绘制并填充方框。下列示例画出一个方框,其左上角为 (500, 500),每边长为 1,000 缇: Line (500, 500)–Step(1000, 0) Line -Step(0, 1000) Line -Step(–1000, 0) Line -Step(0, –1000) 然而,Visual Basic 提供了一个更简单的画方框的方法。当在 Line 方法中使用 B 选项时,Visual Basic 把指定点作为矩形的对角点,可画出一个矩形。所以,可用下列语句,代替上例中的四个语句: Line (500, 500)–Step(1000, 1000), , B 注意:在 B 之前要有两个逗点,以表示色彩参数被省略了。
3.3.3 Line 方法 FillStyle 和 FillColor 只要不改变 FillStyle 属性的设置值,所画的方框将是空的。(该方框使用缺省的 FillStyle 和设置值来进行填充,不过 FillStyle 的缺省值是 1-透明。)可将 FillStyle 属性改变为下表列出的任意设置值。 设置值 描述 实心的。可用 FillColor 属性设置的颜色填充方框。 1 透明(缺省值)。无论使用何种色彩,图形对象表现为空。 2 水平线。 3 垂直线。 4 向上的对角线。 5 向下的对角线。 6 十字交叉线。 7 对角交叉线。
3.3.3 Line 方法 将 FillStyle 设置为 0,就可以用 FillColor 属性的颜色设置,将方框填充为实心。是在 B 之后指定 F。(注意,没有 B 就不能用 F。)当使用 F 选项时,Line 方法将忽略 FillColor 和 FillStyle 属性。使用 F 选项时,方框总是被填充为实心。下述语句使用具有 ForeColor 属性的一种实心图样,对方框进行填充。 Me.Line (500, 500)-Step(1000, 1000), , BF
3.3.4 画圆 Circle 方法可画出圆形和椭圆形的各种形状。另外,Circle 方法还可以画出圆弧(圆的一部分)和楔形饼块。使用变化的 Circle 方法,可画出多种曲线。 为了画圆,Visual Basic 需要给出该圆的圆心位置和它的半径。画一个理想圆的语法是: [object.]Circle [Step](x, y), radius[, color] Object:对象名。 Step:任选项,在使用此关键字时,(x,y)表示为相对坐标,即与由CurrentX,CurrentY属性表示的当前位置的相对坐标。 (x,y):x参数和y参数是圆心的坐标。 Radius:半径。 例如,下面语句将画出一个以 (1200,1000) 为圆心、750 为半径的圆: Circle (1200, 1000), 750
3.3.4 画圆 这个语句产生的精确作用,还要依赖于窗体的大小和窗体的坐标系。如果不知道窗体的大小,也就不能知道这个圆是否可见。可使用绘图区的标尺属性,将该圆的圆心置于窗体的中心处: Circle ((ScaleWidth + ScaleLeft) / 2, (ScaleHeight + ScaleTop) / 2), ScaleWidth / 4 此时,关于 ScaleWidth 和 ScaleHeight 所有应知道的是,它们能帮助将图形定位于窗体的中心。 注意 圆的半径通常是按照水平单位来指定的。如果坐标系使用的水平单位和垂直单位是相同的话(按照缺省规定,应当这样),可以不用考虑单位问题。但如果使用的是自定义标尺,则水平单位和垂直单位可能对应不同的长度。上例中,半径是用水平单位来指定的,可以保证圆的实际高度和实际宽度相等。
3.3.4 画圆 画圆弧 为了用 Circle 方法画出圆弧,应以弧度为单位,给出定义弧线 start 和 end 的角度参数。画圆弧的语法是: [object.]Circle [Step](x, y), radius, [color], start, end[, aspect] 如果 start 参数或 end 参数是负数的话,Visual Basic 将画一条连接圆心到负端点的线。例如,下面的过程将用消除切片方式画出一个饼。 Private Sub Form_Click () Const PI = 3.14159265 Circle (3500, 1500), 1000, , –PI / 2, –PI / 3 End Sub 注意 将度换算成弧度的公式是将度数乘以 Pi/180。
3.3.5 画椭圆 圆的方位比,决定了圆是显得很圆(圆)还是被拉长(椭圆)。Circle 方法的完整语法是: [object.]Circle [Step](x, y), radius, [color], [start], [end] [, aspect] start 参数和 end 参数是可选的;但是,如果想省掉参数,逗号是不能省的。例如:如果含有 radius 参数和 aspect 参数,省掉了 color、start、end 三个参数,则必须加上四个连续的逗号,它表明这三个参数被省掉了。 Circle (1000, 1000), 500, , , , 2 aspect 参数指定了水平长度和垂直长度比。该 aspect 参数是正浮点数,这说明它既可以是整数表达式,也可以是小数表达式,但不能是负数。该 aspect 参数较大时,椭圆沿垂直轴线拉长;相反,该 aspect 参数较小时,则沿水平轴线拉长。由于椭圆有两个半径—水平方向的 x 半径和垂直方向 y 半径— Visual Basic 在 Circle 语句中只使用了一个参数 radius 对应椭圆的长轴。如果 aspect 参数小于 1 的话,该 radius 半径指的是水平方向的 x 半径,如果 aspect 参数大于或等于 1 的话,则 radius 指的是垂直方向的 y 半径。
3.3.5 画椭圆 注意 aspect 参数指定的总是水平长度和垂直长度的实际物理距离比,要保证这一点(即便用的是自定义标尺),半径应以水平单位指定。 下列过程说明的是,不同的 aspect 参数值,Circle 方法是如何决定对 radius 参数的使用的;是将它作为椭圆的 x 半径,还是作为椭圆的 y 半径: Private Sub Form_Click () '画一个实心椭圆。 FillStyle = 0 Circle (600, 1000), 800, , , , 3 '画一个空心椭圆。 FillStyle = 1 Circle (1800, 1000), 800, , , , 1 / 3 End Sub
3.3.6 在任意位置绘制图形 使用 PaintPicture 方法,可以在窗体、图片框和 Printer 对象上的任何地方,绘制图形。PaintPicture 方法的语法是: [object.]PaintPicture pic, destX, destY[, destWidth[, destHeight[, srcX [, srcY[, srcWidth[, srcHeight[,RasterOp]]]]]]] object:对象名,指的是窗体、图片框或 Printer 对象。如果 object 被忽略了,则认为指定的就是当前的窗体 PaintPicture:方法名。 Pic:必须参数,要绘制到 object 上的图形源,是一个图片对象,它是由窗体或控件的 Picture 属性决定。
3.3.6 在任意位置绘制图形 DestX 、DestY : 可选的。单精度值,指定在 object 上绘制 picture 的目标坐标(x-轴和y-轴)object 的 ScaleMode 属性决定使用的度量单位。 destWidth 、 destHeight:可选参数,用来设置在 object 目标中该图象的宽度和高度。如果目标宽度或高度比源宽度 (SrcWidth)或高度(SrcHeight)大或小,将适当地拉伸或压缩 picture 。如果该参数省略,则使用源宽度或高度。 srcX 、srcY:可选参数,均为单精度值。用来定义 pic 中裁剪区左上角的 x 和 y 坐标。 SrcWidth:可选参数,单精度值。指示 pic 内剪贴区的源宽度。object 的 ScaleMode 属性决定使用的度量单位。如果该参数省略,则使用整个源宽度。 SrcHeight:可选参数,单精度值。指示 pic 内剪贴区的源高度。object 的 ScaleMode 属性决定使用的度量单位。如果该参数省略,则使用整个源高度。
3.3.6 在任意位置绘制图形 RasterOp:可选参数,用来定义当在目标 object 上绘图时,在图片上执行的光栅操作(例如,AND 和 XOR)。
3.3.7 指定线宽 DrawWidth 属性用来指定图形方法输出时线的宽度,BorderWidth 属性用来指定直线和形状控件轮廓线的粗细。 下列过程将画出几条不同宽度的线。 Private Sub Form_Click () DrawWidth = 1 Line (100, 1000)–(3000, 1000) DrawWidth = 5 Line (100, 1500)–(3000, 1500) DrawWidth = 8 Line (100, 2000)–(3000, 2000) End Sub
3.3.8 指定线型 DrawStyle 属性指定用图形方法创建的线,是实线还是虚线。形状控件的 BorderStyle 属性的作用与 DrawStyle 属性相同,但是仅应用于某些对象。 object.DrawStyle [= number] 常数 设置值 描述 VbSolid (缺省值)实线 VbDash 1 虚线 VbDot 2 点线 VbDashDot 3 点划线 VbDashDotDot 4 双点划线 VbInvisible 5 无线 VbInsideSolid 6 内收实线
3.3.9 DrawMode 的显示控制作用 number 的设置值为: DrawMode 属性决定,当把一个样式画在另一个之上时,能够取得什么结果。尽管改变 DrawMode 属性,经常会带来一些影响(尤其是彩色系统),但是当在一个空白或是纯白色的背景上,或者是在未定义颜色的背景上绘制时,是没有必要使用该属性的。 设置值 描述 4 Not Copy 笔。画出相反的直线样式,不管该处原来的存在如何。 7 Xor 笔。显示出直线样式和现存显示的区别,参阅本节后面的解释。用这种模式绘制对象两次,将精确地恢复该处原来的背景。 11 无操作,效果相当于关掉了绘画。 13 Copy 笔(缺省值)。使用直线的样式,不管该处原来的存在如何。
3.3.9 DrawMode 的显示控制作用 Xor 笔 对于动画来说,7 是 DrawMode 的一个有用的设置值。一条线画出两次,就可精确还原该线画出之前地有的显示内容。这样就可能创建一个在背景上移动却不会使其毁坏的对象,因为在移动时,可以还原背景。大多数模式不能保护原来的背景。 例如,下列代码的作用是:每单击一下鼠标就移动一个圆,无论圆底下有什么,它都能被还原。 Private Sub Form_Click () ForeColor = 255 : DrawMode = 7 Circle (CurrentX, CurrentY), 1000 CurrentX = CurrentX + 220 CurrentY = CurrentY + 220 End Sub
3.3.9 DrawMode 的显示控制作用 Xor 笔的绘图模式(以及大多数其它的 DrawMode 设置值),是通过将绘图样式(被称作“笔”)中的各个像素与存在区(被称作“目标”)中的相应像素进行比较的方式工作的。在单色系统中,像素不是被打开就是被关闭,Visual Basic 进行一种简单的逻辑比较:如果笔和目标中有一个打开,而不是两个同时都打开时,则使像素打开。 在彩色系统中,每一个像素都赋给一个色值。对于 DrawMode 的 Xor 笔这样的设置值来说,Visual Basic 将对笔和目标里相应的每一对像素进行比较,执行二进制(位方式)的比较操作。结果决定生成像素的色值。
3.3.9 DrawMode 的显示控制作用 使用 Xor 笔给直线像素设置二进制值 示例:橡皮条技术,程序可用于屏幕矢量化。在窗体上添加一个PictureBox控件,名称为Picture1,利用Picture1的Picture属性添加一幅图。程序运行时,利用鼠标左键进行取点画线,鼠标右键结束画线。
3.3.10 窗体加载时创建图形 当窗体加载时为了在创建其上显示的图形,应考虑将各种图形方法安放在 Form_Paint 事件中。Form_Paint 图形在每一个绘画事件中将自动地被重画。如果将图形放入 Form_Load 事件中,则应将窗体上的 AutoRedraw 属性设置为 True。在这种情况下,Form_Load 将显示窗体并画上图形。请记住,在 Form_Load 事件中窗体是不可见的。因为 Visual Basic 对于不可见窗体上的图形方法不进行处理,除非 AutoRedraw 被设置为 Ture,否则 Form_Load 事件中的图形方法将被忽略。
3.4 颜色 图像是通过光波映入眼中产生视觉。 光是电磁波的一种形式,频率为105--1025Hz。可见光是其中很小部分(波长为780nm 的红光到波长为380nm 的紫光)。 彩色视觉属人眼的一种明视觉 人眼的视网膜由感光细胞覆盖。 感光细胞包括: 杆状细胞:能提供感光力强的单色夜视 锥状细胞:能提供在较高的光学亮度下的彩色视觉 锥状细胞将电磁光谱的可见部分分为三个波段红绿和蓝,因此人类视觉为三色的。
3.4.1色彩空间 一束普通白光经过棱镜显示可以分解为赤橙黄绿青蓝紫其中最基本的是Red、Green 、Blue。 1、 加色法系统(RGB 三色原理) 任何颜色可以用R G B 叠加产生 R 0---255 G 0---255 B 0---255 RGB 为计算机的显示色
3.4.1色彩空间 2、减色法系统(CMYK 四色系统) 充满颜色时为黑色,没有颜色时为白色,使用RGB 的补色做基本色青(cyan) 品(Magenta)和黄(Yellow)。 CMYK是印刷业的标准。理论上前三种颜色可以组成黑色,但考虑到印刷油墨黑度不够, 所以黑色就独立出来自成一色,以保障印刷质量。 CMYK 空间比RGB 空间小,所以彩色打印效果远不如显示。 例如: 白(0 0 0 0) 青(100 0 0 0) 蓝(100 100 0 0) 品(0 100 0 0)
3.4.1色彩空间 3、HSI 模式(HSV,HSB模式) 艺术家使用的模式 H(Hue)色调、S(Saturation)饱和度、B (Brightnees) 亮度 HSB 是人类容易理解的模式,但由于设备限制,显示时要转为RGB ,打印时要转为CMYK。
3.4.1色彩空间 4、 LAB 模式 与HSI 模式类似它所用的参数是光强和色度。L为光强度,A保存从绿色到紫色所的色彩信息;而B 保存从蓝色到黄色所对应的色彩信息。单个A 或B 无意义只。有A 、B 结合才有意义。 LAB 模式所的颜色空间最大,其他几个颜色空间都是它的子集。
3.4.1色彩空间 5、YIQ 模式 美国国家制式委员会提出的NTSC 彩色传输制式使用YIQ 三刺激值它与RGB 的关系是:
3.4.1色彩空间 6、YUV 模式 我国和一些西欧国家采用PAL制式。 Y 为亮度,U 和V 为色度。 好处: 使使黑白电视能接受彩色电视信号 (2)可以利用人眼的特性来降低数字彩色图象所需的存储容量。人眼对彩色细节的分辨能力远比亮度细节的分辨能力低。 它与RGB 的关系是:
3.4.2 在VB程序中使用颜色 对于所有的颜色属性和图形方法,Visual Basic 使用固定的系统。每种颜色都由一个 Long 整数表示,并且在指定颜色的所有上下文中,该数值的意义相同。 1、在运行时指定颜色 在运行时有四种方式可指定颜色值: 使用 RGB 函数 使用 QBColor 函数,选择 16 种 Microsoft QuickBasic(R) 颜色中的一种。 使用在“对象浏览器”中列出的内部常数之一。 直接输入一种颜色值。
3.4.2 在VB程序中使用颜色 2、使用 RGB 函数 可以用 RGB 函数来指定任何颜色。 (1)对三种主要颜色(红、绿、蓝)中的每种颜色,赋给从 0 到 255 中的数值,0 表示亮度最低,而 255 表示亮度最高。 (2)用红-绿-蓝的排列方式,将三个数值输入给 RGB 函数。 (3)将结果赋给颜色属性或颜色参数。
3.4.2.1 使用颜色属性 Visual Basic 中的许多控件,有决定控件显示颜色的属性。请记住,这些属性中有些也适用于不是图形的控件。下表描述了这些颜色属性。 属性 描述 BackColor 对用于绘画的窗体或控件设置背景颜色。如果在绘图方法进行绘图之后改变 BackColor 属性,则已有的图形将会被新的背景颜色所覆盖。 ForeColor 设置绘图方法在窗体或控件中创建文本或图形的颜色。改变 ForeColor属性不影响已创建的文本或图形。 BorderColor 给形状控件边框设置颜色。 FillColor 为用 Circle 方法创建的圆和用 Line 方法创建的方框,设置填充颜色。
3.4.2.1 使用颜色属性 1、使用定义的常数 当使用“对象浏览器”中列出的内部常数时,没有必要去了解这些常数是如何产生的。另外,这些内部常数也无须声明。例如:无论什么时候想指定红色,作为颜色参数或颜色属性的设置值,都可以使用常数 vbRed: BackColor = vbRed
3.4.2.1 使用颜色属性 2、直接使用颜色设置值 正常的 RGB 颜色的有效范围,是从 0 到 16,777,215 (&HFFFFFF&)。每种颜色的设置值(属性或参数)都是一个四字节的整数。对于这个范围内的数,其高字节都是 0,而低三个字节,从最低字节到第三个字节,分别定义了红、绿、蓝三种颜色的值。红、绿、蓝三种成分都是用 0 到 255 (&HFF) 之间的数表示。
3.4.2.1 使用颜色属性 3、用十六进制数&HBBGGRR&来指定颜色 BB 指定蓝颜色的值,GG 指定绿颜色的值,RR 指定红颜色的值。每个数段都是两位十六进制数,即从 00 到 FF。中间值是 80。因此,下面的数值是这三种颜色的中间值,指定了灰颜色: &H808080& 将最高位设置为 1,就改变了颜色值的含义:颜色值不再代表一种 RGB 颜色,而是一种从 Windows“控制面板”指定的环境范围颜色。这些数值对应的系统颜色范围是 从 &H80000000 到 &H80000015。
3.4.2.1 使用颜色属性 4、使用系统颜色: 在应用程序中设置控件或窗体的颜色时,可以不指定颜色值,而用操作系统指定的颜色。如果指定了操作系统的颜色,当应用程序的用户改变计算机上的系统颜色值时,应用程序将自动地反映用户所指定的颜色值。 每一种系统颜色,既有所定义的常数也有直接的颜色设置值。对系统颜色来说,其直接颜色设置值的高位字节与普通 RGB 颜色的高位字节是不同的。对于 RGB 颜色来说,其高位字节为 0,而对于系统颜色来说,其高位字节为 80,剩下的数字则指的是某一特定的系统颜色。例如:&H80000002& 这个十六进制数,是用来指定一个活动窗口的标题颜色。
3.5 使用图片对象 在某些方面,Picture 对象与 Printer 对象很相似— 它不可见,但很有用。可将图片对象想象为一个不可见的图片框,作为图象的一个显示区使用。例如,以下代码装入一个带位图的图片对象,使用该位图可设置图片框控件的 Picture 属性: Private Sub Command1_Click() Dim objPic As Picture Set objPic = LoadPicture("Butterfly.bmp") Set Picture1.Picture = objPic End Sub Picture 对象支持位图,GIF 图象,JPEG 图象,元文件和图标。可用图片对象数组,把一系列图形保存在内存中,而不必用包含多个图形框或图象控件的窗体。当制作动画或其它应用程序时,在要求图象快速变换的地方,这是非常有用的。数组在模块级声明: Dim objPics(1) As Picture 将下列代码添加到 Form_Load 事件中: 将位图加载到图片对象数组。 Set objPics(0) = LoadPicture("Butterfly1.bmp") Set objPics(1) = LoadPicture("Butterfly2.bmp")
3.5 使用图片对象 在 Windows API 中可使用位图、图标或元文件做许多事情,不过图片对象已做了其中大部分事情。这就是说,如果有可能的话,使用图片对象来代替 Windows API 比较好。而且,图片对象能使用 jpeg 和 gif 文件,而 Windows API 则不行。 Picture.Handle 和 PictureBox.hDC 之间没有直接联系。hDC 属性是操作系统提供给图片框控件的设备上下文的句柄。Picture 对象的 Handle 属性,实际上是图片对象所含 GDI 对象的句柄。 现在有两种完全不同的方法可在窗口中画图。可在对象的 hDC 上使用 BitBlt 或 StretchBlt,也可在图片对象或属性中使用 PaintPicture 方法。若有图象控件,则只能用 PaintPicture,因为图象控件没有 hDC。
3.6 使用API函数 这些内容同样可以从API文本游览器中拷贝过来。这些结构中的变量名可随意改动,而不会影响结构本身。也就是说,这些成员变量都是虚拟的。如,POINTAPI结构可改为如下∶ Public Type POINTAPI MyX As Long '点在X坐标(横坐标)上的坐标值 MyY As Long '点在Y坐标(纵坐标)上的坐标值 End Type 不过,一般来讲,是没有这种必要的。结构本身是一种数据类型,因此,使用时必须声明具体变量为该结构型,才能在程序中真正使用到该结构。结构的声明方法和其他数据的声明方法一样,如,以下语句把变MyPoint声明为POINTAPI结构类型∶ MyPoint As POINTAPI
3.6 使用API函数 所谓API本来是为C和C++程序员写的,是一种函数,他们包含在一个附加名为DLL的动态连接库文件中。用标准的定义来讲,API就是Windows的32位应用程序编程接口Application Programming Interface(API),是一系列很复杂的函数,消息和结构,它使编程人员可以用不同类型的编程语言编制出的运行在Windows95和Windows NT操作系统上的应用程序。
3.6 使用API函数 结构是C和C++语言中的说法。在VB中一般称为自定义数据类型。在API领域里,我更喜欢把它叫做结构,因为API各种结构类型根本不是我定义(自定义)的。在VB中,API结构同样由TYPE.......END TYPE语句来定义。如,在API中,点(Point)结构的定义方法如下: Public Type POINTAPI X As Long '点在X坐标(横坐标)上的坐标值 Y As Long '点在Y坐标(纵坐标)上的坐标值 End Type 又如,API中矩形(Rect)结构的定义如下∶ Public Type RECT Left As Long '矩形左上角的X坐标 Top As Long '矩形左上角的Y坐标 Right As Long '矩形右下角的X坐标 Bottom As Long '矩形右下角的Y坐标
3.6 使用API函数 引用结构中的成员变量也十分简单,在结构名后面加上一个".",然后紧接着写要引用的成员变量即可。这很象VB中的引用一个对象的某个属性。如,假如我们把上面已经声明的MyPoint结构中的X变量的值赋给变量Temp&则代码如下∶ Temp&=MyPoint.X 但,特别注意的是,千万不要认为上例中的MyPoint是一个值。它不是值,而是地址(指针)。值和地址是完全不同的概念。结构要求按引用传递给WINDOWS函数,即所有API函数中,结构都是按ByRef传递的(在Declare语句 中ByRef是默认型)。对于结构的传递,你不要试图采用ByVal,你将一无所获。由于结构名实际上就是指向这个结构的指针(这个结构的首地址),所以,你也就传送特定的结构名就可以了。由于结构传送的是指针,所以函数将直接对结构进行读写操作。这种特性很适合于把函数执行的结果装载在结构之中。
3.6 使用API函数 启动VB,新建一个项目,添加一个命令按钮,并把下面的代码拷贝到代码段中,运行它。 Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long Private Type POINTAPI ‘定义点(Point)结构 X As Long '点在X坐标(横坐标)上的坐标值 Y As Long '点在Y坐标(纵坐标)上的坐标值 End Type Sub PrintCursorPos( ) Dim dl AS Long Dim MyPoint As POINTAPI dl&= GetCursorPos(MyPoint) '调用函数,获取屏幕鼠标坐标 Debug.Print "X=" & Str(MyPoint.X) & " and " & "Y=" & Str(MyPoint.Y) End Sub Private Sub Command1_Click() PrintCursorPos
3.6.1绘图设备环境 Visual Basic绘图与WindowsAPI绘图不同。Visual Basic绘图功能比较比较简单,主要是通过几种图形方法(比如Pset、Line和Circle等)以及图形控件(如PictureBox控件和Image控件)完成绘图操作,绘制的图形包含ForeColor、FillColor和FillStyle等绘图属性。而WindowsAPI绘图,则是在设备环境中绘制图形。在Windows的绘图过程中,经常使用的绘图对象包括以下几种:
3.6.1绘图设备环境 设备(Device):可以显示窗口、打印页面或其他的可获取设备环境的输出设备。 设备环境(Device Context):可用来确定对设备进行绘图和各种参数,并定义绘图的坐标系统。 画笔(Pen):定义画线的方式,主要属性包括宽度、颜色和线型。 画刷(Brush):定义区域填充的方式。画刷可以是立体的、带阴影的,也可以用位图进行填充。 绘图属性:定义有画笔和画刷绘制图形如何与设备中已存在的图形结合. 剪裁区:定义设备环境中可以实际绘制的区域。 调色板:定义窗口中的可见颜色。 路径(Path):定义一个可被绘制式填充的复杂形状。 设备环境(Device Context),简称DC,是Windows的一种对象,可用来在一个窗口或设备上绘图。对某个设备的图形和文本输出都是通过设备环境进行的。Windows提供了一组预定义的设备环境,可用于窗口和设备绘图。当需要绘图时,可以从该组中申请一个设备环境,定义其属性,然后通过它进行绘图。绘图完毕后,如果不需要该设备环境了,则应将其释放。如果不使用预定义的设备环境,也可以自己建立设备环境,还可以规定某一类中的每个窗口都有自己的设备环境,或者让某一类的所有窗口共用一个设备环境。
3.6.1绘图设备环境 1、设备环境的分类 大多数的Windows绘图函数通常都需要设备环境句柄作为其中的一个参数。设备环境是Windows的内部数据结构,根据建立和获取的方法的不同,可以把设备环境分为以下3类: (1)专用设备环境 当一个窗口属于一个具有指定样式的类进,它将拥有一个专用的设备环境。这里的“指定样式”是指CS_OWNDC、CS_PARENTDC或CS_CLASSDC。当属于CS_CLASSDC时,一个设备环境被类中所有的窗口共享。而CS_PARENTDC样式窗口的设备环境与其父窗口相同。如果窗口属于CS_OWNDC样式,则每个窗口都有自己的设备环境。CS_OWNDC样式窗口的优点是,当向窗口绘图时,设备环境总是可用的,Windows系统不能以任何方式修改它;缺点是,每个窗口都需要一定的内存开销。Visual Basic中的窗体和图片框控件就具有CS_OWNDC样式。 (2)缓存设备环境 为了节省资源,Windows提供了一块内部设备环境缓存,它可以被所有应用程序和窗口共享。 (3)自定义设备环境 用户可以根据需要,建立自己的设备环境,这称为自定义设备环境。
3.6.1绘图设备环境 2、设备环境的属性 属性 默认值 背景色(Background Color) 白色(White) 背景模式(Background Mode) 不透明(Opaque) 位图(Bitmap) 无(None) 画刷(Brush) 白色画刷(White Brush) 画刷原点(Brush Origin) 0,0 剪载区(Cliping Region) 整个窗口或设备表面 调色板(Coloe Palette) 默认调色板(Default Palette) 画笔位置(Pen Position) 绘图模式(Drawing Mode) R2_COPEYPEN 字体(Font) 系统字体(System Font) 字间距(Intercharacter Spacing) 映射模式(Mapping Mode) MM_TEXT 画笔(Pen) 黑色(Black) 多边形填充模式(Polygon-Filling Mode) ALTERNATE 伸缩模式(Streching Mode) BLACKONWHITE 文本颜色(Text Color) 黑色 视口原点(Viewport Origin) 视口范围(Viewport Extents) 1,1 窗口起点(Window Origin) 窗口范围(Windows Extents) 2、设备环境的属性
3.6.1绘图设备环境 3、设备环境的获取和释放 获取设备环境的操作通过GetDC或GetDCEx函数来实现,而释放设备环境的操作通过ReleaseDC函数来完成。 (1)GetDC函数 GetDC函数用于获取指定窗口的设备环境,其在VB中的声明为: Public Declare Function GetDC Lib "user32" _ Alias "GetDC" (ByVal hwnd As Long) As Long 其中,参数hwnd为要获取指定设备环境的窗口的句柄,如果为0,则获取整个屏幕的DC。如果函数调用成功,则返回指定窗口工作区的设备环境;如果失败,则返回Null。
3.6.1绘图设备环境 (2)ReleaseDC函数 ReleaseDC函数用于释放设备环境,使得该设备环境可供其他应用程序使用,其在VB中的声明为: Public Declare Function ReleaseDC Lib "user32" Alias "ReleaseDC"_ (ByVal hwnd As Long, ByVal hdc As Long) As Long 其中,参数hwnd为要释放的指定设备环境的窗口的句柄。HDC是要释放的设备环境的句柄,如果函数调用成功,则返回值为1,反之为0。 每次调用GetWindowDC和GetDC函数检索公用设备之后,必须调用ReleaseDC函数来释放设备环境。面由CreateDC建立的设备环境不能用ReleaseDC来释放,只能用 DeleteDC函数来删除。 实例:首先在窗体上添加一个图片框、文本框、框架和4个命令按钮控件
3.6.2画笔 画笔是用来画几何图形的GDI对象,当在设备上画一个矩形或多边形时,矩形或多边形的边框就是用画笔画出来的。 WIN32提供了3种类型的画笔: (1)标准画笔 标准画笔有3个属性,即颜色、宽度和线型。其中,颜色用来定义所画线条的RGB颜色,实际使用的颜色与设备有关,GDI可以自动选择与设备最近的颜色。 (2)装饰画笔 装饰画笔是一种扩展画笔,其宽度总是为一个逻辑单位,可以是实线,也可以是标准的虚线和点线,还可以是由用户定义图样的虚线或点线。 (3)几何画笔 几何画笔也是一种扩展画笔,可以是各种宽度、线型和点线图样,并带有增强控制,可以控制两个线条的边接方式。
3.6.2画笔 1、创建画笔 众所周知,画家在开始作画前,都要准备好画笔。两样,在用API作图时,则需要使用API函数建立所需要的画笔。为了在设备环境中使用绘图对象,必须先把指定的绘图对象选入设备环境中,这类似于在绘画时选择画笔。把绘图对象选入设备环境所使用的函数是SelectObjec。建立和获取画笔的API函数有: CreatePen 建立画笔 CreatePenIndirect 根据LOGPEN结构建立一个画笔 ExtCreatePen 建立扩展画笔 SelectObject 把画笔选入设备环境 下面详细介绍这几个函数
3.6.2画笔 (1)CreatePen函数 CreatePen函数用于使用指定的样式、宽度和颜色,建立一个逻辑画笔。在VB中的声明为: Public Declare Function CreatePen Lib "gdi32" _ Alias "CreatePen" (ByVal nPenStyle As Long, _ ByVal nWidth As Long, _ ByVal crColor As Long) As Long 其中:nPenStyle用于指定画笔的样式,可以是下列常量之一: PS_SOLID:实线画笔。 PS_DASH:虚线画笔(nWidth必须为1)。 PS_DOT:点线画笔(nWidth必须为1)。 PS_DASHDOT:点线画笔(nWidth必须为1)。 PS_DASHDOTDOT:点线画笔(nWidth必须为1)。 PS_NULL:画笔不能画图。 PS_INSIDEFRAME:画笔在有椭圆,矩形,圆角矩形,扇形图及弦等生成的封闭对象框中画图;用该画笔所画线的尺寸将根据画笔的宽度进行收缩,经便能完全适合封闭对象;该值只能用于几何画笔。
3.6.2画笔 参数nWidth指定画笔的宽度,以逻辑单位表示,如果该参数为0,则画笔的宽度为1个像素。 参数crColor指定画笔的RGB颜色。 如果函数调用成功,则返回指向新画笔的句柄,该画笔随后就可以被设备使用;如果调用不成功,则返回0值。 建立画笔之后,可以通过调用SelectObject函数将它选入一个设备环境中,之后即可用它来画线。当建立的画笔不再需要时,应调用DeleteObject函数将其删除。 需要说明的是,nWidth参数与nPenStyle参数互相关联。NWidth的值为0,则用该画笔绘制的直线将是为1个像素宽,无论当前的变换方式是什么。如果nWidth的值大于1,则nPenStyle参数必须是PS_SOLID、 PS_NULL或者 PS_INSIDEFRAME。
3.6.2画笔 (2)CreatePenIndirect函数 CreatePenIndirect函数根据指定的LOGPEN结构建立一个逻辑装饰。装饰其在VB中的声明为: Public Declare Function CreatePenIndirect Lib "gdi32" _ Alias "CreatePenIndirect" (lpLogPen As LOGPEN) As Long 其中lpLogPen参数指定逻辑画笔结构。该结构在VB中的定义如下: Public Type LOGPEN lopnStyle As Long lopnWidth As POINTAPI lopnColor As Long End Type LOGPEN结构包括3个成员,其含义分别如下: LopnStyle:指定画笔的样式,与CreatePen函数中nPenStyle参数的含义相同。 lopnWidth:用逻辑单位指定包含画笔宽度的POINT结构。 LopnColor:指定画笔的颜色。 如果函数调用成功,则返回一个逻辑装饰画笔的句柄,如果调用不成功,则返回Null(0)。
3.6.2画笔 (3)ExtCreatePen函数 ExtCreatePen函数用于建立一个扩展画笔,其在VB中的声明为: Public Declare Function ExtCreatePen Lib "gdi32" _ Alias "ExtCreatePen" (ByVal dwPenStyle As Long, _ ByVal dwWidth As Long, _ lplb As LOGBRUSH, _ ByVal dwStyleCount As Long, _ lpStyle As Long) As Long 其中,参数dwPenStyle用于指定画笔的类型、样式、笔尖形状及连接属性,它是下列值的组合(Or操作)。 笔的类型可以下列值之一: PS_ALTERNATE:几何画笔。 PS_COSMETIC:装饰画笔。
3.6.2画笔 笔的样式可以是下列值之一: PS_ALTERNATE:Windows NT,画笔可以设置其他像样素(仅用于装饰画笔)。 PS_SOLID:实线画笔。 PS_DASH:虚线画笔。 ' ------- PS_DOT:点线画笔。 ' ....... PS_DASHDOT:点划线画笔。 ' _._._._ PS_DASHDOTDOT:双点划线画笔。 ' _.._.._ PS_NULL :空画笔。 PS_USERSTYLE :用于Windows NT,画笔使用用户提供一个样式数组。 PS_INSIDEFRAME:实线画笔,可以在任何图形设备接口(GDI)的绘图函数中使用
3.6.2画笔 只有几何画笔才需要指定笔尖形状。笔尖开关可以取下列值之一: PS_ENDCAP_ROUND :圆形笔尖。 PS_ENDCAP_FLAT :平面笔尖。 PS_ENDCAP_SQUARE :方形笔尖。 只有几何画笔才需要指定连接方式。连接方式可以限下列值之一: PS_JOIN_BEVEL:斜切连接。 PS_JOIN_MITER:在斜接极值的范围内进行斜角连接,如果超过斜接极值,则进行斜切连接,斜接极值用SetMiterLimit函数设置。 PS_JOIN_ROUND:圆滑连接。
3.6.2画笔 参数dwWidth指定画笔的宽度。 参数lplb指向LOGBRUSH结构。 参数dwStyleCountr用于指定lpStyle数组的长度,以DWORD为单位。DwPenStyle参数的值不是PS_USERSTYLE,则该值必须为0。 参数lpStyle是一个DWORD类型的数组,用来指定用户定义的画笔样式。数组的第一个指标是第一段虚线的长度,第二个指标是第一段空格的长度。等等。
3.6.2画笔 (4)SelectObject函数 SelectObject函数可以选择一个对象,放到指定的设备环境中,用新对象替换先前的相同类型的对象。其在VB中声明为: Public Declare Function SelectObject Lib "gdi32" Alias _ "SelectObject" (ByVal hdc As Long, ByVal hObject As Long) As Long 其中,参数hDC是设备环境的句柄。参数hObject是被选择的对象的句柄。该对象可以是位图、画笔、字体、笔或者区域,这些对象必须由指定的函数建立。
3.6.2画笔 2、删除画笔 建立画笔之后,如果需要使用画笔,必须选用SelectObject函数将其选入指定的设备环境。在同一时刻,一个设备环境中每种类型的对象只能有一个。对象选入DC时,SelectObject函数的返回值为设备环境中该类型原有的对象。例如,当把一个画笔选入DC时其返回值为原来所选画笔的句柄。该句柄需要保存起来,以便在删除DC前将它恢复到设备环境中。 在删除DC前,一定要恢复初始GDI对象,可以用SaveDC或RestoreDC函数实现该操作。 画笔删除有DeleteObject函数来完成,DeleteObject函数用于删除一个对象,释放所有与该对象有关的系统资源,在对象被删除之后,指定的句柄随之矢效。要删除的对象包括逻辑笔、画笔、字体、区域或者调色板。在VB中声明如下: Public Declare Function DeleteDC Lib "gdi32" Alias _ "DeleteDC" (ByVal hdc As Long) As Long 参数hdc是一个对象的句柄。 3、示例 该示例在程序功能是使用画笔在窗体上画一个矩形。首先在窗体上添加3个命令按钮。源代码如下: