cad.net 定义lisp
通用枚举值...
// 本枚举融合 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的更多相关文章
- Lisp使用Lambda语法
lamdba 其实就是一个匿名函数. 定义Lisp的lambda语法非常的简单,如下: (lambda ([parameter]) [experssion]) 调用lambda的语法有三种方法,如下: ...
- Lisp之根源
原文:http://www.paulgraham.com/rootsoflisp.html 约翰麦卡锡于1960年发表了一篇非凡的论文,他在这篇论文中对编程的贡献有如 欧几里德对几何的贡献.1 他向我 ...
- Lisp之根源 --- 保罗格雷厄姆
Lisp之根源 --- 保罗格雷厄姆 来源 http://daiyuwen.freeshell.org/gb/rol/roots_of_lisp.html 约翰麦卡锡于1960年发表了一篇非凡的论文, ...
- ssget使用方法
语法: (ssget [sel-method] [pt1 [pt2]] [pt-list] [filter-list]) ssget 的参数均为可选参数,需要注意的是可选参数之间的组合条件.以下语法表 ...
- [转载]ssget 用法详解 by yxp
总结得很好的ssget用法.....如此好文,必须转载. 原文地址: http://blog.csdn.net/yxp_xa/article/details/72229202 ssget 用法详解 b ...
- 超文本传输协议-HTTP/1.1
超文本传输协议-HTTP/1.1(修订版) ---译者:孙超进本协议不限流传发布.版权声明Copyright (C) The Internet Society (1999). All Rights R ...
- 借助CAD在Altium Designer中定义不规则PCB外形
借助绘图软件CAD在Altium Designer中定义不规则PCB外形. 工具/原料 CAD2007 Altium Designer2015 方法/步骤 借助CAD绘制的不规则外形,保存成DXF格式 ...
- cad二次开发中各种头的定义
Database db=HostApplicationServices.WrokingDatabase; Editor ed=Autodesk.AutoCAD.ApplicationService.A ...
- cad 画图面板的尺寸大小定义
输入limits 输入左下角点为 0,0 输入右上角点为大家需要的数 这里为100,50 输入zoom 输入a 就可以实现自定义编辑 注意事项 如果在你已经操作过的图纸上可能会失效 重新建一张图纸就 ...
随机推荐
- C#利用newtonsoft.json读取.so配置文件内容
今天花 了点时间来使用 C#读取json文件 ,文件后缀为 .so文件 ,也是基于文件流的形式 获取 对象 ,然后解析; 之所以尝试 使用 json读取 ,是因为其配置文件的格式 更为友好 和方便,直 ...
- php操作cassandra
php操作 https://www.cnblogs.com/fakis/archive/2010/04/16/1976653.html 这篇文章还没试过.暂时留着有时间再实验
- ORACLE ORION测试IO性能
https://www.oracle.com/technetwork/cn/topics/index-088165-zhs.html 下载地址 Orion是Oracle提供的IO性能测试工具,运行该工 ...
- ML-逻辑回归推导
认识 是一个经典的二元(y=0 或 y=1) 分类算法, 不是回归 输入特征还是线性回归, 输出是 [0,1] 的一个概率值, 其判别函数的形式为: \(P(y=1|x) = \frac {1}{1+ ...
- redis不能保存bean对象
可用JSON转为json格式 // 2.3 将用户信息存储在redis中 String memberToJson = JSON.toJSON(member).toString(); 需要maven坐标 ...
- Mysql高性能优化规范
数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意 ...
- mysql语法之union
UNION的语法结构: SELECT ... UNION [ ALL | DISTINCT ] SELECT .... [ UNION [ ALL | DISTINCT ] SELECT ..... ...
- 微信公众号 $GLOBALS['HTTP_RAW_POST_DATA']数据问题
公司的微信公众号最近出现问题,所有的功能都不能用,一开始以为是微信公众号验证的问题,经过排查才发现是$GLOBALS['HTTP_RAW_POST_DATA']这里的问题,微信公众号会把用户的一些操作 ...
- Alipay支付宝调用错误:Call to undefined function openssl_sign()
打开php.ini,找到这一行 ;extension=php_openssl.dll,将前面的“;”去掉: 重启服务器.
- ZABBIX监控TCP连接状态
一.获取监控数据 # /bin/netstat -an|awk '/^tcp/{++S[$NF]}END{for(a in S) print a,S[a]}' LISTEN ESTABLISHED T ...