Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Книги_AutoCad_2 / AutoCAD 2006 and AutoCAD LT 2006 Bible_2004г__.pdf
Скачиваний:
142
Добавлен:
09.04.2015
Размер:
17.83 Mб
Скачать

Chapter 36 Exploring Advanced AutoLISP Topics 1079

Working with Visual LISP ActiveX Functions

ActiveX is an interface that exposes objects to the user, a programmer, or an application. AutoLISP supports ActiveX, giving you more information and flexibility in working with your drawings. You can also use ActiveX to work with objects in other Windows applications that support ActiveX. ActiveX is a programming interface that is used within a programming language that supports it. For example, you can also use ActiveX with Visual Basic for Applications (see the next chapter) and C++.

Cross-

In ActiveX, objects are structured in a hierarchy. You need to understand this structure before

Reference

working extensively with ActiveX. Chapter 37 covers this hierarchical structure in more detail.

 

ActiveX enables you to get information about objects (called get functions) and modify them (called put functions). The next section first reviews how you create these two functions in AutoLISP.

Reviewing AutoLISP retrieval and modification

In this section, you look at developing a small routine, written in AutoLISP, that mimics ActiveX properties and methods. This will help you to compare how AutoLISP works compared to ActiveX.

To understand Visual LISP’s ActiveX features, you need to know how AutoCAD exposes an object’s properties in AutoLISP. The following examples work with a line that is 10 units long, and created using the following AutoLISP function:

;;; This function creates a line using the AutoLISP

;;; command function and returns nil. (defun make-aLine ()

 

(command “_line” “5,5” “15,5” “”)

 

)

Note

The uppercase letter (in the function name) is used for readability, but you can type all lower-

 

case letters if that’s easier for you.

After loading it, you can use this function (that is, draw the line) by typing the following in the Visual LISP Console:

(make-aLine)

As explained in Chapter 35, to retrieve the last object that was created (the line), you use ENTLAST, as shown in the following code fragment. The next expression assigns the value of the last created entity, as an entity name, to the variable LineEntity. To try this out, type the following code in the Console:

(setq LineEntity (entlast))

Visual LISP responds with the entity name. As soon as you receive the entity name, you can use ENTGET to retrieve the object property list of the line entity name. The following code fragment places the property list value in the variable LinePropertyList. If you type the following in the Console and press Enter, Visual LISP responds with the property list:

(setq LinePropertyList (entget LineEntity))

1080 Part VII Programming AutoCAD

Here is an example of a property list, which is formatted for readability:

((-1 . <Entity name: 1456d60>) (0 . “LINE”)

(330 . <Entity name: 1456cf8>) (5 . “2C”)

(100 . “AcDbEntity”)

(67 . 0)

(410 . “Model”) (8 . “0”)

(100 . “AcDbLine”)

(10 5.0 5.0 0.0)

(11 15.0 5.0 0.0)

(210 0.0 0.0 1.0))

As you can see, ENTGET returns an entity’s properties as a collection of lists, all of which have a distinctive number at their first position. These group codes (also commonly known as DXF fields, because you can also find them in DXF files) were listed in Chapter 35. For this exercise, you just need to remember that the 10 group code is associated with the start point of a line.

Having the entity list and knowing which values to retrieve, you can use the AutoLISP function ASSOC, which returns an associated item from a property list.

To retrieve the start point of the line, you would use the following code, which you can type in the Console:

(setq StartofLineList (assoc 10 LinePropertyList))

The Console returns the list that is associated with the 10 group code, including the group code and the coordinates:

(10 5.0 5.0 0.0)

Because the only value that you require is the start point of the line object, use the function CDR to remove the first element of the list, as shown in the following code.

(setq StartofLine (cdr (assoc 10 LinePropertyList)))

This code returns only the start point coordinate:

(5.0 5.0 0.0)

Now that you’ve reviewed how to retrieve a value from an AutoCAD object, you can see that retrieving information from an associated list is relatively straightforward. But how about retrieving more than one property at a time? As you can see from the preceding example, you’d have to repeat the same body of code many times over to retrieve any information. Knowing this, you could write a simple interface function, putting together all of the steps that I have just explained, to retrieve any group code — not just the 10 group code — from an object.

Note An interface function is a function that hides a complex behavior from the user. The user needs to provide only basic information, but the function uses the information in several steps to obtain the desired result.

An example of an interface function is shown in the following lines:

;;;returns any group code value if it is present in the entity

;;;the required parameters are an entity name and a group code. (defun Get-A-Group-Code (EntityName GroupCode)

(cdr (assoc GroupCode (entget EntityName)))

)

Chapter 36 Exploring Advanced AutoLISP Topics 1081

After you create this function and load it, you can test it out in the Console as follows, using the LineEntity variable that was previously defined:

(Get-A-Group-Code LineEntity 10) (5.0 5.0 0.0)

As you can see, the function returns only the value of the 10 group code.

You can refine this small interface by defining a separate 10 group 10 function, such as the following. The only required parameter is an entity name. The group code is included in the call to Get-A-Group-Code. You could do the same for an 11 group code, if you want.

(defun Get-Group-10-Code (anEntityName) (Get-A-Group-Code anEntityName 10)

)

After loading, test the function, as follows:

(Get-Group-10-Code LineEntity)

Visual LISP returns the start point of the line:

(5.0 5.0 0.0)

These examples summarize how you would create a simple function to get the start point of a line using AutoLISP. What if you need to change an object’s property? You can do this by using the functions CONS, SUBST, and ENTMOD, which Chapter 35 covers.

CONS constructs a list. Use it when you want to create new values for a group code within an entity list, as in the following example, which you can type in the Console window:

(setq NewStartPoint (cons 10 ‘( 0 0 0 )))

Visual LISP returns the following:

(10 0 0 0)

Using the variables NewStartPoint and LinePropertyList, you can now substitute the newly created group 10 code. You do this using the SUBST function explained in Chapter 35. The following code substitutes the new group 10 code that is represented by the variable NewStartPoint for the 10 association in LinePropertyList in the list called LinePropertyList.

(Setq LinePropertyList

(subst NewStartPoint (assoc 10 LinePropertyList)

LinePropertyList)

)

To test this out, type the preceding code in the Console window. To see the new start point, you need to scroll all the way to the right. The list (nicely formatted) now has a new group 10 value (the start point), shown on the third-to-last line that follows:

((-1 .

<Entity name: 1456d60>)

(0 .

“LINE”)

(330

. <Entity name: 1456cf8>)

(5 .

“2C”)

(100

. “AcDbEntity”)

(67 . 0)

(410

. “Model”)

(8 .

“0”)

1082 Part VII Programming AutoCAD

(100 . “AcDbLine”)

(10 0 0 0)

(11 15.0 5.0 0.0)

(210 0.0 0.0 1.0))

To reflect the modification of this line in AutoCAD, as explained in Chapter 35, you can now use the function ENTMOD, by typing it in the Console, as follows. This code actually changes the start point of the line. (You can return to AutoCAD to check it out.)

(entmod LinePropertyList)

As you can see from this example, getting object properties and modifying them can be a tedious and time-consuming process. For the next example, you write an interface function that modifies any group code that is contained in any object.

(defun put-group-code-value (Entityname Groupcode Value / PropertyList)

(setq PropertyList (entget EntityName)) (setq PropertyList

(subst

(cons GroupCode Value)

(assoc GroupCode PropertyList) PropertyList

)

)

(entmod PropertyList)

)

This function combines all of the preceding steps into one function. Here’s how it works:

Line 1 defines the function with three arguments: the entity name, a group code, and a new value for the group code. It also declares a local variable, PropertyList, which is the property list of the object.

Line 2 sets the property list equal to the ENTGET of the entity name.

Line 3 starts the process of setting the same property list to the new value.

Lines 4 through 7 execute the substitution. They substitute the new group, created by (cons GroupCode Value), for the current group value, created with the ASSOC function, in the property list named PropertyList.

Line 8 closes the SUBST function.

Line 9 closes the second SETQ function.

Line 10 modifies the drawing database using ENTMOD.

Line 11 closes the DEFUN function.

Using the preceding function, you now have a much simpler interface for modifying any group code. Next, you use the function Put-Group-Code-Value to modify the 10 group code of the line object.

After entering and loading the preceding function, you can test the function by typing the following in Visual LISP:

(Put-Group-Code-Value LineEntity 10 ‘(5 5 0))

This function changes the start point of the line to 5,5,0.

Chapter 36 Exploring Advanced AutoLISP Topics 1083

Using the same logic to write the GET functions, you can now define a separate 10 group code modifier function. You can do the same for any group code.

(defun Put-Group-10-Code (EntityName Value) (Put-Group-Code-Value EntityName 10 Value)

)

After entering and loading this function, type the following in the Console to change the start point of the line to 15,–5,0.

(Put-Group-10-Code LineEntity ‘( 15 -5 0 ))

Activate AutoCAD to check that the line has been changed.

Using ActiveX with Visual LISP

ActiveX enables you to retrieve and modify objects similar to the method used in the previous section of this chapter, but it requires some preparation. In the following section, you read about using some ActiveX functions to create, retrieve, and modify an object.

Retrieving and modifying object information with ActiveX

Visual LISP enables you to retrieve and modify any AutoCAD object using AutoCAD’s ActiveX interface. That is to say, AutoCAD exposes all of its objects to ActiveX-enabled applications. This includes Visual LISP as ActiveX objects, all of which expose their properties, including PUT (modify) and GET (retrieve) functions.

Using Visual LISP to communicate with AutoCAD is very straightforward. You must first load all of the ActiveX functions using the VL-LOAD-COM function within Visual LISP. This exposes all of the ActiveX interface functions. You need to load the VL-LOAD-COM function only once each time that you open AutoCAD, because VL-LOAD-COM loads the ActiveX functions for the entire drawing session. (However, using VL-LOAD-COM more than once doesn’t cause any harm.) To load VL-LOAD-COM, enter it on the command line:

(vl-load-com)

