0% found this document useful (0 votes)
152 views

Using A VB ActiveX DLL From Visual LISP

The document discusses how to create a user interface module in Visual Basic that can be called from Visual LISP or VBA. It provides steps to create an ActiveX DLL using Visual Basic that exposes functions callable from Visual LISP and VBA. The document also discusses how to debug the ActiveX DLL while it is being used from Visual LISP.

Uploaded by

ecobo243075
Copyright
© © All Rights Reserved
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
152 views

Using A VB ActiveX DLL From Visual LISP

The document discusses how to create a user interface module in Visual Basic that can be called from Visual LISP or VBA. It provides steps to create an ActiveX DLL using Visual Basic that exposes functions callable from Visual LISP and VBA. The document also discusses how to debug the ActiveX DLL while it is being used from Visual LISP.

Uploaded by

ecobo243075
Copyright
© © All Rights Reserved
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 4

Using a VB ActiveX DLL from Visual LISP or VBA

Published date: 2005-03-11


Applies to:

ID: TS15992

AutoCAD 2005 AutoCAD 2004 AutoCAD 2002

Issue
How can I create a user-interface module in Visual Basic that can also be easily called from Visual LISP or VBA?
Solution
The simplest and most efficient way is to write an in-process Automation client of AutoCAD, such as a VB
ActiveX DLL. This DLL can then be loaded from Visual LISP, VBA, Java (via Automation) and ObjectARX. The
DLL may be an Automation client of AutoCAD, or any other Automation server, or of multiple servers.
Using Visual Basic 6:
1. Start Visual Basic.
2. Select "ActiveX DLL" in the New Project Wizard.
3. Change the project's "name" property to "MyProject".
4. There is a default class module in the project, change its "name" property
to "MyClass1".
5. Add a function or sub-routine to the class module such as:

' This function takes three arguments, and will


' return an array of data to the calling function
Public Function MyFn(ByRef arg1 As Integer, ByRef arg2 As String, ByRef arg3 As Double) As
Variant
Dim MyForm1 As New MyForm1
'Populate textboxes with passed-in values
MyForm1.TextBox1.Text = arg1
MyForm1.TextBox2.Text = arg2
MyForm1.TextBox3.Text = arg3
MyForm1.Show vbModal

' Create an array of items to return to the caller


Dim MyArray(2) As Variant
MyArray(0) = CInt(MyForm1.TextBox1.Text)
MyArray(1) = MyForm1.TextBox2.Text
MyArray(2) = CDbl(MyForm1.TextBox3.Text)
MyFn = MyArray
End Function
(Where MyForm1 is a form you are adding to the project. Be aware that this just as well could be a function,
which returns a value or a list of values to the calling process).
6. Add a Form to the project. Change its name to "MyForm1".
7. Add three TextBox controls to the Form.
8. Add a Button control which, when clicked, will hide the Form:

Private Sub Command1_Click()


Me.Hide
End Sub

9. Select File -> Make MyProject.dll. This creates the DLL and registers it with COM. (You'll need to ensure that
the DLL is registered on any other computers you want to run this on. That's usually handled by creating a setup
package for your DLL with Visual Basic.)
10. If you want to use the DLL from Visual LISP, simply create a function such as
the following, and load it into AutoCAD:

(defun showDialog (/ acadApp vbApp retVal retList)


(vl-load-com)
;; get the main AutoCAD application object
(setq acadApp (vlax-get-acad-object))
;; load VB ActiveX DLL into AutoCAD's address space
(setq vbApp (vla-GetInterfaceObject acadApp "MyProject.MyClass1"))
(if (not vbApp)
(princ "\nError loading ActiveX DLL.")
(vlax-invoke vbApp "MyFn"
7
; arg1, an integer
"Arbitrary string" ; arg2, a string
1.5
; arg3, a 'double'
)
)
)

To call the exposed function, type (showDialog) at the command line:


This will return the following list to AutoCAD:
(7 "Arbitrary string" 1.5)
You can see that you can pass arguments to the VB dialog function and also process return values back in
AutoCAD. This is particularly useful for creating options dialogs, as these settings need to be initialized and the
modified values need to be returned.
11. If you want to use this DLL from VBA, add a reference to this DLL (registering it with COM should add it to the
list of ActiveX servers available from VBA, otherwise just browse and select MyProject.dll).
12. Use the following mechanism to load the DLL in-process, and call the function (the values are returned in an
array):

