Author Topic: Calling AutoCAD command  (Read 10287 times)

0 Members and 1 Guest are viewing this topic.

latour_g

  • Newt
  • Posts: 184
Calling AutoCAD command
« on: April 30, 2013, 02:34:55 PM »
Hi,
I want to call the command measure and pass the parameters.   

I put my parameters in a array with \n for the return character:

Here are the questions of the command Measure and my parameters :
Select object to measure : pl2d.ObjectId --> pl2d is a polyline2d
Specify length of segment or [Block] : B
Enter name of block to insert : FLEX100
Align block with object? [Yes/No] : Y
Specify length of segment : 1.5

Wich give that in my code :

Code: [Select]
       
object[] data = { "_.measure" + "\n" + pl2d.ObjectId + "\n" + "B" + "\n" + "FLEX100" + "\n" + "Y" + "\n" + "1.5" + "\n" };
ActiveDoc.GetType().InvokeMember("SendCommand", System.Reflection.BindingFlags.InvokeMethod, null, ActiveDoc, data);

I ain't passing the correct parameter for the first question because I'm having this message :
Select object to measure: (0)
; error: bad function: 0

I joined a picture of what would the final result be of this measure command.     

BlackBox

  • King Gator
  • Posts: 3770
Re: Calling AutoCAD command
« Reply #1 on: April 30, 2013, 02:59:22 PM »
Consider the SendStringToExecute Method.
"How we think determines what we do, and what we do determines what we get."

latour_g

  • Newt
  • Posts: 184
Re: Calling AutoCAD command
« Reply #2 on: April 30, 2013, 03:39:30 PM »
I thought about using that but I wasn't sure how I would need to pass the first parameter :

AcadApp.DocumentManager.MdiActiveDocument.SendStringToExecute("._measure pl2d.ObjectId,b,FLEX100,o,1.5", true, false, false);

This is not working either since I'm obviously doing something wrong.

BlackBox

  • King Gator
  • Posts: 3770
"How we think determines what we do, and what we do determines what we get."

latour_g

  • Newt
  • Posts: 184
Re: Calling AutoCAD command
« Reply #4 on: April 30, 2013, 04:45:18 PM »
Unfortunately no.  I would need to find an example of a command that need an object in parameter.

BlackBox

  • King Gator
  • Posts: 3770
Re: Calling AutoCAD command
« Reply #5 on: April 30, 2013, 04:59:33 PM »
Have you tried using the HandEnt LispFunction Method within your SendStringToExecute() Method Call?

Pseudo-code:
Code - C#: [Select]
  1. "(handent " + pl2d.ObjectId.Handle.ToString() + ")"
  2.  

** Note - I'm not in Visual Studio at the moment, so you may need to modify with (char)34, etc.
"How we think determines what we do, and what we do determines what we get."

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Calling AutoCAD command
« Reply #6 on: April 30, 2013, 05:02:42 PM »
Hi,

Search for 'RunCommand' in this forum. Tony Tanzillo shared some nice wrappers for this undocumented method which allows to pass managed types as arguments.
Speaking English as a French Frog

BlackBox

  • King Gator
  • Posts: 3770
Re: Calling AutoCAD command
« Reply #7 on: April 30, 2013, 05:07:14 PM »
Search for 'RunCommand' in this forum. Tony Tanzillo shared some nice wrappers for this undocumented method which allows to pass managed types as arguments.

Thank you, Gile (and Tony, of course)



For others:

http://www.theswamp.org/index.php?topic=44191.msg494532#msg494532
"How we think determines what we do, and what we do determines what we get."

latour_g

  • Newt
  • Posts: 184
Re: Calling AutoCAD command
« Reply #8 on: May 01, 2013, 11:44:13 AM »
BlackBox : I have try "(handent " + pl2d.ObjectId.Handle.ToString() + ")" but it's not working. It's giving this error :
Select object to measure : (handent 21D)
; error: incorrect argument type : stringp nil

