Author Topic: The Master's Example Classes  (Read 9619 times)

0 Members and 1 Guest are viewing this topic.

Keith Brown

  • Swamp Rat
  • Posts: 601
The Master's Example Classes
« on: October 31, 2012, 05:13:23 PM »
I see some links on this forum and on the official forum to some classes that Tony created and shared with the community.  Unfortunately those links all point to his website which is no longer available.  Are those classes still available for public download?  I would really love to use them as a learning experience of the power of dotnet and the Autocad API.  Thanks.
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

Jeff H

  • Needs a day job
  • Posts: 6144
Re: The Master's Example Classes
« Reply #1 on: October 31, 2012, 05:28:05 PM »
There are links to a couple of them here
http://www.theswamp.org/index.php?topic=39109.msg444119

TheMaster

  • Guest
Re: The Master's Example Classes
« Reply #2 on: November 01, 2012, 05:16:28 AM »
I see some links on this forum and on the official forum to some classes that Tony created and shared with the community.  Unfortunately those links all point to his website which is no longer available.  Are those classes still available for public download?  I would really love to use them as a learning experience of the power of dotnet and the Autocad API.  Thanks.

Let me know what links you're referring to and I'll see what I can do

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: The Master's Example Classes
« Reply #3 on: November 01, 2012, 10:53:05 AM »
Hi Tony,

I was mainly thinking of your commandline class and your overrule example.  Your localsystemvariables class is available on this forum.  That one has already been a great help just in thinking about the bigger picture and making sure that you can see the forest even when you are standing among the trees.  Thanks again.
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

TheMaster

  • Guest
Re: The Master's Example Classes
« Reply #4 on: November 01, 2012, 11:40:33 AM »
Hi Tony,

I was mainly thinking of your commandline class and your overrule example.  Your localsystemvariables class is available on this forum.  That one has already been a great help just in thinking about the bigger picture and making sure that you can see the forest even when you are standing among the trees.  Thanks again.

