Create Autocad Drawing From Vbnet

CAD Clinic: AutoCAD Commands in VB .NET

14 Jun, 2005

By: Mike Tuersley

Cadalyst


Use .NET Editors to Create Simple AutoCAD commands

Welcome back! This month we're going to create two simple AutoCAD commands in Visual Basic .Net. If you have not already read last month's column discussing .NET editors, please do so before continuing with this article. With the commands that I will create here, you can use any editor -- including Windows' NotePad -- because no graphics are involved. I will use the free .NET editor SharpDevelop by SharpDevelop.

For this article, we will recreate the classic "Hello World" example and throw the text into AutoCAD's command line and into an MText object. The code is derived from the Autodesk sample available in the AutoCAD 2006 install, in the AutoCAD 2006 ObjectARX toolkit and from the Autodesk Web site.

To begin, open SharpDevelop and create a new combine -- a combine is equivalent to a new project in Microsoft Visual Basic. In the next dialog box, select a Class Library combine (figure 1).

figure
Figure 1. Creating a new project in SharpDevelop.

Now add the references to the project just like with Visual Basic 6 or VBA. An important difference exists between Microsoft's Visual Studio products and SharpDevelop here. After selecting to add a reference in VS, you must browse to AutoCAD's installed directory and select the managed libraries: ACDBMGD.DLL and ACMGD.DLL. Don't select the AutoCAD 2006 type library in the COM tab! That would create a COM InterOp project similar to VB6-based programming. This project will be a .NET managed project, so you need to hook into the MGD files (please refer to last month's column for information regarding managed code). This step is easier in SharpDevelop because the two files are selected through the GAC tab (figure 2).

figure
Figure 2. Adding references in SharpDevelop

Now you should have the code window open for SharpDevelop. Its environment is similar to Visual Studio's. For more information, please refer to SharpDevelop's Help file. Okay, let's look at the code to accomplish the first "Hello World!" example in VB.NET. The easiest way is for me to show the code then describe it:

          Imports System Imports System.Runtime.InteropServices Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.ApplicationServices  Imports acadApp = Autodesk.AutoCAD.ApplicationServices.Application  Public Class HelloWorld                          _   Public Sub HelloCommand()     acadApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage( _     vbNewLine & "Hello World!" & vbNewLine)     acadApp.UpdateScreen()   End Sub  End ClassM                  

Starting from the top, the first block of code is the Imports statements. Besides adding references to the assemblies (references) in .NET, you specifically state which assemblies' namespaces are to be used. Think of a namespace as an object within the reference that you want to access. This step also saves typing within your code. For example, in the Autodesk examples, you'll see them call the MdiActiveDocument.Editor like this:

          Autodesk.AutoCAD.ApplicationServices.DocumentManager.   MdiActiveDocument.Editor        

That's a lot of code to type in if you don't need to.

Also notice that within the Imports block, I also create a global variable AND set it in the same statement. This is a great feature of .NET where you can declare and set variables all in one line such as:

• In VB6-based code:

          Dim sText As String sText = "Hello World"        

• In .NET code:

          Dim sText As String = "Hello World"        

The next block of code is our class object. Just as in VB6-based programming, our DLL needs a class so it can be called from AutoCAD. Then I have the actual subroutine, HelloCommand, where I write the message to AutoCAD's command line. Notice the subroutine has a descriptor attached to it:

          <Autodesk.AutoCAD.Runtime.CommandMethod("HELLO")>        

This is all we need to make our subroutine accessible from within AutoCAD! No more calling it through VBA or writing a LISP wrapper to access it. That functionality alone is worth the learning curve of .NET.

          Imports System Imports Microsoft.VisualBasic Imports acadApp = Autodesk.AutoCAD.ApplicationServices.Application  Public Class HelloWorld  <Autodesk.AutoCAD.Runtime.CommandMethod("HELLO")> _   Public Sub HelloCommand()     acadApp.DocumentManager.MdiActiveDocument.Editor. 	  WriteMessage(vbNewLine & _     "Hello World!" & vbNewLine)     acadApp.UpdateScreen()   End Sub  End Class        

To test this program, compile it. Then fire up AutoCAD 2006, type in NETLOAD and load the DLL you just created. Once it loads, type HELLO into AutoCAD's command prompt and "Hello World!" should echo back after you press the Enter key.

figure
Figure 3. Using NETLOAD in AutoCAD and the end result of Hello World

No unloading option exists with .NET assemblies, so AutoCAD needs to be shutdown if you want to load the DLL a second time. This is important to note in case, for example, the DLL did not work and you need to change it and re-test it.

