Home > Articles

Writing AutoCAD Macros with VBA

Microsoft's Component Object Model (COM) is the mechanism that allows AutoCAD to communicate with other applications using ActiveX Automation interfaces. Learn how to design macros that operate entirely within AutoCAD or share information and processes with other programs as either client or server applications.
This chapter is from the book

All consistent axiomatic formulations of number theory include undecidable propositions. — Kurt Gödel

It is fitting, I suppose, that having begun my professional life as an architect, I continue to look for the elegance of structural details. Later in this book you will find this predilection reflected in examples demonstrating the use of AutoCAD objects. Buckminster Fuller's vector equilibrium, a deceptively simple structure defined by the close packing of spheres, is almost infinitely scalable in the form of the geodesic dome. In Chapter 9 we use it to demonstrate AutoCAD's PolyfaceMesh entity.

In his book Gödel, Escher, Bach: An Eternal Golden Braid, Douglas Hofstadter discusses metamathematics in relation to music, visual art, and computer programming. The common thread in his dialogues is that understanding such systems generally requires jumping out of them in order to view them from a higher level. This is suggestive of an ancient model of creation, in which this world of action is contained within another, that of formation. AutoCAD's object model is built upon a similar and ingenious organizational foundation, the Component Object Model (COM). In the domain that is the subject of this book, the center of that next-higher shell has the appropriate name IUnknown.

The development of integrated solutions in Visual Basic and VBA depends on COM. The AutoCAD 2002 object model is constructed according to the rules of COM, which provides the shell in which it operates. A short course in COM may not be what you signed on for here, but understanding its basic concepts is important if you really want to take control of AutoCAD and make it work with other applications. Its fundamentals are simpler than you might imagine.

Components and Automation

COM establishes a standardized means by which one piece of software can call upon another for services. A server application shares its objects with other applications. Conversely, a program that uses other applications' objects is called a client application. This sharing of objects is accomplished through the COM technology known as Automation.

As Figure 1-1 illustrates, AutoCAD and Excel can fill the role of either client or server in VBA. The client application is the one that is launched by the user, which then calls upon the objects in the server application through COM interfaces. The components from both object models are then executed in-process with the client application. We will see examples of both configurations in later chapters.

Figure 1-1Figure 1-1 COM Automation

By contrast, a Visual Basic application executes in its own memory space but calls upon the object models of other applications through the same COM interfaces. This is not to say that a VBA procedure cannot access more than one server application. It can. But a VB application runs independently, out-of-process, as an EXE program. In either case the actual components are located in dynamic link libraries (DLLs) or ActiveX controls.

Since the focus of this book is on AutoCAD VBA macros, most of the examples we present are written in that context. Later in this chapter, though, we look at a short VB program that passes information from Excel into AutoCAD without either application ever being visible. First, however, let's delve a little more deeply into COM.

The Foundation

To understand how Automation works, we need to look above the AutoCAD object model (which is the subject of Chapter 4) to see how COM-enabled applications communicate.

Characteristics of Objects

