- 积分
- 24557
- 明经币
- 个
- 注册时间
- 2004-3-17
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
楼主 |
发表于 2004-5-11 10:19:00
|
显示全部楼层
问:我已经写了一个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
|
|