Assuming that worked, let's change the program to insert the "Hello World!" text into the current drawing as MText. The code to accomplish this is going to look like:

          Imports System Imports System.Type Imports System.CLSCompliantAttribute Imports System.Reflection Imports System.Runtime.InteropServices Imports Microsoft.VisualBasic Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.EditorInput  Imports acadApp = Autodesk.AutoCAD.ApplicationServices.Application  Public Class HelloWorld  <Autodesk.AutoCAD.Runtime.CommandMethod("HELLOTEXT")> _   Public Function HelloTextCommand()     Dim acadMText As MText     Dim acadBT As BlockTable     Dim acadBTR As BlockTableRecord     Dim acadDB As Database = HostApplicationServices.WorkingDatabase     Dim acadTrans As Transaction     acadTrans = acadDB.TransactionManager.StartTransaction()     Try       acadBT = trans.GetObject(acadDB.BlockTableId, _         Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead)       acadBTR = trans.GetObject(acadBT(acadBTR.ModelSpace), _         Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)       acadMText = New MText()       acadMText.Contents = "Hello World!!"       acadBTR.AppendEntity(acadMText)       acadTrans.AddNewlyCreatedDBObject(acadMText, True)       acadTrans.Commit()     Catch       acadTrans.Abort()     Finally       If Not isnothing(acadTrans) Then acadTrans.Dispose()       If Not isnothing(acadMText) Then acadMText.dispose()       If Not isnothing(acadBT) Then acadBT.dispose()       If Not isnothing(acadDB) Then acadDB.dispose()     End Try   End Function End Class        

Starting at the top, again, I added some more calls to the Imports section. Because this required drawing the text, I had to go into AutoCAD instead of just using its command line. After that, I declared my class object and my subroutine. Here, I changed the sub name and the AutoCAD command so this code can co-exist in a project alongside the first example.

Communicate with AutoCAD
Next, is the actual communication with AutoCAD, which is extremely important! You'll use this same structure again and again as you do more managed projects, so it is worth delving into in more detail.

With unmanaged, COM-based code, I could access the appropriate drawing space (model or layout) and add the MText object. With managed code however, I am inserting an MText object directly into the drawing's database. In order to complete this task, I must go through the AutoCAD Transaction object just as if this were a program I was writing that talked to a Microsoft Access or SQL database. This process can be stepped out like so:

  1. Start a Transaction
  2. Connect to the drawing's database
  3. Connect to the drawing database's Block table
  4. Create a record in the Block table
  5. Save or Cancel the transaction

After the transaction is initiated, I talk to the Block table to retrieve an instance of the space I am looking to draw in -- model space in this example. Remember that model and layouts are seen as blocks to a drawing. Next I talk to the block table and retrieve a new entry for the MText object. Think of this step as adding a new row to a database table. I create my MText entity and set up its properties -- text string, color, etc. -- add it to the block table and commit the transaction to the drawing's database. Sounds fairly complicated, but once you get used to it, it becomes second nature.

Try-Catch-Finally Loop
The other new concept in this block of code is the Try-Catch-Finally loop in .NET. The Try statement is a hook to .NET's garbage collection and handles error trapping for us. In .NET, we don't need the old "On Error Resume" statements, and you should not use them because they bypass the automatic garbage collector in .NET. The way this structure works is if any error occurs within the code following the Try command, it is sent to the Catch statement. Multiple Catch statements can handle different errors just like the COM approach of testing for error codes in an error handler. For example, a typical Catch statement looks like: CATCH ex As Exception. The Finally command is optional. If included, the program goes there regardless of whether an error occurs or not. In this example, I want to clear out my object variables no matter what happens. As you can see, I call the individual object's Dispose method to terminate the object reference instead of setting the object to Nothing as in VB6. If I were to set an object to Nothing in .NET, the reference to the object would still exist -- it would just be nothing.

Source Code Notes
If you are just starting with .NET, the source code for this month is complete, but you may need to remove and reattach the references to the MGD files. If you are using another editor instead of SharpDevelop, the only file needed in the source code is the NEW CLASS.VB file. From Microsoft's Visual Studio, create a new class library project and then add the file to it. For other editors, just use this file as you need. The nice feature with .NET is that the VB file is ASCII text until the time it is compiled, so it can be opened with a program as simple as NotePad.

Kick It Up A Notch!
Using this code as an example, explore what else you can create in the managed world. Remember to use the Object Browser to walk yourself through the API as you do more complicated tasks. Next month, I will take both these examples and do them again in C#. See you then!

More News and Resources from Cadalyst Partners




Visit Cadalyst's Library for free CAD resources


lorentzbetly1979.blogspot.com

Source: https://www.cadalyst.com/cad/autocad/cad-clinic-autocad-commands-vb-net-5195

0 Response to "Create Autocad Drawing From Vbnet"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel