CorelDraw插件开发教程(8):变量和对象

  • 0

CorelDraw插件开发教程(8):变量和对象

Category:COREL插件 Tags : 

原创: 刘肖健 创意之代码 1周前

CorelDraw插件开发教程(8):变量和对象

 

刘肖健

浙江工业大学工业设计研究院

11.  数据类型:变量和对象

11.1    变量

VBA的常用数据类型有:

Double:实数

Integer:整数

Long:长整数

Boolean:布尔型数

String:字符串

当我们在程序中使用常数时,比如90,它有可能是实数、整数、字符串,为了指示数据类型,通常在常数后面加个符号,如90#表示实数90,Double型数据,$表示String型数据;%表示Integer型数据;&表示Long型数据。

定义变量用Dim语句:

 

Dim x As Double : x=3.14

Dim i As Integer : i=50

Dim R As Long : R=255

Dim myName as String : myName=”Bill”

Dim blackOrNot as Boolean : blackOrNot=True

 

有关变量定义的一些说明:

1)变量的定义可以放在程序的任何位置,这个跟C语言不一样,不要求必须放在前面先把所有变量都定义完了再开始执行性的语句。

2)一个变量名只能定义一次,否则出错,系统提示“变量重定义”。所以不能在循环内部定义变量,因为每次执行循环都会对同一个变量进行定义,重定义了。

3)变量的命名有一定的规则,请查看VBA帮助文档。

4)变量命名要避开关键字。关键字包括Dim、Sub、For等系统已经“占用”的字,以及Sin、Cos等已经存在的函数名。

5)变量可以不定义而直接用,如果没赋值,则其值默认为是等于0的数值量。所以,一个被敲错的变量名会被系统当做一个新变量,且其值为零,但系统不会指出这一错误。为了避免变量名敲错查找困难,可以强制要求所有变量必须定义才能使用,否则就报错。具体方法是在程序文档的第一行加一句:

 

Option Explicit

 

有了这句,整个文档的变量必须都要先定义才能使用。

 

变量的作用范围:

1)子程序(Sub)和函数(Function)内部定义的变量(即内部变量),只能在Sub和Function内部使用。所以可以在不同的Sub或Function内部定义名称一样的变量,而不会得到“变量重定义”的系统报错。

2)一个文档(窗体或模块)中,在所有Sub和Function外面定义的变量(即外部变量),可以在整个文档中通用,各Sub和Function都可以使用它,如在一个Function中为一个变量赋值,可以在另一个Function中使用这个值。

3)内部变量可以与外部变量重名,此时只有内部变量起作用。

4)如果想在一个文档(窗体或模块)中使用另一个文档中定义的变量,则该变量必须被定义为“公有型”,语句格式是用Public代替Dim,如:Public bmpHeight As Double

11.2    对象

对象可以简单理解为“复杂”的变量。除了整数、实数、字符串等常见数据类型外,在制作界面时会遇到对话框、按钮、输入框等复杂数据,在设计过程中会遇到图形、曲线、色彩、页面等复杂的数据,它们称为对象。

我们前面的例子中遇到最多的对象就是Shape:

 

Dim s1 As Shape

Set s1 = ActiveLayer.CreateEllipse2(x, y, r, r, 90#,90#, False)

 

定义一个变量为某对象数据类型,与常规变量的定义一样,也是用Dim语句。但对象类变量不能直接用等号“=”赋值,而是要在前面增加关键字“Set”。

对象跟一般的变量不一样,它可以带有自己“下属”的变量、对象、函数、子程序。

上述语句中的另一个对象ActiveLayer,它是一个CorelDraw内部定义的Layer型对象,用于指代当前绘图层。大部分直接创建图形的函数(如CreateEllipse2)都是Layer型对象的下属函数。

当我们在界面上建立了一个按钮,并取了名,就定义了一个CommandButton类型的对象,可以通过下述方法观察该对象“下属”的内容:

1)在任何位置键入对象名,如前面定义的按钮对象DrawCirclePage;

2)在对象名后键入点号“.”,则该对象的下属内容会自动跳出,按字母顺序排列:

可以看到,这里的很多下属变量都是按钮的属性,如高度(Height)、宽度(Width)、位置(Left/Top)、色彩(BackColor)、文字(Caption)、图片(Picture)等。这些属性可以在属性窗口修改,也可以在程序中用代码修改。

下面编写一个简单的“逃跑按钮”小游戏,来解释如何在事件子程序中修改对象下属变量。

这个游戏程序是这样运行的:界面上有一个按钮,点击它会启动单击事件(Click)并弹出对话框显示“Bingo!”。但是当鼠标掠过该按钮时会启动鼠标移动事件(MouseMove),该事件将改变按钮的位置,将其改到对话框界面上的一个随机位置。如此,鼠标的位置就会落空,导致点不到按钮,除非按钮位置改变后刚好鼠标还在其上。

这个程序的代码非常简单,按5.4节所述的方法为所创建的Button_Escape按钮添加Click和MouseMove事件,然后写入如下代码:

 

Private Sub Button_Escape_Click()

MsgBox “Bingo!”

End Sub

 

Private Sub Button_Escape_MouseMove(ByVal Button AsInteger, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)

Button_Escape.Top = Rnd * (Escape.Height – 2 *Button_Escape.Height)

Button_Escape.Left = Rnd * (Escape.Width -Button_Escape.Width)

End Sub

 

按钮的“逃跑”动作通过修改按钮对象的Top和Left两个变量实现。Top是指按钮与对话框上边界的距离,Left是指按钮与对话框左边界的距离,以像素计算。Escape是对话框(对象)的名称,Escape.Height和Escape.Width分别为对话框的高度和宽度。

运行后出现如下对话框:

当鼠标划过按钮时,按钮就会“逃跑”,随机出现在另一个位置上。

11.3    CorelDraw的常用对象

这里简单介绍一下CorelDraw常用的几个对象。

 

1Application

 

Application对象是指当前的CorelDraw软件。如果我们想知道当前使用的CorelDraw版本,可以用如下代码获得:

 

MsgBox Application.Version

 

上述代码会弹出一个对话框,告诉你当前的软件版本号:

你可能会觉得知道版本号没什么意义,但是对程序是有意义的,因为不同的CorelDraw版本的VBA库略有不同,有的插件在X3运行良好,但是在X7或X8上运行就会出错。下述代码是根据版本号来调用不同子程序的示例:

 

Dim cdrVersion As String

cdrVersion = Left(Application.Version, 2)

If cdrVersion = “13” Then

‘调动X3版插件功能

DrawCircleRow_Ver13

ElseIf cdrVersion = “15” Then

‘调用X5版插件功能

DrawCircleRow_Ver15

End If

If CInt(cdrVersion) <= 12 Then

MsgBox “本插件仅用于CorelDraw X3以上版本。”

Exit Sub

End If

 

在上述代码中,我们为“画一行圆”这个子程序准备了若干个版本的函数,它们的名称分别为DrawCircleRow_Ver13、DrawCircleRow_Ver15等。Application.Version是一个字符串,它的最前面两个数字就是大的版本号,后面还有些数字表示该版本下的各种小的改进版。我们只需要知道大的版本号即可,所以用Left函数把字符串的最前面两个字符提取出来。Left函数的用法可以查阅VBA语法帮助得到。

由于CorelDraw 12以前的版本区别比较大,所以插件不适用于12以前的老版。这时就不针对每个版本分别响应了,而是把用Left提取出来的两个字符(如“13”)转换成整数,然后再判断它的大小,如果小于或等于12,就弹出对话框给出提示,然后终止程序。

注意,字符串12和整数12是两个不同类型的数据,前者是String型,后者是Integer型。字符串12代表两个字符,跟“ab”、“*&”一样,仅仅是两个字符而已。字符是没有大小的,只有整数才能比较大小,所以使用CInt函数把字符串强制转换成对应的整数。

 

2Document

 

Application对象用到的场合并不多,除了版本号之外,能常用到的有它的如下两个成员(下属)对象:

 

Application.ActiveDocument

Application.Documents(n)

 

Application对象的这两个成员对象在使用时都可以不带前面的Application对象名。ActiveDocument是指当前文档;Documents(n)是指处于打开状态的第n个文档。

Application.Documents.Count则是指当前打开的文档数量。

Document对象用于指代.cdr文档。下述代码先告诉用户当前打开了几个文档,然后关闭第一个打开的文档。

 

Dim n as Integer

n= Application.Documents.Count

Application.Documents(n).Close

 

3Page

 

Page是Document对象的成员,指文档中的页面。以下代码增加一个新页面,为其重新命名并修改其宽高:

 

Dim myPage As Page

Set myPage = ActiveDocument.AddPages(1)

myPage.Name = “TestPage”

‘设置当前文档的长度单位为毫米(默认是英寸)

ActiveDocument.Unit = cdrMillimeter

myPage.SizeHeight = 210

myPage.SizeWidth = 297

 

4Layer

 