After the ActiveX interface is loaded, you can interrogate the line that you created previously, but first you need to convert the entity name into a vla-object. A vla-object is no different from an entity name, except that the ActiveX object exposes certain properties that its AutoLISP counterpart does not. To convert the entity name into a vla-object, you use the function VLAX-ENAME->VLA-OBJECT, as shown here:

(setq vla-line (vlax-ename->vla-object (entlast)))

Visual LISP returns the following:

#<VLA-OBJECT IAcadLine 03612b14>

As you can see by the return value of vlax-ename->vla-object, the value of the variable vla-line contains a vla-object. At this point, you can visually inspect the variable by selecting it and choosing View Inspect. Although you see the line’s property in a dialog box, you can also “dump” its property and values to the Console by using the VLAX-DUMP-OBJECT Visual LISP function as follows:

(vlax-dump-object vla-line)

1084 Part VII Programming AutoCAD

This causes Visual LISP to display the following:

;IAcadLine: AutoCAD Line Interface

;Property values:

;Angle (RO) = 1.5708

;Application (RO) = #<VLA-OBJECT IAcadApplication 00af9594>

;Delta (RO) = (0.0 10.0 0.0)

;Document (RO) = #<VLA-OBJECT IAcadDocument 038be900>

;EndPoint = (15.0 5.0 0.0)

;Handle (RO) = “89”

;HasExtensionDictionary (RO) = 0

;Hyperlinks (RO) = #<VLA-OBJECT IAcadHyperlinks 01011d44>

;Layer = “0”

;Length (RO) = 10.0

;Linetype = “ByLayer”

;LinetypeScale = 1.0

;Lineweight = -1

;Normal = (0.0 0.0 1.0)

;ObjectID (RO) = 2130009736

;ObjectName (RO) = “AcDbLine”

;OwnerID (RO) = 2130009336

;PlotStyleName = “ByLayer”

;StartPoint = (15.0 -5.0 0.0)

;Thickness = 0.0

;TrueColor = #<VLA-OBJECT IAcadAcCmColor 01015170>

;Visible = -1

T

You’ll probably have to resize the window to see all of these properties. Notice the similarities between the “named” properties shown here, such as EndPoint and StartPoint, and the line’s group codes that you retrieve using AutoLISP. As you can see, one of the advantages of using an ActiveX-enabled object is that ActiveX exposes more information to the programmer than standard AutoLISP. One of the benefits of using ActiveX is its interface. Previously, you queried and modified a line object’s start point and endpoint by using the 10 and 11 group codes. Using ActiveX to query the start point and endpoint is very straightforward. However, ActiveX returns these points in a data type called a variant that you need to convert to the familiar coordinate format.

To get the start point of an object, you use the VLA-GET-STARTPOINT function. In the current example, the line has been set to vla-line, and so you would type the following expression:

(setq Starting (vla-get-startpoint vla-line))

Visual LISP responds as follows:

#<variant 8197 ...>

To convert the start point from the variant data type to a usable coordinate format, you would type the following line:

(safearray-value (vlax-variant-value Starting))

Visual LISP responds with a coordinate:

(15.0 -5.0 0.0)

Chapter 36 Exploring Advanced AutoLISP Topics 1085

To modify the StartPoint property of a line to (0,0,0), you would use the following expression:

(vla-put-startpoint vla-line (vlax-3d-point ‘(0 0 0 )))

You can return to AutoCAD to check out the line. To verify the new StartPoint, you can also use the VLA-GET-STARTPOINT function:

(safearray-value (vlax-variant-value (vla-get-StartPoint vla-line)))

Visual LISP returns the start point of the line:

(0.0 0.0 0.0)

As you can see, this is very similar to the small routine that was developed in AutoLISP earlier in this chapter.

STEPS: Retrieving and Modifying Objects with ActiveX

1.To start a new drawing session, open AutoCAD. If AutoCAD is already open, close and re-open it.

2.Start a new drawing using the acad.dwt template.

3.Draw any line. Neither the start point nor the endpoint should be 0,0,0.

4.Choose Tools AutoLISP Visual LISP Editor.

5.In the Console window, type (vl-load-com) to load the ActiveX functions.

6.To convert the entity name into a vla-object, type (setq vla-line (vlax-ename->vla-object (entlast))) .

7.To view the line’s properties, type (vlax-dump-object vla-line) .

8.To get the start point of the line, type (setq Starting (vla-get-startpoint vla-line)) .

9.To convert the start point from the variant data type to coordinate format, type

(safearray-value (vlax-variant-value Starting)) .

10.To change the line’s start point to 0,0,0, type (vla-put-startpoint vla-line (vlax-3d-point '(0 0 0 ))) .

11.Choose Activate AutoCAD on the Visual LISP View toolbar to check out the line. Its start point is now 0,0,0.

Creating objects with ActiveX

This section looks at object-creation functions. When you work with ActiveX, you need to retrieve objects in their hierarchical order. This hierarchy concept is discussed in more detail in the next chapter. For this chapter, you need to know that before you can retrieve an object, you need to retrieve the following:

Acad-object: Represents the AutoCAD application.

ActiveDocument: Represents your drawing.

ModelSpace/PaperSpace: Represents the type of space that you want to use within the AutoCAD application.

Соседние файлы в папке Книги_AutoCad_2