Sub MyVBAProject()
Dim oMyApp As New MyClass1
Dim vReturn As Variant
Set oMyApp = ThisDrawing.Application.GetInterfaceObject("MyProject.MyClass1")
'Call function w/three arguments
vReturn = oMyApp.MyFn(7, "Arbitrary string", 1.5)
'Display values returned by function
MsgBox "Integer: " & CStr(vReturn(0)) & vbCr _
& "String: " & vReturn(1) & vbCr _
& "Double: " & CStr(vReturn(2)), _
vbOKOnly, "Returned values"
End Sub

If you watch the vReturn variable after the call to MyFn, you will see that it contains the same values as seen in
AutoLISP.
Using Visual Studio .Net:
It is also possible to do this with a Visual Basic Class Library, with some minor changes.
1. Start Visual Studio .Net.
2. Select "VisualBasic Projects" and "Class Library" in the New Project Wizard.
3. Change the project's "name" property to "MyProject".
4. There is a default class module in the project, change its "name" property
to "MyClass1".
5. Add a function or sub-routine to the class module such as:

Public Class MyClass1

' This function takes three arguments, and will


' return an array of data to the calling function

' Note: In VB.NET, the function now must return a type Object instead of
Variant.

Public Function MyFn(ByRef arg1 As Integer, ByRef arg2 As String, ByRef arg3 As
Double) As Object
Dim MyForm1 As New MyForm1()
'Populate textboxes with passed-in values
MyForm1.TextBox1.Text = arg1
MyForm1.TextBox2.Text = arg2
MyForm1.TextBox3.Text = arg3
MyForm1.ShowDialog()

' Create an array of items to return to the caller


Dim MyArray(2) As Object
MyArray.SetValue(CInt(MyForm1.TextBox1.Text), 0)
MyArray.SetValue(MyForm1.TextBox2.Text, 1)
MyArray.SetValue(CDbl(MyForm1.TextBox3.Text), 2)
Return MyArray
End Function

End Class
6. Perform steps 6 through 8 above.
7. In your project's Property Pages, go to Configuration Properties -> Build.
Check the box labeled "Register for COM Interop". Click "OK".
If you want to use this .NET DLL from VBA, add a reference to the .tlb file.
(MyProject.tlb).

Unloading and debugging ActiveX dlls from visual LISP


Published date: 2005-01-27
ID: TS34023
Applies to:
AutoCAD 2005
AutoCAD 2004
AutoCAD 2002
Issue
I am using a Visual Basic ActiveX DLL from Visual LISP, but when I rebuild it,
VB denies permission to do this. I have to close AutoCAD so that I can rebuild
the DLL. I am using (vla-GetInterfaceObject) to load the COM server. WHy does
this occur?
Solution
You are not releasing the DLL from memory. You need to call (vlax-releaseobject)
with the ActiveX object variable to release the DLL. This decrements the
reference count for the COM server, and should allow unloading. To use more
functionality in the DLL, you will have to reload it, of course.
An alternative method to debug ActiveX DLLs is to change the project settings.
Select Project->Properties in VB, then select the Debugging tab. Make sure that
the radio button "Wait for components to be created" is selected.
Now when you select Run->Start in VB, it will wait for a call to be made to load
the DLL (such as (vla-GetInterfaceObject acadApp "MyProject.MyClass")). You will
be able to set breakpoints in your DLL, which will break when the corresponding
methods are called from Visual LISP. You will be able to modify the DLL code
much more freely using this approach.
Note that when you stop execution from VB, it will ask the following question if
Visual LISP still has a reference to the DLL: "Other applications are currently
accessing an object in your program. Ending the program now could cause errors
in those programs. End at this time?" If you choose Yes, then any Visual LISP
variables referring to the DLL will be invalid. In addition, if you are calling
functionality in the DLL from Visual LISP, then Visual LISP will report a
message such as: "; error: MyProject: Application-defined or object-defined
error". You should be able to restart the debugging without having to close
AutoCAD.

You might also like