First, what is an Object? Objects are fundamentally regions of computer memory. A particular object is a specific region of memory with a name, a defined set of code and data (the object's attributes), and an interface. Each object is an instance, a specific occurrence of a (general) class. When an object is created, it is said to be instantiated from its class. Each object in C++, the language in which AutoCAD itself is now written, supports a single interface with a single set of methods. A COM object, on the other hand, has multiple interfaces, each set of which is identified by a different Class.

We speak of computer languages as being object-oriented. In addition to creating objects made up of methods and data, then organizing them according to classes, object orientation requires that three additional characteristics be present. Inheritance is one of them. COM objects support interface inheritance, which allows a child object to build on the features of the parent object, making them specific. In AutoCAD, for example, a Line is a special case of an Entity. But there is more to this hierarchy, as we shall see momentarily.

The second characteristic, polymorphism, allows a single object to appear in different guises at different times. COM allows Visual Basic objects to implement multiple interfaces, thus an Entity can be a Line, or it can be a Circle, or it can be a PolyfaceMesh! Moreover, COM provides for the evolution of software applications so that new functionality can be introduced without breaking old code.

The third defining characteristic of objects is encapsulation. The only way to access an object is through its methods, properties, or events. Methods are actions that you can tell the object to perform. Properties are characteristics that an object possesses, some of which you can set or modify. Events occur when an object changes its state, and you can create code that will execute when triggered by a specific event. The object's internal operation, however, is always concealed from the user in order to protect the object's data from being modified either accidentally or by design. (Visual Basic and VBA modules themselves implement another kind of encapsulation by defining procedures as being either public or private.)

Classes and Interfaces

But what, then, is a Class? A Class is a user-defined data type, an aggregation of standard data types (byte, double, string, etc.) used together for a specific purpose. COM classes are the means of defining interfaces with objects, complete with their own methods, properties, and events. An object's class defines whether the object is public and in what circumstances it can be created. Type libraries, the contents of which can be viewed using object browsers, are used to store descriptions of classes and their interfaces.

Automation Interfaces

An Automation interface, or simply interface, is a defined group of member functions through which clients communicate with component objects. It is important not to confuse the interface with the classes or objects themselves. An interface represents the functionality and expected behavior of a COM object in a definite (and permanent) manner. The uniqueness of each interface is guaranteed by its globally unique identifier (GUID), a 128-bit value assigned when the interface is initially defined. Once defined, interfaces are never changed. If a new version of an interface is required for whatever reason, a new interface is defined with its own GUID, and the old interface remains in place. Thus applications relying on the old interface can continue to function.

Binding

When you use an object in Visual Basic or VBA, you first declare it as an object and then create a reference to the object in an object variable. This process is known as binding. There are two types of binding, early and late, and as you might guess, late binding is the slower of the two. For example:

Dim xAP As Object
Set xAP = CreateObject("Excel.Application")

When a variable is declared simply as object or as variant, VB/VBA does not have enough information to determine at compile time what sort of object reference the variable will ultimately contain. This determination must be made at run time, hence the term late binding.

Early binding occurs when a specific type of object is specified in the declaration, as in the following code fragment:

Dim xAP as Excel.Application
Set xAP as Excel.Application

It follows, of course, that a variable declared as belonging to a specific class may only contain references to objects of that class. Whether object references are early or late bound is completely dependent on the way the variables are declared and has nothing to do with the manner of creating the objects. Use of early binding in creating the AutoCAD Application object is recommended, as the VB example later in this chapter shows.

Early binding is further subdivided into two types: vtable and DispID. Every property or method in a type library has a procedure identification number or DispID (dispatch identifier). DispID binding uses this number. If a component is represented in a type library but does not support vtable binding, VB uses the DispID during compilation to locate and bind the function.

With vtable binding, the fastest method, an offset address into a virtual function table provides direct access to the function. In general, if a client application declares object variables using explicit class names, vtable binding is assured. This is the method recommended in most circumstances and the one used by AutoCAD 2002. This is fortunate, because although you can control whether early or late binding is used by the way you declare object variables, the use of vtable versus DispID binding is controlled by the component object.

A High-Level View

Except when it comes to the question of bandwidth, it doesn't matter whether COM components are in the same place or on the other side of the planet. The terms COM and DCOM (Distributed COM) are often confused because the very concept of component implies distribution. Strictly speaking, COM becomes DCOM when network protocols replace local procedure calls. George Gilder, the pundit of the telecosm, tells us that soon we will enjoy infinite bandwidth at zero cost. Then it really won't matter!

Figure 1-2a illustrates an in-process client call with no intermediaries and therefore no overhead. Different processes that need to interact introduce some overhead because of the need to protect the processes from one another. This is the function of the operating system, which manages interprocess communication through run-time libraries while providing the required shielding. Figure 1-2b shows this link as a local procedure call (LPC).

When the client and the components reside on different machines, the COM run-time uses the operating system's security provider, together with remote procedure calls (RPCs) to generate network packets in accordance with the DCOM wire-protocol standard. This arrangement is pictured in Figure 1-2c. The only essential difference between Figure 1-2b and c is the length of the connecting fiber.

Figure 1-2Figure 1-2 Component Object Model

Details

There are two COM interfaces above the AutoCAD object model that are essential to its operation: IDispatch and IUnknown. (Interface names begin with the letter I by convention.) These primary interfaces are located in your Windows\System subdirectory in a type library file called StdOle2.tlb.

Explicitly declared object variables provide access to an identification number called a procedure ID, or DISPID, for every property and method belonging to the object. AutoCAD's DISPIDs are found in its type library, Acad.tlb, and establish the necessary link to IDispatch through early binding. If an object variable is not explicitly declared, as an entity for example, without specifying what kind of entity, the method or property is accessed by name at run time, which is known as late binding.

IDispatch

All the interfaces in AutoCAD's object model except one, IAcadObjectEvents, inherit methods from the IDispatch interface that allow for late binding. If declared explicitly, they obtain type information from the Acad.tlb type library at compile time, supporting direct access through early vtable binding. For this reason they are said to support dual interfaces. As we have seen, the type of binding used is determined by the manner in which object variables are declared.

The IDispatch interface supports four methods:

  1. GetTypeInfoCount

    Retrieves the number of type information interfaces that the object provides (either 1 or 0); always 1 for AutoCAD objects.

  2. GetTypeInfo

    Retrieves the type information for an object, which can then be used to get the type information for an interface.

  3. GetIDsOfNames

    Maps a single member, along with an optional set of argument names, to a corresponding set of DispIDs (integers), which caches them for later use in subsequent calls to the Invoke method. GetIDsOfNames is used in late binding, when an IDispatch client binds to names at run time.

  4. Invoke

    Provides access to the methods and properties exposed by an object.

IUnknown

The IUnknown interface is quite literally the center of the COM universe. It allows clients to obtain pointers to other interfaces belonging to a given object and manages the existence of every object throughout its lifetime. All interfaces, including IDispatch, inherit from IUnknown, whose three methods constitute the uppermost entries in the vtable for all other interfaces. These three methods are as follows:

  1. QueryInterface

    Returns a pointer to the specific interface on an object to which a client currently holds an interface pointer. When a client accesses a component object to perform a function, all aspects of its internal behavior are hidden. Only through the interface pointer can the client access the functions exposed in the interface. It is this enforced encapsulation that enables COM to provide both local and remote transparency through an effective binary standard.

  2. AddRef

    Increments the reference count of calls to an object's interface.

  3. Release

    Decrements the reference count of calls to an interface on an object.

AddRef and Release together control the life spans of the objects in an executing program. This provides the mechanism by which, through inheritance, references to all components are dynamically resolved. These two methods simply maintain a count of the references to each component object while it is using the interface. As long as the reference count is greater than zero, the object must remain in memory. When the reference count decrements to zero, no other components reference the object, which can then unload safely.

Example 1-1 illustrates IUnknown. It is written in IDL (Interface Development Language), which looks something like C/C++ and nothing like Visual Basic. A distinguishing feature is the use of attributes, which are the keywords in square brackets that specify the characteristics of the interface together with the data and methods within. The standard format in IDL begins with a header containing the interface attributes followed by the body of the interface enclosed in braces (curly brackets).

Example 1-1. IUnknown

 [
   odl,
   uuid(00000000-0000-0000-C000-000000000046),
   hidden
   ]
  interface IUnknown
  {[restricted] HRESULT _stdcall QueryInterface
             ([in] GUID* riid,
             [out] void** ppvObj);
   [restricted] unsigned long _stdcall AddRef();
   [restricted] unsigned long _stdcall Release();
  };

The most significant part of IUnknown's header is its UUID, the universally unique identifier (same as GUID). This is its 128-bit ID in the form of a five-node string comprised of 8 hexadecimal digits followed by three groups of 4 digits, and finally 12 digits. Hidden suppresses the display of the item in an object browser, as it cannot be accessed directly. The ODL attribute is no longer required but remains for backward compatibility.

The body of IUnknown contains the declarations of the three remote procedures in the interface, along with their data types. The restricted keyword specifies that a method cannot be called arbitrarily. In the QueryInterface method, riid is the requested interface identifier of the client program passing data into the remote procedure. ppvObj contains the address of the pointer variable requested in riid, which is passed out of the remote procedure.

So What Does this Mean to AutoCAD?

Earlier we pointed out that all except one of the interfaces in AutoCAD's object model inherit methods from the IDispatch interface, which in turn inherits from IUnknown. Figure 1-3 uses the IAcadObject interface to illustrate how AutoCAD objects inherit the necessary methods that allow them to interoperate through COM.

Figure 1-3Figure 1-3 Object Inheritance

IAcadObject inherits IDispatch's four methods along with the three belonging to IUnknown. These methods are thus passed down to all the objects that inherit from IAcadObject. There are 13 methods and properties to which IAcadObject provides direct access, of which you will see only 11 in the VBA object browser. The method and property designated with an H are hidden, meaning that they serve internal functions in AutoCAD and are not directly accessible. The Database property returns the database object, and the Erase property erases the entity object. These member functions, which are essential to maintaining the AutoCAD database, are inherited by virtually all the objects in AutoCAD along with the visible ones.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020