cad.net 选择集问题
保留关键字
无论是cad.arx还是cad.net的开发人员都需要注意交互的保留关键字.
N S W E
是东南西北四个方位,s是南方270度,在设置关键字的时候必须避开这四个关键字.
这个设置在早期的R14也有:
在使用选择集的时候,设置关键字不可以用a,它会是all的首字母,更多的参考一下飞诗的lisp选择集屏蔽关键字.
选择集预选
动图演示
本次测试
测试环境: Acad2008
这个bug是这样的,在预选状态时候执行命令,会导致该命令去重设一次选择集,
而没有预选则十分正常
错误代码
[CommandMethod("tta", CommandFlags.Modal | CommandFlags.UsePickSet | CommandFlags.Redraw)]
public static void tta()
{
Editor ed = Acap.DocumentManager.MdiActiveDocument.Editor;
var psr = ed.GetSelection();
if (psr.Status != PromptStatus.OK)
return;
//重构了一个选择集,为什么预选的时候,要等到再次点鼠标才能成功显示呢?
ed.SetImpliedSelection(psr.Value.GetObjectIds());
//ed.Regen();
}
如果最后加一句:ed.Regen();
是可以成功的,但是,这不应该啊.
因为其中的奥妙在于,预选的获取不应该利用 ed.GetSelection(pso, filter);
而是应该利用 ed.SelectImplied();
正确代码
[CommandMethod("tta", CommandFlags.Modal | CommandFlags.UsePickSet | CommandFlags.Redraw)]
public static void tta()
{
Editor ed = Acap.DocumentManager.MdiActiveDocument.Editor;
var psr = ed.SelectImplied();//预选
if (psr.Status != PromptStatus.OK) //数量0也是不ok
psr = ed.GetSelection(pso, filter);//手选
if (psr.Status != PromptStatus.OK)
return;
ed.SetImpliedSelection(psr.Value.GetObjectIds()); //重构了一个选择集
}
原因为什么会这样呢?
因为手选的 ed.GetSelection()
直接读取了选择集缓冲区,没有很好的处理预选状态..
导致了引起了选择的内部错误,是函数单一职责的封装问题.
相关阅读
com选择集的例子
/// <summary>
/// 输出WMF<br/>
/// </summary>
/// <param name="editor">命令行对象</param>
/// <param name="saveFile">保存文件</param>
/// <param name="ids">选择集的对象,为null时候手选</param>
/// <exception cref="ArgumentNullException"></exception>
public static void ExportWMF(this Editor editor, string saveFile, ObjectId[]? ids = null)
{
if (string.IsNullOrEmpty(saveFile))
throw new ArgumentNullException(nameof(saveFile));
if (File.Exists(saveFile))
throw new FileFormatException("文件重复:" + saveFile);
var dm = Acap.DocumentManager;
if (dm.Count == 0)
return;
// 剔除后缀
int dot = saveFile.LastIndexOf('.');
if (dot != -1)
{
// 因为文件名可以有.所以后缀点必须是最后\的后面
int s = saveFile.LastIndexOf('\\');
if (s < dot)
saveFile = saveFile.Substring(0, dot);
}
// ActiveSelectionSet:
// 第一次执行会触发选择,
// 再次重复命令执行的时候,它会无法再选择
// 因此此处选择一次,此时必然有当前选择集,它就直接获取当前选择集
if (ids == null || ids.Length == 0)
{
var psr = editor.SelectImplied();// 预选
if (psr.Status != PromptStatus.OK)
psr = editor.GetSelection();// 手选
if (psr.Status != PromptStatus.OK)
return;
}
#if zcad
var com = Acap.ZcadApplication;
#else
var com = Acap.AcadApplication;
#endif
var doc = com.GetProperty("ActiveDocument");
var wmfSet = doc.GetProperty("ActiveSelectionSet");
doc.Invoke("Export", saveFile, "wmf", wmfSet); // JPGOUT,PNGOUT
wmfSet.Invoke("Delete");
}
关键字回调
关键字回调时候会重新进入选择集,此时需要再空格才能退出.
如何立即退出?
arx在关键字上面发送cad命令\003,
net可以引发异常退出,自己构造一个异常.
net发送命令它会经过命令模式,进行重入,不好,还是触发异常好
(完)