• No results found

Using AutoLISP in a Menu

In document ABC's of Autolisp (Page 44-46)

There are two reasons why you might write AutoLISP code directly into the menu file. The first is to selectively load external AutoLISP programs as they are needed. You may have several useful but infrequently used programs that take up valuable memory. You might prefer not load these programs at startup time. By placing them in the menu file, they will only load when they are selected from the menu. In fact, this is what the AutoShade and 3dobjects menu options do. When you pick Ashade from either the screen or pull down menu, and AutoShade is present on your computer, an AutoLISP program called Ashade.lsp is loaded.

The code of the program can be present in the menu file or you can use a method similar to the one described earlier to load external AutoLISP files. However, if you use the menu system to load external AutoLISP files, you must a slightly different method.

In the example we gave for loading programs from external AutoLISP file, the loader program is replaced by the fully operational program of the same name. But if you were to place the following expression in a menu, the program would load every time the menu option was selected.

[box]^C^C(load "box");box

There is nothing wrong with loading the program each time it is run but if the AutoLISP file is lengthy, you may get tired of waiting for the loading to complete every time you select the item from the menu. A better way to load a program from the menu is to use the If function as in the following:

[box]^C^C(if (not C:box)(load "box")(princ "Box is already loaded. ");box

In this example, we show three new functions, If, Not and Princ. The If functions checks to see if certain conditions can be met then evaluates an expression depending on the result. The If functions expects the first argument to test the condition that is to be met while the second argument is the expression to be evaluated if the condition is true. A third expression can optionally be added for cases where you want an expression to be evaluated when the test condition returns nil. The Not function returns a T for true if its argument evaluates to nil, otherwise it returns nil (see figure 2.11).

Figure 2.11: Using the If function

So, in the menu sample above, if C:BOX does not exists, Not will return T for true and the If function evaluates the (load "box") expression thereby loading the Box program. If C:BOX has already been loaded, then Not function returns nil and box.lsp will not be loaded again. Instead, the second argument will be evaluated. This expression:

(princ "Box is already loaded. ") simply displays the string:

Box is already loaded. on the command prompt.

You may have noticed that the If function does not conform to the standard rules of evaluation. Where If is used, the second or third argument is evaluated depending on the value of the first argument.

The second reason for placing code in the menu is speed. Instead of creating a function using Defun, you can set up a program to be read and executed line by line. This saves time since the interpreter reads and executes each expression of your program as they occur in the menu listing instead of reading the entire set of expressions then executing the program. Memory is also saved since Defun is not used to define a new function. Figure 2.11 shows a listing of how the box program from chapter 1 would look as a menu option.

[BOX] ^C^C(setvar "menuecho" 1);+

(setq pt1 (getpoint "Pick first corner: "));\+

(setq pt3 (getcorner pt1 "Pick opposite corner: "));\+ (setq pt2 (list (car pt3) (cadr pt1)));+

(setq pt4 (list (car pt1) (cadr pt3)));+ line; pt1; pt2; pt3; pt4;C;)

NOTE that the Defun function is absent from the listing. When the box option is picked from the menu, AutoCAD reads the associated text just as it would any menu option. Since the text in this case is AutoLISP code, the AutoLISP interpreter evaluates each expression as if it were entered through the keyboard.

NOTE that the semicolon is used to indicate the enter key at the end of each expression. A backslash is used to pause for input, just as you would have a backslash in other commands that require mouse or keyboard input. Also note the use of the plus sign indicating the continuation of the menu item. Finally, note that the last line of the menu item uses the exclamation point to enter the values of the variables as responses to the Line command. The last C is the Close option of the Line command. You may have noticed a new expression:

(setvar "menuecho" 1)

The Setvar function in the above expression does the same thing as the Setvar command in AutoCAD. In this case, it sets the menuecho system variable to 1. This setting prevents the actual AutoLISP code from being displayed on the command prompt.

1. Using your word processor, copy the above listing into a file called Box.mnu, again being careful to input the listing exactly as shown above.

2. Get back into the AutoCAD drawing editor then use the Menu command to load the Box menu you just created. The AutoCAD menu will disappear and will be replaced by the single word Box.

3. Pick the Box option from the menu, and you will see the prompts you entered when you created the Box menu above. This program will work in the same way as the Box.lsp program.

4. To get the AutoCAD menu back, enter the command Menu and enter acad at the menu name prompt. Since Defun is not used in this example, no argument list is used. Any variables used in the listing becomes global. For this reason, when using menus for AutoLISP programs, it especially important to keep track of variable names so they do not conflict with other variables from other programs.

In document ABC's of Autolisp (Page 44-46)