通用枚举值...

    // 本枚举融合 Autodesk.AutoCAD.Runtime.LispDataType
// Autodesk.AutoCAD.EditorInput.PromptStatus
public enum EnumBufCode
{
// resbuf元素的类型
None = , //没有结果 回车耶
Double = , //实数 Real
Point2d = , //2维点
Int16 = , //短整数 Short
Angle = , //角度
Text = , //字符串 String
ObjectId = , //实体名称 Ename
SelectionSet = , //选择集名 PickSet
Orientation = , //方向
Point3d = , //3维点
Int32 = , //长整数 Long
Void = , //空白符号
ListBegin = , //list begin
ListEnd = , //list end
DottedPair = , //点对
Nil = , //nil(空表)
Dxf0 = , //DXF代码0仅适用于ads_bListldlist
T_atom = , //T(原子) Resbuf = , //resbuf Modeless = , //被无模式对话中断
Other = , // 错误返回代码
OK = , //请求成功,用户输入值有效 Norm
Error = -,//其他一些错误
Cancel = -,//用户取消请求-Ctl-C
RejectRequest = -,//AutoCAD拒绝请求-无效
FailureLink = -,//链接失败-Lisp可能已经死了
Keyword = -,//从getxxx()例程返回的关键字
Inputtruncated = -,//输入并不都适合缓冲区
}

首先是传参型lisp的定义,它在低版本有个问题,就是所有的返回值都要用表包裹着,而高版本就修复了这个问题.

为了所有版本统一,返回值应该统一成 ResultBuffer ,在lisp再(car 返回值).... 我这里既有 ResultBuffer,又有object返回,供各位参考.

        //传参型lisp的定义:传点
