Lisp与VBA比较(摘自明经通道)
樱花满开
樱花满开 Lv.13
2012年11月30日 11:06:30
只看楼主

我听到许多关于这样的问题。AutoLISP与VBA有什么不同呢?我要学习怎样二次开发AutoCAD,但我不能确定先学哪一个工具。哪一个工具更好呢?简洁的回答是他们都好,你应当两者都学。分析我的回答,你可以知道这不是最快的解决办法,但在你做出一个完整的决定前,一个完整的回答需要时间和更多的问题。举个例子:你懂BASIC吗?如果你懂,那么VBA学起来会更快一些;如不懂BASIC,那么你学过其它的编程语言吗?如果你学的正好是FORTRAN或PASCAL的话,那也很好。因为如果你已掌握了这两种语言,则VBA的学习将十分简单。如果你一点儿也不懂程序设计语言,那么AutoLISP将会是适合你学习的语言。

我听到许多关于这样的问题。AutoLISP与VBA有什么不同呢?我要学习怎样二次开发AutoCAD,但我不能确定先学哪一个工具。哪一个工具更好呢?

简洁的回答是他们都好,你应当两者都学。分析我的回答,你可以知道这不是最快的解决办法,但在你做出一个完整的决定前,一个完整的回答需要时间和更多的问题。举个例子:你懂BASIC吗?如果你懂,那么VBA学起来会更快一些;如不懂BASIC,那么你学过其它的编程语言吗?如果你学的正好是FORTRAN或PASCAL的话,那也很好。因为如果你已掌握了这两种语言,则VBA的学习将十分简单。如果你一点儿也不懂程序设计语言,那么AutoLISP将会是适合你学习的语言。

如果你正好没有程序设计的知识和经验,那么在AutoCAD里你应当学习什么语言?这个问题很难回答。这取决于你希望完成什么样的工作?每种语言都有其优点和缺点,AutoLISP擅长建立新命令和产生已有命令的连接。VBA擅长执行包括在其他应用程序中的组件,如Microsoft的Excel和Access。AutoLISP是基于表处理的编程体系,它允许程序员随意地存储和操作传送信息,然而VBA部件包括数据和对复杂情况的各种有效操作,这就是问题变得复杂的地方,除非你已真正懂得这些工具的好处,否则,很难回答你应该选择哪一个,但你应当知道你想完成什么和允许完成什么,因为它将引导你向正确的解决方法前进。

稍后,你会发现这一简洁的回答是恰当的,你将会学习两种语言,你要做的一些事,可以在AutoLISP中用十分简单的几行代码来解决。另一方面,你会发现VBA提供了一些最简捷的应用程序解决方案。例如,建立一个复杂的包括许多对话框的应用,AutoLISP支持对话框,但是不如VBA支持的程度强,同时,在AutoCAD中一个任务的情况下,VBA提供在对象级别上访问AutoCAD系统,但它对AutoCAD的一些基本命令的支持性并不是很好,而AutoLISP在这一点上却做的很好。

这两种语言不具有很好的兼容性,这种情况是必然的,就是说,你不能把在AutoLISP中写的东西放到VBA中随意使用,反之亦然。我并不是说这种情况不可能的,但却是很难以实现。最低限度是,一但你选择了一种语言来设计程序,你就不可能中途又用另一种语言来解决程序中的问题,你不得不继续使用你最初选择的语言。

建立个词汇表

那么,让我们从学术角度讨论一些两种语言间的不同之处。前面提到的AutoLISP是综合了逻辑结构与传统AutoLISP命令的一个完美工具,你能组合AutoCAD命令并放在一个有条件的逻辑脚本里,而产生强有力的自定义命令,这些命令能被用于自动操作通常的任务,也能解决计算问题而得到一个结果。基于命令种类的思想比目标角度的思想更简单,一个清楚直接指出不同点的例子:在一个多义线对象里打断编辑方法。如果你要打断一条多义线,你必须先计算并重新更新这个物体,Extend和Trim命令也一样。这些命令现在还并不包含在AutoCAD对象系统的实体对象编辑方法中。在不久它们会随时出现,这就是对象的好处。

在许多情况下,对象级的处理比命令方式更高级。当你执行一个命令时,你有可能可以也有可能不可以直接操作你所选取的对象。因为你必须依赖于AutoCAD的对象选择机制。对象不是模糊不清的。当你专门指定一个对象时,对你要操作的对象,它是很清楚的。

