As requested, Wayne has kindly provided transcripts for the recently posted (and now complete) series of DevTV sessions on AutoCAD .NET development.
To recap, here are the posts for the various lessons:
- Introduction and Sessions Overview, Getting Started
- User Input
- Database Fundamentals
- Database Events, PaletteSet
- Dictionaries, Containers, Type Identification, Casting
- InputPoint Monitor
- User Interface elements
Here are the scripts that Wayne used to record the material. Wayne created them as a guide for himself (and others – should we end up translating the material), rather than being a verbatim record of what Wayne ended up saying. Please forgive any typos or inconsistencies: Wayne probably didn’t expect to share them publicly, but has kindly done so at my request. Also, there are scripts for some, but not all, of the demos.
Introduction and Sessions Overview
- Welcome to this DevTV presentation - “AutoCAD .NET API Training”. This is the Introduction and sessions overview.
- Hello my name is Wayne Brill and I’ll be the presenter for these DevTV presentations. I work for Developer Technical Services and I live in the Seattle Area in Washington state. Developer technical Services is a group of engineers who support the Autodesk Developer Network. If you see me at a conference please stop and introduce yourself – I would enjoy meeting you.
- The objective of this course is to understand the fundamentals of the AutoCAD .NET Application Programming Interface and it is intended to help you learn the API on your own. Please keep in mind that this course is not going to teach you the .NET framework or how to program. Also the training is not going to provide complete coverage of all the functions in the AutoCAD .NET API. I do hope that after you have watched these DevTV recordings and completed the labs, that you will have gained confidence in your ability to customize AutoCAD with this powerful and fun API.
- If you are just getting started with .NET these links to the Visual Basic Developer Center and the C# developer center should be very useful. At these sites you will find a lot of useful information and resources such as training videos and you can also download Visual Basic Express. Another great resource is the .NET Framework Primer for the Visual Basic Developer.
- Now let’s focus on the DevTV recordings and the labs for this training. There are eight sessions. The first session will cover how to create a visual studio project, this project will create a dll that you can load in AutoCAD and it will have one command that prints a message on the AutoCAD command line. Next we will cover some simple user interaction and user Input that will show you how to communicate with the user from the command line. In the third session you will learn about the AutoCAD drawing database including details about the symbol tables, transactions and how to access and create entities. After this we learn how to use database events and how to add a graphical user interface element called a PaletteSet. In session five we will focus on more database elements, such dictionaries and other topics such type identification and casting. The InputPoint Monitor explained in session 6 will allow you to provide dynamic feedback to the user through events that occur with the cursor. Following this you will learn about jigs which allow custom applications to create a drag image when entities are added to the AutoCAD drawing. The last session covers more User Interface elements including context menus which are right click menus, drag and drop functionality, and we will also learn how to extend the options dialog with custom settings.
- The training includes a DevTV recording for each section as well as a lab. The labs are provided for both VB.NET and C#. The labs are provided in Word documents. These word documents contain an overview of the labs as well as the lab steps. There are also Visual Studio projects with the lab steps in the source code as comments. So you can do the labs in two different ways. The first way is to create own project and copy in the comments from the word document. The other way is to use the word document for the general overview and then just use the provided visual studio projects to complete the lab steps. The first lab is a little different however as the goal of this lab is to create a new Visual Studio project so there is not a project provided. If you need an example of a completed project for lab1 you can take a look at the completed Lab2. For labs two through eight there are visual studio projects that are completed and these can be used as a reference if you run into a problem. (Note: show lab document one and discuss how it is laid out. Also show lab2 document and show the comments. Also show Visual Studio and the steps in Lab 2.)
- When you work through the labs you may want to find more information about the AutoCAD .NET API. For this you can use the AutoCAD .NET Developer’s Guide at this location. Another resource is the AutoCAD Developer Center where you download the AutoCAD .NET Visual Studio Wizard. You will need the wizard for Lab2. There is also a link on Developer Center where you can download a DWF file this is an object model of the AutoCAD .NET classes. I would also recommend downloading the ObjectARX SDK to get the documentation and the .NET samples. (Note: show and talk through the .NET developer’s Guide, Developer Center, The ObjectARX SDK directory of the samples, and the ObjectARX Developer’s guide section on using the .NET API.)
- Some of you may be unfamiliar with ADN, so here’s a little more about it. The Autodesk Developer Network is a program providing professional support to programmers writing add-in applications for Autodesk software. If you think the program benefits listed here would be useful to you, then visit this URL and read more about it. You don’t have to be a commercial software developer to join ADN.
- Thank you for your interest in learning the AutoCAD .NET API.
- Welcome to this DevTV presentation on the AutoCAD .NET API. This is Session one, getting started.
- The objective of this session is to understand a few things about the .NET API. This will be a high level overview of .NET and should give you an idea of what’s happening on the system when a .NET application is loaded and run. In this session we will also discuss what it takes to create a .NET application for AutoCAD. We will be using visual studio to make an application that will have one command that prints a message on the AutoCAD command line.
- Ok, lets dive in and discuss a couple main components of the .NET API. These are the Common Language Runtime and the Framework class library. In visual studio when you compile a .NET application it creates an assembly that is a dll or exe. These assemblies contain code in intermediate language. At runtime this intermediate language is interpreted by the common language runtime. Because the .NET compilers create the same intermediate language you can use different source code such VB.NET or C#. Assemblies that are processed by the common language runtime are considered managed code. Sometimes you may see the AutoCAD .NET API discussed as the AutoCAD Managed API. The framework class library, also sometimes referred to as the base class library, contains services that form the building blocks for .NET Applications. These libraries are in language independent IL code and are installed with the .NET Framework. The framework class library contains hundreds of classes and simplify programming with the .NET API.
- To make this more clear here we have an execution model for the Common language runtime. First we start with source code that could be in any language that supports the .NET API such VB.NET, C# or C++. (click) This source code is then compiled into an assembly. (click) Keep in mind that this .NET dll is much different than a dll created using Visual Basic 6 or a dll that is created by some other compiler. (click) The CLR then ensures that everything the assembly needs is available on the system and it processes the intermediate language code and starts the Just In time compiler. (click) The JIT compiler is what gives .NET its platform independence as there will be a different JIT compiler for different types of systems. (click) The JIT compiler then creates the native code.
- An assembly will contain a manifest that describes the assembly. This description is what provides the intellisense and object browser capability when the assembly is referenced. The assembly also contains the IL code which is interpreted by the CLR and for AutoCAD the assembly will be a dll. Later in this session we will use a utility named I l d a s m.exe which is an Intermediate language disassembler to explore the contents of the assembly that we will be creating.
- The first thing we do is create a Class Library which will create a dll. And then we add references to AutoCAD’s managed assemblies. Two of the AutoCAD Managed assemblies contain the main AutoCAD .NET API. They are named acdbmgd.dll and acmgd.dll. One reason there are two dlls is because of a product named RealDWG. RealDWG is used to access the dwg file and the drawing database but does not have anything to do with AutoCAD. So if you are going to be using the .NET API for RealDWG you would only reference acdbmgd.dll. For AutoCAD most applications will need to reference both of these dlls. You will find these dlls in the same directory where acad.exe is or if you have the ObjectARX SDK it will in the inc directory. I would recommend that you install the ObjectARX SDK and reference the files from there.
- Note: before moving to slide 7. Demo using Visual Studio to start creating a class library. Add the references from ObjectARX directory. Then use the Object browser to explore what is in the AutoCAD namespaces. Then come back to the slides. (Switch back to the project after discussing slide 7, 8 and 9).
- After we add the references we can add namespaces which can make our source code easier. In visual basic we use the Imports keyword and in C# it is done with the using keyword. The namespaces that are going to be common to most AutoCAD applications are Autodesk.AutoCAD.ApplicationServices, Runtime and EditorInput. These namespaces are available after the AutoCAD dlls are referenced.
- To add an AutoCAD command you use the CommandMethod attribute. In this example a command HelloWorld is created. When the user types helloworld on the command line the procedure HelloWorld will be called. Keep in mind that the name of the procedure and the name of the command do not have to be the same as in this example. The attribute is added to the assembly as metadata and this is used by AutoCAD to add the command. This example is using the simplest signature of the CommandMethod attribute. You use other parameters of this attribute to control the behavior of the command. This will be necessary in some situations such as when the command is going to be accessing multiple documents. In that case the command needs to run in Application context so you would use the CommandFlags enumeration with the Session setting.
- Now that what we have a command that will run our procedure let’s use the API to print text on the AutoCAD command line. To do this we use the Editor class and the WriteMessage function. Notice that this function takes the string that will be displayed on the command line. To instantiate the Editor variable “ed” we use the Editor property of the MDIActiveDocument which is a property of the DocumentManager which is a property of the Application.
Note: Go back to the project and add the namespaces, use the CommandMethod attribute to add the command, use the Editor class to print to the command line. Build and debug the application.
- As we have seen you use the NETLOAD command to manually load your AutoCAD .NET dll. You can also have your dll loaded automatically. You can have it loaded on startup or when your command is run. Here you see the keys that need to be used to add this capability. If you have an installer it can add these keys to the registry.
- Now let’s review the steps to create an AutoCAD .NET dll. First we need to have the project create a class library application. Then we need the references to the AutoCAD managed assemblies and add namespaces to the code window. Then we use the CommandMethod attribute and add a procedure that will be run when the command is run. The rest of these sessions on the .NET API will be on how to use the functionality provided by the classes in acdbmgd.dll and acmgd.dll.
- After you create your .NET dll you may want to use these tools to help understand the behavior that is occurring with your application. You can use tools such as Reflector or ILDASM to explore the contents of the .NET assembly. Fuslogvw will help you find out why a dll is not loading correctly. If you want to check your application for conformance with design guidelines use a tool named fxcop.
Note: Use ILDASM.exe and demo by exploring the dll you created.
- Thank you for watching this DevTV presentation and good luck with LAB 1. We will continue our AutoCAD .NET API training in Session 2 where we will show how to use the AutoCAD .NET Wizard to create the application and how to get input from the user from the command line.
- Welcome to this DevTV presentation on the AutoCAD .NET API. This is Session two of this series. In this session we focus on User Interaction – User Input.
- The main objective of this session is to understand how to use the API to get input from the AutoCAD user. Because we’re just getting started with the API, this is also a good time to see how use the AutoCAD .NET Plug-In Wizard for Visual Studio.
- The wizard is a Visual Studio Add-In and after you have it installed there will be templates available for VB.NET and C# AutoCAD Applications. The install for the Wizard is available on the developer center at Autodesk.com. Here is the address. Lets take a look at how you can download the AutoCAD .NET Wizard.
- Demo: Show the link where the wizard can be downloaded from.
- Script: The link will take us to the Developer Center for AutoCAD. You can download the AutoCAD .NET wizards here using this link:
- Demo: Show the Wizard by creating a new project named Lab2.
- Script. Once the AutoCAD Wizard is installed you will see a choice for the “AutoCAD plug-in” in the Templates window on the New Project dialog. This is actually the beginning of Lab2 as you can see in the Lab 2 doc file.
- Go to the File menu then New and select Project, then select the “AutoCAD plug-in” in the Templates window.
- Well change the name to Lab2 and select a directory where we want the project to be created.
- On the AutoCAD .NET Wizard Configurator dialog notice that we can specify the location of the ObjectARX SDK.
- On my system this is correct by default so we’ll leave it at the default. On your system you may need to browse to a different location.
- For the functionality that we will have in our plug-in we do not need to reference any other assemblies besides the AutoCAD Database and AutoCAD.
- Select ok and then notice what the Wizard has created for us. There are two vb modules. These are myCommands.vb and myPlugin.vb. If we look at the references we can see that AcDbMgd and AcMgd have been referenced and the Copy Local setting is False. In myCommands.vb we find that the namespaces that we will need to add a command such as Autodesk.AutoCAD.Runtime have been added. The wizard has also added a couple of commands. Another step the wizard has done is to make the setting for debugging. If we go to properties and Debug, we see that it is already set to run acad.exe. I will change this to run AutoCAD 2011. When we go to the Debug menu and select start debugging AutoCAD is started up. We can load the dll with the NETLOAD command. We can copy the command name from the project and paste it on the AutoCAD command line and hit enter. Notice that our break point is hit. This shows that the wizard has created a working plug-in that we can load into AutoCAD. Once the break point is hit we can continue by going to debug menu and selecting continue. Or we can just use the Function key F5. To stop debugging use the Debug menu and select stop debugging. Our next step is to add functionality that will get input from the user when they run our command. Let’s take a look at the classes that enable us to do this.
- We can categorize the classes and methods used to get input from the user into three groups. One group of classes has Prompt as the first part of their name and Options as the last part of its name. These classes control what the user will see and how they can interact when we get the input from them. The next category is the methods of the Editor class that have Get as the first part of the name. The Get methods take one of the classes from the first category as an argument (these are ones with options in the name) and the Get methods return the other category of classes that have Prompt as the first part of their name and Result as the last part of the name.
- They type of input you are getting from the user determines which Prompt Options class to use. For example if you want the user to provide an Angle use PromptAngleOptions. If you need to get a point use PromptPointOptions. If you want the user to select entities then use PromptSelectionOptions. This list gives you an idea of the available classes for Prompt Options.
- The properties of the Prompt Options classes are what enable you to control the way the get function will work. The Message property is the text the user will see on the command line. Keywords enable the user to select from a list of options. In this example here they could enter the letter T to select triangle, the letter S to select Square and P for Pentagon. Using keywords sets the default for user input. The properties with Allow in their name such as AllowNegative make it easier to get the behavior you need. AllowNegative set to False will only allow the user to provide a value of zero or positive numbers as input.
- The Get methods of the Editor class such as GetString is the call that actually gets the input from the user. The Get functions normally take a Prompt Options and return a Prompt Result. In this code snippet a PromptKeywordOptions is created with the New keyword. The constructor takes two arguments, both are strings. The first argument is the text the user will see on the command and the second argument are the keywords they can choose from. The GetKeywords function of the Editor takes the PromptKeywordOptions named getWhichEntityOptions. The return is a PromptResult named getWhichEntityResult.
- As we have seen in the previous slide, a PromptResult or a class derived from it such as PromptDoubleResult is returned from the Get functions. You can make sure the Get function was successful by testing the Status property and see if it equals PromptStatus.OK. The PromptResult will also have a property that returns the value that was selected by the user. In this example we use the StringResult property.
- Now that we have an idea of how to get input from the user lets go ahead and work through the steps in lab2.
- Thank you for watching this DevTV presentation and good luck with LAB 2. We’ll continue our AutoCAD .NET API training in Session 3 where we’ll show how to use the AutoCAD .NET API to create AutoCAD entities such a circle, Block and a Block Reference.
- Welcome to this DevTV presentation on the AutoCAD .NET API. This is Session three, AutoCAD Database Fundamentals.
- The main objective of this session is to understand how to use the API to access and create entities in an AutoCAD drawing. We will do this by focusing on the AutoCAD drawing database and how you use Transactions and more specifically how transactions are used with the AutoCAD .NET API to create entities.
- When you work on a drawing in AutoCAD it may look like you are creating graphics. It is true that what you see in the AutoCAD editor is graphical. However what is really happening is that a database of AutoCAD objects are being created and these entities are being rendered on the screen. The database contains and organizes the entities in a hierarchical fashion. When you save the drawing, the database is in the dwg file. When the drawing is opened, the database is placed in memory. All the objects in the database have an ObjectId that is unique in the AutoCAD session. This ObjectId is similar to a Primary key in a relational database. Also many objects refer to other objects and may require them to exist such as a line needing to have the layer that the line is on be also in the drawing database.
- It is helpful to see the organization of the AutoCAD Database. There are the Symbol tables that have been in AutoCAD drawings sense Release 12 of AutoCAD. These symbol tables are used for elements such as layers and Linetypes. The Block Table contains Model and Paperspace as well as other Blocks. These blocks which are BlockTableRecords in the API contain the entities that you see rendered in the AutoCAD editor. The Named Object Dictionary contains dictionaries that were introduced in later releases of AutoCAD. New functionality that it is added in AutoCAD will often use the Named Objects Dictionary. Examples of this are Layouts and PlotSettings. The database also has variables that are unique to the drawing.
- Now lets drill down and explore Symbol tables in more detail. The symbol tables store SymbolTableRecords such as a LayerTableRecord and LineTypeTableRecord. In the API all of the SymbolTables have methods, that allow you to add a new record. They also have an Item property and a Has method that allows you to find if a SymbolTableRecord already exists in the Symbol Table. The Symbol Table can only contain records of a certain type. The LayerTable for example can only contain LayerTableRecords.
- The BlockTable is similar to other SymbolTables, however it contains BlockTableRecords. In AutoCAD what you see as a block is a BlockTableRecord in the API. The BlockTableRecord contains the entities that you see in the AutoCAD editor. The two BlockTableRecord, Model space and at least one PaperSpace BlockTableRecord will always exist in every drawing. You can search for a BlockTableRecord using a string with the name of the block or an ObjectId. The Block Table and Symbol Tables are automatically created when you create a new drawing. There is an example that will be useful when you are learning about the AutoCAD drawing database. This is an ARX example called ARXDBG. You can find this example in the ObjectARX SDK in samples, database directory. Using the SNOOPDB command from this example you can see the contents of database objects such as the BlockTable and BlockTableRecords. Let’s take a few moments and use the ARXDBG example to examine an AutoCAD drawing.
- Demo: use ArxDBG
- In AutoCAD, use Appload to load ARXDBG. (The reason not to use MGDDBG is that it is available from a DevNote. Trainees may not be ADN Members)
- Run the SNOOPDB command and look at the empty BlockTableRecord for model space.
- Add a line, run the snoopdb command and see the line in the Modelspace BTR.
- Add a circle and an ellipse and make a block from them. Run the snoopdb command again and look at the new BTR and the BlockReference that was added in modelspace.
- The AutoCAD .NET API will allow you to create an AutoCAD Database. This can either be a new one or one that you can populate with a dwg file. The most common workflow however is to get the currently active database. There are two ways to do this. One is to use the WorkingDatabase property of HostApplicationServices. The other is to use the Database property of the MdiActiveDocument as in this C# snippet.
- When we use the AutoCAD .NET API we will most likely be using ObjectIds. Every object will have an ObjectId and it is unique throughout the session of AutoCAD. This means that even with multiple drawings open there will not be any two objects with the same ObjectId. The ObjectId is automatically generated when the entity is added to the database. We will use the ObjectId with Transactions to open objects for manipulation.
- Using transactions makes working with the AutoCAD NET API easier and it is the recommended way to access objects in the AutoCAD drawing database. There maybe times that you need to open an object directly but that will be very rare. A transaction creates a boundary for your code. They allow you to handle errors cleanly and they operate with a single undo filer. The transaction needs to be committed to have the changes that your code made to be permanent. If the transaction is aborted then the changes made in the transaction are rolled back. Another thing to keep in mind is that transactions can be nested. What this means if the outer transaction is aborted, then so are the nested transactions even if they were committed.
- Here we see an example of creating a transaction. After we get the Database, we declare a transaction named trans. It is created using the StartTransaction method of the TransactionManager of that Database. A transaction has a Commit method that we use if everything went fine. If there was a problem we will call the Abort method. Always remember to explicitly dispose the Transaction. This is often done in the finally block of a Try Catch block.
- We use the GetObject method of the Transaction to Open objects. We use an ObjectId with this method. We also need to set whether to open the object for Read, Write or Notify. In many cases you will want to open the object for Read, test some its properties and then Upgrade the object to Open for write if you need to make changes to the object. This example shows how to open the BlockTable for write. Notice that the Database has a BlockTableId property that we can use for the ObjectId.
- In this more complete example we can see that we are relying on the Using keyword to dispose of the transaction. Notice that if everything was successful the commit method of the transaction is called. In your code you will want to also use a Try Catch block so you can gracefully handle any error that may occur. In the Catch block you can tell the user there was an error and take appropriate action. You would not need to dispose of the Transaction explicitly however because the Using keyword will take care of that for us.
- In the previous slide we saw an example that opens the BlockTable. The example did not do anything to the BlockTable or add any new BlockTableRecord. Here let’s focus on how you would add an object to the database. First you would need to find the right object to add the new object to. If we are creating a new layer then we would need to add a new layerTableRecord to the LayerTable. If we want to add a new circle to the drawing then we would need to append it to either the Model Space blockTableRecord or PaperSpace BlockTableRecord. Remember to always use the AddNewlyCreatedDBObject of the transaction to let the transaction now about the new object.
- This diagram shows some of the managed classes. Notice that in the .NET API, all of the objects inherit from DBObject. Objects like lines also inherit from Curve and Entity. You can see here a couple of other objects in the drawing database such as BlockTable.
- It is helpful to understand a few things about memory when we use the AutoCAD .NET API. The managed Objects in the .NET API are wrapped by unmanaged C++ objects. When we use the New keyword to create a new object you do not need to dispose of them because of the .NET garbage collection behaviour. If the object is disposed and it is not in the database the underlying unmanaged object is deleted. If the object is database resident the underlying unmanaged object is closed. If we use a transaction, which we will do most of the time, disposing or committing the transaction closes the unmanaged object. Now let’s put these ideas we covered in this presentation about the AutoCAD drawing database, ObjectId’s and transactions to work by going through lab three.
- In Lab3 we’ll use the API to create a circle, block and a BlockReference.
- Thank you for watching this DevTV presentation and good luck with LAB 3. We’ll continue our AutoCAD .NET API training in Session 4 where we’ll show how to use the AutoCAD .NET API to create Database Events and use the PaletteSet.
- Welcome to this DevTV presentation on the AutoCAD .NET API. This is Session four, Database Events and PaletteSet.
- The main objectives of this session is to understand how to use the API to create database events which will allow your application to respond when an event occurs in the AutoCAD drawing. You will also see how to use a PaletteSet which is a way to communicate with the user, with a graphical interface.
- The AutoCAD .NET API allows your application to take some action when something happens in AutoCAD. The way this works is that a notification that the event has occurred are sent to functions that have been set up to be notified of the event. The sender, in this case AutoCAD only requires a function pointer to dispatch the notification message. Multiple applications can receive the notification. The function that will be notified is required to have a specific signature. We use delegates to set up this event system. Delegates are similar to a class but they have a signature. They are like a type safe function pointer.
- The Delegate in the AutoCAD .NET API will usually have EventHandler in it’s name. The Object Browser is very useful when we need to find the signature of the delegate. Here you can see the ObjectEventHandler signature. Once you have the signature you create a function that uses that signature. In this case it requires two arguments, an Object and an ObjectEventArgs. In this C# code snippet you see how to instantiate the delegate, the constructor takes the function we create. Notice how the plus equals is used to add the delegate to sender’s list of listeners in C#. In this example, curDwg is the database of the Active AutoCAD Document.
- In VB you also create the event handler. In this example it is a Sub Procedure named objAppended. Notice it is using the required signature for an ObjectAppended event handler which needs two arguments. The first argument is an object and the second is an ObjectEventArgs. You use AddHandler to set up the event. Notice the first argument is the Event, in this case the ObjectAppended event of the database, and the second argument is a new ObjectEventHandler that uses the AddressOf with the name of the Sub we created named objAppended. You remove the event by using RemoveHandler and AddressOf.
- When you create a .NET application you may want to have a user interface that looks like it is built right into AutoCAD. A PaletteSet will allow you to do this. You can create a window that you can dock in the AutoCAD editor. Sometimes these are referred to as enhanced secondary windows. Or ESW. The paletteset class which allows you to create this user interface is in the Autodesk.AutoCAD.Windows namespace. You also need to add a Reference to PresentationCore.dll. Your PaletteSet will contain crontols such as a UserControl. Use Visual Studio wizards to create the controls and then use the Add method of the PaletteSet to add the UserControl to the PaletteSet.
- When you create a new PaletetSet you will need to supply a GUID. This is a unique identifier and can be created in Visual Studio by going to the Tools menu and selecting “Create Guid”. This option may not be available however as it depends on what settings were in effect when Visual Studio was installed. In your application you will want to have a global variable that will allow you to know whether or not the PaletteSet was previously created. You do this because the PaletteSet can be hidden or displayed, but you would not want to recreate it each time the user re-displays it.
- Let’s put what we have learned to the test by doing the steps in Lab 4, where we’ll add database events and create a PalettSet.
- Thank you for watching this DevTV presentation and good luck with LAB 4. We’ll continue our AutoCAD .NET API training in Session 5 where we’ll show how to use the AutoCAD .NET API to create Dictionaries and Containers and also learn about Type Identification and Casting.
- Welcome to this DevTV presentation on the AutoCAD .NET API. This is Session five, Dictionaries, Containers, Type Identification and Casting.
- In this session the main objective is to understand how dictionaries are used in the API to store data. This will include a discussion on Xrecords. We’ll also learn how to traverse other containers such as the BlockTable. Two other topics we’ll cover are Type Identification and casting.
- In the AutoCAD drawing database there are dictionaries. A dictionary is a type of container that only contains data or other dictionaries that contain the data. These are non-graphical objects that are derived from dbObject, Dictionaries do not contain objects that are derived from DbEntity. Each item in a dictionary will have a key that will allow you to find out if a particular item already exists in that dictionary. You use the GetAt method or item property for this.
- If you examine the database of brand new drawing you will find that a dictionary is automatically created. The name of this dictionary is the Named Objects Dictionary. Commonly referred to as the NOD. This dictionary will contain other dictionaries. You can think of it as the root dictionary for the drawing and it is used to store data at the database level. There is another type of dictionary that can be created. It is called an Extension dictionary an it can exist for any Entity in the drawing. You use the extension dictionary to store data with that entity. This dictionary is only created by a custom program and does not exist by default. Lets use the ARXDBG example to see the dictionaries in the AutoCAD drawing database.
- Here are a couple of VB code snippets. The first one gets the Named Object Dictionary. It does this by getting the database and then by using the GetObject method of a transaction. Notice that you use the NamedObjectsDictionaryId of the database for the OBjectId argument of GetObject. This line of code will instantiate a variable named NOD as a DBDictionary. The second snippet shows how to create an extension dictionary by using the CreateExtensionDictionary method of the entity.
- One of the most common type of object added to a dictionary is the xrecord. An xrecord is a Result Buffer which is a linked list of TypedValues. A TypedValue is a DataType and value pair. An xrecord will not have a search key and you should keep track of the order that the data is stored. In this code snippet you can see how a ResultBuffer is created. Notice how the constructor for the ResultBuffer takes new TypedValues. You can use the DxfCode enumeration for the type argument for the TypeValue constructor. The second argument is the actual value. In this first TypedValue DxfCode.Int16 is used and the value for this TypedValue is 1. The Data property of the Xrecord is then used to incorporate the new ResultBuffer that was created with the TypedValues.
- In this series we have discussed Symbol Tables, BlockTableRecords and Dictionaries. These objects are containers and the API allows you to iterate through them. There are other objects that are enumerable as well such as Polylines, the polyfacemesh and Acis solids. When you place a blockreference with attributes you will need to iterate through the attributes of the BlockReference to set the values for the attributes.
- Here is a VB example of traversing the BlockTable. As we have seen you can use the WorkingDatabase of HostApplicationServices to get the database of the Active drawing. We then use the GetObject method of a transaction. The argument for the ObjectId is the BlockTableId property of the database. This will get us the BlockTable. We can then use a For each loop to get the ObjectId of each BlockTableRecord in the BlockTable. We would then use the BlockTableRecord to add entities or take some other action.
- The .NET API through the System.Reflection namespace allows you to query the metadata in a .NET module at runtime. It will also allow you to query type information for an object. The System.Type class is fundamental to Runtime Type Identification. You use the GetType method of the object to get the type. In this C# example GetType and the Name property is used to find out if the entity is a Polyline2d. In VB there is also a GetType function and the equivalent in C# is the typeof operator. You will use these functions to ensure your code is working on the right type of entity.
- The .NET API allows you to cast an object from one type to another. This is necessary when iterating objects in a collection that has multiple types and you only want to work with a certain type in that collection. For example lets say the code is iterating through the modelspace blockTableRecord and you want to do something only with the BlockReferences. The code would test to see if the type of entity is a BlockReference and if it is, it would cast that entity to a BlockReference. In Visual Basic casting is done using the Ctype function. Notice that this function takes the object for the first argument, and a type for the second argument. In C# you use the Type in parentheses to cast the entity to the object on the left side of the equals sign. You can also use the as operator and then test to make sure the object is not null. The is operator can also be helpful to test the type of the object.
- Now let’s go ahead and use the API in LAB 5 to access dictionaries.
- Thank you for watching this DevTV presentation and good luck with LAB 5. We’ll continue our AutoCAD .NET API training in Session 6 where we’ll show how to use the AutoCAD .NET API to work with the PointMonitor a powerful API which will allow you to monitor user input.
- Welcome to this DevTV presentation on the AutoCAD .NET API. This is Session 6 covering the InputPoint Monitor.
- In this session you learn about the InputPoint monitor and see how it is used to provide feedback to the user.
- The InputPoint Monitor monitors the input mechanism in AutoCAD. This event gives your application a lot of control for dynamically interacting with the user. The InputPoint Monitor allows you to get real time aperture data such as the current cursor position and a list of all the entities that the aperture is currently hovering over. We can also get which of the mouse buttons were pressed. We can tell which grip point is selected, and more. We can also create temporary graphics on the fly and display tooltips depending on conditions that we specify. You add a PointMonitor using an event of the Editor. The delegate of this event is a PointMonitorEventHandler. Here is a command that adds a point monitor. Notice that it is created in a similar way to other events such as the database events that were created in Lab 3.
- The PointMonitorEventArgs is passed into to the PointMonitorEventHandler Delegate. This parameter is what you need to use to a append a tooltip to the cursor. The Context property of the PointMonitorEventArgs allows you to get the entities under the cursor with the GetPickedEntities() method. This method will return an array of FullSubEntityPath objects. These objects will have a collection of entities and one thing you can do is get the ObjectId of these entities and open the entity to determine what the entity type is. To create temporary graphics you use the Draw method of the Geometry property of DrawContext. Notice that Draw method takes an entity as argument. To draw entities at a consistent size, regardless of the current zoom value, you use GetNumPixelsInUnitSquare to determine the values to use. This method takes a Point3d object and returns a Point2d object. You use the Point2d objects x and y values to control the size of the entities passed to the draw method.
- Now let’s see an example of creating a PointMonitor by going through the steps in Lab 6.
- Thank you for watching this DevTV presentation and good luck with LAB 6. We’ll continue this AutoCAD .NET API training in Session 7 where we’ll see how to use the Jigs that will allow you to provide a drag image in the AutoCAD editor.
- Welcome to this DevTV presentation on the AutoCAD .NET API. This is Session seven where will focus on Jigs.
- After completing this session the you will understand what a Jig is and how it can be used to help the user place an entity in a drawing.
- In the real world a Jig is a frame to which you can attach an item, hold it firm and then manipulate or form it into position. In AutoCAD, a Jig is very similar – a Jig is an API class which you can use to visually manipulate an entity into place using the User Interface. A good and simple example of this can be seen with the Circle command – you pick the center point of the circle, then to select the radius you can visually resize the circle.
We have 2 types of Jig in the AutoCAD .NET API, the Entity Jig controls just one entity at a time and the DrawJig allows you to attach 1 or more entities. The Entity Jig wraps the ObjectARX implementation, whereas the DrawJig is an exclusive class owned only by the .NET API. To use a jig you will need to create a class that inherits from EntityJig or DrawJig. We will focus on EntityJig in this training.
- The constructor of the class that you derive from EntityJig will take an argument for the entity that is being jigged. In this example we create a new circle and pass that circle into the constructor for a class named myCircleJig that has inherited from EntityJig. We then use the Drag function of the editor and pass in our jig object. Once we call the Drag method several things will happen. First user drag movement is obtained and this movement is interpreted as a distance, angle, or point. These values are then used to update the entity's data and the the entity's WorldDraw method is called to redraw the entity on the screen. When all the desired properties of the entity are gathered by jigging you can append the entity to the drawing.
- In our class that inherited from EntityJig we need to override two functions. These are Sampler and Update. The Sampler function is used to get input from the user such as size and location. In the Update function you update the display of the entity.
- The Sampler function takes one argument. This is a JigPrompts of EditorInput. JigPrompts is used in the Sampler function to control what happens when the entity is being dragged. For example you can use the AcquirePoint function of the JigPrompts to get a point or use the AcquireDistance method to get a distance from the user. The Sampler Function Returns a SamplerStatus Enumeration. You need to determine the value of the SamplerStatus to return. If the location of the drag has not changed you return SamplerStatus.NoChange. Doing this will stop the drag image from doing excisive flickering. Remember that these functions are continuously called during the drag. If there is a change in the location of the drag you return SamplerStatus.OK.
- When the sampler function returns SamplerStatus.OK the Update function is called and this is where you change the properties for the entity you passed into the constructor of your class that inherited from EntityJig. In this example the center of the circle is updated and then the Radius. The select case was used to gather input using a jig in two passes. When the center is being gathered, AcquirePoint is being used in the Sampler Function to set the value for the member variable CenterPoint. When the radius is being determined AcquireDistance is being used to set the radius member variable. From this you get the idea that you will need to coordinate your code in the Sampler function and the Update function so they can work together to give you the behaviour that you need.
- Now lets see an example of using the API to create an EntityJig by going through the steps in Lab 7.
- Thank you for watching this DevTV presentation and good luck with LAB 7. We’ll continue this AutoCAD .NET API training in Session 8 where we’ll see how to create more user interface elements such as a Context menu, Drag & Drop, and Extend Options Dialog.
- Welcome to this DevTV presentation on the AutoCAD .NET API. This is Session eight User Interface Elements.
- After completing this session the you will understand how the .NET API can be used to add user interface elements such as a context menu, customize the AutoCAD Options dialog and how to enable Drag and Drop from a palette to run a command. Keep in mind that this session does not cover customizing the ribbon, toolbars or AutoCAD pull down menus. In this session you will learn about classes in the AutoCAD.Windows namespace not the AutoCAD.Customization namespace. Another way of looking at it, is that we are not covering automating the manipulation of CUIx files.
- You can add a context menu at the application level or you can have a context menu just for certain types of entities. The application level context menu displays when the user clicks on the drawing background. You add this context menu using AddDefaultContextMenuExtension of the Application. In this example a context menu is being created. The class for a context menu is the ContextMenuExtension and it has properties such as the Title. The ContextMenuExtension also has a collection of MenuItems. Here a menu item named MI is created and the constructor for it takes a string which will be the text the user sees on the menu item. When the user right clicks on the drawing background the context menu will display and there will be a new item on the menu with the text “circle Jig”. When they click on the menu, the menu items will display. In this case the menu item will have the text “Run Circle Jig”. When they click on the menu item, the function CallBackOnClick will be called. You can see that AddHander is used to control which function will be used. You can also create a context menu that will display when the user right clicks on a particular type of object. To create this type of context menu, you use AddObjectContextMenuExtension. Notice that one of the arguments for this method takes an RXClass. In this example the context menu will display when the user right clicks on any line in the drawing. In the lab we will only be adding an application level context menu. However it would be easy to change it so it uses the entity as in this example instead.
- When AutoCAD loads a .NET dll, it queries the application's assembly for an ExtensionApplication custom attribute. If this attribute is found, AutoCAD sets the attribute's associated type as the application's entry point. This class specified in the attribute will need to implement the IExtensionApplication interface and this interface has Initialize and Terminate functions. We can use the Initialize function to set up our application such as adding the context menu. The terminate function will be called when the .NET assembly is unloaded. This will happen when AutoCAD is shut down as there is not an straight forward way to unload a .NET module. Also using the ExtensionApplication attribute can save time loading a large .NET module because AutoCAD will not need to check all of the objects in the assembly, to find out if there is a class that is the ExtensionApplication.
- In addition to searching for an IExtensionApplication implementation, AutoCAD will also query the assembly for one or more CommandClass attributes. If instances of this attribute are found, AutoCAD searches only their associated types for command methods. Otherwise, it searches all exported types so using this attribute can also save time loading a large .NET module. Here you see the signature for this assembly attribute.
- Now let’s see how to use the API to create a Context Menu by going through the first part of Lab 8.
- The .NET API allows you to add a tab to the Options dialog. You do this by using the DisplayingOptionDialog event of the Application. In this example AddHander is being used to add a callback to a function named TabHandler. When TabHandler is called it will need a UserControl that will be used for the tab added to the OPTIONS dialog. On the user control you would add controls such as a text box that will allow the user to change a setting. The usercontrol also needs a function that can be called when the user clicks ok in the OPTIONS dialog.
- After adding the DisplayingOptionDialog event our function will be called when the user runs the OPTIONS command. In this example the function is called TabHandler. The function needs to have two arguments, one of the arguments is an Object and the other is a TabbedDialogEventArgs. The AddTab function of the TabbedDialogEventArgs is used to add the new tab. You can see that the AddTab function takes a string for the first argument. This string will be the text on the Tab in the Options dialog. The second argument is a TabbedDialogExtension. Notice that the constructor for the TabbedDialogExtension takes the new UserControl and a TabbedDialogAction. The constructor of the TabbedDialogAction takes a function of the UserControl which in this case is named OnOk. This function will be called when the user clicks ok on the OPTIONS dialog. In this function named OnOk you would get the values that the user put on the form and set your member variables with those values.
- Now lets see how to use the API to add a tab to the OPTIONS dialog by going through the final section in Lab 8.
- You can set up a label on a UserControl that can be used by drag and drop to automate running a command. To do this first add a label to the UserControl and then enable the MouseMove event for that label. In this example the name of the Label is DragLabel. In the MouseMove event you call the DoDragDrop function of the Application. The fourth argument of this function is a class that you need to create that will have a function that will be run when the label is dropped on the AutoCAD drawing. In this case the class is named MyDropTarget. The other arguments are the DragSource and Data arguments and these are set to the UserControl specified by the Me keyword. The AllowedEffects argument is set to All using the DragDropEffectsAll enumeration.
- The class that is passed into the DoDragDrop function needs to inherit from Autodesk.AutoCAD.Windows.DropTarget and also needs to override the OnDrop function. In the OnDrop function you define what happens when the drop occurs. In this example a function AddAnEnt of the adskClass is being run. Notice that the active document is being locked by creating a DocumentLock variable. The document needs to be locked when dragging and dropping if objects are going to be opened in the document. When AddAnEnt is run from a command like was done in previous labs, document locking is taken care of automatically. Because AddAnEnt is going to be opening database objects and is not run from a command, the document needs to be locked or an eLockViolation error would occur. The using, and end using statement with a DocumentLock variable will lock and unlock the document.
- Now lets see how to use the API to enable Drag & Drop by going through the final part of Lab 8.
- The AutoCAD .NET API also supports the status bar and the tray. To see the classes for these elements see the Autodesk.AutoCAD.Windows namespace. Also if you are going to be using dialogs be sure to use the ShowModalDialog and ShowModelessDialog of the Application. Using the standard "ShowDialog" or "Show" methods to display .NET modal (or modeless) forms can cause AutoCAD to freeze or cause some other unwanted behaviour.
- Thank you for watching this DevTV presentation and good luck with your application development and using the .NET API to add user interface elements like the ones you create by doing the steps in LAB 8.