说明
主要学习内容
- Learn how to build and load a .NET project
- Learn how to create a command or AutoLISP function
- Learn about requesting user input
- Learn how to create and display a user form
讲师
- LALee AmbrosiusLee Ambrosius is a Senior Principal Content Experience Designer at Autodesk, Inc., for the AutoCAD® and AutoCAD LT products on Windows and Mac. He works primarily on the customization, developer, and CAD administration documentation along with the user documentation. Lee has presented at over 15 different Autodesk University events on a range of topics, from general AutoCAD customization to programming with the ObjectARX technology. He has authored several AutoCAD-related books, with his most recent projects being Discovering AutoCAD 2024, and AutoCAD Platform Customization: User Interface, AutoLISP, VBA, and Beyond. When Lee isn't writing, you can find him roaming various AutoCAD community forums, posting articles on his or the AutoCAD blog, or tweeting information regarding the AutoCAD product.
LEE AMBROSIUS: Hello, and welcome to "Bridging the Gap-- Extending AutoLISP with .NET." Have you ever wanted to add enhanced or advanced functionality to your existing AutoLISP programs that is normally only accessible to .NET or ObjectARX programs? Or maybe you want to implement a dialog box for your AutoLISP programs and found DCL cumbersome and lacking in functionality?
In this session, I will be discussing how you can extend the functionality of AutoLISP by defining new commands and AutoLISP functions in Managed .NET and implementing modern dialog boxes. In addition to what I know, you should know how to use AutoCAD 2022 or AutoCAD 2016 and later, and use the AutoLISP programming language. Let's get started on what I hope will be an interesting session that opens up new possibilities for extending the functionality of your existing AutoLISP programs.
Before we get started, though, let me introduce myself. My name is Lee Ambrosius, and I'm a principal learning experience designer at Autodesk. I am the lead writer for the customization, developer, and CAD administration documentation for AutoCAD on Windows and Mac OS. The developer documentation includes AutoLISP, ObjectARX, ActiveX, Managed .NET, and JavaScript.
In addition to working on the developer documentation, I am also involved in the AutoCAD "Have You Tried" article series and my "Insights for AutoCAD." I have about 25 years of experience customizing and developing applications for both AutoCAD and Windows. Over those years, I've learned about eight programming languages, with the most recent being Python. I've also written several AutoCAD books, with my most recent being the AutoCAD Customization Platform series published by Wiley & Sons. At the end of the day, I document the past and present of AutoCAD for the future.
That's me on the right, several years ago, after running 48.6 miles at Walt Disney World over four days. That's a 5K, 10K, half marathon, and full marathon. And yes, I paid Disney to run around their parks and for them to call me Dopey.
Things you should know before proceeding-- to get the most from this session, make sure you have AutoCAD 2022 installed, or AutoCAD 2016 and later. The samples are really built around AutoCAD 2022, though. Along with AutoCAD being installed, it is best to have experience with the AutoLISP programming language to get the most out of this session.
Other things you will want for this session is the handout and the additional materials. The handout takes a closer look at the topics covered in this session, while the additional materials contain a sample project that demonstrates the concepts in the presentation. After watching this session, I recommend downloading the materials from the session's page. The handout and material files can be found under the downloads.
Introduction-- by the end of the session, you should know how to build and load a .NET assembly file into AutoCAD, create a command or AutoLISP function, request user input, and create and display a user form. In addition to AutoCAD, you will need to install either Visual Studio 2019 or Visual Studio 2019 Community Edition to develop a .NET project. You will also want to install the ObjectARX SDK and the AutoCAD 2022 .NET wizard. Additionally, you'll want to refer to the AutoCAD Managed .NET Developer's Guide that is part of the AutoCAD product help.
When developing programs with .NET for AutoCAD, you need to make sure you have the correct version of the ObjectARX SDK installed and that you reference the correct .NET framework based on your target AutoCAD release. You may need to build the same program for different releases, such as once for AutoCAD 2022 and another for AutoCAD 2019. .NET for AutoCAD is not compatible with Mac OS. However, you could utilize Objective C with the ObjectARX SDK to achieve similar results.
Create a VB .NET project-- before you can create a VB .NET project, you need to install Visual Studio 2019 or Community Edition and the ObjectARX SDK, while optionally, I highly recommend installing the AutoCAD 2022 .NET wizard. Once everything has been installed, you can create a new project based on one of these templates-- VB Class Library .NET framework or AutoCAD 2022 VB plug-in. The AutoCAD 2022 VB plug-in is only available if you have installed the AutoCAD 2022 .NET wizard. While you don't need the AutoCAD 2022 .NET wizard, it does simplify the process of creating a VB .NET project by walking you through several steps.
After a project has been created, you will need to work with these three assemblies-- AcCoreMgd.dll, which allows you to define commands and AutoLISP functions and work with the drawing editor; AcDbMgd.dll, which allows you to create and modify objects in a drawing file; and AcMgd.dll, which allows you to work with the AutoCAD application and user interface. If you need to work with the AutoCAD ActiveX/COM libraries, which are commonly used with VBA, you need to also reference Autodesk.AutoCAD.Interop.dll, which allows you to work with the AutoCAD application and documents, and Autodesk.AutoCAD.Interop.Common.dll, which allows you to create and modify objects in a drawing.
.NET assemblies are divided into namespaces spaces to organize methods and properties. Common namespaces are Runtime, used for defining custom commands and AutoLISP functions; ApplicationServices, used for working with the application and opening and creating drawings; DatabaseServices, used for working with objects in a drawing; Geometry contains helper data methods for working with coordinates and other geometry-related tasks; and EditorInput, which allows you to display messages and request user input at the command prompt.
Now I'm going to switch over to Visual Studio and create a VBA .NET project that can be compiled into an assembly and then loaded into AutoCAD. With Visual Studio 2019 open, I'm going to click File, New Project. In the Create a New Project dialog box, I'm going to search for the AutoCAD plug-in. From the list, I'll select AutoCAD 2022 VB plug-in, and then click Next.
In the Configure Your New Project dialog box, I'll enter a project name of MyLISPFunctions and choose a folder to store the project. Since we're building this project for AutoCAD 2022, we can keep the default .NET framework a 4.8. I'll click Create to create the new project.
In the AutoCAD .NET wizard configurator, specify the location of the inc folder of the ObjectARX SDK and the location of the autocad.exe file as needed. Click OK to continue with creating the new project.
The new project is created and opened in Visual Studio. The Solution Explorer allows you to see which libraries have been referenced and the code files that have been created by default. The myCommands.vb file is the main file you will be adding code for this project. Notice there is some sample code in here that you can modify and try after building and loading the DLL into AutoCAD.
To find a command-- a command is defined from a public subroutine and declared with the use of the CommandMethod attribute. As part of a CommandMethod attribute, you must provide a group name, global command name, local command name, and command flags. Here's an example of a command in a group named MyGroup with a global name of HelloAU and a local name of BonjourAU. This command, when defined and started in AutoCAD, displays the message "Welcome to AU 2021."
Now I'm going to switch over to Visual Studio and define the HelloAU command. With Visual Studio open in the myCommands.vb file, I'm going to add the new command definition below the sample commands and list functions that are part of the VB .NET project that was created earlier. Now that the command definition has been added, I'm going to save the project. I explain how to build and load the .NET assembly into AutoCAD in the next section.
Build and load a .NET assembly-- a .NET project must be built into a DLL for debugging or release. You build a project for debugging when you're developing and testing your programs, while you build a project for release when you are ready to distribute the program to others for use. Click the Build menu and then choose Configuration Manager to specify either the Debug or Release build configuration. You can also use the Solution Configurations dropdown list to set the current build configuration. Once a configuration has been set, choose Build Solution from the Build menu to create a DLL from your project. Once the DLL has been built, the NETLOAD command can be used to load the DLL into AutoCAD. Here's an example, you might use to load a DLL from an AutoLISP program or file.
Now I'm going to switch over to Visual Studio and build the VB .NET project I previously created. With Visual Studio open, I'm going to choose Release from the Solution Configurations dropdown list. With the Release configuration current, I'll choose Build Solution from the Build menu.
If any errors are displayed in the error list, fix them before building the project again. You should notice the location and name of the DLL created is displayed in the output window. I'll select and copy the location and name of the DLL to simplify its loading into AutoCAD. Now with the DLL built, I'm going to switch over to AutoCAD and load it with the NETLOAD command. In AutoCAD, at the command prompt, I'm going to start the NETLOAD command and specify the location of the DLL.
With the DLL loaded, at the command prompt, I'm going to enter BonjourAU to run the custom command. Notice the message "Welcome to AU 2021" is displayed in the command window. Since this is a command, you can also use the AutoLISP command function to run the command, just like you would with the AutoCAD Line or Erase commands.
Create and expose a function-- AutoLISP functions are defined similar to custom commands. An AutoLISP function is defined from a public function and declared with the use of the LispFunction attribute. The function should accept a single result buffer data type and must always return a value of one of the two data types of a ResultBuffer or TypedValue.
Here's an example of a function named StringReturn. This function, when used, returns the string "My Value."
Before you use a value passed into a function, you should determine if it is a standard data type, a single typed value, or an array of typed values. Here's an example of an if conditional and a for each loop statement used to check the values and array of TypedValues passed into a function. A ResultBuffer in .NET is similar to a list in AutoLISP. It can contain any of the common AutoLISP data types and is used to represent lists and dotted pairs. Each item of a ResultBuffer is a TypedValue data type. The TypeCode property can be used to get the data type of the value assigned to a TypedValue, and the TypeValue property can be used to get the actual assigned value of a TypedValue.
Here is an example of assigning a dotted pair to a ResultBuffer. Now I'm going to switch over to Visual Studio and define the StringReturn function. With Visual Studio open, in the myCommands.vb file, I'm going to add the new function definition below the HelloAU command I added earlier. Now that the function definition has been added, I'm going to rebuild the project. If the DLL was previously loaded into a running instance of AutoCAD, close all instances of AutoCAD before rebuilding the DLL.
Now that the DLL has been rebuilt, I'm going to start AutoCAD and load the DLL. Then, at the command prompt, I'll enter (stringreturn). Notice the string "My Value" is returned to command window. This is the expected result. I could have assigned the return value to a user-defined variable with the SETQ function.
Access AutoLISP user-defined variables-- AutoLISP variables defined with the SETQ can be accessed with the GetLispSymbol function, which gets the value of an AutoLISP user-defined variable and the SetLispSymbol function, which allows you to assign a value to an AutoLISP user-defined variable. You can use the GetType function to determine the data type of a value returned from the GetLispSymbol function.
Here is an example of using the GetLispSymbol function to get the value assigned to the AutoLISP user-defined variable named foo. The data type of the value is then obtained using the GetType function. Now I'm going to switch over to Visual Studio and load a sample project that contains functions to get and set the value of the foo user-defined variable.
With Visual Studio open, I'm going to open one of the completed projects from the exercises in the handout for this session. Instead of building and loading a release version of the DLL into AutoCAD this time, I'm going to switch to the Debug configuration and start AutoCAD from Visual Studio. To do this, I'm going to choose Debug from the Solution Configuration dropdown list, and then display the properties of the project.
In the Project Properties dialog box, I'll click Debug to access the debug settings for this project. Here you can specify the AutoCAD executable you want to start when debugging in Visual Studio. Once the AutoCAD executable has been specified, debugging can be started by clicking Start or choosing Debug, Start Debugging. I'll start debugging from Visual Studio now.
After AutoCAD is launched, I'll load the debugged version of the DLL with the NETLOAD command. Now I can switch back to Visual Studio and add break points to debug the custom functions. I'm going to add a breakpoint to the set foo and fetch foo functions.
With breakpoints set, we're going to switch back to AutoCAD and check the value of the foo user-defined variable by entering !foo. Notice nil is returned, which is expected. Now I'll enter (setfoo) to use the SetFoo Fu function.
Notice execution is shown as being interrupted in Visual Studio. I can now step through the code using the Step Into, Step Over, and Continue tools. While execution is interrupted, I can view the current values of the variables or returned values of functions by hovering over statements in the Code Editor window or using the Watch window.
I'll resume normal execution and check the value of foo in AutoCAD. Notice foo is now set to the text string default value. Now I'll enter (fetchfoo) to use the FetchFoo function. Notice execution is shown as being interrupted in Visual Studio once again. I'll click Continue to resume normal execution. Notice in AutoCAD, at the command prompt, the value of string is returned because the data type of the foo variable is a string.
Request user input-- user input is handled with the Get method, similar to those in AutoLISP. Each Get method requires the use of a PromptOptions object, which controls the method's behavior, and a PromptResult object, which contains the return value or status of the Get method. Get methods are members of the Editor object.
Here's an example of using the Get Point method to request a point or allow the user to specify two different keywords, layer, and undo. The prompt and keywords are set up as part of the PromptPointOptions object. The PromptPointOptions object is then passed to the Get Point method. The action or value the user provides to the Get Point method is returned to the PromptPointResult object.
The biggest advantage of utilizing the Get methods from the .NET API, when compared to those of the AutoLISP programming language, is that pressing Escape doesn't terminate your program. The PromptResult object allows you to check the status of the Get method. Here's an example that shows the use of the Status property of the PromptResult object to determine what type of input the user provided or that they canceled the request for input by pressing Escape. Now I'm going to switch over to Visual Studio and load a sample project that contains a function that demonstrates the requesting of a point or keyword at the command prompt.
With Visual Studio open, I'm going to open one of the completed projects from the exercises in the handout for this session. After opening the project, I'm going to start debugging and load the Debug version of the DLL into AutoCAD. Upon loading the DLL, I'll switch back to Visual Studio and add a break point to the Point or Keyword function. With the breakpoint set, I'm going to switch back to AutoCAD and enter (pointorkeyword). When prompted, I'm going to specify a point. Notice execution is shown as being interrupted in Visual Studio after I specified a point. If I step into the code, you can see the current status is OK when I hover over the Status property.
Let me resume normal execution now. I'm going to use the function again, but this time, I'm going to press Escape instead of picking a point. Now, this time, when I step through the code, the current status is canceled. Now I'll resume normal execution. Notice upon resuming normal execution, a message box appears letting me know that the function wasn't terminated like it would have been in AutoLISP. Clicking OK resumes and ends execution of the function as expected.
Create and display a dialog box-- .NET forms in dialog boxes are simpler to create and display than those defined with DCL. You also have a greater variety of modern controls and experiences with .NET forms and dialog boxes. Forms and dialog boxes are edited using the Form Editor, and controls are added using the Toolbox. Now I'm going to switch over to Visual Studio and load a sample project that contains a user form and function that allows you to display that user form. This user form will allow for the specification of an insertion point and a note type. The note type will be used to control the text string assigned to a multi-line text object.
After opening the project, let's take a look at the user form. This user form contains a text box that shows the specified insertion point and a button to request a point in the drawing. The dropdown list allows you to specify one of the available note types. Then, along the bottom of the dialog box are the standard OK and Cancel buttons. I'm going to double click on the OK button and set a breakpoint in the function.
Notice as part of this function, a ResultBuffer is being created and assigned to a global variable. This global variable will be returned as part of our AutoLISP function when we use the dialog box. Now let's take a look at the custom AutoLISP function used to display the dialog box.
This function accepts a list of two dotted pairs, which is passed to the user form to populate the default insertion and note type. When the OK button is clicked, the values from the dialog box are returned as a list of dotted pairs. Let's start debugging and load the DLL and see the user form in action.
At the command prompt, I'm going to enter (displayinsnote) to display the user dialog box. Next, I'll specify an insertion point and note type and then click OK. Notice that I'm returned into Visual Studio in Debug mode. I'll click Continue to resume normal execution.
Notice the returned value is a list with two dotted pairs representing the insertion point and note type. Now let's take a look at using the DisplayInsNote function in a sample AutoLISP program. Here, the MyNote command uses the DisplayInsNote function to define the insertion point and text for a multi-line text object created with the Text command. Now, let's load the MyNote.lisp file and use the MyNote command. Notice a new multi-line text object is created based on the input provided from the dialog box.
Final thoughts-- this brings us to the end of our journey into looking at creating custom commands in AutoLISP of those functions with .NET. I hope you found this session interesting, and it opens up new possibilities for your existing AutoLISP programs. Extending the functionality of AutoLISP allows you to take advantage of the AutoCAD Managed .NET API and utilize modern dialog boxes and palettes. Being able to utilize multiple programming languages gives you the flexibility to use the best tool for the right job. Programing has many similarities to Wonderland in Lewis Carroll's Alice's Adventures. Both programming and Wonderland are virtually endless and full of many mysterious wonders.
If you have any questions, post a comment on the session's page or feel free to email me and I will get back to you as soon as I can. Thank you for watching this session.