对象级别的处理在VisualLISP也可实现。使用VisualLISP中的(VL)扩展,你能改变对象的参数且在需要时调用对象的方法。你不得不使用对象引用,它可以从已有的实体名或直接产生的对象中生成,在大多数情况下,一个有经验的AutoLISP程序员不需要使用这些对象,但迟早它们会派上用场。

VisualLISP的另一优点是比VBA更接近AutoCAD系统。VBA不是由AutoCAD产生的,它是在其它的环境下同样工作的一个附加的语言,象Microsoft的Word和Excel一样。它也类似于在AutoCAD中用VB(Visualbasic)语言编制程序的方法。VisualLISP仅在AutoCAD里运行,它的优势是软件间有着密切的工作关系。当在命令行里提示用户时,你能发现一个不同点的例子。在VisualLISP里,你可以使用PROMPT或PRINT语句。在VBA里,你必须使用Prompt方法,这是优化对象的一部分,也是绘制对象的一部分,下面的几行代码将对AutoCAD命令行发出一个提示。第一行为VisualLISP语言;第二行用的是VBA。

(Prompt“\nstarting.”)

thisDrawing.Utility.PromptCh$(10)&“starting”

有两件事显而易见,在VisualLISP里,在命令行窗口中,“\n”使光标跳到新的一行。VBA使用Chr$(10)功能,必需把它放在使用“&”操作符的提示字符串前才可以运行。其次是当类型数量相对实用对象的提示方法接近时,才会使用这个。

在AutoLISP中,可使用PRINT语句,在生成值前,“\n”使顺序转到新的一行开始。PRINT的另一个特点是可以输出任何数据类型,而PROMPT功能只能处理字符串。

在VBA里,对于优化对象的方法和AutoLISP里的“GET×××”函数一样,你必须一直使用字符串。AutoLISP包括几种不同的把你要使用的数据类型转化成字符串型的函数。RTOS把数值型转化成字符串型;ITOA把数值型转化成整数型。VBA提供两个数据转换函数:STR和FORMAT。当转化一个非负数时,STR函数返回一个精确的字符串,即在字符串前加上一个空格。这就是,str(-1.1)返回字符串“-1.1”,str(1.1)结果是“1.1”。FORMAT允许你设立特别的转换格式。对正在学习VBA的人,可利用在线帮助查看有关该函数的帮助,它提供了大量的例子来演示数据是怎样被转化产生的。

衡量的尺度

对于AutoCAD的定制来说,由于AutoLISP语言是以命令的标准建立的,这促进了偏向于支持AutoLISP的尺度。你能使用AutoLISP中带“C:”作为新命令名称的头两个字符的方式来定义函数,该命令就像AutoCAD命令一样使用。“C:”函数被叫做“命令函数”。VBA有宏,你必须从程序管理器里运行宏。从命令提示(或普通的macro菜单)里运行不了宏,这就存在着一个重要问题。用户可以使用AutoLISP启动VBA程序管理,然后以相同的方式执行宏。使用命令行语句时,你应该确信在语句前加了“-”,格式如下:

command“-VBALOAD”“mymacros”“-VBARUN”“mymacro”

如果你未用此负号,将会出现一个对话框,提示用户装载VBA和运行宏。在多数情况下用户并不想出现这个对话框。取而代之的是在命令行装载宏并用一个VBA模块来运行它,这样,首先出现的是在AutoLISP中很强列关注的东西,不再仅仅只是一个倾向。一但一个错误和漏洞发生,就会有其他相关问题出现,这在编程中并不寻常。

另外一点,VBA允许一个经由AutoLISP启动的过程,VBA还有一个反应绘图及同时处理多个图形的优良机制。在VisualLISP里,你能做这些工作,但在VBA里就不是如此容易了。其反应的事物与图形连系在一起,甚至嵌入图形模板中,有多种原因允许你所编程绘制图形。VisualLISP没有一些灵活的运行程序或操作菜单,因此它没有这些能力。VBA与VisualLISP争夺的另一领域为数据种类。VBA的数据种类多于VisualLISP,它包括了一些有用的如Date、Time的数据类型。在VisualLISP里日期和时间是用字符串或是数值存储的。在一张图形里,当你通过系统变量存取系统日期信息时,你会得到纯数字而不是日历天数。

