- UID
- 76071
- 积分
- 1505
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2003-8-30
- 最后登录
- 1970-1-1
|
楼主 |
发表于 2004-6-3 21:15:03
|
显示全部楼层
问:我已经写了一个VisualLisp函数和一个VBA宏。这个VBA宏显示一个对话框,并且有一些按钮允许有用户输入(例如:输入一个字符串)。现在我从VisualLisp用(vl-vbarun)调用这个VBA宏。当AutoCAD执行到这一行时,LISP停在这一行。但是一旦我在此宏中使用了一个用户输入函数,LISP就不等VBA对话框出现,而继续执行下面的LISP函数。有些时候甚至首先执行LISP的输入函数,然后再执行VBA宏中的输入语句。怎样才能使我的LISP函数和VBA宏同步?
答:现在只有一个解决办法。在你的LISP函数中(vl-vbarun)
函数必须最后调用。当关闭VBA对话框或者从VBA宏中返回时,你得调用另一个你想继续执行的LISP函数。你可以象下面这样做。
首先:你需要一个LISP函数调用这个VBA宏:
(defun c:test ()
;; Call a VBA macro which displays
;; a dialog and writes a file.
(vl-vbarun "test")
;;If you uncomment the following line, then AutoCAD will prompt you
;;to select an entity first, input a string second.
;;(entsel)
(princ)
)
然后你需要第二个LISP函数以供你的VBA宏返回时调用:
(defun c:test_cont ()
;; Here you can continue.
(print “ I am continuing.”)
(princ)
)
以下是这个VBA宏的示例:
Sub test()
' Show a dialog which uses some
' user input functions.
UserForm1.Show
' Call the lisp function which should
' be now executed.
' You can use the SendCommand method:
' ThisDrawing.SendCommand ("test_cont ")
' or use the ActiveX interface of VisualLisp:
' In order to use it, please remember to reference vl.tlb file which is in
Acad2000 folder
' into your VBA project and execute (vl-load-com) on the AutoCAD command
line first.
Dim vl As Object
Set vl = CreateObject("VL.Application.1")
vl.ActiveDocument.functions.Item("c:test_cont").funcall
End Sub
问:怎样用Visual Basic生成一个用户接口模块以供Visual LISP方便地调用?
答:最简单和最有效的方法是为AutoCAD写一个内过程(in-process)的自动客户(Automation Client)。例如:一个VB
ActiveX DLL。这个DLL 以后可以从 Visual LISP, VBA, Java
(通过Automation)和ObjectARX加载。它可以是一个AutoCAD的自动客户,也可以是一个任何的自动服务器( Automation
server),或者多重服务器。
1. 启动Visual Basic 5 or 6;
2. 在New Project Wizard中选择ActiveX DLL;
3. 把工程名改为"MyProject";
4. 在工程中有一个缺省的类模块,把它的名称改为"MyClass";
5. 添加一个函数或者子例程到类模块中。例如:
' This function takes two arguments, and will return a list of data to the
calling function
Public function MyFn(ByRef arg1 as Integer, ByRef arg2 as Double) As
Variant
myForm.Show vbModal
' Create a list of items to return to the caller (the items are in this
case purely arbitrary)
MyFn = Array(1.0,"Arbitrary string",2)
End function
(这里,myForm是一个你必须添加到工程中的表格。同时切记MyFn是一个函数,它将返回一个值或者一组值给调用例程。)
6. 点取File -> Make
MyProject.dll。这就会生成一个DLL并且把它注册为COM。(如果你想在其他机器上运行此DLL,你需要首先确认在所有的机器上安装并注册了这个DLL。这通常需要你用Visual
Basic生成一个安装包。)
7. 如果你想从Visual LISP中使用此DLL,你需要定义一个简单的函数,并且把他加载到AutoCAD中:
(defun showDialog (/ acadApp vbApp retVal retList)
;; required in AutoCAD 2000, not R14
(if (car (atoms-family 1 '("vl-load-com"))) (vl-load-com))
;; get the main AutoCAD application object
(setq acadApp (vlax-get-acad-object))
;; load VB ActiveX DLL into AutoCAD's address space (either line will
work)
;;(setq vbApp (vlax-invoke acadApp "GetInterfaceObject"
"MyProject.MyClass")
(setq vbApp (vla-GetInterfaceObject acadApp "MyProject.MyClass"))
(if (not vbApp)
(princ "\nError loading ActiveX DLL.")
(vlax-invoke vbApp "MyFn"
7 ; arg1, an integer
1.5 ; arg2, a 'double'
)
)
)
为了调用已经暴露出的ActiveX方法,在命令行上输入:
(showDialog)
将把下列内容返回给AutoCAD:
(1.0 "Arbitrary string" 2)
你会发现你可以给VB对话框传递参数并且在AutoCAD中处理返回值。这对于生成选项对话框非常有用,因为有些参数需要初始化并且修改后的值需要返回给AutoCAD。
7. 如果你想从VBA使用这个DLL,你需要把此DLL添加到引用中。(用COM注册它,就会把它添加到ActiveX
服务器的列表中。然后它就可以被VBA引用,不然就请浏览并且选择MyProject.dll。)
8. 然后你就可以用下面的机制加载这个内过程 ActiveX DLL,并且调用其中的函数:
Sub MyVBAProject()
Dim oMyApp as Object
dim vReturn as Variant
set oMyApp = ThisDrawing.Application.GetInterfaceObject(
"MyProject.MyClass"
)
vReturn = oMyApp.MyFn(7,1.5)
End Sub
问:可以在VBA中获得带有预览图象的AutoCAD "Open File Dialog"对话框吗?
答:在VBA没有直接的方法这样做。但是,你可以通过LISP和AutoCAD之间的通讯来完成。在LISP中有一个名叫getfiled的函数,它可以预览DWG并且与AutoCAD的"Open
File Dialog"表现一样。
首先,通过SendCommand方法发送getfiled表达式给AutoCAD命令行并且定义一个系统变量USERS1以保存文件名。然后,你可以用GetVariable方法获得这个系统变量。最后,象使用其它任何变量一样使用它。
Public Sub OpenDialog()
Dim fileName As String
ThisDrawing.SendCommand "(setvar " & """users1""" & "(getfiled " &
"""Select a DWG File""" & """c:/program files/acad2000/""" & """dwg""" &
"8)) "
fileName = ThisDrawing.GetVariable("users1")
MsgBox "You have selected " & fileName & "!!!", , "File Message"
End Sub |
|