函 数 说 明
CreateBrushIndirect 在一个LOGBRUSH数据结构的基础上创建一个刷子
CreateDIBPatternBrush 用一幅与设备无关的位图创建一个刷子,以便指定刷子样式(图案)
CreateDIBPatternBrushPt
用一幅与设备无关的位图创建一个刷子,以便指定刷子样式(图案)
CreateHatchBrush
创建带有阴影图案的一个刷子(阴影图案见注解)
CreatePatternBrush
用指定了刷子图案的一幅位图创建一个刷子
CreatePen
用指定的样式、宽度和颜色创建一个画笔
CreatePenIndirect
根据指定的LOGPEN结构创建一个画笔
CreateSolidBrush
用纯色创建一个刷子
ExtCreatePen
创建一个扩展画笔(装饰或几何)
GetStockObject
取得一个固有对象(Stock)。这是可由任何应用程序使用的windows标准对象之一
例1∶创建一个红色实线画笔,画笔宽度为3个像素点
Dim NewPen As Long
Private Const PS_SOLID =
0
NewPen&=CreatePen
(PS_SOLID,3,RGB(255,0,0))
注∶其中PS_SOLID常数代表实线
例2∶创建阴影刷子
LOGBRUSH结构的定义如下∶
Private Type LOGBRUSH
lbStyle As Long
lbColor As Long
lbHatch As Long
End Type
以下代码餍了创建一个 刷子样式为 阴影(BS_HATCHED)
,阴影类型为十字交叉(HS_CROSS)的红色画笔。
Dim BrushInfo As
LOGBRUSH
BrushInfo.lbStyle =
BS_HATCHED
BrushInfo.lbColor =
RGB(255,0,0)
BrushInfo.lbHatch =
HS_CROSS
NewBrush =
CreateBrushIndirect(BrushInfo)
例3∶用纯色创建刷子(这个例子中是红色)
NewBrush =CreateSolidBrush(vbRed)
同样,用其他几个函数,按照其用法可以创建相应的GDI绘图对象。现在,您大概了解有以上这些函数和,理解给出的几个例子就可以了。稍后,我们结合实际例子,更深入地探讨这些函数的用法。
三、拿起和放下画笔(GDI对象)
现在我感觉好象向一群绘画系的学生讲课,尽管自己不怎么会绘画。首先是练基本功,怎样拿起画笔和放下画笔,这可能是绘画专业学生首先要学习的吧?当然,更广义地讲应当是怎样选择和删除GDI绘图对象。
在通过前述方法来创建一个GDI对象句柄(上例中的NewBrush,NewPen等)以后,为了使用它们,我们必须用SelectObjecth
API函数把它们选入相应的设备场景。一个设备场景在某一时刻、在每一种类型中只能拥有一个对象,如一个画笔和一个刷子一个位图等。
SelectObjecth函数的用法非常简单,需要记住的是,此被调用后,如果成功将返回旧的对象句柄。你需要把它保存起来。当然,这一过程只需要把返回值附值于某一Long型变量就可以了。如∶
OldPen&=SelectObject(Picture1.hDC
, NewPen&)
接下来该做什么呢?对对,这位同学说的对∶绘图。该怎么绘图呢?不,不,不要着急,这个问题,我们留在下一节中讨论,现在你只需记住,这里可以画些圆呀、矩形呀、添充多边型呀的操作。那么,绘图操作结束以后该怎么办呢?答案是∶应当把旧的绘图对象回设到设备场景中去。如下∶
SelectObject
Picture1.hDC,OldPen&
这样,设备场景将恢复到我们为其选入绘图对象以前的状态。因为,我们不能断定其他绘图函数会使用什么样的绘图对象。因此把原来的绘图对象放回去乃是一个上策。但,如果你接着要为设备场景选择另一个对象,这个步骤可以留在后面进行。那么在这次的选入过程中就没有必要保存旧的对象句柄了,这是因为SelectObject函数返回的旧对象的句柄就是刚才我们为其选择的句柄。
绘图也完了,设备场景也恢复了原始状况,那么就操作告一段落了吗?不,还有一点。您最好把您自己创建的GDI对象删除掉,释放掉刚才使用过的资源。操作如下∶
DeleteObject NewPen
又如∶
DeleteObject NewBrush
其实,您不删除这些对象资源,应用程序退出时会自动释放的。这是因为在Win32中,资源为每个应用程序私有的。由于这种原因,应用程序之间也不能共享一个GDI对象。但是,删除你所创建的GDI对象仍是一个好的编程习惯。既然不用,留着它做什么呢,何必占用资源空间呢?
外,您千万千万切记,切记,千万∶不要删除已经选入设备场景的系统GDI对象。
还有一点,GetStockObject函数返回的对象是系统对象,请不要用DeleteObject函数删除它,否则会出现非常非常可怕的事情———你的硬盘将被永远用不了啦。@@~
呵呵,吓唬你一把,其实没那么严重。不过,我想您大概不是明知整了坏,偏向坏里整的人吧?
如果是的话,随便整好了。
OK,以下展示了使用GDI对象的API函数。
函 数 说 明
DeleteObject
用这个函数删除GDI对象,比如画笔、刷子、字体、位图、区域以及调色板等等。对象使用的所有系统资源都会被释放
EnumObjects
枚举可随同指定设备场景使用的画笔和刷子
GetCurrentObject
用于获得指定类型的当前选定对象
GetObjectAPI
取得对指定对象进行说明的一个结构。windows手册建议用GetObject
这个名字来引用该函数。GetObjectAPI在vb中用于避免与GetObject关键字混淆
GetObjectType
判断由指定句柄引用的GDI对象的类型
SelectObject
每个设备场景都可能有选入其中的图形对象。其中包括位图、刷子、字体、画笔以及区域等等。一次选入设备场景的只能有一个对象。选定的对象会在设备场景的绘图操作中使用。例如,当前选定的画笔决定了在设备场景中描绘的线段颜色及样式
除了DeleteObject和SelectObject以外的其他函数用于从系统或指定设备场景中获取有关GDI对象的信息,一般不十分常用。
这样,假如我们要用画笔和刷子来做一些绘图朝着的话,编写代码的大概步骤是这样的。
Dim NewPen As Long
Dim NewBrush As Long
Dim OldPen As Long
Dim OldBrush As Long
NewPen& =
CreatePen(PS_SOLID, 3, RGB(255, 0, 0)) * 创建画笔
NewBrush& =
CreateSolidBrush(vbRed) * 创建画刷
OldPen& =
SelectObject(Picture1.hDC,NewPen&)
'添加绘图操作代码
OldBrush& =
SelectObject(Picture1.hDC,NewBrush)
'添加填充操作代码
SelectObject
Picture1.hDC,OldPen&
SelectObject
Picture1.hDC,OldBrush&
DeleteObject
NewPen&
DeleteObject
NewBrush&
注意一点,要用API绘图函数,并非一定要创建画笔和刷子。完全可以使用现有的GDI对象,直接调用函数来绘图。记住,设备场景中总有个默认的画笔和刷子,问题是它符不符合您的要求了。但我觉得,在绘图之前选择画笔是个好习惯。有些VB功能也可以结合使用,比如你想用红色画笔,你可以设置Forcolor属性为红色、想加宽画笔的宽度,可以设置DrawWidth属性等。
四、绘图属性与绘图函数
到目前为止,我们已经学会了绘图所需要的一切准备工作。上一节中最后给出的代码就说明这一点。代码中,现在只缺少具体的绘图代码。本节就讨论关于如何绘图的问题。
在接触绘图函数之前,首先需要了解绘图属性。设备场景定义了一系列绘图属性。这些绘图属性定义了刷子和画笔与窗口或设备表面当前内容相互作用的方法。比如,当前画笔的位置、当前背景颜色、圆弧和矩形的绘制方向、光栅操作模式等等。虽然后面给出了很多属性控制函数,但用VB自身的函数和方法属性,更容易实现。比如,设置背景模式,只要设置控件的BackColor属性就可以很轻松、带愉快地完成。但是,如果是要在一个不与窗口关联的自建设备场景中绘图的话,想必依靠这些函数是不可逃避的。
线光栅操作∶我们已经知道,光栅操作是一种位操作。通常你想用画笔进行绘图时,都假定画笔色彩只是简单的绘制到显示器或设备上。实际上,WINDOWS支持16种不同的线绘图模式,它们定义了一条线如何与显示器上已有的信息组合。这些模式就叫做线光栅操作(有时叫ROP2模式)。并且它们被作为绘图模式引入到了VisualBasic。ROP2光栅操作相当于设置VB的DrawMode属性。
背景模式∶阴影刷子、虚线画笔和文本都有一个背景。对于阴影刷,它是指阴影线之间的区域,对于虚线画笔,则指点和虚线之间的区域。而对于文本,它是指每个字符单元的背景。背景模式决定了WINDOWS如何处理这些背景区。它可以是不透明的,也可以是透明的。若是不透明的,则背景区设置为背景色;否则如果是透明的,则背景区域保持原状。
当前位置∶在VB中,要画一条直线其实非常简单,采用Line方法就可以,而且能够在一个语句中表达完成。如Line
(5,5)-(10,10)
但在API中并不这样简单了(但也不是太麻烦)。要画直线,需要首先设定直线的起点。一般用MoveToEx函数来完成。然后在下一行代码中绘制直线,如LineTo
10,10。MoveToEx函数是经常使用的函数之一,用来确定绘图前的起始位置。。
绘图属性控制函数
函 数 说 明
GetArcDirection
画圆弧的时候,判断当前采用的绘图方向
GetBkColor
取得指定设备场景当前的背景颜色
GetBkMode
针对指定的设备场景,取得当前的背景填充模式
GetCurrentPositionEx
在指定的设备场景中取得当前的画笔位置
GetMiterLimit
取得设备场景的斜率限制(Miter)设置——斜率限制是指斜角长度与线宽间的比率
GetNearestColor
根据设备的显示能力,取得与指定颜色最接近的一种纯色
GetPolyFillMode
针对指定的设备场景,获得多边形填充模式。
GetROP2
针对指定的设备场景,取得当前的绘图模式。这样可定义绘图操作如何与正在显示的图象合并起来
MoveToEx
为指定的设备场景指定一个新的当前画笔位置。
SetArcDirection
设置圆弧的描绘方向
SetBkColor
为指定的设备场景设置背景颜色。背景颜色用于填充阴影刷子、虚线画笔以及字符(如背景模式为OPAQUE)中的空隙。也在位图颜色转换期间使用。
SetBkMode
指定阴影刷子、虚线画笔以及字符中的空隙的填充方式
SetMiterLimit
设置设备场景当前的斜率限制
SetPolyFillMode
设置多边形的填充模式。
SetROP2
设置指定设备场景的绘图模式。与vb的DrawMode属性完全一致。
同VisualBasic相比较,API提供了功能更强大的绘图函数。大部分绘图函数的用法都非常简单明了,只要按其说明使用就可以,觉得没有必要我多加说明。
WindoesAPI绘图函数
函 数 说 明
AngleArc
用一个连接弧画一条线,参考注解
Arc 画一个圆弧
ArcTo 画一个圆弧,并更新当前位置
CancelDC
取消另一个线程里的长时间绘图操作
Chord 画一条弦线(椭圆的平分线)
Ellipse
描绘一个椭圆,由指定的矩形围绕。椭圆用当前选择的画笔描绘,并用当前选择的刷子填充
FillRect
用指定的刷子填充一个矩形
FloodFill
用当前选定的刷子在指定的设备场景中填充一个区域。区域是由颜色crColor定义的
FrameRect
用指定的刷子围绕一个矩形画一个边框(组成一个帧),边框的宽度是一个逻辑单位
GetPixel
在指定的设备场景中取得一个指定像素的当前RGB值
InvertRect
通过反转每个像素的值,从而反转一个设备场景中指定的矩形
LineDDA
枚举指定线段中的所有点
Pie 画一个扇形
PolyBezier
绘一条或多条贝塞尔(Bezier)曲线。
PolyBezierTo
绘一条或多条贝塞尔(Bezier)曲线,并将当前画笔位置设为前一条曲线的终点
PolyDraw
描绘一条复杂的曲线,由线段及贝塞尔曲线组成
Polygon
描绘一个多边形,由两点或三点的任意系列构成。windows会将最后一个点与第一个点连接起来,从而封闭多边形。多边形的边框用当前选定的画笔描绘,多边形用当前选定的刷子填充
Polyline
用当前画笔描绘一系列线段。使用PolylineTo函数时,当前位置会设为最后一条线段的终点。它不会由Polyline函数改动
PolylineTo
同上,并设置当前画笔位置用当前选定画笔描绘两个或多个多边形。根据由SetPolyFillMode函数指定的多边形填充模式,用当前选定的刷子填充它们。每个多边形都必须是封闭的
PolyPolygon
用当前选定画笔描绘两个或多个多边形。根据由SetPolyFillMode函数指定的多边形填充模式,用当前选定的刷子填充它们。每个多边形都必须是封闭的
PolyPolyline
用当前选定画笔描绘两个或多个多边形
Rectangle
用当前选定的画笔描绘矩形,并用当前选定的刷子进行填充
RoundRect
用当前选定的画笔画一个圆角矩形,并用当前选定的刷子在其中填充。X3和Y3定义了用于生成圆角的椭圆
SetPixel
在指定的设备场景中设置一个像素的RGB值,并返回该点的颜色
SetPixelV
在指定的设备场景中设置一个像素的RGB值