在VBA中操作日期和时间是非常容易的,Format函数可以产生几乎任一种描述的格式,你可以用基本的数值来完成比较和区别。你能以某种自定义的格式存储或操作时间信息,方法简单。我听说顽固的AutoLISP程序员声称VBA不支持表处理而LISP支持,这是事实。但VBA不支持Variants类型,Variants与LISP库中的一些数据种类标志十分相似。Variants允许VBA使用不同类型的数据和结构,但不如LISP中的表处理功能强大。表能存储许多种类型的数据且用几行基于MAPCAR、FOREACH、APPLY的代码就可以快速操作它们。但是这些程序设计体系需要时间去掌握,许多程序设计的新手在使用VBA时,将不会遗漏结构的存取。

坦白的说,表处理进程并不像对象操作那样令人感兴趣。在VBA(和VisualLISP)中你能连接其它系统支持的对象。对程序员而言,ActiveX是面向Windows的一个面向对象的过程到过程的通信编程系统,它允许你的VBA程序运行在AutoCAD里,并且可借用Excel或其它一些支持自动操作的程序。因为Excel支持VBA,所以你能在一个Excel工作表中驱动AutoCAD。当你试着思考它时,多自动进程处理有着某些让人敬畏的潜力。

在下载部分的链接里,你会发现两个程序:

一个是在VBA(带有DVB扩展)里的,另一个在VisualLISP(带有LSP扩展)里,这些函数完成相同的事:他们提示用户输入一些定义一个铣槽的参数,并画出这个铣槽,这个铣槽可以放在任何角落且有一个90°的圆角或一个完整的半圆帽。这些例子表明了VBA与VisualLISP运行程序的风格的几个不同点,或许这就是最明显的产生lightweight多义线的的方法,在VBA里,该对象由一系列点确定,雏形产生后,拐点也相应产生了,VisualLISP的例子简单使用PLINE命令去产生点和弧,因为他们可以从命令行提示中配置。从运行程序这一点而言,VisualLISP版本很容易产生,因为你不必知道任何拐点和他们怎样在多义线中使用,在VisualLISP我用EntMake语句,在一个实体列表中确定拐点,这个版本的基本命令很容易编译代码。如果你更深入地学习,你会发现VisualLISP和VBA是十分平衡的,这个的弱项正是另一个的强项。然而VBA支持一些新的理论,对于AutoLISP程序员而然,他的缺点是把一个简单问题复杂化。在大多数情况下,我倾向于VisualLISP,因为它提供了更多的自由度。对于AutoCAD的定制我有许多经验,但有些时候,根据客户需求,我会用VBA,因为对客户而言,其更容易维护。它提供了一些面向自动生成的模板。我的许多客户在定制AutoCAD时,并没有广博的经验,但他们有Basic语言基础,因为这点,他们使用我推荐的VBA。对于不久将需改变的元素的操作,他们感到很轻松。

上面所有的原因,就是我为什么推荐VisualLISP和VBA二者都学的缘故。话又说回来,这还要依据你所使用的工具而定,学会其一,已可以了,但你会错过向另一个方向发展的时间,这是必然的冲突。第一步,你可能从VBA中学习怎样运行LISP语句或者从VisualLISP中学习运行传统VBA的方法。谁知道下一个将会是什么?

从哪里开始

为了决定先学哪一个语言,让我们做一些自我评价:如果你很好地了解了AutoCAD的命令并希望自动使用它们,那么VisualLISP将是你的首选;如果你不懂AutoCAD,但你是一名知道对象是如何工作的计算机程序员,你可以学习VBA;如果你是一名C++程序员,你可以通过学习VBA而了解对象集是怎么结合在一起的,然后花一点时间学习ObjectARX(一个DLLs结构的C++库,运行于AutoCAD自身相同的内存映像),在这篇文章中没有讨论ObjectARX,是因为你必须使用外部的C++编译器,且必须从Autodesk公司获得开发工具包,而AutoCAD2000中直接配有VisualLISP和VBA编译器。

给想学习AutoCAD的人最后一点建议:

寻找那些有范例的书和杂志。

上网查询这些内容,甚至是例子。VisualLISP和VBA的在线帮助常令初学者感到困惑,因为一些函数从VBA中引证,而另一些从VisualLISP中引证。无论你使用哪一个语言,你都有可能有从其它语言里偶然得到帮助的好机遇,因为它们是相关的。因此我强烈推荐看一本或两本书。你有大量选择的自由,多存些好书。

[编者注:有关这些内容推荐两本好书,BillKramer的《AutoLispTreasureChest》;BillKramer和JohnGibb的《UsingVisualBasicwithAutoCAD》(第二版)]

存在着许多选择,每一个都有其优点。无论你先学什么,在某一时间你应当学习所有的东西,为了去追寻更多的知识,这就意味着要不停的编制程序。BillCramer——有着二十多年的运用CAD/CAM/CAE系统的经验,对于代码的更新,可到下载处下载。

(本文摘录于明经通道 http://www.mjtd.com/Html/Develop/DevBas/108620060627104154.htm
樱花满开
2012年11月30日 11:07:44
2楼
Visual LISP 与 ActiveX/VBA 的比较


以下表格比较了 Visual LISP 函数与类似的 ActiveX®、VBA 和 Visual Basic 6 函数和运算符。“AutoCAD.Application”表示 ActiveX Automation 的等效项。Visual Basic 6 等效项作为函数或运算符列出。
Visual LISP 与 ActiveX/VBA 的比较

AutoLISP 函数
ActiveX、VBA 或 Visual Basic 6 等价对象

+(加)
+(加运算符)

-(减)
-(减运算符)

*(乘)
*(乘运算符)

/(除)
/(除运算符)

=(等于)
=(等于比较运算符)

/=(不等于)
<>(不等于比较运算符)

<(小于)
<(小于比较运算符)

<=(小于或等于)
<=(小于等于比较运算符)

/=(不等于)
<>(不等于比较运算符)

>(大于)
>(大于比较运算符)

>= (大于或
等于)
>=(大于等于比较运算符)

~(按位取反)
非运算符

1+(递增)
使用 +(加运算符)

1-(递减)
使用 -(减运算符)

abs
Abs 函数

acad_colordlg
未提供

acad_helpdlg
在联机帮助索引中搜索 HELP

acad_strlsort
在联机帮助索引中搜索 SORT

action_tile
使用对话框编辑器

add_list
使用对话框编辑器

ads
AutoCAD.Application.ListADS 方法

alert
MsgBox 函数

and
与运算符

angle
AutoCAD.Application.ActiveDocument.Utility.
AngleFromXAxis 方法

angtof
AutoCAD.Application.ActiveDocument.Utility.AngleToReal 方法

angtos
AutoCAD.Application.ActiveDocument.Utility.
AngleToString 方法

append
使用数组操作函数

apply
未提供

arx
AutoCAD.Application.ListARX 方法

arxload
AutoCAD.Application.LoadARX 方法

arxunload
AutoCAD.Application.UnloadARX 方法

ascii
Asc 函数

assoc
未提供

atan
Atn 函数

atof
CDbl 函数

atoi
CInt 函数

atom
在联机帮助索引中搜索 IS

atoms-family
未提供

autoarxload
未提供

autoload
未提供

Boole
使用逻辑运算符

boundp
在联机帮助索引中搜索 IS

car/cdr
使用数组操作函数

chr
Chr 函数

client_data_tile
使用对话框编辑器

close
AutoCAD.Application.Documents.Close 方法

command
AutoCAD.ActiveDocument.SendCommand 方法

cond
Select Case 语句

cons
使用数组操作函数或 AutoCAD.Application.collection.Add <图元名称> 方法

cos
Cos 函数

cvunit
使用转换函数

defun
关键字函数和 End 函数

dictadd
AutoCAD.Application.ActiveDocument.Dictionaries.Add 方法

dictnext
AutoCAD.Application.ActiveDocument.Dictionaries.Item 方法

dictremove
AutoCAD.Application.ActiveDocument.Dictionaries.
Dictionary.Delete 方法

dictrename
AutoCAD.Application.ActiveDocument.Dictionaries.
Dictionary.Rename 方法

dictsearch
AutoCAD.Application.ActiveDocument.Dictionaries.
Dictionary.GetName 和 GetObject 方法

dimx_tile 和 dimy_tile
使用对话框编辑器

distance
AutoCAD.Application.Utility.GetDistance,用于交互式方法。

distof
未提供

done_dialog
使用对话框编辑器

end_image
使用对话框编辑器

end_list
使用对话框编辑器

entdel
AutoCAD.Application.ActiveDocument.collection_object.
Delete 方法

entget
AutoCAD.Application.ActiveDocument.collection_object.
property 特性

entlast
AutoCAD.Application.ActiveDocument.Modelspace.
Item(总数 - 1)

entmake
AutoCAD.Application.ActiveDocument.Modelspace.
Add <图元名称> 方法

entmakex
AutoCAD.Application.ActiveDocument.Modelspace.
Add <图元名称> 方法

entmod
使用对象的任何读写特性

entnext
AutoCAD.Application.ActiveDocument.collection.Item 方法

entsel
AutoCAD.Application.ActiveDocument.SelectionSets 对象/方法/特性

entupd
AutoCAD.Application.ActiveDocument.Modelspace.object.
Update 方法

eq
未提供

equal
Eqv 运算符

*error*
Error 对象/方法/特性

eval
未提供

exit
AutoCAD.Application.Quit 方法

exp
Exp 函数

expand
未提供

expt
^(指数运算符)

fill_image
使用对话框编辑器

findfile
Dir 函数

fix
Fix、Int、Cint 函数

float
CDbl 函数

foreach
For Each...Next 语句

gc
AutoCAD.Application.ActiveDocument.PurgeAll

gcd
未提供

get_attr
使用对话框编辑器

get_tile
使用对话框编辑器

getangle
AutoCAD.Application.ActiveDocument.Utility.GetAngle 方法

getcfg
AutoCAD.Application.Preferences.property 特性

getcname
未提供

getcorner
AutoCAD.Application.ActiveDocument.Utility.GetCorner 方法

getdist
AutoCAD.Application.ActiveDocument.Utility.GetDistance 方法

getenv
AutoCAD.Application.Preferences.property 特性

getfiled
使用文件对话框

getint
AutoCAD.Application.ActiveDocument.Utility.GetInteger 方法

getkword
AutoCAD.Application.ActiveDocument.Utility.GetKeyword 方法

getorient
AutoCAD.Application.ActiveDocument.Utility.
GetOrientation 方法

getpoint
AutoCAD.Application.ActiveDocument.Utility.GetPoint 方法

getreal
AutoCAD.Application.ActiveDocument.Utility.GetReal 方法

getstring
AutoCAD.Application.ActiveDocument.Utility.GetString 方法

getvar
AutoCAD.Application.GetVariable 方法

graphscr
AppActivate AutoCAD.Application.Caption

grclear
Obsolete 函数

grdraw
未提供

grread
未提供

grtext
AutoCAD.Application.ActiveDocument.Utility.Prompt

grvecs
未提供

handent
AutoCAD.Application.ActiveDocument.ModelSpace.object.
Handle 特性

help
在联机帮助索引中搜索 HELP

if
If… Then… Else 语句

initget
AutoCAD.Application.ActiveDocument.Utility.
InitializeUserInput

inters
AutoCAD.Application.ActiveDocument.Modelspace.object.
IntersectWith

itoa
Str 函数

lambda
未提供

last
arrayname(UBound(arrayname))

length
UBound 函数

list
ReDim 语句

listp
IsArray 函数

load_dialog
使用对话框编辑器

load
Automation 不支持 AutoLISP

log
Log 函数

logand
And 函数

logior
Or 函数

lsh
Imp 函数

mapcar
未提供

max
Max 函数

mem
未提供

member
使用集合

menucmd
AutoCAD.Application.MenuBar 对象

menugroup
AutoCAD.Application.MenuGroup 对象

min
Min 函数

minusp
使用 < 0 语法

mode_tile
使用对话框编辑器

namedobjdict
AutoCAD.Application.ActiveDocument.Dictionaries 集合

nentsel
AutoCAD.Application.ActiveDocument.SelectionSets.
SelectionSet.SelectAtPoint 方法

nentselp
AutoCAD.Application.ActiveDocument.SelectionSets.
SelectionSet.SelectAtPoint 方法

new_dialog
使用对话框编辑器

not
使用逻辑运算符

nth
使用 object(n) 语法

null
IsNull 函数

numberp
TypeName 函数

open
Open 函数

or
使用逻辑运算符

osnap
未提供(用户可以使用 SetVariable 方法控制 OSMODE 系统变量。)

polar
AutoCAD.Application.ActiveDocument.Utility.PolarPoint 方法

prin1
AutoCAD.Application.ActiveDocument.Utility.Prompt

princ
AutoCAD.Application.ActiveDocument.Utility.Prompt

print
AutoCAD.Application.ActiveDocument.Utility.Prompt

progn
未提供

prompt
AutoCAD.Application.ActiveDocument.Utility.Prompt

quit
AutoCAD.Application.Quit 方法

quote
未提供

read
未提供

read-char
Input 函数

read-line
行输入函数

redraw
AutoCAD.Application.ActiveDocument.Modelspace.object.
Update 方法

regapp
AutoCAD.Application.ActiveDocument.
RegisteredApplications.Add 方法

rem
Mod 函数

repeat
For… Each, While,

reverse
未提供

rtos
AutoCAD.Application.ActiveDocument.Utility.RealToString 方法

set
Set 函数

set_tile
使用对话框编辑器

setcfg
AutoCAD.Application.Preferences.property 特性

setfunhelp
未提供

setq
Set 函数

setvar
AutoCAD.Application.SetVariable 方法

sin
Sin 函数

setview
AutoCAD.Application.ActiveDocument.Viewports.Viewport.
SetView 方法

slide_image
使用对话框编辑器

snvalid
未提供

sqrt
Sqr 函数

ssadd
AutoCAD.Application.ActiveDocument.SelectionSets.Add 方法

ssdel
AutoCAD.Application.ActiveDocument.SelectionSets.
SelectionSet.Delete 方法

ssget
AutoCAD.Application.ActiveDocument.SelectionSets.
SelectionSet.SelectOnScreen 方法

ssgetfirst
未提供

sslength
AutoCAD.Application.ActiveDocument.SelectionSets.
SelectionSet.Count 方法

ssmemb
比较对象的 ID 和 SelectionSet 成员

ssname
AutoCAD.Application.ActiveDocument.SelectionSets.
SelectionSet.Name 特性

ssnamex
未提供

sssetfirst
AutoCAD.Application.ActiveDocument.PickfirstSelectionSet

startapp
Shell 函数

start_dialog
使用对话框编辑器

start_image
使用对话框编辑器

start_list
使用对话框编辑器

strcase
StrConv 函数

strcat
& 运算符

strlen
Len 函数

subst
未提供

substr
Mid 函数

tablet
未提供

tblnext
AutoCAD.Application.ActiveDocument.collection_object.
Item 方法

tblobjname
AutoCAD.Application.ActiveDocument.collection_object.
Name 方法

tblsearch
AutoCAD.Application.ActiveDocument.collection_object.
Name 方法

term_dialog
使用对话框编辑器

terpri
未提供

textbox
AutoCAD.Application.ActiveDocument.space.object.
GetBoundingBox 方法

textpage
未提供

textscr
未提供

trace
未提供

trans
AutoCAD.Application.ActiveDocument.Utility.
TranslateCoordinates 方法

type
TypeName 函数

unload_dialog
使用对话框编辑器

untrace
未提供

vector_image
使用对话框编辑器

ver
AutoCAD.Application.Version 特性

vports
AutoCAD.Application.ActiveDocument.Viewports 集合

wcmatch
Like 运算符

while
While… Wend

write-char
Print 函数

write-line
Print 函数

xdroom
未提供

xdsize
未提供

zerop
使用 = 0 语法
回复
nobodyfield
2013年02月17日 14:54:18
3楼
感觉好厉害的:lol
回复
a56846390
2013年03月21日 17:16:49
4楼
抢个沙发 哈哈啊哈哈
回复
dinglinbmw
2015年01月07日 11:11:14
5楼
很好,
有帮助
回复
安穆明weibo
2016年01月26日 17:09:58
6楼
网站元老的头衔,把我吓到了。多多向前辈们学习~~
回复
安穆明weibo
2016年01月26日 17:10:32
7楼
网站元老的头衔,把我吓到了。多多向前辈们学习~~
回复
cym12345678900
2016年01月29日 11:38:47
8楼
网站元老的头衔,把我吓到了。多多向前辈们学习~~
回复
摩斯菲尔
2016年08月25日 11:04:21
9楼
又是掉头发的东西,CAD真难
回复

相关推荐

APP内打开