明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 25446|回复: 28

[命令] 调用AutoCad命令的方法

    [复制链接]
发表于 2009-9-12 10:59:00 | 显示全部楼层 |阅读模式
本帖最后由 作者 于 2010-6-28 20:17:52 编辑

从Lisp转向.Net的朋友可能都有点郁闷,Lisp可能很短的代码,.NetApi要写很长的
而且很多功能都习惯于使用Command函数去调用AutoCAD的命令实现,因为这样很简单
而NetApi提供的调用命令的方法SendStringToExecute确实鸡肋,它的机理和VBA的SendCommand相同,只是简单的向命令行发送字符,要实现Command函数的复杂控制是不可能的
那么应该怎么办呢?P/Invoke可以!
Lisp的Command函数实质是ObjectArx函数acedCmd的封装,那么使用平台调用,在.Net里也可以实现自己的封装,具体的方式可以看看Kean的相关文章:)

最终的版本
InvokeArx.cs
  1. using System;
  2. using System.Reflection;
  3. using System.Runtime.InteropServices;
  4. using Autodesk.AutoCAD.Runtime;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7. using Autodesk.AutoCAD.DatabaseServices;
  8. using Autodesk.AutoCAD.ApplicationServices;
  9. namespace TlsCad.Utils
  10. {
  11.     /// <summary>
  12.     /// 平台调用类
  13.     /// </summary>
  14.     public class InvokeArx
  15.     {
  16.         private static void AddValueToResultBuffer(ref ResultBuffer rb, object obj)
  17.         {
  18.             if (obj == null)
  19.             {
  20.                 rb.Add(new TypedValue((int)LispDataType.Text, ""));
  21.             }
  22.             else
  23.             {
  24.                 if (obj is string)
  25.                 {
  26.                     rb.Add(new TypedValue((int)LispDataType.Text, obj));
  27.                 }
  28.                 else if (obj is Point2d)
  29.                 {
  30.                     rb.Add(new TypedValue((int)LispDataType.Text, "_non"));
  31.                     rb.Add(new TypedValue((int)LispDataType.Point2d, obj));
  32.                 }
  33.                 else if (obj is Point3d)
  34.                 {
  35.                     rb.Add(new TypedValue((int)LispDataType.Text, "_non"));
  36.                     rb.Add(new TypedValue((int)LispDataType.Point3d, obj));
  37.                 }
  38.                 else if (obj is ObjectId)
  39.                 {
  40.                     rb.Add(new TypedValue((int)LispDataType.ObjectId, obj));
  41.                 }
  42.                 else if (obj is SelectionSet)
  43.                 {
  44.                     rb.Add(new TypedValue((int)LispDataType.SelectionSet, obj));
  45.                 }
  46.                 else if (obj is double)
  47.                 {
  48.                     rb.Add(new TypedValue((int)LispDataType.Double, obj));
  49.                 }
  50.                 else if (obj is short)
  51.                 {
  52.                     rb.Add(new TypedValue((int)LispDataType.Int16, obj));
  53.                 }
  54.                 else if (obj is int)
  55.                 {
  56.                     rb.Add(new TypedValue((int)LispDataType.Int32, obj));
  57.                 }
  58.                 else if (obj is TypedValue)
  59.                 {
  60.                     rb.Add(obj);
  61.                 }
  62.             }
  63.         }
  64.         #region Redraw
  65.         [System.Security.SuppressUnmanagedCodeSecurity]
  66.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  67.         private static extern Int32 acedRedraw(long[] name, Int32 mode);
  68.         public static void Redraw()
  69.         {
  70.             acedRedraw(null, 1);
  71.         }
  72.         //[DllImport("acdb17.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AAY01JVAcDbObjectId@@@Z")]
  73.         //private static extern int acdbGetAdsName(long[] name, ObjectId objId);
  74.         //public static void Redraw(ObjectId id)
  75.         //{
  76.         //    long[] adsname = new long[2];
  77.         //    acdbGetAdsName(adsname, id);
  78.         //    acedRedraw(adsname, 1);
  79.         //}
  80.         #endregion
  81.         #region TextScr
  82.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  83.         private static extern int acedTextScr();
  84.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  85.         private static extern int acedGraphScr();
  86.         public static bool DisplayTextScreen
  87.         {
  88.             set
  89.             {
  90.                 if (value)
  91.                     acedTextScr();
  92.                 else
  93.                     acedGraphScr();
  94.             }
  95.         }
  96.         #endregion
  97.         #region Command
  98.         /// <summary>
  99.         /// 控制命令行回显
  100.         /// </summary>
  101.         public static bool CmdEcho
  102.         {
  103.             get
  104.             {
  105.                 return (int)Application.GetSystemVariable("cmdecho") == 1;
  106.             }
  107.             set
  108.             {
  109.                 Application.SetSystemVariable("cmdecho", Convert.ToInt16(value));
  110.             }
  111.         }
  112.         [DllImport("acad.exe")]
  113.         private static extern int acedCmd(IntPtr vlist);
  114.                                     
  115.         /// <summary>
  116.         /// 调用AutoCad命令
  117.         /// </summary>
  118.         /// <param name="prompt">命令行提示</param>
  119.         /// <param name="arg">参数</param>
  120.         public static void Command(string prompt, object arg)
  121.         {
  122.             EdUtility.WriteMessage(prompt);
  123.             ResultBuffer rb = new ResultBuffer();
  124.             AddValueToResultBuffer(ref rb, arg);
  125.             try
  126.             {
  127.                 acedCmd(rb.UnmanagedObject);
  128.             }
  129.             catch { }
  130.             finally
  131.             {
  132.                 rb.Dispose();
  133.             }
  134.         }
  135.         /// <summary>
  136.         /// 调用AutoCad命令
  137.         /// </summary>
  138.         /// <param name="endCommandByUser">命令结束方式</param>
  139.         /// <param name="ldnode">参数</param>
  140.         public static void Command(bool endCommandByUser, ResultBuffer rb)
  141.         {
  142.             ResultBuffer rbend = new ResultBuffer();
  143.             try
  144.             {
  145.                 Document doc = Application.DocumentManager.MdiActiveDocument;
  146.                 string currCmdName = doc.CommandInProgress;
  147.                 acedCmd(rb.UnmanagedObject);
  148.                 if (endCommandByUser)
  149.                 {
  150.                     rbend.Add(new TypedValue((int)LispDataType.Text, "\"));
  151.                 }
  152.                 while (doc.CommandInProgress != currCmdName)
  153.                 {
  154.                     acedCmd(rbend.UnmanagedObject);
  155.                 }
  156.             }
  157.             catch { }
  158.             finally
  159.             {
  160.                 rb.Dispose();
  161.                 rbend.Dispose();
  162.             }
  163.         }
  164.         /// <summary>
  165.         /// 调用AutoCad命令
  166.         /// </summary>
  167.         /// <param name="endCommandByUser">命令结束方式</param>
  168.         /// <param name="args">参数</param>
  169.         public static void Command(bool endCommandByUser, params object[] args)
  170.         {
  171.             ResultBuffer rb = new ResultBuffer();
  172.             ResultBuffer rbend = new ResultBuffer();
  173.             foreach (object val in args)
  174.             {
  175.                 AddValueToResultBuffer(ref rb, val);
  176.             }
  177.             try
  178.             {
  179.                 Document doc = Application.DocumentManager.MdiActiveDocument;
  180.                 string currCmdName = doc.CommandInProgress;
  181.                 acedCmd(rb.UnmanagedObject);
  182.                 if (endCommandByUser)
  183.                 {
  184.                     rbend.Add(new TypedValue((int)LispDataType.Text, "\"));
  185.                 }
  186.                 while (doc.CommandInProgress != currCmdName)
  187.                 {
  188.                     acedCmd(rbend.UnmanagedObject);
  189.                 }
  190.             }
  191.             catch { }
  192.             finally
  193.             {
  194.                 rb.Dispose();
  195.                 rbend.Dispose();
  196.             }
  197.         }
  198.         #endregion
  199.         
  200.         #region Lisp
  201.         [System.Security.SuppressUnmanagedCodeSecurity]
  202.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  203.         extern static private int acedPutSym(string name, IntPtr result);
  204.         [System.Security.SuppressUnmanagedCodeSecurity]
  205.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  206.         extern static private int acedGetSym(string name, out IntPtr result);
  207.         [System.Security.SuppressUnmanagedCodeSecurity]
  208.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  209.         extern static private int acedInvoke(IntPtr args, out IntPtr result);
  210.         public static ResultBuffer CallLispFunction(ResultBuffer args)
  211.         {
  212.             IntPtr ip = IntPtr.Zero;
  213.             int st = acedInvoke(args.UnmanagedObject, out ip);
  214.             if (ip != IntPtr.Zero)
  215.             {
  216.                 ResultBuffer rbRes = ResultBuffer.Create(ip, true);
  217.                 return rbRes;
  218.             }
  219.             return null;
  220.         }
  221.         public static ResultBuffer CallLispFunction(string name, params object[] args)
  222.         {
  223.             ResultBuffer rbArgs = new ResultBuffer();
  224.             rbArgs.Add(new TypedValue((int)LispDataType.Text, name));
  225.             foreach (object val in args)
  226.             {
  227.                 AddValueToResultBuffer(ref rbArgs, val);
  228.             }
  229.             return CallLispFunction(rbArgs);
  230.         }
  231.                
  232.         internal static ResultBuffer GetLispSym(string name)
  233.         {
  234.             IntPtr ip = IntPtr.Zero;
  235.             acedGetSym(name, out ip);
  236.             if (ip != IntPtr.Zero)
  237.             {
  238.                 ResultBuffer rbRes = ResultBuffer.Create(ip, true);
  239.                 return rbRes;
  240.             }
  241.             return null;
  242.         }
  243.         #endregion
  244.     }
  245. }



测试代码,结合ResultList/ResultTree类
  1.         [CommandMethod("t11")]
  2.         public static void Test11()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Database db = doc.Database;
  6.             Editor ed = doc.Editor;
  7.             PromptEntityResult res1 = ed.GetEntity("\nSelect a Entity:");
  8.             InvokeArx.CmdEcho = false;
  9.             InvokeArx.Command(
  10.                 false,
  11.                 new ResultTree
  12.                 {
  13.                     "break",
  14.                     new ResultTree(ResultType.List)
  15.                     {
  16.                         res1.ObjectId,
  17.                         res1.PickedPoint
  18.                     },
  19.                     res1.PickedPoint
  20.                 });
  21.             InvokeArx.CmdEcho = true;
  22.         }
复制代码

评分

参与人数 1金钱 +6 收起 理由
东_东 + 6

查看全部评分

发表于 2018-3-28 10:43:36 | 显示全部楼层
学习了,胡歌 厉害了
 楼主| 发表于 2009-9-12 11:28:00 | 显示全部楼层
本帖最后由 作者 于 2010-6-28 20:02:27 编辑

两段简单的测试代码,但注意NetApi最好还是少调用命令为好
  1.         [CommandMethod("tt10")]
  2.         public static void Test10()
  3.         {
  4.             //调用Line命令,由用户结束
  5.             InvokeArx.Command(true, "_.line");
  6.             //调用Line命令并结束
  7.             InvokeArx.Command(false, "_.line", Point3d.Origin, new Point3d(10, 10, 0));
  8.         }
  9.         [CommandMethod("tt11")]
  10.         public static void Test11()
  11.         {
  12.             //找回Hatch边界的命令版,当然你需要有一个填充先
  13.             PromptEntityOptions opts = new PromptEntityOptions("\nselect a Hatch:");
  14.             opts.SetRejectMessage("\nnot a Hatch!");
  15.             opts.AddAllowedClass(typeof(Hatch), false);
  16.             PromptEntityResult res = Helper.Editor.GetEntity(opts);
  17.             InvokeArx.Command(false, "_.HATCHEDIT", res.ObjectId, "B", "P", "Y");
  18.         }
复制代码
 楼主| 发表于 2009-9-14 20:12:00 | 显示全部楼层
本帖最后由 作者 于 2009-12-28 10:24:39 编辑

完整的代码
同时测试代码提供了可更改CommandLine提示的调用方式,
但是如果不小心键入U(回退),效果就会消失
  1.         [CommandMethod("tt12")]
  2.         public static void Test10()
  3.         {
  4.             EdUtility.CmdEcho = false;
  5.             EdUtility.Command("Hello", "_.line");
  6.             EdUtility.Command("请输入第一点", "\");
  7.             EdUtility.Command("请输入第二点", "\");
  8.             EdUtility.Command("结束", "");
  9.             EdUtility.CmdEcho = true;
  10.             
  11.         }
复制代码
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.InteropServices;
  4. using System.Reflection;
  5. using Autodesk.AutoCAD.Runtime;
  6. using Autodesk.AutoCAD.Geometry;
  7. using Autodesk.AutoCAD.EditorInput;
  8. using Autodesk.AutoCAD.DatabaseServices;
  9. using Autodesk.AutoCAD.ApplicationServices;
  10. namespace TlsCad.Utils
  11. {
  12.     public struct DottedPair
  13.     {
  14.         private ObjectId _id;
  15.         private Point3d _pnt;
  16.         public ObjectId ObjectId
  17.         {
  18.             get { return _id; }
  19.         }
  20.         public Point3d Point
  21.         {
  22.             get { return _pnt; }
  23.         }
  24.         public DottedPair(ObjectId id,Point3d pnt)
  25.         {
  26.             _id = id;
  27.             _pnt = pnt;
  28.         }
  29.         public DottedPair(PromptEntityResult res)
  30.         {
  31.             _id = res.ObjectId;
  32.             _pnt = res.PickedPoint;
  33.         }
  34.     }
  35.     public static class EdUtility
  36.     {
  37.         #region Command
  38.         public static bool CmdEcho
  39.         {
  40.             get
  41.             {
  42.                 return (int)Application.GetSystemVariable("cmdecho") == 1;
  43.             }
  44.             set
  45.             {
  46.                 Application.SetSystemVariable("cmdecho", Convert.ToInt16(value));
  47.             }
  48.         }
  49.         private static void AddValueToResultBuffer(ref ResultBuffer rb, object obj)
  50.         {
  51.             if (obj == null)
  52.             {
  53.                 rb.Add(new TypedValue((int)LispDataType.Text, ""));
  54.             }
  55.             else
  56.             {
  57.                 if (obj is string)
  58.                 {
  59.                     rb.Add(new TypedValue((int)LispDataType.Text, obj));
  60.                 }
  61.                 else if (obj is Point2d)
  62.                 {
  63.                     rb.Add(new TypedValue((int)LispDataType.Text, "_non"));
  64.                     rb.Add(new TypedValue((int)LispDataType.Point2d, obj));
  65.                 }
  66.                 else if (obj is Point3d)
  67.                 {
  68.                     rb.Add(new TypedValue((int)LispDataType.Text, "_non"));
  69.                     rb.Add(new TypedValue((int)LispDataType.Point3d, obj));
  70.                 }
  71.                 else if (obj is ObjectId)
  72.                 {
  73.                     rb.Add(new TypedValue((int)LispDataType.ObjectId, obj));
  74.                 }
  75.                 else if (obj is SelectionSet)
  76.                 {
  77.                     rb.Add(new TypedValue((int)LispDataType.SelectionSet, obj));
  78.                 }
  79.                 else if (obj is double)
  80.                 {
  81.                     rb.Add(new TypedValue((int)LispDataType.Double, obj));
  82.                 }
  83.                 else if (obj is short)
  84.                 {
  85.                     rb.Add(new TypedValue((int)LispDataType.Int16, obj));
  86.                 }
  87.                 else if (obj is int)
  88.                 {
  89.                     rb.Add(new TypedValue((int)LispDataType.Int32, obj));
  90.                 }
  91.                 else if (obj is TypedValue)
  92.                 {
  93.                     rb.Add(obj);
  94.                 }
  95.                 else if (obj is DottedPair)
  96.                 {
  97.                     DottedPair dp = (DottedPair)obj;
  98.                     rb.Add(new TypedValue((int)LispDataType.ListBegin));
  99.                     rb.Add(new TypedValue((int)LispDataType.ObjectId,dp.ObjectId));
  100.                     rb.Add(new TypedValue((int)LispDataType.Point3d, dp.Point));
  101.                     rb.Add(new TypedValue((int)LispDataType.ListEnd));
  102.                 }
  103.             }
  104.         }
  105.         
  106.         [DllImport("acad.exe")]
  107.         private static extern int acedCmd(IntPtr vlist);
  108.         public static void Command(string prompt, object arg)
  109.         {
  110.             WriteMessage(prompt);
  111.             ResultBuffer rb = new ResultBuffer();
  112.             AddValueToResultBuffer(ref rb, arg);
  113.             try
  114.             {
  115.                 acedCmd(rb.UnmanagedObject);
  116.             }
  117.             catch { }
  118.             finally
  119.             {
  120.                 rb.Dispose();
  121.             }
  122.         }
  123.         /*
  124.          *功能:
  125.          *      调用AutoCad命令
  126.          *参数:
  127.          *      endCommandByUse     命令结束方式
  128.          *      args                参数
  129.          *返回:
  130.          *      无
  131.          */
  132.         public static void Command(bool endCommandByUser, params object[] args)
  133.         {
  134.             ResultBuffer rb = new ResultBuffer();
  135.             ResultBuffer rbend = new ResultBuffer();
  136.             foreach (object val in args)
  137.             {
  138.                 AddValueToResultBuffer(ref rb, val);
  139.             }
  140.             try
  141.             {
  142.                 Document doc = Application.DocumentManager.MdiActiveDocument;
  143.                 string currCmdName = doc.CommandInProgress;
  144.                 acedCmd(rb.UnmanagedObject);
  145.                 if (endCommandByUser)
  146.                 {
  147.                     rbend.Add(new TypedValue((int)LispDataType.Text, "\"));
  148.                 }
  149.                 while (doc.CommandInProgress != currCmdName)
  150.                 {
  151.                     acedCmd(rbend.UnmanagedObject);
  152.                 }
  153.             }
  154.             catch { }
  155.             finally
  156.             {
  157.                 rb.Dispose();
  158.                 rbend.Dispose();
  159.             }
  160.         }
  161.         //2009版本提供了acedCmd函数的封装
  162.         //但可能有Bug,所以未公开
  163.         //谨慎使用
  164.         private static MethodInfo _runCommand =
  165.             typeof(Editor).GetMethod(
  166.                 "RunCommand",
  167.                 BindingFlags.NonPublic | BindingFlags.Instance);
  168.         /*
  169.          *功能:
  170.          *      反射调用AutoCad命令(2009版本以上)
  171.          *参数:
  172.          *      editor          Editor对象
  173.          *      args            参数
  174.          *返回:
  175.          *      无
  176.          */
  177.         public static PromptStatus Command(Editor editor, params object[] args)
  178.         {
  179.             return (PromptStatus)_runCommand.Invoke(editor, new object[] { args });
  180.         }
  181.         #endregion
  182.     }
  183. }
发表于 2009-9-19 12:51:00 | 显示全部楼层
好像无法执行load命令,如果(load"d:\\1.lsp")就无法执行
 楼主| 发表于 2009-9-19 15:17:00 | 显示全部楼层

load在这里不是命令,而是Lisp函数,

P/Invoke的话要用acedInvoke调用

但我在2008、2010似乎都无法正确使用,汗,以前的版本倒是可以

不过Lisp可以实现的,NetApi也可以实现,为什么不直接用NetApi做?

发表于 2009-9-19 18:56:00 | 显示全部楼层
lzh741206发表于2009-9-19 15:17:00load在这里不是命令,而是Lisp函数,P/Invoke的话要用acedInvoke调用但我在2008、2010似乎都无法正确使用,汗,以前的版本倒是可以不过Lisp可以实现的,NetApi也可以实现,为什么不直接用NetAp

NetApi如何实现这个功能,先生给点提示和简单代码好吧?谢谢!

 楼主| 发表于 2009-9-19 19:11:00 | 显示全部楼层

在theswamp看到过的用法

不过似乎只能调用.Net自己定义的Lisp

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
 楼主| 发表于 2009-12-28 10:27:00 | 显示全部楼层
2008.12.28
加入点对支持
3楼代码已更改
调用示例
  1.         [CommandMethod("tt10")]
  2.         public static void Test10()
  3.         {
  4.             Editor ed = Helper.Editor;
  5.             PromptEntityResult res1 = ed.GetEntity("\n选择直线:");
  6.             PromptPointResult res2 = ed.GetPoint("选择第二点");
  7.             InvokeArx.Command(false, "._break", new DottedPair(res1), res2.Value);
  8.             
  9.         }
复制代码
发表于 2009-12-28 12:37:00 | 显示全部楼层
在狐哥的基础上修改了一点点:
调用格式与Lisp的command函数高度一致
自动将object[] ,解释成相当于Lisp中的 (list ....))
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using Autodesk.AutoCAD.Runtime;
  4. using Autodesk.AutoCAD.Geometry;
  5. using Autodesk.AutoCAD.EditorInput;
  6. using Autodesk.AutoCAD.DatabaseServices;
  7. using Autodesk.AutoCAD.ApplicationServices;
  8. namespace FsxmAcad
  9. {
  10.     public static class EdUtility
  11.     {
  12.         public static bool CmdEcho
  13.         {
  14.             get
  15.             {
  16.                 return (int)Application.GetSystemVariable("cmdecho") == 1;
  17.             }
  18.             set
  19.             {
  20.                 Application.SetSystemVariable("cmdecho", Convert.ToInt16(value));
  21.             }
  22.         }
  23.         /// <summary>将一个对像生成TypedValue后加入到ResultBuffer</summary>
  24.         /// <param name="rb">Ref 集合ResultBuffer</param>
  25.         /// <param name="obj">要加入的对象</param>
  26.         public static void AddValue(this ResultBuffer rb, object obj)
  27.         {
  28.             if (obj == null)
  29.             {
  30.                 rb.Add(new TypedValue((int)LispDataType.Text, ""));
  31.             }
  32.             else if (obj is object[])
  33.             {
  34.                 rb.Add(new TypedValue((int)LispDataType.ListBegin)); //5016
  35.                 foreach (object item in (object[])obj)
  36.                 {
  37.                     AddValue(rb, item);
  38.                 }
  39.                 rb.Add(new TypedValue((int)LispDataType.ListEnd));//5017
  40.             }
  41.             else if (obj is string)//5005
  42.             {
  43.                 rb.Add(new TypedValue((int)LispDataType.Text, obj));
  44.             }
  45.             else if (obj is Point2d)//5002
  46.             {
  47.                 rb.Add(new TypedValue((int)LispDataType.Point2d, obj));
  48.             }
  49.             else if (obj is Point3d)//5009
  50.             {
  51.                 rb.Add(new TypedValue((int)LispDataType.Point3d, obj));
  52.             }
  53.             else if (obj is ObjectId)//5006
  54.             {
  55.                 rb.Add(new TypedValue((int)LispDataType.ObjectId, obj));
  56.             }
  57.             else if (obj is SelectionSet)//5007
  58.             {
  59.                 rb.Add(new TypedValue((int)LispDataType.SelectionSet, obj));
  60.             }
  61.             else if (obj is double)//5001
  62.             {
  63.                 rb.Add(new TypedValue((int)LispDataType.Double, obj));
  64.             }
  65.             else if (obj is short)//5003
  66.             {
  67.                 rb.Add(new TypedValue((int)LispDataType.Int16, obj));
  68.             }
  69.             else if (obj is int)//5010
  70.             {
  71.                 rb.Add(new TypedValue((int)LispDataType.Int32, obj));
  72.             }
  73.             else if (obj is TypedValue)
  74.             {
  75.                 rb.Add(obj);
  76.             }
  77.         }
  78.         /// <summary>调用AutoCad命令原始Api</summary>
  79.         [DllImport("acad.exe")]
  80.         public static extern int acedCmd(IntPtr vlist);
  81.         /// <summary>调用AutoCad命令</summary>
  82.         /// <param name="args">参数列表</param>
  83.         public static void Command(params object[] args)
  84.         {
  85.             ResultBuffer rb;
  86.             using (rb = new ResultBuffer())
  87.             {
  88.                 foreach (object val in args)
  89.                 {
  90.                     rb.AddValue(val);
  91.                 }
  92.                 acedCmd(rb.UnmanagedObject);
  93.             }
  94.         }
  95.         [CommandMethod("tt")]
  96.         public static void Test10()
  97.         {
  98.             PromptEntityResult er = Application.DocumentManager.MdiActiveDocument.Editor.GetEntity("选剪切对像:");
  99.             if (rst.Status != PromptStatus.OK)
  100.                 return;
  101.             EdUtility.CmdEcho = true;
  102.             EdUtility.Command(".trim", "", new object[] { rst.ObjectId, rst.PickedPoint }, "");
  103.         }
  104.     }
  105. }
 楼主| 发表于 2009-12-28 16:17:00 | 显示全部楼层
本帖最后由 作者 于 2010-6-28 19:59:42 编辑

最终的版本
InvokeArx.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.InteropServices;
  4. using System.Reflection;
  5. using Autodesk.AutoCAD.Runtime;
  6. using Autodesk.AutoCAD.Geometry;
  7. using Autodesk.AutoCAD.EditorInput;
  8. using Autodesk.AutoCAD.DatabaseServices;
  9. using Autodesk.AutoCAD.ApplicationServices;
  10. using TlsCad.Collections;
  11. namespace TlsCad.Utils
  12. {
  13.     /// <summary>
  14.     /// 平台调用类
  15.     /// </summary>
  16.     public class InvokeArx
  17.     {
  18.         private static void AddValueToResultBuffer(ref ResultBuffer rb, object obj)
  19.         {
  20.             if (obj == null)
  21.             {
  22.                 rb.Add(new TypedValue((int)LispDataType.Text, ""));
  23.             }
  24.             else
  25.             {
  26.                 if (obj is string)
  27.                 {
  28.                     rb.Add(new TypedValue((int)LispDataType.Text, obj));
  29.                 }
  30.                 else if (obj is Point2d)
  31.                 {
  32.                     rb.Add(new TypedValue((int)LispDataType.Text, "_non"));
  33.                     rb.Add(new TypedValue((int)LispDataType.Point2d, obj));
  34.                 }
  35.                 else if (obj is Point3d)
  36.                 {
  37.                     rb.Add(new TypedValue((int)LispDataType.Text, "_non"));
  38.                     rb.Add(new TypedValue((int)LispDataType.Point3d, obj));
  39.                 }
  40.                 else if (obj is ObjectId)
  41.                 {
  42.                     rb.Add(new TypedValue((int)LispDataType.ObjectId, obj));
  43.                 }
  44.                 else if (obj is SelectionSet)
  45.                 {
  46.                     rb.Add(new TypedValue((int)LispDataType.SelectionSet, obj));
  47.                 }
  48.                 else if (obj is double)
  49.                 {
  50.                     rb.Add(new TypedValue((int)LispDataType.Double, obj));
  51.                 }
  52.                 else if (obj is short)
  53.                 {
  54.                     rb.Add(new TypedValue((int)LispDataType.Int16, obj));
  55.                 }
  56.                 else if (obj is int)
  57.                 {
  58.                     rb.Add(new TypedValue((int)LispDataType.Int32, obj));
  59.                 }
  60.                 else if (obj is TypedValue)
  61.                 {
  62.                     rb.Add(obj);
  63.                 }
  64.             }
  65.         }
  66.         #region Redraw
  67.         [System.Security.SuppressUnmanagedCodeSecurity]
  68.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  69.         private static extern Int32 acedRedraw(long[] name, Int32 mode);
  70.         public static void Redraw()
  71.         {
  72.             acedRedraw(null, 1);
  73.         }
  74.         //[DllImport("acdb17.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AAY01JVAcDbObjectId@@@Z")]
  75.         //private static extern int acdbGetAdsName(long[] name, ObjectId objId);
  76.         //public static void Redraw(ObjectId id)
  77.         //{
  78.         //    long[] adsname = new long[2];
  79.         //    acdbGetAdsName(adsname, id);
  80.         //    acedRedraw(adsname, 1);
  81.         //}
  82.         #endregion
  83.         #region TextScr
  84.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  85.         private static extern int acedTextScr();
  86.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  87.         private static extern int acedGraphScr();
  88.         public static bool DisplayTextScreen
  89.         {
  90.             set
  91.             {
  92.                 if (value)
  93.                     acedTextScr();
  94.                 else
  95.                     acedGraphScr();
  96.             }
  97.         }
  98.         #endregion
  99.         #region Command
  100.         /// <summary>
  101.         /// 控制命令行回显
  102.         /// </summary>
  103.         public static bool CmdEcho
  104.         {
  105.             get
  106.             {
  107.                 return (int)Application.GetSystemVariable("cmdecho") == 1;
  108.             }
  109.             set
  110.             {
  111.                 Application.SetSystemVariable("cmdecho", Convert.ToInt16(value));
  112.             }
  113.         }
  114.         [DllImport("acad.exe")]
  115.         private static extern int acedCmd(IntPtr vlist);
  116.                                     
  117.         /// <summary>
  118.         /// 调用AutoCad命令
  119.         /// </summary>
  120.         /// <param name="prompt">命令行提示</param>
  121.         /// <param name="arg">参数</param>
  122.         public static void Command(string prompt, object arg)
  123.         {
  124.             EdUtility.WriteMessage(prompt);
  125.             ResultBuffer rb = new ResultBuffer();
  126.             AddValueToResultBuffer(ref rb, arg);
  127.             try
  128.             {
  129.                 acedCmd(rb.UnmanagedObject);
  130.             }
  131.             catch { }
  132.             finally
  133.             {
  134.                 rb.Dispose();
  135.             }
  136.         }
  137.         /// <summary>
  138.         /// 调用AutoCad命令
  139.         /// </summary>
  140.         /// <param name="endCommandByUser">命令结束方式</param>
  141.         /// <param name="ldnode">参数</param>
  142.         public static void Command(bool endCommandByUser, ResultBuffer rb)
  143.         {
  144.             ResultBuffer rbend = new ResultBuffer();
  145.             try
  146.             {
  147.                 Document doc = Application.DocumentManager.MdiActiveDocument;
  148.                 string currCmdName = doc.CommandInProgress;
  149.                 acedCmd(rb.UnmanagedObject);
  150.                 if (endCommandByUser)
  151.                 {
  152.                     rbend.Add(new TypedValue((int)LispDataType.Text, "\"));
  153.                 }
  154.                 while (doc.CommandInProgress != currCmdName)
  155.                 {
  156.                     acedCmd(rbend.UnmanagedObject);
  157.                 }
  158.             }
  159.             catch { }
  160.             finally
  161.             {
  162.                 rb.Dispose();
  163.                 rbend.Dispose();
  164.             }
  165.         }
  166.         /// <summary>
  167.         /// 调用AutoCad命令
  168.         /// </summary>
  169.         /// <param name="endCommandByUser">命令结束方式</param>
  170.         /// <param name="args">参数</param>
  171.         public static void Command(bool endCommandByUser, params object[] args)
  172.         {
  173.             ResultBuffer rb = new ResultBuffer();
  174.             ResultBuffer rbend = new ResultBuffer();
  175.             foreach (object val in args)
  176.             {
  177.                 AddValueToResultBuffer(ref rb, val);
  178.             }
  179.             try
  180.             {
  181.                 Document doc = Application.DocumentManager.MdiActiveDocument;
  182.                 string currCmdName = doc.CommandInProgress;
  183.                 acedCmd(rb.UnmanagedObject);
  184.                 if (endCommandByUser)
  185.                 {
  186.                     rbend.Add(new TypedValue((int)LispDataType.Text, "\"));
  187.                 }
  188.                 while (doc.CommandInProgress != currCmdName)
  189.                 {
  190.                     acedCmd(rbend.UnmanagedObject);
  191.                 }
  192.             }
  193.             catch { }
  194.             finally
  195.             {
  196.                 rb.Dispose();
  197.                 rbend.Dispose();
  198.             }
  199.         }
  200.         #endregion
  201.         
  202.         #region Lisp
  203.         [System.Security.SuppressUnmanagedCodeSecurity]
  204.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  205.         extern static private int acedPutSym(string name, IntPtr result);
  206.         [System.Security.SuppressUnmanagedCodeSecurity]
  207.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  208.         extern static private int acedGetSym(string name, out IntPtr result);
  209.         [System.Security.SuppressUnmanagedCodeSecurity]
  210.         [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl)]
  211.         extern static private int acedInvoke(IntPtr args, out IntPtr result);
  212.         public static ResultBuffer CallLispFunction(ResultBuffer args)
  213.         {
  214.             IntPtr ip = IntPtr.Zero;
  215.             int st = acedInvoke(args.UnmanagedObject, out ip);
  216.             if (ip != IntPtr.Zero)
  217.             {
  218.                 ResultBuffer rbRes = ResultBuffer.Create(ip, true);
  219.                 return rbRes;
  220.             }
  221.             return null;
  222.         }
  223.         public static ResultBuffer CallLispFunction(string name, params object[] args)
  224.         {
  225.             ResultBuffer rbArgs = new ResultBuffer();
  226.             rbArgs.Add(new TypedValue((int)LispDataType.Text, name));
  227.             foreach (object val in args)
  228.             {
  229.                 AddValueToResultBuffer(ref rbArgs, val);
  230.             }
  231.             return CallLispFunction(rbArgs);
  232.         }
  233.                
  234.         internal static ResultBuffer GetLispSym(string name)
  235.         {
  236.             IntPtr ip = IntPtr.Zero;
  237.             acedGetSym(name, out ip);
  238.             if (ip != IntPtr.Zero)
  239.             {
  240.                 ResultBuffer rbRes = ResultBuffer.Create(ip, true);
  241.                 return rbRes;
  242.             }
  243.             return null;
  244.         }
  245.         #endregion
  246.     }
  247. }


测试代码,结合ResultList/ResultTree类
  1.         [CommandMethod("t11")]
  2.         public static void Test11()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Database db = doc.Database;
  6.             Editor ed = doc.Editor;
  7.             PromptEntityResult res1 = ed.GetEntity("\nSelect a Entity:");
  8.             InvokeArx.CmdEcho = false;
  9.             InvokeArx.Command(
  10.                 false,
  11.                 new ResultTree
  12.                 {
  13.                     "break",
  14.                     new ResultTree(ResultType.List)
  15.                     {
  16.                         res1.ObjectId,
  17.                         res1.PickedPoint
  18.                     },
  19.                     res1.PickedPoint
  20.                 });
  21.             InvokeArx.CmdEcho = true;
  22.         }
复制代码


您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-25 08:40 , Processed in 0.295246 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表