//复制到命令栏运行: (Test_AddLine (getpoint))
[LispFunction("Test_AddLine")] //注意: 这里不是command!
public static ResultBuffer AddLine(ResultBuffer rbArgs)
{
Database db = Acap.DocumentManager.MdiActiveDocument.Database;
Editor ed = Acap.DocumentManager.MdiActiveDocument.Editor; Point3d p1 = Point3d.Origin;
Point3d p2 = Point3d.Origin;
if (rbArgs != null)
{
foreach (TypedValue rb in rbArgs)
{
try
{
//ed.WriteMessage(Environment.NewLine + "rb.ToString()=" + rb.ToString());
//ed.WriteMessage(Environment.NewLine + "rb.TypeCode.ToString()=" + rb.TypeCode.ToString());
//ed.WriteMessage(Environment.NewLine + "rb.Value.ToString()=" + rb.Value.ToString()); var str = rb.Value.ToString();
str = str.Substring().Substring(, str.Length - ); var pts = str.Split(',');
p2 = new Point3d(double.Parse(pts[]), double.Parse(pts[]), double.Parse(pts[]));
}
catch
{ }
}
}
var line = new Line(p1, p2);
using (Transaction tr = db.TransactionManager.StartTransaction())
{
var acBlkTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
var acBlkTblRec = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
// line.SetDatabaseDefaults();设置数据库默认值
acBlkTblRec.AppendEntity(line);
tr.AddNewlyCreatedDBObject(line, true);
tr.Commit();
}
var rbrtn = new ResultBuffer(new TypedValue[]
{
new TypedValue((int)EnumBufCode.ObjectId, line.ObjectId),
new TypedValue((int)EnumBufCode.Point3d, p1),
new TypedValue((int)EnumBufCode.Point3d, p2)
});
ed.WriteMessage(Environment.NewLine + " rbrtn=" + rbrtn.ToString());
ed.WriteMessage(Environment.NewLine);
return rbrtn; //返回值此处有图元名
} //传参型lisp的定义:加法
//复制到命令栏运行: (Test_MyAdd 1 2 3)
[LispFunction("Test_MyAdd")] //注意: 这里不是command!
public static object Test_MyAdd(ResultBuffer args) //高版本这里可以返回double,但是08只能返回ResultBuffer
{
var ds = new List<double>();
if (args != null)
{
foreach (TypedValue rb in args)
{
try
{
var a = double.Parse(rb.Value.ToString());
ds.Add(a);
}
catch
{ }
}
} double number = ;
foreach (var item in ds)
{
number += item;
} //08只能返回ResultBuffer 会返回表内数字(6.0)
//高版本可以返回其他的
var rbrtn = new ResultBuffer(new TypedValue[]
{
new TypedValue((int)EnumBufCode.Double, number),
}); var dotPair = new ResultBuffer(new TypedValue[] {
new TypedValue((int)EnumBufCode.ListBegin, -),
new TypedValue((int)EnumBufCode.Int16, ),
new TypedValue((int)EnumBufCode.Int16, ),
new TypedValue((int)EnumBufCode.DottedPair, -),
}); #if AC2008
return rbrtn; //但是08只能返回ResultBuffer 会返回(6.0)
#else
return number; //高版本这里可以返回double 会返回6.0
#endif } //传参型lisp的定义:选择集
//复制到命令栏运行: (Test_ssget (ssget))
[LispFunction("Test_ssget")] //注意: 这里不是command!
public static object Test_ssget(ResultBuffer args)
{
//var dt = new List<object>();
var ds = new List<object>();
if (args != null)
{
foreach (TypedValue rb in args)//{((5007,(((-2181752),Crossing,0,)((-2181760),Crossing,0,))))}
{
try
{
//dt.Add(rb.TypeCode);
ds.Add(rb.Value);
}
catch
{ }
}
} var tl = new List<TypedValue>();
foreach (var item in ds)
{
tl.Add(new TypedValue((int)EnumBufCode.SelectionSet, item));
}
var rbrtn = new ResultBuffer(tl.ToArray());
return rbrtn;
} //传参型lisp的定义:点对
//复制到命令栏运行: (Test_dotPair 0 100)
[LispFunction("Test_dotPair")] //注意: 这里不是command!
public static object Test_dotPair(ResultBuffer args)
{
var ds = new List<object>();
if (args != null)
{
foreach (TypedValue rb in args)//{((5007,(((-2181752),Crossing,0,)((-2181760),Crossing,0,))))}
{
try
{
ds.Add(rb.Value);
}
catch
{ }
}
} var ls = new List<TypedValue>(); ResultBuffer dotPair = null;
if (ds.Count == )
{
ls.Add(new TypedValue((int)EnumBufCode.ListBegin, -)); ls.Add(new TypedValue((int)EnumBufCode.Int16, ds[]));
if (short.TryParse(ds[].ToString(), out short num))
{
ls.Add(new TypedValue((int)EnumBufCode.Int16, num));
ls.Add(new TypedValue((int)EnumBufCode.DottedPair, -));
dotPair = new ResultBuffer(ls.ToArray());
}
}
return dotPair; //返回点对表
}

在c#读取和赋值lisp变量的值 ,测试命令: Test_setLisp

#if !HC2020
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Application = Autodesk.AutoCAD.ApplicationServices.Application;
#else
using GrxCAD.DatabaseServices;
using GrxCAD.EditorInput;
using GrxCAD.Geometry;
using GrxCAD.ApplicationServices;
using GrxCAD.Runtime;
using GrxCAD.Colors;
using GrxCAD.GraphicsInterface;
using Viewport = GrxCAD.DatabaseServices.Viewport;
using Application = GrxCAD.ApplicationServices.Application;
#endif using System.Runtime.InteropServices;
using System; namespace JoinBox.CommandLisp
{
// 操作lisp赋值
// https://blog.csdn.net/qq_21489689/article/details/80630817
// 我验证了2008和2019,32位 DllImport("accore.dll" 好像不对,没有环境验证 public static class LStructure
{
//LSP变量的写入-64位
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("accore.dll", EntryPoint = "acedPutSym", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
extern static private int AcedPutSym64(string args, IntPtr result); #if AC2008
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("acad.exe", EntryPoint = "acedPutSym", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
extern static private int AcedPutSym32(string args, IntPtr result);
#else
//没有环境验证
//LSP变量的写入-32位
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("accore.dll", EntryPoint = "_acedPutSym", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
extern static private int AcedPutSym32(string args, IntPtr result);
#endif /// <summary>
/// 设置Lisp变量值
/// </summary>
/// <param name="name">变量名</param>
/// <param name="rb">变量值</param>
static int SetLispSym(string name, ResultBuffer rb)
{
int ret = ;
//判断系统是32位还是64位
switch (Marshal.SizeOf(typeof(IntPtr)))
{
case :
{
ret = AcedPutSym32(name, rb.UnmanagedObject);
}
break;
case :
{
ret = AcedPutSym64(name, rb.UnmanagedObject);
}
break;
}
return ret;
} //LSP变量的读取-64位
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("accore.dll", EntryPoint = "acedGetSym", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
extern static private int AcedGetSym64(string args, out IntPtr result); #if AC2008
//LSP变量的读取-32位
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("acad.exe", EntryPoint = "acedGetSym", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
extern static private int AcedGetSym32(string args, out IntPtr result);
#else
//没有环境验证
//LSP变量的读取-32位
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("accore.dll", EntryPoint = "_acedGetSym", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
extern static private int AcedGetSym32(string args, out IntPtr result);
#endif /// <summary>
/// 获取Lisp变量值
/// </summary>
/// <param name="name">变量名</param>
/// <returns>变量值,如果失败则为空</returns>
static ResultBuffer GetLispSym(string name)
{
IntPtr ip;
//判断系统是32位还是64位
switch (Marshal.SizeOf(typeof(IntPtr)))
{
case :
{
int status = AcedGetSym32(name, out ip);
if (status == (int)EnumBufCode.OK && ip != IntPtr.Zero)
{
return ResultBuffer.Create(ip, true);
}
}
break;
case :
{
int status = AcedGetSym64(name, out ip);
if (status == (int)EnumBufCode.OK && ip != IntPtr.Zero)
{
return ResultBuffer.Create(ip, true);
}
}
break;
}
return null;
} /// <summary>
/// lisp变量赋值
/// </summary>
/// <param name="varName">变量名</param>
/// <param name="varValue">变量值</param>
/// <param name="cEnumRes">变量值类型,原子,字符串等等</param>
public static void SetLspVar(EnumBufCode cEnumRes, string varName, object varValue = null)
{
using (var rb = new ResultBuffer())
{
rb.Add(new TypedValue((int)cEnumRes, varValue));
SetLispSym(varName, rb);
}
} /// <summary>
/// 读取LSP变量
/// </summary>
/// <param name="varName">变量名</param>
/// <returns></returns>
public static object GetLspVar(string varName)
{
object varValue = null;
ResultBuffer rb = GetLispSym(varName);
if (rb != null)
{
foreach (var val in rb)
{
varValue = val.Value;
}
}
return varValue;
} [CommandMethod("Test_setLisp")]
public static void Test_setLisp()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
string varName = "a";
object v;
// 赋值例子
// (setq a "35432")
SetLspVar(EnumBufCode.Text, varName, ""); //返回 "3543252351515"
v = GetLspVar(varName);
ed.Princ(v); // (setq a 35432)
SetLspVar(EnumBufCode.Double, varName, ""); //返回 3543252351515
v = GetLspVar(varName);
ed.Princ(v); // (setq a T)
SetLspVar(EnumBufCode.T_atom, varName, true); //返回 T
SetLspVar(EnumBufCode.T_atom, varName, false); //返回 T
v = GetLspVar(varName);
ed.Princ(v); // (setq a nil)
SetLspVar(EnumBufCode.Nil, varName); //返回 nil
v = GetLspVar(varName);
ed.Princ(v);
} static void Princ(this Editor ed, object var)
{
string varString = "";
if (var == null)
{
varString = "nil";
}
else
{
string type = var.GetType().Name;
switch (type)
{
case "String":
{
varString = var.ToString();
varString = "\"" + varString + "\"";
}
break;
case "Double":
{
varString = var.ToString();
}
break;
case "Boolean":
{
varString = "T"; //返回布尔值都是为true的,不返回才是nil
}
break;
}
}
ed.WriteMessage("\n" + varString);
}
}
}

再来是通过接口发送lisp,这个可以避免用明文方式发送到命令栏,而且它在自动执行函数上面也是同步发送的,很有趣哟: testLisp

#if AC2008 || AC2012
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("acad.exe", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "?acedEvaluateLisp@@YAHPB_WAAPAUresbuf@@@Z")]
private static extern int AcedEvaluateLisp(string lispLine, out IntPtr result); [DllImport("acad.exe", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedInvoke")]
private static extern int AcedInvoke(IntPtr args, out IntPtr result);
#else
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("accore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl,
EntryPoint = "?acedEvaluateLisp@@YAHPEB_WAEAPEAUresbuf@@@Z")]
private static extern int AcedEvaluateLisp(string lispLine, out IntPtr result); [DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedInvoke")]
private static extern int AcedInvoke(IntPtr args, out IntPtr result);
#endif /// <summary>
/// 定义lisp
/// </summary>
/// <param name="arg">lisp语句</param>
/// <returns>缓冲结果,返回值</returns>
public static ResultBuffer RunLisp(string arg)
{
AcedEvaluateLisp(arg, out IntPtr rb);
if (rb != IntPtr.Zero)
{
try
{
var rbb = DisposableWrapper.Create(typeof(ResultBuffer), rb, true) as ResultBuffer;
return rbb;
}
catch
{
return null;
}
}
return null;
} /// <summary>
/// c#发送lisp,这个同步方式可以在自动运行函数上跑,也是同步的
/// </summary>
/// <returns></returns>
[CommandMethod("testLisp")]
public void Cmdtest()
{
string Strlisp = "(setq a 10)";
var res = RunLisp(Strlisp); //有lisp的返回值
}

最后是提供一些发送命令的函数,这里有些备注,他们可以异步发送lisp,有些会导致自动执行时候发送lisp出错,但是却是异步发送的必需品.

    public partial class SendToCad
{
#if AC2006 || AC2007 || AC2008 || AC2009 || AC2010 || AC2011 || AC2012
/// <summary>
/// 发送命令
/// </summary>
/// <param name="strExpr"></param>
/// <returns></returns>
[DllImport("acad.exe", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ads_queueexpr")]
private static extern int Ads_queueexpr(string strExpr);//非同步,这个在08/12发送lisp不会出错,但是发送bo命令出错了.. /// <summary>
/// 发送命令,设置CommandFlags.Session可以同步,
/// 发送lisp也可以,但是非同步,在自动执行函数上面会非同步
/// </summary>
/// <param name="str"></param>
public static void SendLisp(string str)
{
try
{
Ads_queueexpr(str + "\n");
}
catch (Exception ee)
{
//自执行发送lisp都是在最后的(异步执行)
var ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage(Environment.NewLine + "发送命令失败,导致加载失败!");
ed.WriteMessage(Environment.NewLine + "" + ee.Message + Environment.NewLine);
}
} /// <summary>
/// 发送命令
/// </summary>
/// <param name="strExpr"></param>
/// <returns></returns>
[DllImport("acad.exe", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl, EntryPoint = "?acedPostCommand@@YAHPB_W@Z")]
private static extern int AcedPostCommand(string strExpr);
#else
/// <summary>
/// 发送命令
/// </summary>
/// <param name="str">发送lisp加载命令</param>
/// <returns></returns>
public static void SendLisp(string str)
{
Document dc = Application.DocumentManager.MdiActiveDocument;
string commands = str + "\n";
try
{
dc.SendStringToExecute(commands, false, false, false);//08所有都flase会有问题,出现报错
}
catch (System.Exception ee)
{
//自执行发送lisp都是在最后的(异步执行)
var ed = dc.Editor;
ed.WriteMessage(ee.Message);
ed.WriteMessage(Environment.NewLine + "发送命令失败,导致加载失败!");
ed.WriteMessage(Environment.NewLine + ee.Message);
}
}
#endif
/// <summary>
/// 发送命令
/// </summary>
/// <param name="str">命令</param>
/// <returns></returns>
public static bool SendCommand(string str) //非同步,这里加载lisp第二个文档有问题...
{
object ActiveDocument = Com.App.GetType().InvokeMember("ActiveDocument", BindingFlags.GetProperty, null, Com.App, null);
object[] commandArray = { str + "\n" };
ActiveDocument.GetType().InvokeMember("SendCommand", BindingFlags.InvokeMethod, null, ActiveDocument, commandArray);
return true;
}
}

最后的最后是一个发送esc的操作,我也不知道为什么要放这里,可能他存在的价值不高...

        //http://www.tiancao.net/blogview.asp?logID=1871&cateID=3&tdsourcetag=s_pcqq_aiomsg
/*
我想从我的非模态对话框的按钮中启动一些命令。我已经发现,对于SendStringToExecute,我应该使用‘\x03’字符而不是^C。
我唯一的问题是,在这种情况下,如果没有运行命令,那么我将在命令窗口,如果单击菜单项时没有运行命令,则菜单的^C^C不会导致* Cancel*出现。
我怎样才能达到同样的目的呢?
解:
你可以查帐CMDNAMES系统变量,根据当前运行的命令数量,可以在命令字符串的开头添加许多转义字符。
这里有一个样本这表明:
*/
[CommandMethod("sendEsc")]
public void SendEsc()
{
//c#非模态窗体发命令
string esc = "";
string cmds = CadSystem.Getvar("CMDNAMES");
if (cmds.Length > )
{
int cmdNum = cmds.Split(new char[] { '\'' }).Length;
for (int i = ; i < cmdNum; i++)
esc += '\x03';
}
Document doc = Application.DocumentManager.MdiActiveDocument;
doc.SendStringToExecute(esc + "_.LINE ", true, false, true);
//设置cad窗口的焦点激活绘图区
//acApp.MainWindow.Focus();
}

最最后,写一下com接口的新旧版本写法:

    public static class Com
{
#if AC2006 || AC2007 || AC2008 || AC2009 || AC2010 || AC2011 || AC2012
public static AcadDocument Adm { get; } = Application.DocumentManager.MdiActiveDocument.AcadDocument as AcadDocument;
#else
public static AcadDocument Adm { get; } = Application.DocumentManager.MdiActiveDocument.GetAcadDocument() as AcadDocument;
#endif #if !HC2020
public static AcadApplication App { get; } = Application.AcadApplication as AcadApplication;
#else
public static GcadApplication App { get; } = Application.AcadApplication as GcadApplication;
#endif
}

cad.net 定义lisp的更多相关文章

  1. Lisp使用Lambda语法

    lamdba 其实就是一个匿名函数. 定义Lisp的lambda语法非常的简单,如下: (lambda ([parameter]) [experssion]) 调用lambda的语法有三种方法,如下: ...

  2. Lisp之根源

    原文:http://www.paulgraham.com/rootsoflisp.html 约翰麦卡锡于1960年发表了一篇非凡的论文,他在这篇论文中对编程的贡献有如 欧几里德对几何的贡献.1 他向我 ...

  3. Lisp之根源 --- 保罗格雷厄姆

    Lisp之根源 --- 保罗格雷厄姆 来源 http://daiyuwen.freeshell.org/gb/rol/roots_of_lisp.html 约翰麦卡锡于1960年发表了一篇非凡的论文, ...

  4. ssget使用方法

    语法: (ssget [sel-method] [pt1 [pt2]] [pt-list] [filter-list]) ssget 的参数均为可选参数,需要注意的是可选参数之间的组合条件.以下语法表 ...

  5. [转载]ssget 用法详解 by yxp

    总结得很好的ssget用法.....如此好文,必须转载. 原文地址: http://blog.csdn.net/yxp_xa/article/details/72229202 ssget 用法详解 b ...

  6. 超文本传输协议-HTTP/1.1

    超文本传输协议-HTTP/1.1(修订版) ---译者:孙超进本协议不限流传发布.版权声明Copyright (C) The Internet Society (1999). All Rights R ...

  7. 借助CAD在Altium Designer中定义不规则PCB外形

    借助绘图软件CAD在Altium Designer中定义不规则PCB外形. 工具/原料 CAD2007 Altium Designer2015 方法/步骤 借助CAD绘制的不规则外形,保存成DXF格式 ...

  8. cad二次开发中各种头的定义

    Database db=HostApplicationServices.WrokingDatabase; Editor ed=Autodesk.AutoCAD.ApplicationService.A ...

  9. cad 画图面板的尺寸大小定义

    输入limits 输入左下角点为 0,0 输入右上角点为大家需要的数  这里为100,50 输入zoom 输入a 就可以实现自定义编辑 注意事项 如果在你已经操作过的图纸上可能会失效 重新建一张图纸就 ...

随机推荐

  1. UNION ALL \UNION

    (一)UNION ALL \UNION 的用法和区别   UNION UNION    ALL 用途   用于使用SELECT语句组合两个或多个表的结果集. 用于使用SELECT语句组合两个或多个表的 ...

  2. C#实现高性能高并发Socket服务器

    1.高并发服务器实现一 本文转载 转载地址 2.高并发服务器实现二 本文转载 转载内容在于学习C#实现的高并发服务器 以下个人观点 1 需要注意SocketAsyncEventArgs的使用 2 做到 ...

  3. oracle中如何生成awr【性能调优】报告

    1.进入数据库 sqlplus / as sysdba 2.查看用户 show parameter db_name 3.开始压测后执行 exec DBMS_WORKLOAD_REPOSITORY.CR ...

  4. 自动居中标题和内容;aspxgridview允许定义两个关键字为主键的格式

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  5. vue 的 Class 与 Style 绑定

    操作元素的 class 列表和内联样式是数据绑定的一个常见需求.因为它们都是属性,所以我们可以用 v-bind 处理它们:只需要通过表达式计算出字符串结果即可.不过,字符串拼接麻烦且易错.因此,在将 ...

  6. shell公共函数functions

    checkpid:检查是否已存在pid,如果有一个存在,返回0(通过查看/proc目录) daemon:启动服务 killproc:杀死某个进程 pidfileofproc:寻找某个进程的pid pi ...

  7. App过大

    最近开发中遇到一个报错信息 如下 Error:Cannot fit requested classes in a single dex file.Try supplying a main-dex li ...

  8. 找出所有文件最小可resize尺寸

    --找出所有文件最小可resize尺寸 SELECT a.file_id, CEIL( ( NVL( hwm,1 ) * blksize ) / 1024 / 1024 ) smallest_M, C ...

  9. Mycat高可用解决方案一(mysql安装)

    Mycat高可用解决方案一(mysql安装) Mycat关键特性 关键特性 支持SQL92标准 支持MySQL.Oracle.DB2.SQL Server.PostgreSQL等DB的常见SQL语法 ...

  10. docker在linux上的安装

    docker安装在liunx环境上,我电脑用的是ubuntu系统的,需要下载对应系统的docker,我下载的是社区版,对着官方的命令敲就好了, 地址是:https://docs.docker.com/ ...