The AutoCAD API's When and Why
Written
by Andrew Canfield
There
are three major API's with which you can extend AutoCAD. They are
respectively: a C/C++ api called objectARX, a VB/VBA api, and an
AutoLisp/VisualLisp api. Every developer has their favorite but all
partiality aside people often wonder which is better, which should I
use? The answer to those questions is: "It depends on what you need
to accomplish". Each API has different things, which make it better
in given situations. When deciding on which API to use there are 4
things you need to ask yourself. What language am I most comfortable in?
How much time do I have? Who is the target user and how much AutoCAD
experience do they have? How much control over AutoCAD and possibly
Windows do I need to accomplish the task quickly? After I address some
of the functionality of the different API's you will see why these are
relevant. I am only going to deal with these API's as they apply
internally to AutoCAD not as stand alone applications.
The objectARX API:
Out of the three API's this one has the most control over AutoCAD and
Windows. You can register its commands with AutoCAD. The user needs to
know very little about AutoCAD to run your program. The drawbacks to it
are it takes longer to develop in it for most developers than VBA or
Lisp, and often it is overkill especially for simple drafting tools. To
get anything done in this API you should already be very familiar with C
and C++. On a personal level this API is my favorite but that is because
I do 99% of all my development in C and C++ so when I do something for
AutoCAD it's easier for me not to have to switch languages. For me it
falls into the category of "what language am I most comfortable
with?". There are things within AutoCAD that this API can access
that the other API's cannot. This is the major reason for most
developers who use this API. They need to do something and it literally
cannot be done using the other two API's. This is also the only API to
which you can secure your code from having others read and copy your
source. If you need to develop custom objects, work with spatial
filtering, expose functionality to an application using another API, are
developing third party tools for sale, or a host of other things to
which VBA and Lisp cannot access without great difficulty or at all then
this is the API you should use.
The VBA API:
If this is your first time extending the functionality of AutoCAD than
this is most likely the API for you. This API is very friendly towards
new developers. The Visual Basic language reads in such a way that many
times new developers can work out simple questions by just reading the
names of the functions. This API does not have as much access to AutoCAD
as the C++ or Lisp API's do however you can construct and execute Lisp
commands to give yourself access to the few things that Lisp can do
which VBA cannot natively. If you are very good with VBA you can
subclass the AutoCAD command line and then there really isn't anything
Lisp has access to which you wouldn't using VBA. The major drawback to
the VBA API is that it doesn't natively register your functionality with
AutoCAD. It must first be loaded as a dvb in any of the various ways you
can load applications into AutoCAD and then executed via the tools menu
or by a custom button or menu item. Depending on your user base this can
be a big issue. I have worked on contracts where the drafters are all
used to commands and don't want to use anything else. In this case VBA
can be a difficult sell. If the user group isn't that stuck in there
ways then VBA is usually a very easy sell. Especially after they see how
fast you can create tools with it. As with Lisp this is primarily an
internal developer's tool to extend AutoCAD within your company, or if
you have been contracted to work on site to write custom tools. Out of
all the API's this is the one, which can create applications the most
quickly especially applications, which require graphic dialogs. It also
has the most support from AutoDesk.
The Lisp API:
When I am speaking of Lisp I am specifically referring to AutoLisp and
VisualLisp I am not talking about ANSI Common Lisp. First a quick
description of AutoLisp. "AutoLisp: it combines the RAD features of
iX86 with the flexibility of COBOL". All kidding aside the major
reason the Lisp API gets used is because for many developers it
satisfies the question "What language am I most comfortable
in?". For many people this is where they started and it is what
they are fastest developing in. Another reason to use this API is, if
the environment in which you work has large legacy libraries of Lisp
routines. Lisp is harder than VBA to learn yet still far easier than C
or C++. Until AutoCAD 2000, VBA was not very well implemented inside of
AutoCAD and left a great deal to be desired. Lisp was the primary choice
for rapid in house development of macro's. Large libraries of Lisp
functions exist in many places. Re-writing these in VBA is often not
cost effective in the short term. If this is the case then Lisp is the
tool for you and may God have mercy upon your soul. Kidding sort of.
There are some very serious downsides to using Lisp so if you are new to
developing for AutoCAD or need to interface your functionality with any
other Windows programs or the Windows operating system you may want to
look into VBA instead. On the upside if you are interfacing with a
program written for the objectARX API it is a lot easier for the
objectARX developer to expose their functionality to Lisp than VBA but a
good developer should be able to do either so it really depends on who
is writing the C++ side of things as to which they expose their
functionality to.
Here is a simple
checklist for determining which API may be right for your project:
ObjectARX:
-
You are most
comfortable working in C or C++
-
You need the absolute
maximum amount of control over AutoCAD and Windows
-
You need to write
custom objects
-
You need access to
things which are not exposed to VBA or Lisp
-
You require more
speed than can be had using VBA or Lisp
-
Your workplace
requires applications be developed in C or C++
-
You need to use
libraries external to AutoCAD which are only available to C or C++
VBA:
-
You are most
comfortable working in VBA
-
You need to use a
dialogs
-
You need to interface
with Windows or one of the Microsoft office programs like Excel
-
You are new to
developing for AutoCAD or are new to developing period
-
You require maximum
speed of development time yet are not overly worried about
application speed
-
You know you are
going to need a lot of help from Autodesk getting your application
written
Lisp:
-
The world ended and
there are no other tools available
-
You are most
comfortable working in Lisp
-
You are working with
an AutoCAD version prior to 2000
-
You are working in
one of those gray areas in AutoCAD where Lisp can do something that
would require a huge amount of VB knowledge to accomplish the same
thing.
-
Your workplace
requires it
-
Your workplace may
need to interface existing Lisp libraries with your tool
-
You enjoy pain
-
You don't need any
dialogs or graphical user interaction other than the command
line/screen pics in your application
-
Parens make you happy
(oh look here come the men in white coats for you now)
Now I will provide what
you all come here for really. Free code. Yes, that's right we know
that's why you really read this stuff isn't it. So since you suffered
through the above I suppose I shall have to reward you with free code so
that you come back. In each of the three API's I show a way to edit the
first editable attribute in a block reference. The use of
"command" will not be seen here as that is a huge pet peeve of
mine. If you are using "command" you are not programming you
are scripting and they are two completely separate things.
ObjectARX:
void chngAtt()
{
ads_name entres;
ads_point ptres;
AcDbObjectId _Id, _attId;
AcDbObjectIterator *pIttr = NULL;
if(acedEntSel("Select a Block Reference", entres, ptres) != RTNORM )
{
//Selection failed
return;
}
acdbGetObjectId(_Id, entres);
AcDbObjectPointer pRef(_Id,AcDb::kForRead);
if(pRef.openStatus()!=Acad::eOk)
{
//Open failed
return;
}
pIttr = pRef->attributeIterator();
while(!pIttr->done())
{
_attId = pIttr->objectId();
AcDbObjectPointer pAtt(_attId,AcDb::kForWrite);
if(pAtt.openStatus()==Acad::eOk)
{
pAtt->setTextString("We changed this");
break;
}
pIttr->step();
}
delete pIttr;
}
|
VBA:
Option Explicit
Sub chngAtt()
Dim objEnt As AcadObject
Dim objRef As AcadBlockReference
Dim varAtts As Variant
Dim objAtt As AcadAttributeReference
Dim emptyPt As Variant
ThisDrawing.Utility.GetEntity objEnt, emptyPt, "Select Block: "
If objEnt.ObjectName = "AcDbBlockReference" Then
Set objRef = objEnt
If objRef.HasAttributes Then
varAtts = objRef.GetAttributes
Set objAtt = varAtts(0)
objAtt.TextString = "We changed this"
End If
End If
End Sub
|
Lisp:
(defun C:chngAtt ()
(setq Mainent (entsel))
(setq entList (entget (car Mainent)))
(setq entAtt (entget (entnext (cdr (assoc -1 entList)))))
(setq entNewAttVal
(subst (cons 1 "We changed this") (assoc 1 entAtt) entAtt)
)
(entmod entNewAttVal)
(entupd (car Mainent))
(princ)
)
|
|