CorelDraw插件开发教程(7):函数与子程序
Category:COREL插件CorelDraw插件开发教程(7):函数与子程序
刘肖健
浙江工业大学工业设计研究院
10. 函数与子程序
10.1 VBA的自带函数
先来认识一个VBA自带的函数。
在界面下面增加一个“函数测试”按钮,将其命名为TestFunctions:
为按钮TestFunctions写入如下代码:
Private Sub TestFunctions_Click()
Dim Pi As Double ‘圆周率
‘圆周率=1的反正切乘以4
Pi = 4 * Atn(1)
Dim y As Double, alfa As Double
‘角度
alfa = 30
‘Sin():求正弦值;alfa * (Pi / 180):角度换算为弧度
y = Sin(alfa *(Pi / 180))
MsgBox “sin(” & alfa &”)=” & y
End Sub
上述代码的运行结果:
简要解释下代码中的两个函数Atn()和Sin()。
Atn(x)是一个三角函数,对括号中的x求反正切。1的反正切值是π/4,所以需要用到圆周率的时候,用4*Atn(1)就可以得到最精确的圆周率π(定义了一个实数变量Pi来表示),而不用在3.14的小数点后写一大堆数字。
Sin(x)也是一个三角函数,对括号中的x求正弦。注意,x是以弧度来表示的,所以求30度的正弦值的代码应该写为:
Sin(30 * (Pi / 180))
函数的计算结果称为“返回值”,括号内的称为“参数”。
x=Atn(1)
4*Atn(1)
上述两个语句中:第一句,Atn(1)的返回值被赋予了变量x;第二句,Atn(1)的返回值参与了其他计算工作(乘以4)。如果函数的返回值既没有被赋予某个变量,也没有参与其他计算,即独立运行,则运行时不带括号,如:
Atn 1
函数名和参数之间用空格隔开。
事实上,MsgBox也是一个函数,而且经常独立运行,所以我们看到的MsgBox都是不带括号的,因为MsgBox的作用就是显示一个对话框,用户看过后点击“确定”按钮关闭,并不需要一个“计算结果”,也就是返回值。
但有时MsgBox也需要返回值,如提供给用户“确定”和“取消”两个按钮,返回值用于告诉程序用户按下了哪个按钮。下面是一个MsgBox函数返回值用法的实例。
Private Sub TestFunctions_Click()
Dim s1 As Shape
‘记录MsgBox的返回值
Dim vRet As Integer
vRet =MsgBox(“要画一个红色的圆吗?“,vbOKCancel)
If vRet = 1 Then ‘用户按下了OK键
Set s1 =ActiveLayer.CreateEllipse2(2, 2, 1, 1, 90#, 90#, False)
s1.Fill.UniformColor.RGBAssign255, 0, 0 ‘填红色
ElseIf vRet = 2 Then’用户按下了Cancel键
Set s1 =ActiveLayer.CreateEllipse2(2, 2, 1, 1, 90#, 90#, False)
s1.Fill.UniformColor.RGBAssign0, 0, 255 ‘填蓝色
End If
End Sub
上述代码的功能是,按钮点下后弹出对话框:
如果用户点“确定”按钮,则画一个红色的圆;如果用户点“取消”按钮,则画一个蓝色的圆。
程序首先定义了一个名为vRet的整数型变量,然后令其等于MsgBox的返回值(MsgBox返回整数型返回值)。这里MsgBox用了两个参数:第一个是字符串变量,是显示在对话框中的文字;第二个参数vbOKCancel表示在对话框上摆“确定”和“取消”两个按钮。第二个参数可以没有,那么就默认只有一个“确定”按钮。
vbOKCancel是系统定义的常数,它的值恒等于1,所以语句写成:
vRet=MsgBox(“要画一个红色的圆吗?”, 1)
也是可以的。
vbOKCancel比1更容易记忆,让人一看就知道是设置“确定”和“取消”两个按钮,所以VBA定义了很多这类常数。CorelDraw则定义了更多的常数,后面还会提到。
查MsgBox函数的使用帮助可以看到它的定义格式:
MsgBox(prompt[, buttons] [, title] [, helpfile,context])
它最多可以带5个参数(参数之间用逗号隔开),除了第一个是必需的,其他都可以缺省——方括号内的参数均可缺省。它的返回值可以是整数1~7,分别代表不同的用户动作,如1代表按下“确定”键,2代表按下“取消”键,等。
MsgBox函数的详细用法请查阅帮助文档。Atn()、Sin()等函数,以及其他更多的三角函数的用法,请查阅帮助文档。具体方法:用鼠标把函数名拖黑,然后按下F1键。
10.2 CorelDraw VBA的函数
CorelDraw的函数都是在对象中定义的,我们已经接触过一个函数了:
ActiveLayer.CreateEllipse2 x, y, r,r, 90#, 90#, False
函数CreateEllipse2(),查阅它的帮助文档可以发现,它属于Layer对象:
所以ActiveLayer.CreateEllipse2()函数的执行结果就是在ActiveLayer(当前层)创建一个圆。ActiveLayer可以替换成其他用户指定的Layer对象,执行结果就是在该Layer创建圆。
CreateEllipse2()函数的返回值是Shape型对象,这是CorelDraw内部定义的对象类型。对象是一种特殊变量,对对象赋值不能直接用等号,而是要在前面加上Set:
Set s1=ActiveLayer.CreateEllipse2 (x,y, r, r, 90#, 90#, False)
如果返回值是Integer(整数)、Double(实数)、Boolean(布尔数)或数组,则可以直接用等号赋值。有关对象和数据类型,后面还会细讲。
上图是CorelDrawVBA帮助文档中的函数定义格式,因为是英文,所以这里对其中几个要点简单解释下:
1)函数所属的对象写在函数前面,中间以点“.”隔开。
2)函数的返回值类型写在最后,如As Shape。
3)括号内是函数的参数,参数之间以英文逗号隔开,CreateEllipse2()函数最多可以带7个参数。
4)方括号内的参数可以省略,但如果省略的参数后面还有未省略的参数(如省略了第4个参数,但后面三个参数都有),则该参数前后的逗号均不能省略,即并列放两个逗号。示例中有这样的一个语句:CreateEllipse2(0,0,1),只用了三个参数,后面四个参数全部省略,如果最后三个参数都有,则变成CreateEllipse2(0,0,1,, 90#,90#,False)。
5)参数定义中指示了参数的类型,如CenterX As Double,表示第一个参数必须是实数。
6)可省略参数给出了默认值,如StartAngle As Double = 90,如果该参数省略,则StartAngle采用默认值90。
7)参数名前面的ByVal是“By Value”的缩写,意思该参数以“传递值”的形式运行函数。CreateEllipse2()函数的参数全部是ByVal型,即ActiveLayer.CreateEllipse2 (x, y, r, r)运行后,x、y、r等变量的值不变。还有一种是ByRef,是“By Reference”的缩写,函数运行后,作为参数的变量x、y、r有可能会被函数修改,函数运行后变量的值会发生变化。有些函数的参数是ByRef型的,如鼠标点击函数GetUserClick(),后面用到时再详说。
通过帮助文档中的示例可以学习函数的详细用法。
10.3 用户自定义的函数
通过一个实例来看看用户如何定义自己的函数。
我们来画一系列的圆,让他们排列成椭圆的形状。
在界面下端增加一个新的按钮,将其命名为DrawCircleRing:
为该按钮写入如下代码:
Private Sub DrawCircleRing_Click()
Dim i As Integer, x As Double, y As Double, alfa AsDouble
‘Pi为圆周率
Dim Pi As Double: Pi = 4 * Atn(1)
‘椭圆心x坐标
Dim x0 As Double: x0 = ActivePage.LeftX +ActivePage.SizeWidth / 2
‘椭圆心y坐标
Dim y0 As Double: y0 = ActivePage.BottomY +ActivePage.SizeHeight / 2
‘小圆半径
Dim r As Double: r = ActivePage.SizeWidth / 100
‘椭圆长径(x向径)
Dim rA As Double: rA = ActivePage.SizeWidth / 4
‘椭圆短径(y向径)
Dim rB As Double: rB = ActivePage.SizeWidth / 6
‘画小圆的数量
Dim n As Integer: n = 36
For i = 0 To n – 1 ‘画36个圆圈
alfa = i * (2* Pi / n)
‘椭圆x坐标(小圆的圆心x坐标)
x = x0 + rA *Cos(alfa)
‘椭圆y坐标(小圆的圆心y坐标)
y = y0 + rB *Sin(alfa)
Set s1 =ActiveLayer.CreateEllipse2(x, y, r, r, 90#, 90#, False)
Next
End Sub
运行结果:
下面我们来定义两个函数xEllipse()和yEllipse(),分别用于计算椭圆的x坐标和y坐标。修改后的代码如下:
Private Sub DrawCircleRing_Click()
Dim i As Integer, x As Double, y As Double, alfa AsDouble
‘Pi为圆周率
Dim Pi As Double: Pi = 4 * Atn(1)
‘椭圆心x坐标
Dim x0 As Double: x0 = ActivePage.LeftX +ActivePage.SizeWidth / 2
‘椭圆心y坐标
Dim y0 As Double: y0 = ActivePage.BottomY + ActivePage.SizeHeight/ 2
‘小圆半径
Dim r As Double: r = ActivePage.SizeWidth / 100
‘椭圆长径(x向径)
Dim rA As Double: rA = ActivePage.SizeWidth / 4
‘椭圆短径(y向径)
Dim rB As Double: rB = ActivePage.SizeWidth / 6
‘画小圆的数量
Dim n As Integer: n = 36
For i = 0 To n – 1 ‘画36个圆圈
alfa = i *(2 * Pi / n)
x = xEllipse(x0, rA, alfa)
y = yEllipse(y0, rB, alfa)
Set s1 =ActiveLayer.CreateEllipse2(x, y, r, r, 90#, 90#, False)
Next
End Sub
‘x0:椭圆圆心的x坐标;rA:椭圆长径(x向径);a:椭圆的圆周角
Function xEllipse(x0 As Double, rA As Double, a As Double) As Double
Dim x As Double
x = x0 + rA *Cos(a)
‘返回值等于x
xEllipse = x
End Function
‘y0:椭圆圆心的x坐标;rB:椭圆短径(x向径);a:椭圆的圆周角
Function yEllipse(y0 As Double, rB As Double, a As Double) As Double
Dim y As Double
y = y0 + rB *Sin(a)
‘返回值等于y
yEllipse = y
End Function
可以照搬上述函数的定义格式。几点说明:
1)函数的定义格式跟Sub有点像,用Function代替Sub即可;不同的是函数有返回值,所以在第一行末尾括号外要加上返回值的数据类型,如As Double,就像用Dim定义一个变量一样。
2)函数定义可以写在文档的任何位置,但是不能在Sub里面定义函数,也不能在一个函数里面定义另一个函数,即函数定义不能出现在Sub与End Sub之间或Function与End Function之间。
3)函数定义时要在函数名后的括号里指明所有参数的数据类型,如上述x0 As Double, rA As Double等。
4)函数内部只能使用函数名里定义过的参数和Dim语句定义的参数。
5)设置返回值的方式是:函数名=XXX
6)函数不能单独运行,只能通过子程序或其他函数调用。
7)调用函数时,给的参数类型要与函数定义的类型一致,如a参数定义的是Double型,则调用时也必须用一个Double型数据代替a,这是是用alfa代替a,alfa也是Double型数据。
8)把“Function”一词拖黑,按下F1键,可以得到有关函数定义的详细帮助。
有了函数,可以把复杂的程序简化,如上述循环语句可以改为:
……
For i = 0 To n – 1 ‘画36个圆圈
alfa = i *(2 * Pi / n)
Set s1 =ActiveLayer.CreateEllipse2(xEllipse(x0,rA, alfa), yEllipse(y0, rB, alfa),r, r, 90#, 90#, False)
Next
……
这样x和y两个参数都不需要了,因为直接调用函数,产生返回值来充当CreateEllipse2()函数的参数。
可以看出,程序中的函数跟中学数学的函数概念差不多,都是w=f(x,y)的基本形式,f为函数名。但程序中的函数可以用来做更多的事,而不仅仅是计算;返回值也可以多种多样,而不仅仅是一个计算结果,甚至可以返回一系列数值,如返回一个数组,这样的话,椭圆的x和y坐标只用一个函数就可以计算完成了。这些灵活的函数用法后面还会提到。
10.4 子程序
我们编写的第一个程序Helloworld就是以子程序形式运行的。子程序的定义方式如下:
Sub 子程序名()
……
End Sub
代码写在Sub和End Sub之间。
把“Sub”一词拖黑,按下F1键,可以得到有关子程序定义的详细帮助。
有关子程序的一些说明:
1)子程序的定语与函数相似,包括参数的定义,只是没有返回值。
2)子程序可以单独运行:把光标调入子程序定义的内容,点IDE界面的执行按钮
可以运行该子程序。
我们在赋色语句使用过的RGBAssign就是一个子程序,它是Color型对象的函数,s1.Fill.UniformColor是Color对象的一个“实例”(比如,Dim x As Integer表示定义x为Integer型数据的一个实例)。RGBAssign子程序带有三个参数,分别为RGB三个色彩分量。