December 2014

Sun Mon Tue Wed Thu Fri Sat
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      










« AutoCAD 2008 – other new APIs | Main | Using the COM interface for AutoCAD objects from .NET »

February 19, 2007

Getting access to an entity from its handle in AutoCAD .NET

This comment came in overnight from Brian:

I was hoping to work out how to get the Entity from the handle and then erase it, from your posts, I've learned a lot but not found the answer to this one yet, I still have a mountain to climb. (I'm using VB.NET, I've done it in VB6 +COM, even in Lisp but .NET ....)

As it's such a good question, I'm making a post out of it...

The trick is to go from a hexadecimal string to a 64-bit integer (using System.Convert.ToInt64(str,16); which specifies the string as being "base-16" or hexadecimal).

From there you simply use the long integer to create a Handle, which you pass into Database.GetObjectId(): you should specify false for the first argument, as we don't want to create a new ObjectId if one does not exist, and pass 0 into the third argument (which is reserved for future use).

From there you should have a valid ObjectId that can be opened and erased. If the handle entered doesn't exist, then GetObjectId() will throw an exception - I'll leave it to the user to catch this exception more elegantly (i.e. with a nicer error message).

Here's the C# code:


using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

using System;


namespace HandleTest

{

  public class HandleCommands

  {

    [CommandMethod("EH")]

    public void EraseObjectFromHandle()

    {

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      Editor ed = doc.Editor;

      Database db = doc.Database;


      try

      {

        // Ask for a string representing the handle

        PromptResult pr =

          ed.GetString("\nEnter handle of object to erase: ");

        if (pr.Status == PromptStatus.OK)

        {

          // Convert hexadecimal string to 64-bit integer

          long ln = Convert.ToInt64(pr.StringResult, 16);

          // Not create a Handle from the long integer

          Handle hn = new Handle(ln);

          // And attempt to get an ObjectId for the Handle

          ObjectId id = db.GetObjectId(false,hn,0);

          // Finally let's open the object and erase it

          Transaction tr =

            doc.TransactionManager.StartTransaction();

          using (tr)

          {

            DBObject obj =

              tr.GetObject(id, OpenMode.ForWrite);

            obj.Erase();

            tr.Commit();

          }

        }

      }

      catch (System.Exception ex)

      {

        ed.WriteMessage(

          "Exception: " + ex

        );

      }

    }

  }

}

And as Brian specifed VB.NET, here's that, too:


Imports Autodesk.AutoCAD.ApplicationServices

Imports Autodesk.AutoCAD.DatabaseServices

Imports Autodesk.AutoCAD.EditorInput

Imports Autodesk.AutoCAD.Runtime

Imports System


Namespace HandleTest


  Public Class HandleCommands


    <CommandMethod("EH")> _

    Public Sub EraseObjectFromHandle()

      Dim doc As Document = _

        Application.DocumentManager.MdiActiveDocument

      Dim ed As Editor = doc.Editor

      Dim db As Database = doc.Database

      Try

        ' Ask for a string representing the handle

        Dim pr As PromptResult = _

          ed.GetString( _

            vbLf + _

            "Enter handle of object to erase: ")

        If (pr.Status = PromptStatus.OK) Then

          ' Convert hexadecimal string to 64-bit integer

          Dim ln As Long = _

            Convert.ToInt64(pr.StringResult, 16)

          ' Not create a Handle from the long integer

          Dim hn As Handle = New Handle(ln)

          ' And attempt to get an ObjectId for the Handle

          Dim id As ObjectId = _

            db.GetObjectId(False, hn, 0)

          ' Finally let's open the object and erase it

          Dim tr As Transaction = _

            doc.TransactionManager.StartTransaction

          Dim obj As DBObject = _

            tr.GetObject(id, OpenMode.ForWrite)

          obj.Erase()

          tr.Commit()

          tr.Dispose()

        End If

      Catch ex As System.Exception

        ed.WriteMessage("Exception: " + ex.ToString)

      End Try

    End Sub

  End Class

End Namespace

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d83452464869e200d8351a797469e2

Listed below are links to weblogs that reference Getting access to an entity from its handle in AutoCAD .NET:

blog comments powered by Disqus

Feed/Share

10 Random Posts