图层(Layer)是页面(Page)的子对象,也是页面的下一级组织结构。大部分直接画图的命令,如画矩形、画圆、画自由曲线等都是Layer的下属成员函数,因为画图形必须选定画在哪个图层上。

观察自动记录下来的代码可以发现,默认的图形都是创建在一个名为ActiveLayer的图层上。ActiveLayer也是Page的子对象,它可以直接使用,前面不用带它的父对象Page。

 

5Shape

 

Shape对象是用的最多的CorelDraw VBA对象,它用于指代一个图形、一张图片、一个群组等。前面已经见过很多Shape对象的用法,此处不再赘述,后面还会有更多案例。

 

6Fill

 

Fill是Shape的子对象,用于表示图形的填充特性。我们在一个Shape对象名后面的Fill后敲一个点号“.”,就会看到各种填充模式的列表:

“Apply”开头的函数都是各种填充模式,中最后一个ApplyUniformFill是最常见的单色平涂。各种填充模式的具体用法可以查阅CorelDraw VBA的帮助文档。

 

7Color

 

Color是一个图形的色彩信息,获取一个平涂图形的色彩可以用如下代码:

 

Dim myColor As Color

Set myColor = ActivePage.Shapes(1).Fill.UniformColor

 

如果Shape图形不是平涂填充的,则其UniformColor对象为空,上面的代码myColor会得到一个不存在的对象。获得图形的色彩对象后,如果想知道色彩的进一步数据,比如获取该色的GRB值或HSB值,可以用如下代码实现:

 

Dim clrRed As Long, clrGreen As Long, clrBlue As Long

clrRed = myColor.RGBRed

clrGreen = myColor.RGBGreen

clrBlue = myColor.RGBBlue

MsgBox “RGB Color:” & clrRed & “,” &clrGreen & “,” & clrBlue

 

8Curve

 

Curve是Shape对象的子对象,它用于表示Shape图形对象中的曲线,如边界线或内部曲线。

 

9SubPath

 

SubPath是Curve对象的子对象。因为一个Shape对象的Curve有可能有多条曲线构成,如一个内部开了一个洞的矩形,这个Shape的Curve就包含两条SubPath。

用下面的代码可以弹出对话框显示这个图形里的SubPath数。

 

MsgBox ActivePage.Shapes(1).Curve.SubPaths.Count

 

上述代码中,ActivePage.Shapes(1)是指当前页面中最新创建的图形:新图形的编号排第一,如果又创建了一个图形,则刚才的图形变成Shapes(2)。如果我们想找到页面中第一个建立的图形应该怎么办呢?

很简单,它是ActivePage.Shapes(ActivePage.Shapes.Count),ActivePage.Shapes.Count是当前页面中的图形总数,也就是最末一个编号,也就是最先创建的图形的当前编号。

下面的代码可以显示一个Subpath围成的面积大小,如果不是封闭的,则显示零。

 

MsgBox ActivePage.Shapes(1).Curve.SubPaths(1).Area

 

10Node

 

Node是SubPath曲线的节点。CorelDraw的曲线是用三次贝塞尔曲线表达,Node即贝塞尔曲线的节点。要想了解有关贝塞尔曲线及其节点的技术细节,可以查阅计算机图像学的相关资料。

下述代码可以在图形的第一条SubPath的每个节点上画一个小圆圈,标识节点的位置:

 

Dim i As Integer, n As Integer

Dim x As Double, y As Double

Dim sp As SubPath, myNode As Node

Set sp = ActivePage.Shapes(1).Curve.SubPaths(1)

n = sp.Nodes.Count

For i = 1 To n

Set myNode =sp.Nodes(i)

x =myNode.PositionX

y =myNode.PositionY

ActiveLayer.CreateEllipse2x, y, 5, 5

Next

 

代码执行效果如下图所示:

上述曲线的每个节点上都被画了一个小圆圈。

 

11Segment

 

Segment是SubPath的子对象,指SubPath中两个相邻的Node之间的那一段曲线。上图的曲线有5个Node,它包含4个Segment。

Segment对象已经深入到曲线形态的图形学底层,通过Segment可以获得很多曲线的特征数据,如节点处的切向、法向、控制点位置等。比如我们要判断一条曲线上是否有尖点,只要测试每一个Node在前后两个Segment处的切向方向是否一致即可,如果不一致,则表示该处有尖点,否则曲线在该处光滑。


Leave a Reply

搜索

分类目录

公 告

本网站学习论坛:

www.zhlisp.com

lisp中文学习源码:

https://github.com/zhlisp/

欢迎大家来到本站,请积极评论发言;

加QQ群学习交流。