CommandLine.cs was written before Autodesk added the RunCommand method to the Editor class (it's a non-public method, so you have to use reflection to call it, which is quite simple to do).  I'll try to get the original Overrule sample code posted, if I can find it.

This can be used in lieu of CommandLine.cs:

Code - C#: [Select]
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Reflection;
  6. using Autodesk.AutoCAD.Runtime;
  7. using Autodesk.AutoCAD.EditorInput;
  8. using Autodesk.AutoCAD.ApplicationServices;
  9.  
  10. namespace Autodesk.AutoCAD.EditorInput
  11. {
  12.    public static class MyEditorExtensions
  13.    {
  14.       static MethodInfo runCommand = typeof( Editor ).GetMethod(
  15.          "RunCommand", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public );
  16.  
  17.       public static PromptStatus Command( this Editor ed, params object[] args )
  18.       {
  19.          if( Application.DocumentManager.IsApplicationContext )
  20.             throw new InvalidOperationException( "Invalid execution context for Command()" );
  21.          if( ed.Document != Application.DocumentManager.MdiActiveDocument )
  22.             throw new InvalidOperationException( "Document is not active" );
  23.          return (PromptStatus) runCommand.Invoke( ed, new object[] { args } );
  24.       }
  25.    }
  26. }
  27.  
  28.  

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: The Master's Example Classes
« Reply #5 on: November 02, 2012, 08:31:04 AM »
Thanks for sharing Tony.
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: The Master's Example Classes
« Reply #6 on: December 26, 2012, 10:07:02 AM »
CommandLine.cs was written before Autodesk added the RunCommand method to the Editor class (it's a non-public method, so you have to use reflection to call it, which is quite simple to do).  I'll try to get the original Overrule sample code posted, if I can find it.

This can be used in lieu of CommandLine.cs:

Code - C#: [Select]
  1. static MethodInfo runCommand = typeof( Editor ).GetMethod(
  2.          "RunCommand", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public );
  3.  
Why is the "RunCommand" not public?

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: The Master's Example Classes
« Reply #7 on: December 26, 2012, 11:31:58 AM »
I have wrote a simple code:
Code - C#: [Select]
  1. public class TestClass {
  2.     [CommandMethod("test")]
  3.     public void Test() {
  4.         Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  5.         ed.Command("Filedia", 0);
  6.         ed.Command("(princ \"Hello from the Command [1]\")");
  7.         ed.Command("_line", "0,0", "100,100", "");
  8.         ed.Document.SendStringToExecute("(princ \"Hello from the SendStringToExecute [2]\") (princ) ",
  9.             true, false, true);
  10.         ed.Command("Filedia", 1);
  11.         ed.Command("(princ \"Hello from the Command [3]\")");
  12.         // some operations
  13.         ed.WriteMessage("Hello from the WriteMessage [4]");
  14.         ed.Document.SendStringToExecute("(princ \"Hello from the SendStringToExecute [5]\") (princ) ",
  15.             true, false, true);
  16.     }
  17. }
  18.  

Result:
Quote
Command: netload
Command: test
Filedia
Enter new value for FILEDIA <1>: 0
Command: (princ "Hello from the Command [1]") LISP command is not available.

Command: _line Specify first point: 0,0
Specify next point or [Undo]: 100,100
Specify next point or [Undo]:
Command: Filedia
Enter new value for FILEDIA <0>: 1
Command: (princ "Hello from the Command [3]") LISP command is not available.

Command: Hello from the WriteMessage [4]
Command: (princ "Hello from the SendStringToExecute [2]") Hello from the
SendStringToExecute [2]"Hello from the SendStringToExecute [2]"

Command: (princ)
Command: (princ "Hello from the SendStringToExecute [5]") Hello from the
SendStringToExecute [5]"Hello from the SendStringToExecute [5]"

Command: (princ)

I have a little problem: ain't working LISP functions through the Command method. How can I solve it (if I can...)?
« Last Edit: December 26, 2012, 11:55:58 AM by Andrey »

TheMaster

  • Guest
Re: The Master's Example Classes
« Reply #8 on: December 27, 2012, 03:24:59 AM »
The Command() method doesn't execute LISP.

There are several ways to execute LISP functions from .NET.

You can P/Invoke acedInvoke() (there's a sample I wrote floating around)
You can P/Invoke acedEvaluateLisp()
You can use VL.Application.

Forget about using SendStringToExecute().

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: The Master's Example Classes
« Reply #9 on: December 27, 2012, 03:39:33 AM »
The Command() method doesn't execute LISP.

There are several ways to execute LISP functions from .NET.

You can P/Invoke acedInvoke() (there's a sample I wrote floating around)
You can P/Invoke acedEvaluateLisp()
You can use VL.Application.

Forget about using SendStringToExecute().
Thank you.
« Last Edit: December 27, 2012, 06:29:00 AM by Andrey »

MexicanCustard

  • Swamp Rat
  • Posts: 705
Re: The Master's Example Classes
« Reply #10 on: December 27, 2012, 01:36:01 PM »
This was taken from Tony's example

Code: [Select]
[DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
private static extern int acedInvoke(IntPtr args, out IntPtr result);
public ResultBuffer InvokeLisp(ResultBuffer args, ref int stat)
        {
            IntPtr rb = IntPtr.Zero;
            stat = acedInvoke(args.UnmanagedObject, out rb);
            if (stat == (int)PromptStatus.OK && rb != IntPtr.Zero)
                return (ResultBuffer)DisposableWrapper.Create(typeof(ResultBuffer), rb, true);

            return null;
        }

private void PrintResbuff(ResultBuffer res)
        {
            string s = "\n--------------------";
            foreach (TypedValue val in res)
            {
                s += string.Format("\n{0}->{1}", val.TypeCode, val.Value.ToString());
            }
            s += "\n---------------------";

            Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(s);
        }


Call it like this

Code: [Select]
var args = new ResultBuffer();
int stat = 0;

args.Add(new TypedValue((int)LispDataType.Text, "Lisp_Function"));
args.Add(new TypedValue((int)LispDataType.ObjectId, myObject.ObjectId)); //// My fake LISP routine needs an ObjectId and A Point3d
args.Add(new TypedValue((int)LispDataType.Point3d, new Point3d(0, 0, 0)));

ResultBuffer res = InvokeLisp(args, ref stat);
if (stat == 5100 && res != null)
       PrintResbuff(res);

res.Dispose();
Revit 2019, AMEP 2019 64bit Win 10

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: The Master's Example Classes
« Reply #11 on: December 27, 2012, 01:39:15 PM »
Yes, I already found this decision. Thanks. Not to forget, I added it here.

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: The Master's Example Classes
« Reply #12 on: December 27, 2012, 03:52:40 PM »
Hi,

No more need to P/Invoke acedInvoke() since A2011 as the Application.Invoke() managed method wraps it.
Speaking English as a French Frog

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: The Master's Example Classes
« Reply #13 on: December 28, 2012, 12:54:11 AM »
Thank you

TheMaster

  • Guest
Re: The Master's Example Classes
« Reply #14 on: December 29, 2012, 09:52:50 PM »
Hi,

No more need to P/Invoke acedInvoke() since A2011 as the Application.Invoke() managed method wraps it.

Thanks Gile, I forgot about that one.

It may also be worth noting that with acedInvoke(), the LISP function that is called must be previously-registered using the (vl-acad-defun) function or must have a C: prefix.