Well I have found an example that does what I want to do (in VB instead of .NET).  Could I convert my Polyline2d into AcadObject ?
 http://adndevblog.typepad.com/autocad/2012/06/invoking-the-measure-command-using-sendcommand-in-vbnet.html

Code: [Select]
  <CommandMethod("MYMEASURE")> _

    Public Sub MYMEASURE()

      Dim app As AcadApplication = Application.AcadApplication

      Dim obj1, obj2 As Object

      'Use ActiveX GetEntity function, as we only want to select a single entity

      app.ActiveDocument.Utility.GetEntity(obj1, obj2,

                        "select a polyline which you want to measure")

      'Cast Object to AcadObject

      Dim tmpObj As AcadObject = CType(obj1, AcadObject)

      Dim strObjName As String

      strObjName = tmpObj.ObjectName

      '   Check its a polyline

      If strObjName = "AcDbPolyline" Then

        Dim str1 As String

        'Handle of polyline is used to identify it to MEASURE command

        str1 = "(handent """ + tmpObj.Handle + """" + ")"

        Dim str As String

        'Insert instances of 'myblock' at 10 unit spacing along polyline

        '(replace myblock with name of your block)

        ' the polyline needs to be longer than 10

        str = "_measure "

        str = str & str1 & vbCr & "_block" & vbCr & "myblock" &

                                    vbCr & "_Y" & vbCr & "10" & vbCr

        app.ActiveDocument.SendCommand(str)

      End If

    End Sub


gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Calling AutoCAD command
« Reply #9 on: May 01, 2013, 12:29:21 PM »
Hi,

IMO you should avoid to use the COM interop when some .NET methods are available.
What's wrong with the way I purposed using the Editor.Command() extension method ?

Here's a little example:
Code - C#: [Select]
  1. using System;
  2. using System.Linq.Expressions;
  3. using System.Reflection;
  4. using Autodesk.AutoCAD.ApplicationServices;
  5. using Autodesk.AutoCAD.DatabaseServices;
  6. using Autodesk.AutoCAD.EditorInput;
  7. using Autodesk.AutoCAD.Runtime;
  8.  
  9. [assembly: CommandClass(typeof(MeasureSample.CommandMethods))]
  10.  
  11. namespace MeasureSample
  12. {
  13.     public static class EditorInputExtensionMethods
  14.     {
  15.         public static PromptStatus Command(this Editor editor, params object[] args)
  16.         {
  17.             if (editor == null)
  18.                 throw new ArgumentNullException("editor");
  19.             return runCommand(editor, args);
  20.         }
  21.  
  22.         static Func<Editor, object[], PromptStatus> runCommand = GenerateRunCommand();
  23.  
  24.         static Func<Editor, object[], PromptStatus> GenerateRunCommand()
  25.         {
  26.             MethodInfo method = typeof(Editor).GetMethod("RunCommand",
  27.                BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
  28.             ParameterExpression instance = Expression.Parameter(typeof(Editor), "editor");
  29.             ParameterExpression args = Expression.Parameter(typeof(object[]), "args");
  30.             return Expression.Lambda<Func<Editor, object[], PromptStatus>>(
  31.                Expression.Call(instance, method, args), instance, args)
  32.                   .Compile();
  33.         }
  34.     }
  35.  
  36.     public class CommandMethods
  37.     {
  38.         [CommandMethod("YOURMEASURE")]
  39.         public void YourMeasure()
  40.         {
  41.             Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  42.  
  43.             // Prompt the user for selecting a polyline
  44.             PromptEntityOptions peo = new PromptEntityOptions("\nSelect a polyline: ");
  45.             peo.SetRejectMessage("Only a polyline !");
  46.             peo.AddAllowedClass(typeof(Polyline), true);
  47.             PromptEntityResult per = ed.GetEntity(peo);
  48.             if (per.Status != PromptStatus.OK) return;
  49.  
  50.             //  Run the MEASURE command
  51.             ed.Command("_measure", per.ObjectId, "_block", "yourblock", "_yes", 10.0);
  52.         }
  53.     }
  54. }
  55.  

Code - vb.net: [Select]
  1. Imports System.Linq.Expressions
  2. Imports System.Reflection
  3. Imports Autodesk.AutoCAD.ApplicationServices
  4. Imports Autodesk.AutoCAD.DatabaseServices
  5. Imports Autodesk.AutoCAD.EditorInput
  6. Imports Autodesk.AutoCAD.Runtime
  7.  
  8. <Assembly: CommandClass(GetType(MeasureSample.CommandMethods))>
  9.  
  10. Namespace MeasureSample
  11.  
  12.     Module EditorInputExtensionMethods
  13.  
  14.         <System.Runtime.CompilerServices.Extension> _
  15.         Public Function Command(editor As Editor, ParamArray args As Object()) As PromptStatus
  16.             If editor Is Nothing Then
  17.                 Throw New ArgumentNullException("editor")
  18.             End If
  19.             Return runCommand(editor, args)
  20.         End Function
  21.  
  22.         Dim runCommand As Func(Of Editor, Object(), PromptStatus) = GenerateRunCommand()
  23.  
  24.         Private Function GenerateRunCommand() As Func(Of Editor, Object(), PromptStatus)
  25.             Dim method As MethodInfo = GetType(Editor).GetMethod( _
  26.                 "RunCommand", BindingFlags.Instance Or BindingFlags.NonPublic Or BindingFlags.[Public])
  27.             Dim instance As ParameterExpression = Expression.Parameter(GetType(Editor), "editor")
  28.             Dim args As ParameterExpression = Expression.Parameter(GetType(Object()), "args")
  29.             Return Expression.Lambda(Of Func(Of Editor, Object(), PromptStatus)) _
  30.                 (Expression.Call(instance, method, args), instance, args).Compile()
  31.         End Function
  32.  
  33.     End Module
  34.  
  35.     Public Class CommandMethods
  36.  
  37.         <CommandMethod("YOURMEASURE")> _
  38.         Public Sub YourMeasure()
  39.             Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
  40.  
  41.             ' Prompt the user for selecting a polyline
  42.             Dim peo As New PromptEntityOptions(vbLf & "Select a polyline: ")
  43.             peo.SetRejectMessage("Only a polyline !")
  44.             peo.AddAllowedClass(GetType(Polyline), True)
  45.             Dim per As PromptEntityResult = ed.GetEntity(peo)
  46.             If per.Status <> PromptStatus.OK Then
  47.                 Return
  48.             End If
  49.  
  50.             ' Run the MEASURE command
  51.             ed.Command("_measure", per.ObjectId, "_block", "yourblock", "_yes", 10.0)
  52.         End Sub
  53.  
  54.     End Class
  55.  
  56. End Namespace
Speaking English as a French Frog

TheMaster

  • Guest
Re: Calling AutoCAD command
« Reply #10 on: May 01, 2013, 01:08:49 PM »
Adding to Gile's reply,

When we run AutoCAD commands that use coordinate input, it's usually necessary to temporarily disable things like running object snap, etc., to ensure that AutoCAD doesn't alter the coordinate input passed to acedCmd().

See my recent post with the EXPORTLAYOUTS sample, for the ManagedSystemVariable class, which makes it easy to save/change/restore system variables.

latour_g

  • Newt
  • Posts: 184
Re: Calling AutoCAD command
« Reply #11 on: May 01, 2013, 02:25:23 PM »
Gile : thank you Gile, it's working perfectly fine ! I saw the first part of your code this morning on another topic but I didn't know what to do with it since I dont' know a thing about Linq.Expressions but now with your exemple I understand a little more (but I will definitively read about Linq.Expressions)
TT : alright, thanks !

 :-D